mirror of
https://gitee.com/beijing_hongye_huicheng/lilishop-uniapp.git
synced 2026-09-21 20:32:01 +08:00
refactor: 重构多个组件以支持 Vue 3 语法和功能
- 将多个组件转换为 `<script setup>` 语法,提升可读性和性能 - 优化状态管理和事件处理逻辑,简化代码结构 - 更新样式和布局以适应新组件结构 - 添加新功能和修复已知问题,提升用户体验
This commit is contained in:
@@ -1,302 +1,262 @@
|
||||
<template>
|
||||
<view class="coupon-center">
|
||||
<div class="swiper-box">
|
||||
<div class="swiper-item">
|
||||
<div class="scroll-v" enableBackToTop="true" scroll-y>
|
||||
<u-empty mode="coupon" style='margin-top: 20%;' text="没有优惠券了" v-if="whetherEmpty"></u-empty>
|
||||
<view v-else class="coupon-item" v-for="(item, index) in couponList" :key="index">
|
||||
<view class="left">
|
||||
<view class="wave-line">
|
||||
<view class="wave" v-for="(item, index) in 12" :key="index"></view>
|
||||
</view>
|
||||
<view class="message">
|
||||
<view>
|
||||
<!--判断当前优惠券类型 couponType PRICE || DISCOUNT -->
|
||||
<span v-if="item.couponType == 'DISCOUNT'">{{ item.couponDiscount }}折</span>
|
||||
<span v-else>{{ item.price }}元</span>
|
||||
</view>
|
||||
<view>满{{unitPrice(item.consumeThreshold) }}元可用</view>
|
||||
</view>
|
||||
<view class="circle circle-top"></view>
|
||||
<view class="circle circle-bottom"></view>
|
||||
</view>
|
||||
<view class="right">
|
||||
<view>
|
||||
<!-- 根据scopeType 判断是否是 平台、品类或店铺 -->
|
||||
<view class="coupon-title wes-3" v-if="item.scopeType">
|
||||
<span v-if="item.scopeType == 'ALL' && item.storeId == '0'">全平台</span>
|
||||
<span v-if="item.scopeType == 'PORTION_GOODS_CATEGORY'">仅限品类</span>
|
||||
<view v-else>{{ item.storeName == 'platform' ? '全平台' :item.storeName+'店铺' }}使用
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="item.endTime">有效期至:{{ item.endTime.split(" ")[0] }}</view>
|
||||
</view>
|
||||
<view class="receive" @click="receive(item)">
|
||||
<text>点击</text><br />
|
||||
<text>领取</text>
|
||||
</view>
|
||||
<view class="bg-quan"> 券 </view>
|
||||
</view>
|
||||
<view class="coupon-list">
|
||||
<u-empty mode="coupon" style='margin-top: 20%;' text="没有优惠券了" v-if="whetherEmpty"></u-empty>
|
||||
<view v-else class="coupon-card" v-for="(item, index) in couponList" :key="index">
|
||||
<view class="coupon-card-left">
|
||||
<text class="coupon-price-symbol">¥</text>
|
||||
<text class="coupon-price-value">{{ item.couponType == 'DISCOUNT' ? item.couponDiscount + '折' : unitPrice(item.price) }}</text>
|
||||
</view>
|
||||
<view class="coupon-divider"></view>
|
||||
<view class="coupon-card-right">
|
||||
<view class="coupon-info">
|
||||
<text class="coupon-card-name">{{ item.storeName == 'platform' ? '全平台' : item.storeName + '店铺' }}使用</text>
|
||||
<text class="coupon-card-desc">满{{unitPrice(item.consumeThreshold) }}元可用</text>
|
||||
<text class="coupon-card-time" v-if="item.endTime">有效期至:{{ item.endTime.split(" ")[0] }}</text>
|
||||
</view>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<view class="coupon-claim-btn" @click="receive(item)">
|
||||
领取
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
receiveCoupons
|
||||
} from "@/api/members.js";
|
||||
import {
|
||||
getAllCoupons
|
||||
} from "@/api/promotions.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
loadStatus: "more", //下拉状态
|
||||
whetherEmpty: false, //是否为空
|
||||
couponList: [], // 优惠券列表
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
storeId: "", //店铺 id,
|
||||
couponData: ""
|
||||
};
|
||||
},
|
||||
onLoad(option) {
|
||||
this.storeId = option.storeId;
|
||||
this.getCoupon();
|
||||
},
|
||||
onReachBottom() {
|
||||
<script setup lang="ts">
|
||||
import { receiveCoupons } from '@/api/members.js'
|
||||
import { getAllCoupons } from '@/api/promotions.js'
|
||||
import { useStore } from '@/store'
|
||||
import { unitPrice } from '@/utils/filters.js'
|
||||
import {
|
||||
onLoad,
|
||||
onNavigationBarButtonTap,
|
||||
onPullDownRefresh,
|
||||
onReachBottom,
|
||||
} from '@dcloudio/uni-app'
|
||||
import { getCurrentInstance, ref } from 'vue'
|
||||
|
||||
this.loadMore()
|
||||
},
|
||||
onPullDownRefresh() {
|
||||
//下拉刷新
|
||||
this.params.pageNumber = 1;
|
||||
this.couponList = [];
|
||||
this.getCoupon();
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 获取当前优惠券
|
||||
*/
|
||||
getCoupon() {
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
let submitData = {
|
||||
...this.params
|
||||
};
|
||||
// 判断当前是否有店铺
|
||||
this.storeId ? (submitData = {
|
||||
...this.params,
|
||||
storeId: this.storeId
|
||||
}) : "",
|
||||
getAllCoupons(submitData)
|
||||
.then((res) => {
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
uni.stopPullDownRefresh();
|
||||
if (res.data.code == 200) {
|
||||
// 如果请求成功,展示数据并进行展示
|
||||
this.couponData = res.data.result
|
||||
if (this.couponData.total == 0) {
|
||||
// 当本次请求数据为空展示空信息
|
||||
this.whetherEmpty = true;
|
||||
} else {
|
||||
this.couponList.push(...this.couponData.records);
|
||||
this.loadStatus = "noMore";
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 领取优惠券
|
||||
*/
|
||||
receive(val) {
|
||||
this.$u.throttle(()=>{
|
||||
this.fetchCoupon(val)
|
||||
}, 1500)
|
||||
|
||||
},
|
||||
const store = useStore()
|
||||
const { proxy } = getCurrentInstance()!
|
||||
|
||||
fetchCoupon(val){
|
||||
receiveCoupons(val.id).then((res) => {
|
||||
if (res.data.code == 200) {
|
||||
uni.showToast({
|
||||
title: "领取成功",
|
||||
icon: "none",
|
||||
});
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.data.message,
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
const loadStatus = ref('more')
|
||||
const whetherEmpty = ref(false)
|
||||
const couponList = ref<any[]>([])
|
||||
const params = ref({
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
})
|
||||
const storeId = ref('')
|
||||
const couponData = ref<any>(null)
|
||||
|
||||
/**
|
||||
* 加载更多
|
||||
*/
|
||||
loadMore() {
|
||||
if (this.couponData.total > this.params.pageNumber * this.params.pageSize) {
|
||||
this.params.pageNumber++;
|
||||
this.getCoupon();
|
||||
}
|
||||
},
|
||||
},
|
||||
onNavigationBarButtonTap(e) {
|
||||
uni.navigateTo({
|
||||
url: "/pages/cart/coupon/couponIntro",
|
||||
});
|
||||
},
|
||||
};
|
||||
onLoad((option) => {
|
||||
storeId.value = option.storeId || ''
|
||||
getCoupon()
|
||||
})
|
||||
|
||||
onReachBottom(() => {
|
||||
loadMore()
|
||||
})
|
||||
|
||||
onPullDownRefresh(() => {
|
||||
params.value.pageNumber = 1
|
||||
couponList.value = []
|
||||
getCoupon()
|
||||
})
|
||||
|
||||
onNavigationBarButtonTap(() => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/cart/coupon/couponIntro',
|
||||
})
|
||||
})
|
||||
|
||||
function hideLoadingIfNeeded() {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
}
|
||||
|
||||
function getCoupon() {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
const submitData = storeId.value
|
||||
? { ...params.value, storeId: storeId.value }
|
||||
: { ...params.value }
|
||||
|
||||
getAllCoupons(submitData)
|
||||
.then((res) => {
|
||||
hideLoadingIfNeeded()
|
||||
uni.stopPullDownRefresh()
|
||||
if (res.data.code == 200) {
|
||||
couponData.value = res.data.result
|
||||
if (couponData.value.total == 0) {
|
||||
whetherEmpty.value = true
|
||||
} else {
|
||||
couponList.value.push(...couponData.value.records)
|
||||
loadStatus.value = 'noMore'
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
hideLoadingIfNeeded()
|
||||
})
|
||||
}
|
||||
|
||||
function receive(val: any) {
|
||||
proxy.$u.throttle(() => {
|
||||
fetchCoupon(val)
|
||||
}, 1500)
|
||||
}
|
||||
|
||||
function fetchCoupon(val: any) {
|
||||
receiveCoupons(val.id).then((res) => {
|
||||
if (res.data.code == 200) {
|
||||
uni.showToast({ title: '领取成功', icon: 'none' })
|
||||
} else {
|
||||
uni.showToast({ title: res.data.message, icon: 'none' })
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function loadMore() {
|
||||
if (couponData.value?.total > params.value.pageNumber * params.value.pageSize) {
|
||||
params.value.pageNumber++
|
||||
getCoupon()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
page {
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.coupon-center {
|
||||
height: 100%;
|
||||
.coupon-center {
|
||||
min-height: 100vh;
|
||||
background: #f7f8fa;
|
||||
}
|
||||
|
||||
.swiper-box {
|
||||
.coupon-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 220rpx;
|
||||
margin: 20rpx;
|
||||
.coupon-list {
|
||||
padding: 24rpx;
|
||||
}
|
||||
|
||||
.left {
|
||||
height: 100%;
|
||||
width: 260rpx;
|
||||
background-color: $light-color;
|
||||
position: relative;
|
||||
.coupon-card {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
background: #fff;
|
||||
border-radius: 24rpx;
|
||||
margin-bottom: 24rpx;
|
||||
position: relative;
|
||||
box-shadow: none;
|
||||
border: 1rpx solid #f0f1f5;
|
||||
overflow: hidden;
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
|
||||
.message {
|
||||
color: $font-color-white;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
margin-top: 40rpx;
|
||||
&:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
view:nth-child(1) {
|
||||
font-weight: bold;
|
||||
font-size: 60rpx;
|
||||
}
|
||||
&::before,
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
background: #f7f8fa;
|
||||
border-radius: 50%;
|
||||
left: 204rpx;
|
||||
z-index: 2;
|
||||
box-shadow: inset 0 0 0 1rpx #eceef2;
|
||||
}
|
||||
|
||||
view:nth-child(2) {
|
||||
font-size: $font-sm;
|
||||
}
|
||||
}
|
||||
&::before {
|
||||
top: -16rpx;
|
||||
}
|
||||
|
||||
.wave-line {
|
||||
height: 220rpx;
|
||||
width: 8rpx;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background-color: $light-color;
|
||||
overflow: hidden;
|
||||
&::after {
|
||||
bottom: -16rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.wave {
|
||||
width: 8rpx;
|
||||
height: 16rpx;
|
||||
background-color: #ffffff;
|
||||
border-radius: 0 16rpx 16rpx 0;
|
||||
margin-top: 4rpx;
|
||||
}
|
||||
}
|
||||
.coupon-card-left {
|
||||
width: 220rpx;
|
||||
min-height: 180rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
color: #ff3b30;
|
||||
position: relative;
|
||||
background: linear-gradient(135deg, #fff5f5 0%, #ffecec 100%);
|
||||
}
|
||||
|
||||
.circle {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
background-color: $bg-color;
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
z-index: 111;
|
||||
}
|
||||
.coupon-price-symbol {
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
margin-right: 4rpx;
|
||||
}
|
||||
|
||||
.circle-top {
|
||||
top: -20rpx;
|
||||
right: -20rpx;
|
||||
}
|
||||
.coupon-price-value {
|
||||
font-size: 56rpx;
|
||||
font-weight: 900;
|
||||
line-height: 1;
|
||||
letter-spacing: -1rpx;
|
||||
}
|
||||
|
||||
.circle-bottom {
|
||||
bottom: -20rpx;
|
||||
right: -20rpx;
|
||||
}
|
||||
}
|
||||
.coupon-divider {
|
||||
position: absolute;
|
||||
left: 220rpx;
|
||||
top: 24rpx;
|
||||
bottom: 24rpx;
|
||||
width: 0;
|
||||
border-left: 2rpx dashed #eceef2;
|
||||
}
|
||||
|
||||
.right {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 450rpx;
|
||||
font-size: $font-sm;
|
||||
height: 100%;
|
||||
background-color: #ffffff;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
.coupon-card-right {
|
||||
flex: 1;
|
||||
padding: 32rpx 32rpx 32rpx 40rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 20rpx;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
>view:nth-child(1) {
|
||||
color: #666666;
|
||||
margin-left: 20rpx;
|
||||
display: flex;
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
.coupon-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12rpx;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
>view:nth-child(1) {
|
||||
color: #ff6262;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
}
|
||||
.coupon-card-name {
|
||||
font-size: 30rpx;
|
||||
color: #111;
|
||||
font-weight: 700;
|
||||
line-height: 1.3;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.receive {
|
||||
color: #ffffff;
|
||||
background-color: $main-color;
|
||||
border-radius: 50%;
|
||||
width: 86rpx;
|
||||
height: 86rpx;
|
||||
text-align: center;
|
||||
margin-right: 30rpx;
|
||||
vertical-align: middle;
|
||||
padding-top: 8rpx;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
.coupon-card-desc {
|
||||
font-size: 24rpx;
|
||||
color: #8a8f99;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.bg-quan {
|
||||
width: 244rpx;
|
||||
height: 244rpx;
|
||||
border: 6rpx solid $main-color;
|
||||
border-radius: 50%;
|
||||
opacity: 0.1;
|
||||
color: $main-color;
|
||||
text-align: center;
|
||||
padding-top: 30rpx;
|
||||
font-size: 130rpx;
|
||||
position: absolute;
|
||||
right: -54rpx;
|
||||
bottom: -60rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.coupon-card-time {
|
||||
font-size: 22rpx;
|
||||
color: #b0b3bf;
|
||||
}
|
||||
|
||||
.coupon-title {
|
||||
width: 260rpx;
|
||||
.coupon-claim-btn {
|
||||
flex-shrink: 0;
|
||||
padding: 16rpx 32rpx;
|
||||
border-radius: 40rpx;
|
||||
font-size: 26rpx;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #ff6b35, #ff4b2b);
|
||||
box-shadow: 0 8rpx 16rpx rgba(255, 75, 43, 0.25);
|
||||
|
||||
}
|
||||
&:active {
|
||||
opacity: 0.9;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -2,52 +2,46 @@
|
||||
<view class="content">
|
||||
<view class="body">
|
||||
<view class="top-view">
|
||||
<view class="title">{{coupon.title}}</view>
|
||||
<view class="price" v-if="coupon.couponType =='PRICE'"><text>¥</text>{{unitPrice(coupon.price)}}</view>
|
||||
<view class="price" v-if="coupon.couponType =='DISCOUNT'">{{coupon.discount}}折</view>
|
||||
<view class="text">满{{coupon.consumeThreshold}}元可用</view>
|
||||
<view class="bg-quan">
|
||||
券
|
||||
</view>
|
||||
<view class="jiao-1" :class="{'used-color':coupon.used_status!=0}">
|
||||
<text class="text-1">{{coupon.used_status == 0?'新到':coupon.used_status_text}}</text>
|
||||
<view class="title">{{ coupon.title }}</view>
|
||||
<view class="price" v-if="coupon.couponType == 'PRICE'"><text>¥</text>{{ unitPrice(coupon.price) }}</view>
|
||||
<view class="price" v-if="coupon.couponType == 'DISCOUNT'">{{ coupon.discount }}折</view>
|
||||
<view class="text">满{{ coupon.consumeThreshold }}元可用</view>
|
||||
<view class="bg-quan">券</view>
|
||||
<view class="jiao-1" :class="{ 'used-color': coupon.used_status != 0 }">
|
||||
<text class="text-1">{{ coupon.used_status == 0 ? '新到' : coupon.used_status_text }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="bottom-view">
|
||||
<view class="text">• 使用范围:{{
|
||||
coupon.scopeType == 'ALL' && coupon.storeId == '0'
|
||||
? "全平台"
|
||||
: coupon.scopeType == "PORTION_GOODS"
|
||||
? "部分商品"
|
||||
: coupon.scopeType == "PORTION_GOODS_CATEGORY"
|
||||
? "部分分类商品"
|
||||
: coupon.storeName == 'platform' ? '全平台' :coupon.storeName+''
|
||||
}}使用</view>
|
||||
<view class="text">• 有效期至:{{coupon.endTime}}</view>
|
||||
|
||||
coupon.scopeType == 'ALL' && coupon.storeId == '0'
|
||||
? '全平台'
|
||||
: coupon.scopeType == 'PORTION_GOODS'
|
||||
? '部分商品'
|
||||
: coupon.scopeType == 'PORTION_GOODS_CATEGORY'
|
||||
? '部分分类商品'
|
||||
: coupon.storeName == 'platform' ? '全平台' : coupon.storeName + ''
|
||||
}}使用</view>
|
||||
<view class="text">• 有效期至:{{ coupon.endTime }}</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
coupon: {}, //优惠券数据
|
||||
};
|
||||
},
|
||||
onLoad(option) {
|
||||
this.coupon = JSON.parse(decodeURIComponent(option.item));
|
||||
},
|
||||
};
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { unitPrice } from '@/utils/filters.js'
|
||||
|
||||
const coupon = ref<Record<string, any>>({})
|
||||
|
||||
onLoad((option) => {
|
||||
coupon.value = JSON.parse(decodeURIComponent(option.item))
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
page,
|
||||
.content {
|
||||
// background: $main-color;
|
||||
height: 100%;
|
||||
}
|
||||
.body {
|
||||
|
||||
@@ -59,81 +59,59 @@
|
||||
</view>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { useCoupon } from "@/api/trade.js";
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, watch, onMounted } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { useCoupon } from '@/api/trade.js'
|
||||
import { unitPrice } from '@/utils/filters.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
lightColor: this.$lightColor,
|
||||
current: 0,
|
||||
list: [
|
||||
{
|
||||
name: "可用优惠券",
|
||||
},
|
||||
{
|
||||
name: "不可用优惠券",
|
||||
},
|
||||
],
|
||||
couponsList: [], //优惠券集合
|
||||
params: {
|
||||
//传参
|
||||
memberCouponStatus: "NEW", //优惠券状态
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
scopeId: "", //商品skuid
|
||||
storeId: "", //店铺id
|
||||
totalPrice: "", //价格
|
||||
},
|
||||
routerVal: "", //上级传参
|
||||
};
|
||||
},
|
||||
onLoad(options) {
|
||||
this.routerVal = options;
|
||||
},
|
||||
watch: {
|
||||
current(val) {
|
||||
console.log(this.$store.state.cantUseCoupons);
|
||||
val == 0
|
||||
? (this.couponsList = this.$store.state.canUseCoupons)
|
||||
: (this.couponsList = this.$store.state.cantUseCoupons);
|
||||
},
|
||||
},
|
||||
const store = useStore()
|
||||
|
||||
mounted() {
|
||||
this.init();
|
||||
console.log(this.routerVal);
|
||||
},
|
||||
const lightColor = computed(() => store.getters.lightColor)
|
||||
const current = ref(0)
|
||||
const list = [
|
||||
{ name: '可用优惠券' },
|
||||
{ name: '不可用优惠券' },
|
||||
]
|
||||
const couponsList = ref<any[]>([])
|
||||
const routerVal = ref<Record<string, any>>({})
|
||||
|
||||
methods: {
|
||||
/**
|
||||
* 从vuex中拿取优惠券信息
|
||||
*/
|
||||
init() {
|
||||
this.couponsList = this.$store.state.canUseCoupons;
|
||||
},
|
||||
/**
|
||||
* 领取优惠券
|
||||
*/
|
||||
clickWay(coupon) {
|
||||
useCoupon({
|
||||
memberCouponId: coupon.id,
|
||||
used: !this.routerVal.selectedCoupon.includes(coupon.id),
|
||||
way: this.routerVal.way,
|
||||
}).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.navigateBack();
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.data.message,
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
onLoad((options) => {
|
||||
routerVal.value = options || {}
|
||||
})
|
||||
|
||||
watch(current, (val) => {
|
||||
couponsList.value = val == 0
|
||||
? store.state.canUseCoupons
|
||||
: store.state.cantUseCoupons
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
|
||||
function init() {
|
||||
couponsList.value = store.state.canUseCoupons
|
||||
}
|
||||
|
||||
function clickWay(coupon: any) {
|
||||
useCoupon({
|
||||
memberCouponId: coupon.id,
|
||||
used: !routerVal.value.selectedCoupon.includes(coupon.id),
|
||||
way: routerVal.value.way,
|
||||
}).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.navigateBack()
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.data.message,
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.desc {
|
||||
|
||||
@@ -1,471 +1,393 @@
|
||||
<template>
|
||||
<view class="b-content">
|
||||
<view class="navbar">
|
||||
<!-- 循环出头部tab栏 -->
|
||||
<view
|
||||
v-for="(item, index) in navList"
|
||||
:key="index"
|
||||
class="nav-item"
|
||||
@click="handleTabClick(index)"
|
||||
><text :class="{ current: tabCurrentIndex === index }">{{
|
||||
item.text
|
||||
}}</text></view
|
||||
>
|
||||
</view>
|
||||
<swiper
|
||||
:current="tabCurrentIndex"
|
||||
class="swiper-box"
|
||||
duration="300"
|
||||
@change="changeTab"
|
||||
>
|
||||
<swiper-item
|
||||
class="tab-content"
|
||||
v-for="(navItem, navIndex) in navList"
|
||||
:key="navIndex"
|
||||
>
|
||||
<scroll-view
|
||||
class="list-scroll-content"
|
||||
scroll-y
|
||||
@scrolltolower="loadData"
|
||||
>
|
||||
<!-- 空白页 -->
|
||||
<u-empty
|
||||
mode="coupon"
|
||||
text="暂无优惠券了"
|
||||
v-if="navItem.whetherEmpty"
|
||||
></u-empty>
|
||||
|
||||
<!-- 数据 -->
|
||||
<view
|
||||
class="coupon-item"
|
||||
:class="{ 'coupon-used': navIndex != 0 }"
|
||||
v-for="(coupon, index) in navItem.dataList"
|
||||
:key="index"
|
||||
>
|
||||
<view class="left">
|
||||
<view class="wave-line">
|
||||
<view
|
||||
class="wave"
|
||||
v-for="(item, index) in 12"
|
||||
:key="index"
|
||||
></view>
|
||||
</view>
|
||||
<view class="message">
|
||||
<view class="price" v-if="coupon.couponType == 'DISCOUNT'"
|
||||
>{{ coupon.discount }}折</view
|
||||
>
|
||||
<view class="price" v-else>{{ coupon.price }}元</view>
|
||||
<view class="sub-price"
|
||||
>满{{unitPrice(coupon.consumeThreshold) }}可用</view
|
||||
>
|
||||
</view>
|
||||
<view class="circle circle-top"></view>
|
||||
<view class="circle circle-bottom"></view>
|
||||
</view>
|
||||
<view class="right" v-if="coupon">
|
||||
<view class="content">
|
||||
<view class="title-1">{{ coupon.title }}</view>
|
||||
<view class="title-2"
|
||||
>使用范围:{{
|
||||
coupon.scopeType == "ALL" && coupon.storeId == "0"
|
||||
? "全平台"
|
||||
: coupon.scopeType == "PORTION_GOODS"
|
||||
? "部分商品"
|
||||
: coupon.scopeType == "PORTION_GOODS_CATEGORY"
|
||||
? "部分分类商品"
|
||||
: coupon.storeName == "platform"
|
||||
? "全平台"
|
||||
: coupon.storeName + ""
|
||||
}}使用</view
|
||||
>
|
||||
<view v-if="coupon.endTime">{{ coupon.endTime }}</view>
|
||||
<view @click="couponDetail(coupon)"
|
||||
>详细说明
|
||||
<u-icon
|
||||
style="float: right; margin-top: 10rpx"
|
||||
name="arrow-right"
|
||||
></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
<view class="jiao-1" v-if="navIndex == 0">
|
||||
<text class="text-1">新到</text>
|
||||
<text class="text-2" v-if="coupon.used_status == 1"
|
||||
>将过期</text
|
||||
>
|
||||
</view>
|
||||
<image
|
||||
class="no-icon"
|
||||
v-if="navIndex == 1"
|
||||
src="@/static/img/used.png"
|
||||
></image>
|
||||
<image
|
||||
class="no-icon"
|
||||
v-if="navIndex == 2"
|
||||
src="@/static/img/overdue.png"
|
||||
></image>
|
||||
<view
|
||||
class="receive"
|
||||
v-if="navIndex == 0"
|
||||
@click="useItNow(coupon)"
|
||||
>
|
||||
<text>立即</text><br />
|
||||
<text>使用</text>
|
||||
</view>
|
||||
<view class="bg-quan"> 券 </view>
|
||||
</view>
|
||||
</view>
|
||||
<uni-load-more :status="navItem.loadStatus"></uni-load-more>
|
||||
</scroll-view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getMemberCoupons } from "@/api/members.js";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
tabCurrentIndex: 0, //tab栏下标默认为0 未使用
|
||||
navList: [
|
||||
//每个tab存储的信息
|
||||
{
|
||||
text: "未使用",
|
||||
loadStatus: "more",
|
||||
dataList: [],
|
||||
params: {
|
||||
memberCouponStatus: "NEW",
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
status: 1,
|
||||
},
|
||||
whetherEmpty: false,
|
||||
},
|
||||
{
|
||||
text: "已使用",
|
||||
loadStatus: "more",
|
||||
dataList: [],
|
||||
params: {
|
||||
memberCouponStatus: "USED",
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
status: 2,
|
||||
},
|
||||
whetherEmpty: false,
|
||||
},
|
||||
{
|
||||
text: "已过期",
|
||||
loadStatus: "more",
|
||||
dataList: [],
|
||||
params: {
|
||||
memberCouponStatus: "EXPIRE",
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
status: 3,
|
||||
},
|
||||
whetherEmpty: false,
|
||||
},
|
||||
],
|
||||
couponList: [], //优惠券列表
|
||||
};
|
||||
},
|
||||
|
||||
onShow() {
|
||||
this.navList[this.tabCurrentIndex].params.pageNumber = 1;
|
||||
this.navList[this.tabCurrentIndex].dataList = [];
|
||||
this.getData();
|
||||
},
|
||||
|
||||
watch: {
|
||||
/**
|
||||
* 监听切换顶部tab栏实现刷新数据
|
||||
*/
|
||||
tabCurrentIndex(val) {
|
||||
if (this.navList[val].dataList.length == 0) this.getData();
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 顶部tab点击
|
||||
*/
|
||||
handleTabClick(index) {
|
||||
this.tabCurrentIndex = index;
|
||||
},
|
||||
|
||||
/**
|
||||
* 读取优惠券
|
||||
*/
|
||||
getData() {
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
let index = this.tabCurrentIndex;
|
||||
getMemberCoupons(this.navList[index].params).then((res) => {
|
||||
uni.stopPullDownRefresh();
|
||||
if (res.data.success) {
|
||||
let data = res.data.result.records;
|
||||
if (data.length == 0) {
|
||||
if (res.data.pageNumber == 1) {
|
||||
this.navList[index].whetherEmpty = true;
|
||||
} else {
|
||||
this.navList[index].loadStatus = "noMore";
|
||||
}
|
||||
} else if (data.length < 10) {
|
||||
this.navList[index].loadStatus = "noMore";
|
||||
this.navList[index].dataList.push(...data);
|
||||
} else {
|
||||
this.navList[index].dataList.push(...data);
|
||||
}
|
||||
}
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 切换tab
|
||||
*/
|
||||
changeTab(e) {
|
||||
this.tabCurrentIndex = e.target.current;
|
||||
},
|
||||
|
||||
/**
|
||||
* 加载数据
|
||||
*/
|
||||
loadData() {
|
||||
let index = this.tabCurrentIndex;
|
||||
if (this.navList[index].loadStatus != "noMore") {
|
||||
this.navList[index].params.pageNumber++;
|
||||
this.getData();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 立即使用优惠券
|
||||
*/
|
||||
useItNow(item) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/navigation/search/searchPage?promotionsId=${item.couponId}&promotionType=COUPON`,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 优惠券详情
|
||||
*/
|
||||
couponDetail(item) {
|
||||
uni.navigateTo({
|
||||
url:
|
||||
"/pages/cart/coupon/couponDetail?item=" +
|
||||
encodeURIComponent(JSON.stringify(item)),
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
page {
|
||||
height: 100%;
|
||||
}
|
||||
$item-color: #fff;
|
||||
|
||||
.b-content {
|
||||
background: $page-color-base;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.swiper-box {
|
||||
height: calc(100vh - 40px);
|
||||
}
|
||||
|
||||
.list-scroll-content {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
.coupon-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 220rpx;
|
||||
margin: 20rpx;
|
||||
|
||||
.left {
|
||||
height: 100%;
|
||||
width: 260rpx;
|
||||
background-color: $light-color;
|
||||
position: relative;
|
||||
|
||||
.message {
|
||||
color: $font-color-white;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
margin-top: 40rpx;
|
||||
|
||||
view:nth-child(1) {
|
||||
font-weight: bold;
|
||||
font-size: 60rpx;
|
||||
}
|
||||
|
||||
view:nth-child(2) {
|
||||
font-size: $font-sm;
|
||||
}
|
||||
}
|
||||
|
||||
.wave-line {
|
||||
height: 220rpx;
|
||||
width: 8rpx;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background-color: $light-color;
|
||||
overflow: hidden;
|
||||
|
||||
.wave {
|
||||
width: 8rpx;
|
||||
height: 16rpx;
|
||||
background-color: #ffffff;
|
||||
border-radius: 0 16rpx 16rpx 0;
|
||||
margin-top: 4rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.circle {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
background-color: $bg-color;
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
z-index: 111;
|
||||
}
|
||||
|
||||
.circle-top {
|
||||
top: -20rpx;
|
||||
right: -20rpx;
|
||||
}
|
||||
|
||||
.circle-bottom {
|
||||
bottom: -20rpx;
|
||||
right: -20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 450rpx;
|
||||
font-size: $font-sm;
|
||||
height: 100%;
|
||||
background-color: #ffffff;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
.content {
|
||||
color: #666666;
|
||||
margin-left: 20rpx;
|
||||
line-height: 2em;
|
||||
> view:nth-child(1) {
|
||||
color: #ff6262;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
|
||||
.title-1,
|
||||
.title-2,
|
||||
.title-3 {
|
||||
font-size: 25rpx;
|
||||
}
|
||||
}
|
||||
.receive {
|
||||
color: #ffffff;
|
||||
background-color: $main-color;
|
||||
border-radius: 50%;
|
||||
width: 86rpx;
|
||||
height: 86rpx;
|
||||
text-align: center;
|
||||
margin-right: 48rpx;
|
||||
vertical-align: middle;
|
||||
padding-top: 8rpx;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.jiao-1 {
|
||||
background-color: #ffc71c;
|
||||
width: 400rpx;
|
||||
transform: rotate(45deg);
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
color: #ffffff;
|
||||
right: -130rpx;
|
||||
top: 0;
|
||||
.text-1 {
|
||||
margin-left: 68rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
.text-2 {
|
||||
margin-left: 68rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
.no-icon {
|
||||
border-radius: 50%;
|
||||
width: 86rpx;
|
||||
height: 86rpx;
|
||||
margin-right: 48rpx;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
.bg-quan {
|
||||
width: 244rpx;
|
||||
height: 244rpx;
|
||||
border: 6rpx solid $main-color;
|
||||
border-radius: 50%;
|
||||
opacity: 0.1;
|
||||
color: $main-color;
|
||||
text-align: center;
|
||||
padding-top: 30rpx;
|
||||
font-size: 130rpx;
|
||||
position: absolute;
|
||||
right: -54rpx;
|
||||
bottom: -60rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.navbar {
|
||||
display: flex;
|
||||
height: 80rpx;
|
||||
padding: 0 5px;
|
||||
background: #fff;
|
||||
color: $light-color;
|
||||
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.06);
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
|
||||
.nav-item {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
font-size: 26rpx;
|
||||
color: $light-color;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
text {
|
||||
line-height: 80rpx;
|
||||
}
|
||||
.current {
|
||||
font-weight: bold;
|
||||
font-size: 28rpx;
|
||||
&:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
bottom: 10rpx;
|
||||
left: 108rpx;
|
||||
width: 30rpx;
|
||||
border-bottom: 2px solid $light-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<view class="b-content">
|
||||
<view class="coupon-tabs">
|
||||
<u-tabs
|
||||
:list="navList"
|
||||
keyName="text"
|
||||
:scrollable="false"
|
||||
:inactiveStyle="{ color: '#333' }"
|
||||
v-model:current="tabCurrentIndex"
|
||||
:lineColor="lightColor"
|
||||
:activeStyle="{ color: lightColor }"
|
||||
></u-tabs>
|
||||
</view>
|
||||
<swiper
|
||||
:current="tabCurrentIndex"
|
||||
class="swiper-box"
|
||||
duration="300"
|
||||
@change="changeTab"
|
||||
>
|
||||
<swiper-item
|
||||
class="tab-content"
|
||||
v-for="(navItem, navIndex) in navList"
|
||||
:key="navIndex"
|
||||
>
|
||||
<scroll-view
|
||||
class="list-scroll-content"
|
||||
scroll-y
|
||||
@scrolltolower="loadData"
|
||||
>
|
||||
<u-empty
|
||||
mode="coupon"
|
||||
text="暂无优惠券了"
|
||||
v-if="navItem.whetherEmpty"
|
||||
></u-empty>
|
||||
|
||||
<view
|
||||
class="coupon-card"
|
||||
:class="{ 'coupon-used': navIndex != 0, 'coupon-expired': navIndex == 2 }"
|
||||
v-for="(coupon, index) in navItem.dataList"
|
||||
:key="index"
|
||||
>
|
||||
<view class="coupon-card-left">
|
||||
<text class="coupon-price-symbol" v-if="coupon.couponType != 'DISCOUNT'">¥</text>
|
||||
<text class="coupon-price-value">{{ coupon.couponType == 'DISCOUNT' ? coupon.discount + '折' : unitPrice(coupon.price) }}</text>
|
||||
</view>
|
||||
<view class="coupon-divider"></view>
|
||||
<view class="coupon-card-right">
|
||||
<view class="coupon-info">
|
||||
<text class="coupon-card-name">{{ coupon.title }}</text>
|
||||
<text class="coupon-card-desc">使用范围:{{
|
||||
coupon.scopeType == "ALL" && coupon.storeId == "0"
|
||||
? "全平台"
|
||||
: coupon.scopeType == "PORTION_GOODS"
|
||||
? "部分商品"
|
||||
: coupon.scopeType == "PORTION_GOODS_CATEGORY"
|
||||
? "部分分类商品"
|
||||
: coupon.storeName == "platform"
|
||||
? "全平台"
|
||||
: coupon.storeName + ""
|
||||
}}使用</text>
|
||||
<text class="coupon-card-time" v-if="coupon.endTime">{{ coupon.endTime }}</text>
|
||||
</view>
|
||||
<view class="coupon-status-btn" v-if="navIndex == 0" @click="useItNow(coupon)">
|
||||
立即使用
|
||||
</view>
|
||||
<view class="coupon-status-btn disabled" v-else-if="navIndex == 1">
|
||||
已使用
|
||||
</view>
|
||||
<view class="coupon-status-btn disabled" v-else>
|
||||
已过期
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<uni-load-more :status="navItem.loadStatus"></uni-load-more>
|
||||
</scroll-view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { getMemberCoupons } from '@/api/members.js'
|
||||
import { useStore } from '@/store'
|
||||
import { unitPrice } from '@/utils/filters.js'
|
||||
import { onShow } from '@dcloudio/uni-app'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
|
||||
const store = useStore()
|
||||
|
||||
const lightColor = computed(() => store.getters.lightColor)
|
||||
const tabCurrentIndex = ref(0)
|
||||
const navList = ref([
|
||||
{
|
||||
text: '未使用',
|
||||
loadStatus: 'more',
|
||||
dataList: [] as any[],
|
||||
params: {
|
||||
memberCouponStatus: 'NEW',
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
status: 1,
|
||||
},
|
||||
whetherEmpty: false,
|
||||
},
|
||||
{
|
||||
text: '已使用',
|
||||
loadStatus: 'more',
|
||||
dataList: [] as any[],
|
||||
params: {
|
||||
memberCouponStatus: 'USED',
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
status: 2,
|
||||
},
|
||||
whetherEmpty: false,
|
||||
},
|
||||
{
|
||||
text: '已过期',
|
||||
loadStatus: 'more',
|
||||
dataList: [] as any[],
|
||||
params: {
|
||||
memberCouponStatus: 'EXPIRE',
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
status: 3,
|
||||
},
|
||||
whetherEmpty: false,
|
||||
},
|
||||
])
|
||||
|
||||
onShow(() => {
|
||||
navList.value[tabCurrentIndex.value].params.pageNumber = 1
|
||||
navList.value[tabCurrentIndex.value].dataList = []
|
||||
getData()
|
||||
})
|
||||
|
||||
watch(tabCurrentIndex, (val) => {
|
||||
if (navList.value[val].dataList.length == 0) getData()
|
||||
})
|
||||
|
||||
function hideLoadingIfNeeded() {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
}
|
||||
|
||||
function handleTabClick(index: number) {
|
||||
tabCurrentIndex.value = index
|
||||
}
|
||||
|
||||
function getData() {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
const index = tabCurrentIndex.value
|
||||
getMemberCoupons(navList.value[index].params).then((res) => {
|
||||
uni.stopPullDownRefresh()
|
||||
if (res.data.success) {
|
||||
const data = res.data.result.records
|
||||
if (data.length == 0) {
|
||||
if (res.data.pageNumber == 1) {
|
||||
navList.value[index].whetherEmpty = true
|
||||
} else {
|
||||
navList.value[index].loadStatus = 'noMore'
|
||||
}
|
||||
} else if (data.length < 10) {
|
||||
navList.value[index].loadStatus = 'noMore'
|
||||
navList.value[index].dataList.push(...data)
|
||||
} else {
|
||||
navList.value[index].dataList.push(...data)
|
||||
}
|
||||
}
|
||||
hideLoadingIfNeeded()
|
||||
})
|
||||
}
|
||||
|
||||
function changeTab(e: any) {
|
||||
tabCurrentIndex.value = e.detail.current
|
||||
}
|
||||
|
||||
function loadData() {
|
||||
const index = tabCurrentIndex.value
|
||||
if (navList.value[index].loadStatus != 'noMore') {
|
||||
navList.value[index].params.pageNumber++
|
||||
getData()
|
||||
}
|
||||
}
|
||||
|
||||
function useItNow(item: any) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/navigation/search/searchPage?promotionsId=${item.couponId}&promotionType=COUPON`,
|
||||
})
|
||||
}
|
||||
|
||||
function couponDetail(item: any) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/cart/coupon/couponDetail?item=' + encodeURIComponent(JSON.stringify(item)),
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.b-content {
|
||||
background: #f7f8fa;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.coupon-tabs {
|
||||
background: #fff;
|
||||
height: 88rpx;
|
||||
box-shadow: 0 1rpx 8rpx rgba(0, 0, 0, 0.04);
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
:deep(.u-tabs),
|
||||
:deep(.u-tabs__wrapper),
|
||||
:deep(.u-tabs__wrapper__scroll-view-wrapper),
|
||||
:deep(.u-tabs__wrapper__scroll-view),
|
||||
:deep(.u-tabs__wrapper__nav) {
|
||||
background: #fff;
|
||||
height: 88rpx;
|
||||
}
|
||||
|
||||
:deep(.u-tabs__wrapper__nav__item) {
|
||||
min-height: 88rpx;
|
||||
}
|
||||
|
||||
:deep(.u-tabs__wrapper__nav__item__text) {
|
||||
color: #333;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.swiper-box {
|
||||
height: calc(100vh - 88rpx - var(--status-bar-height));
|
||||
}
|
||||
|
||||
.list-scroll-content {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
padding: 24rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.coupon-card {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
background: #fff;
|
||||
border-radius: 24rpx;
|
||||
margin-bottom: 24rpx;
|
||||
position: relative;
|
||||
box-shadow: none;
|
||||
border: 1rpx solid #f0f1f5;
|
||||
overflow: hidden;
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
|
||||
&:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
&::before,
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
background: #f7f8fa;
|
||||
border-radius: 50%;
|
||||
left: 204rpx;
|
||||
z-index: 2;
|
||||
box-shadow: inset 0 0 0 1rpx #eceef2;
|
||||
}
|
||||
|
||||
&::before {
|
||||
top: -16rpx;
|
||||
}
|
||||
|
||||
&::after {
|
||||
bottom: -16rpx;
|
||||
}
|
||||
|
||||
&.coupon-used {
|
||||
.coupon-card-left {
|
||||
background: linear-gradient(135deg, #f5f5f5 0%, #eeeeee 100%);
|
||||
color: #999;
|
||||
}
|
||||
.coupon-status-btn {
|
||||
background: #ccc;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.coupon-expired {
|
||||
.coupon-card-left {
|
||||
background: linear-gradient(135deg, #f5f5f5 0%, #eeeeee 100%);
|
||||
color: #999;
|
||||
}
|
||||
.coupon-status-btn {
|
||||
background: #ccc;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.coupon-card-left {
|
||||
width: 220rpx;
|
||||
min-height: 180rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
color: #ff3b30;
|
||||
position: relative;
|
||||
background: linear-gradient(135deg, #fff5f5 0%, #ffecec 100%);
|
||||
}
|
||||
|
||||
.coupon-price-symbol {
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
margin-right: 4rpx;
|
||||
}
|
||||
|
||||
.coupon-price-value {
|
||||
font-size: 56rpx;
|
||||
font-weight: 900;
|
||||
line-height: 1;
|
||||
letter-spacing: -1rpx;
|
||||
}
|
||||
|
||||
.coupon-divider {
|
||||
position: absolute;
|
||||
left: 220rpx;
|
||||
top: 24rpx;
|
||||
bottom: 24rpx;
|
||||
width: 0;
|
||||
border-left: 2rpx dashed #eceef2;
|
||||
}
|
||||
|
||||
.coupon-card-right {
|
||||
flex: 1;
|
||||
padding: 32rpx 32rpx 32rpx 40rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 20rpx;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.coupon-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12rpx;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.coupon-card-name {
|
||||
font-size: 30rpx;
|
||||
color: #111;
|
||||
font-weight: 700;
|
||||
line-height: 1.3;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.coupon-card-desc {
|
||||
font-size: 24rpx;
|
||||
color: #8a8f99;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.coupon-card-time {
|
||||
font-size: 22rpx;
|
||||
color: #b0b3bf;
|
||||
}
|
||||
|
||||
.coupon-status-btn {
|
||||
flex-shrink: 0;
|
||||
padding: 16rpx 32rpx;
|
||||
border-radius: 40rpx;
|
||||
font-size: 26rpx;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #ff6b35, #ff4b2b);
|
||||
|
||||
&:active {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
background: #ccc;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
<template>
|
||||
<view class="error-page">
|
||||
<u-navbar title="支付失败" :border="false" :fixed="true" :placeholder="true" :auto-back="true"></u-navbar>
|
||||
<view class="error-content">
|
||||
<u-icon name="close-circle-fill" color="#f56c6c" size="120"></u-icon>
|
||||
<text class="error-title">支付失败</text>
|
||||
<text class="error-desc">{{ errorMessage || '支付过程中出现错误,请重试' }}</text>
|
||||
<view class="btn-group">
|
||||
<u-button type="primary" text="返回订单" @click="goBack"></u-button>
|
||||
<u-button type="warning" text="去支付" @click="rePay"></u-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
|
||||
const errorMessage = ref('')
|
||||
const orderSn = ref('')
|
||||
|
||||
onLoad((options: any) => {
|
||||
if (options) {
|
||||
errorMessage.value = options.message || ''
|
||||
orderSn.value = options.orderSn || ''
|
||||
}
|
||||
})
|
||||
|
||||
function goBack() {
|
||||
uni.navigateBack({
|
||||
fail: () => {
|
||||
uni.switchTab({ url: '/pages/tabbar/user/my' })
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function rePay() {
|
||||
if (orderSn.value) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/cart/payment/payOrder?orderSn=${orderSn.value}`
|
||||
})
|
||||
} else {
|
||||
goBack()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.error-page {
|
||||
min-height: 100vh;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.error-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 200rpx 40rpx;
|
||||
}
|
||||
|
||||
.error-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-top: 40rpx;
|
||||
}
|
||||
|
||||
.error-desc {
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
margin-top: 20rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.btn-group {
|
||||
display: flex;
|
||||
gap: 24rpx;
|
||||
margin-top: 60rpx;
|
||||
width: 100%;
|
||||
|
||||
:deep(.u-button) {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -66,410 +66,264 @@
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import * as API_Trade from "@/api/trade";
|
||||
import {payCallback} from '@/api/members'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
//路径传参
|
||||
routerVal: "",
|
||||
//收银台参数
|
||||
cashierParams: "",
|
||||
//支付方式集合
|
||||
payList: "",
|
||||
//支付sn
|
||||
sn: "",
|
||||
//订单类型
|
||||
orderType: "",
|
||||
//支付异常
|
||||
exception: {},
|
||||
//支付表单
|
||||
payForm: {},
|
||||
//支付类型 APP/WECHAT_MP/H5/NATIVE app/微信小程序/h5/二维码
|
||||
paymentType: "",
|
||||
// 支付客户端 APP/NATIVE/JSAPI/H5
|
||||
paymentClient: "",
|
||||
//余额
|
||||
walletValue: 0.0,
|
||||
// 支付倒计时(毫秒)
|
||||
autoCancelTime: 0,
|
||||
|
||||
};
|
||||
},
|
||||
onLoad(val) {
|
||||
this.routerVal = val;
|
||||
<script setup lang="ts">
|
||||
import { ref, getCurrentInstance, onMounted } from 'vue'
|
||||
import { onLoad, onBackPress } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import * as API_Trade from '@/api/trade'
|
||||
import { payCallback } from '@/api/members'
|
||||
import { unitPrice } from '@/utils/filters.js'
|
||||
|
||||
//初始化参数
|
||||
// #ifdef APP-PLUS
|
||||
this.paymentType = "APP";
|
||||
this.paymentClient = "APP";
|
||||
//#endif
|
||||
// #ifdef MP-WEIXIN
|
||||
this.paymentType = "WECHAT_MP";
|
||||
this.paymentClient = "MP";
|
||||
//#endif
|
||||
// #ifdef H5
|
||||
this.paymentType = "H5";
|
||||
//如果是微信浏览器,则使用公众号支付,否则使用h5,
|
||||
// 区别是:h5是通过浏览器外部调用微信app进行支付,而JSAPI则是 在微信浏览器内部,或者小程序 调用微信支付
|
||||
this.paymentClient = this.isWeiXin() ? "JSAPI" : "H5";
|
||||
//#endif
|
||||
const store = useStore()
|
||||
const { proxy } = getCurrentInstance()!
|
||||
|
||||
const routerVal = ref<Record<string, string>>({})
|
||||
const cashierParams = ref<Record<string, any>>({ price: 0 })
|
||||
const payList = ref<string[]>([])
|
||||
const sn = ref('')
|
||||
const orderType = ref('')
|
||||
const paymentType = ref('')
|
||||
const paymentClient = ref('')
|
||||
const walletValue = ref(0)
|
||||
const autoCancelTime = ref(0)
|
||||
|
||||
onLoad((val) => {
|
||||
routerVal.value = val || {}
|
||||
// #ifdef APP-PLUS
|
||||
paymentType.value = 'APP'
|
||||
paymentClient.value = 'APP'
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN
|
||||
paymentType.value = 'WECHAT_MP'
|
||||
paymentClient.value = 'MP'
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
paymentType.value = 'H5'
|
||||
paymentClient.value = isWeiXin() ? 'JSAPI' : 'H5'
|
||||
// #endif
|
||||
})
|
||||
|
||||
//
|
||||
},
|
||||
onBackPress(e) {
|
||||
if (e.from == "backbutton") {
|
||||
if(this.routerVal.recharge_sn){
|
||||
uni.switchTab({
|
||||
url: '/pages/tabbar/user/my'
|
||||
});
|
||||
}
|
||||
else{
|
||||
uni.navigateTo({
|
||||
url: "/pages/order/myOrder?status=0",
|
||||
});
|
||||
}
|
||||
return true; //阻止默认返回行为
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.cashierData();
|
||||
},
|
||||
methods: {
|
||||
onBackPress((e) => {
|
||||
if (e.from == 'backbutton') {
|
||||
if (routerVal.value.recharge_sn) {
|
||||
uni.switchTab({ url: '/pages/tabbar/user/my' })
|
||||
} else {
|
||||
uni.navigateTo({ url: '/pages/order/myOrder?status=0' })
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
/**
|
||||
* 支付成功后跳转
|
||||
*/
|
||||
callback(paymentMethod){
|
||||
uni.navigateTo({
|
||||
url: "/pages/cart/payment/success?paymentMethod=" +
|
||||
paymentMethod +
|
||||
"&payPrice=" +
|
||||
this.cashierParams.price+
|
||||
"&orderType="+this.orderType
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取收银详情
|
||||
*/
|
||||
cashierData() {
|
||||
let parms = {};
|
||||
onMounted(() => {
|
||||
cashierData()
|
||||
})
|
||||
|
||||
if (this.routerVal.recharge_sn) {
|
||||
// 判断当前是否是充值
|
||||
this.sn = this.routerVal.recharge_sn;
|
||||
this.orderType = "RECHARGE";
|
||||
|
||||
} else if (this.routerVal.trade_sn) {
|
||||
this.sn = this.routerVal.trade_sn;
|
||||
this.orderType = "TRADE";
|
||||
} else {
|
||||
this.sn = this.routerVal.order_sn;
|
||||
this.orderType = "ORDER";
|
||||
}
|
||||
parms.sn = this.sn;
|
||||
parms.orderType = this.orderType;
|
||||
parms.clientType = this.paymentType;
|
||||
function hideLoadingIfNeeded() {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
}
|
||||
|
||||
API_Trade.getCashierData(parms).then((res) => {
|
||||
|
||||
if(res.data.success){
|
||||
this.cashierParams = res.data.result;
|
||||
function callback(paymentMethod: string) {
|
||||
uni.navigateTo({
|
||||
url:
|
||||
'/pages/cart/payment/success?paymentMethod=' +
|
||||
paymentMethod +
|
||||
'&payPrice=' +
|
||||
cashierParams.value.price +
|
||||
'&orderType=' +
|
||||
orderType.value,
|
||||
})
|
||||
}
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
this.payList = res.data.result.support.filter((item) => {
|
||||
return item != "ALIPAY";
|
||||
});
|
||||
// #endif
|
||||
function cashierData() {
|
||||
const parms: Record<string, string> = {}
|
||||
|
||||
|
||||
if(this.routerVal.recharge_sn){
|
||||
this.payList = res.data.result.support.filter((item) => {
|
||||
return item != "WALLET";
|
||||
})
|
||||
}
|
||||
else{
|
||||
this.payList = res.data.result.support;
|
||||
}
|
||||
// #ifdef H5
|
||||
//判断是否微信浏览器
|
||||
var ua = window.navigator.userAgent.toLowerCase();
|
||||
if (ua.match(/MicroMessenger/i) == 'micromessenger') {
|
||||
|
||||
this.payList = res.data.result.support.filter((item) => {
|
||||
return item != "ALIPAY";
|
||||
});
|
||||
// 充值的话仅保留微信支付
|
||||
if(this.orderType == "RECHARGE"){
|
||||
this.payList = res.data.result.support.filter((item) => {
|
||||
return item == "WECHAT";
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
// #endif
|
||||
|
||||
|
||||
|
||||
if (routerVal.value.recharge_sn) {
|
||||
sn.value = routerVal.value.recharge_sn
|
||||
orderType.value = 'RECHARGE'
|
||||
} else if (routerVal.value.trade_sn) {
|
||||
sn.value = routerVal.value.trade_sn
|
||||
orderType.value = 'TRADE'
|
||||
} else {
|
||||
sn.value = routerVal.value.order_sn
|
||||
orderType.value = 'ORDER'
|
||||
}
|
||||
parms.sn = sn.value
|
||||
parms.orderType = orderType.value
|
||||
parms.clientType = paymentType.value
|
||||
|
||||
this.walletValue = res.data.result.walletValue;
|
||||
const cancelAt = Number(res.data.result.autoCancel);
|
||||
this.autoCancelTime = cancelAt > 0 ? Math.max(cancelAt - Date.now(), 0) : 0;
|
||||
}
|
||||
else if(res.data.code == 32000){
|
||||
setTimeout(()=>{
|
||||
uni.redirectTo({
|
||||
url: `/pages/order/myOrder?status=0`
|
||||
});
|
||||
},500)
|
||||
|
||||
}
|
||||
});
|
||||
},
|
||||
API_Trade.getCashierData(parms).then((res) => {
|
||||
if (res.data.success) {
|
||||
cashierParams.value = res.data.result
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
payList.value = res.data.result.support.filter((item: string) => item != 'ALIPAY')
|
||||
// #endif
|
||||
|
||||
awaitPay(payment){
|
||||
this.$u.throttle(()=>{
|
||||
this.pay(payment)
|
||||
}, 2000)
|
||||
},
|
||||
if (routerVal.value.recharge_sn) {
|
||||
payList.value = res.data.result.support.filter((item: string) => item != 'WALLET')
|
||||
} else {
|
||||
payList.value = res.data.result.support
|
||||
}
|
||||
|
||||
padTime(val) {
|
||||
return String(val ?? 0).padStart(2, '0');
|
||||
},
|
||||
// #ifdef H5
|
||||
const ua = window.navigator.userAgent.toLowerCase()
|
||||
if (ua.match(/MicroMessenger/i) == 'micromessenger') {
|
||||
payList.value = res.data.result.support.filter((item: string) => item != 'ALIPAY')
|
||||
if (orderType.value == 'RECHARGE') {
|
||||
payList.value = res.data.result.support.filter((item: string) => item == 'WECHAT')
|
||||
}
|
||||
}
|
||||
// #endif
|
||||
|
||||
onPayTimeout() {
|
||||
uni.showToast({
|
||||
title: '支付超时,请重新下单',
|
||||
icon: 'none',
|
||||
});
|
||||
setTimeout(() => {
|
||||
uni.redirectTo({
|
||||
url: '/pages/order/myOrder?status=0',
|
||||
});
|
||||
}, 1500);
|
||||
},
|
||||
walletValue.value = res.data.result.walletValue
|
||||
const cancelAt = Number(res.data.result.autoCancel)
|
||||
autoCancelTime.value = cancelAt > 0 ? Math.max(cancelAt - Date.now(), 0) : 0
|
||||
} else if (res.data.code == 32000) {
|
||||
setTimeout(() => {
|
||||
uni.redirectTo({ url: '/pages/order/myOrder?status=0' })
|
||||
}, 500)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//订单支付
|
||||
async pay(payment) {
|
||||
|
||||
// 支付编号
|
||||
const sn = this.sn;
|
||||
// 交易类型【交易号|订单号】
|
||||
const orderType = this.orderType;
|
||||
function awaitPay(payment: string) {
|
||||
proxy.$u.throttle(() => {
|
||||
pay(payment)
|
||||
}, 2000)
|
||||
}
|
||||
|
||||
const clientType = this.paymentType;
|
||||
let params = {
|
||||
sn,
|
||||
orderType,
|
||||
clientType,
|
||||
};
|
||||
function padTime(val: number) {
|
||||
return String(val ?? 0).padStart(2, '0')
|
||||
}
|
||||
|
||||
//支付方式 WECHAT/ALIPAY
|
||||
const paymentMethod = payment;
|
||||
// 客户端类型 APP/NATIVE/JSAPI/H5
|
||||
const paymentClient = this.paymentClient;
|
||||
|
||||
uni.showLoading({
|
||||
title: "正在唤起支付...",
|
||||
mask:true
|
||||
});
|
||||
|
||||
// #ifdef APP-PLUS
|
||||
//APP pay
|
||||
// 初始化支付签名
|
||||
await API_Trade.initiatePay(paymentMethod, paymentClient, params).then(
|
||||
(signXml) => {
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
//如果支付异常
|
||||
if (!signXml.data.success) {
|
||||
uni.showToast({
|
||||
title: signXml.data.message,
|
||||
duration: 2000
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
let payForm = signXml.data.result;
|
||||
|
||||
let paymentType = paymentMethod === "WECHAT" ? "wxpay" : "alipay";
|
||||
|
||||
if(paymentMethod === "WALLET"){
|
||||
uni.showToast({
|
||||
icon: "none",
|
||||
title: "支付成功!",
|
||||
});
|
||||
this.callback(paymentMethod)
|
||||
}
|
||||
else{
|
||||
uni.requestPayment({
|
||||
provider: paymentType,
|
||||
orderInfo: payForm || '',
|
||||
success: (e) => {
|
||||
uni.showToast({
|
||||
icon: "none",
|
||||
title: "支付成功!",
|
||||
});
|
||||
this.callback(paymentMethod)
|
||||
},
|
||||
fail: (e) => {
|
||||
console.log(this);
|
||||
this.exception = e;
|
||||
uni.showModal({
|
||||
content: "支付失败,如果您已支付,请勿反复支付",
|
||||
showCancel: false,
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
//APP pay
|
||||
// #endif
|
||||
function onPayTimeout() {
|
||||
uni.showToast({ title: '支付超时,请重新下单', icon: 'none' })
|
||||
setTimeout(() => {
|
||||
uni.redirectTo({ url: '/pages/order/myOrder?status=0' })
|
||||
}, 1500)
|
||||
}
|
||||
|
||||
//#ifdef H5
|
||||
//H5 pay
|
||||
await API_Trade.initiatePay(paymentMethod, paymentClient, params).then(
|
||||
(res) => {
|
||||
let response = res.data;
|
||||
//如果非支付宝支付才需要进行判定,因为支付宝h5支付是直接输出的,没有返回所谓的消息状态
|
||||
if(paymentMethod !== "ALIPAY"){
|
||||
//如果支付异常
|
||||
if (!response.success) {
|
||||
uni.showToast({
|
||||
title: response.message,
|
||||
duration: 2000,
|
||||
icon:"none"
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (paymentMethod === "ALIPAY") {
|
||||
document.write(response);
|
||||
} else if (paymentMethod === "WECHAT") {
|
||||
if (this.isWeiXin()) {
|
||||
//微信公众号支付
|
||||
WeixinJSBridge.invoke(
|
||||
"getBrandWCPayRequest",
|
||||
response.result,
|
||||
(res) => {
|
||||
if (res.err_msg == "get_brand_wcpay_request:ok") {
|
||||
// 使用以上方式判断前端返回,微信团队郑重提示:
|
||||
//res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
|
||||
uni.showToast({
|
||||
icon: "none",
|
||||
title: "支付成功!",
|
||||
});
|
||||
this.callback(paymentMethod)
|
||||
|
||||
} else {
|
||||
uni.showModal({
|
||||
content: "支付失败,如果您已支付,请勿反复支付",
|
||||
showCancel: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
} else {
|
||||
window.location.href = JSON.parse(response.result).h5_url;
|
||||
const searchParams = {
|
||||
...params,
|
||||
price:this.cashierParams,
|
||||
}
|
||||
const timer = setInterval(()=>{
|
||||
payCallback(searchParams).then(res=>{
|
||||
if(res.data.result){
|
||||
clearTimeout(timer);
|
||||
uni.navigateTo({
|
||||
url:"/pages/order/myOrder"
|
||||
})
|
||||
}
|
||||
})
|
||||
},3000)
|
||||
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
}
|
||||
} else if (paymentMethod === "WALLET") {
|
||||
uni.showToast({
|
||||
title: response.message,
|
||||
icon: "none",
|
||||
});
|
||||
if (response.success) {
|
||||
this.callback(paymentMethod)
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
//H5pay
|
||||
// #endif
|
||||
function goPayError(message = '支付失败,如果您已支付,请勿反复支付') {
|
||||
const query = [`orderSn=${encodeURIComponent(sn.value)}`, `message=${encodeURIComponent(message)}`]
|
||||
uni.navigateTo({ url: `/pages/cart/payment/error?${query.join('&')}` })
|
||||
}
|
||||
|
||||
//#ifdef MP-WEIXIN
|
||||
//微信小程序
|
||||
await API_Trade.initiatePay(paymentMethod, paymentClient, params).then(
|
||||
(res) => {
|
||||
let response = res.data.result;
|
||||
//如果支付异常
|
||||
if (!res.data.success) {
|
||||
uni.showModal({
|
||||
content: res.data.message,
|
||||
showCancel: false,
|
||||
})
|
||||
return;
|
||||
}
|
||||
if (paymentMethod === "WECHAT") {
|
||||
uni.requestPayment({
|
||||
provider: "wxpay",
|
||||
appid: response.appid,
|
||||
timeStamp: response.timeStamp,
|
||||
nonceStr: response.nonceStr,
|
||||
package: response.package,
|
||||
signType: response.signType,
|
||||
paySign: response.paySign,
|
||||
success: (e) => {
|
||||
console.log(e);
|
||||
uni.showToast({
|
||||
icon: "none",
|
||||
title: "支付成功!",
|
||||
});
|
||||
this.callback(paymentMethod)
|
||||
|
||||
},
|
||||
fail: (e) => {
|
||||
console.log(e);
|
||||
this.exception = e;
|
||||
uni.showModal({
|
||||
content: "支付失败,如果您已支付,请勿反复支付",
|
||||
showCancel: false,
|
||||
});
|
||||
},
|
||||
});
|
||||
} else {
|
||||
uni.showToast({
|
||||
icon: "none",
|
||||
title: "支付成功!",
|
||||
});
|
||||
this.callback(paymentMethod)
|
||||
|
||||
}
|
||||
}
|
||||
);
|
||||
// #endif
|
||||
},
|
||||
isWeiXin() {
|
||||
var ua = window.navigator.userAgent.toLowerCase();
|
||||
if (ua.match(/MicroMessenger/i) == "micromessenger") {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
async function pay(payment: string) {
|
||||
const params = {
|
||||
sn: sn.value,
|
||||
orderType: orderType.value,
|
||||
clientType: paymentType.value,
|
||||
}
|
||||
const paymentMethod = payment
|
||||
const client = paymentClient.value
|
||||
|
||||
uni.showLoading({ title: '正在唤起支付...', mask: true })
|
||||
|
||||
// #ifdef APP-PLUS
|
||||
await API_Trade.initiatePay(paymentMethod, client, params).then((signXml) => {
|
||||
hideLoadingIfNeeded()
|
||||
if (!signXml.data.success) {
|
||||
uni.showToast({ title: signXml.data.message, duration: 2000 })
|
||||
return
|
||||
}
|
||||
const payForm = signXml.data.result
|
||||
const provider = paymentMethod === 'WECHAT' ? 'wxpay' : 'alipay'
|
||||
if (paymentMethod === 'WALLET') {
|
||||
uni.showToast({ icon: 'none', title: '支付成功!' })
|
||||
callback(paymentMethod)
|
||||
} else {
|
||||
uni.requestPayment({
|
||||
provider,
|
||||
orderInfo: payForm || '',
|
||||
success: () => {
|
||||
uni.showToast({ icon: 'none', title: '支付成功!' })
|
||||
callback(paymentMethod)
|
||||
},
|
||||
fail: () => {
|
||||
goPayError()
|
||||
},
|
||||
})
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
|
||||
// #ifdef H5
|
||||
await API_Trade.initiatePay(paymentMethod, client, params).then((res) => {
|
||||
const response = res.data
|
||||
if (paymentMethod !== 'ALIPAY' && !response.success) {
|
||||
uni.showToast({ title: response.message, duration: 2000, icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (paymentMethod === 'ALIPAY') {
|
||||
document.write(response)
|
||||
} else if (paymentMethod === 'WECHAT') {
|
||||
if (isWeiXin()) {
|
||||
WeixinJSBridge.invoke('getBrandWCPayRequest', response.result, (payRes: any) => {
|
||||
if (payRes.err_msg == 'get_brand_wcpay_request:ok') {
|
||||
uni.showToast({ icon: 'none', title: '支付成功!' })
|
||||
callback(paymentMethod)
|
||||
} else {
|
||||
goPayError()
|
||||
}
|
||||
})
|
||||
hideLoadingIfNeeded()
|
||||
} else {
|
||||
window.location.href = JSON.parse(response.result).h5_url
|
||||
const searchParams = { ...params, price: cashierParams.value }
|
||||
const timer = setInterval(() => {
|
||||
payCallback(searchParams).then((cbRes) => {
|
||||
if (cbRes.data.result) {
|
||||
clearInterval(timer)
|
||||
uni.navigateTo({ url: '/pages/order/myOrder' })
|
||||
}
|
||||
})
|
||||
}, 3000)
|
||||
hideLoadingIfNeeded()
|
||||
}
|
||||
} else if (paymentMethod === 'WALLET') {
|
||||
uni.showToast({ title: response.message, icon: 'none' })
|
||||
if (response.success) callback(paymentMethod)
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
await API_Trade.initiatePay(paymentMethod, client, params).then((res) => {
|
||||
const response = res.data.result
|
||||
if (!res.data.success) {
|
||||
uni.showModal({ content: res.data.message, showCancel: false })
|
||||
return
|
||||
}
|
||||
if (paymentMethod === 'WECHAT') {
|
||||
uni.requestPayment({
|
||||
provider: 'wxpay',
|
||||
appid: response.appid,
|
||||
timeStamp: response.timeStamp,
|
||||
nonceStr: response.nonceStr,
|
||||
package: response.package,
|
||||
signType: response.signType,
|
||||
paySign: response.paySign,
|
||||
success: () => {
|
||||
uni.showToast({ icon: 'none', title: '支付成功!' })
|
||||
callback(paymentMethod)
|
||||
},
|
||||
fail: () => {
|
||||
goPayError()
|
||||
},
|
||||
})
|
||||
} else {
|
||||
uni.showToast({ icon: 'none', title: '支付成功!' })
|
||||
callback(paymentMethod)
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
|
||||
function isWeiXin() {
|
||||
const ua = window.navigator.userAgent.toLowerCase()
|
||||
return ua.match(/MicroMessenger/i) == 'micromessenger'
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.method_icon {
|
||||
|
||||
@@ -49,7 +49,13 @@
|
||||
|
||||
<!-- 倒计时 -->
|
||||
<div class="count-down" v-if="!isOver && master.toBeGroupedNum">
|
||||
<u-count-down bg-color="#ededed" :hide-zero-day="true" @end="isOver" :timestamp="timeStamp"></u-count-down>
|
||||
<u-count-down
|
||||
v-if="timeStamp > 0"
|
||||
bgColor="#ededed"
|
||||
:time="timeStamp * 1000"
|
||||
format="HH:mm:ss"
|
||||
@finish="onCountDownEnd"
|
||||
></u-count-down>
|
||||
</div>
|
||||
|
||||
<div class="user-list" v-if="data.pintuanMemberVOS">
|
||||
@@ -59,173 +65,184 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<popupGoods :addr="addr" ref="popupGoods" :buyMask="maskFlag" @closeBuy="closePopupBuy" :goodsDetail="goodsDetail" :goodsSpec="goodsSpec" v-if="goodsDetail.id " @handleClickSku="getGoodsDetail" />
|
||||
<shares @close="closeShare" :link="'/pages/cart/payment/shareOrderGoods?sn='+this.routers.sn+'&sku='+this.routers.sku+'&goodsId='+this.routers.goodsId" type="pintuan"
|
||||
:thumbnail="data.promotionGoods.thumbnail" :goodsName="data.promotionGoods.goodsName" v-if="shareFlag " />
|
||||
<popupGoods
|
||||
:addr="addr"
|
||||
ref="popupGoodsRef"
|
||||
:buyMask="maskFlag"
|
||||
@closeBuy="closePopupBuy"
|
||||
:goodsDetail="goodsDetail"
|
||||
:goodsSpec="goodsSpec"
|
||||
v-if="goodsDetail.id"
|
||||
@handleClickSku="getGoodsDetail"
|
||||
/>
|
||||
<shares
|
||||
@close="closeShare"
|
||||
:link="shareLink"
|
||||
type="pintuan"
|
||||
:thumbnail="data.promotionGoods.thumbnail"
|
||||
:goodsName="data.promotionGoods.goodsName"
|
||||
v-if="shareFlag"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getGoods } from "@/api/goods.js";
|
||||
import { getPinTuanShare } from "@/api/order";
|
||||
import shares from "@/components/m-share/index";
|
||||
import storage from "@/utils/storage.js";
|
||||
import popupGoods from "@/components/m-buy/goods"; //购物车商品的模块
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, watch, onMounted } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { getGoods } from '@/api/goods.js'
|
||||
import { getPinTuanShare } from '@/api/order'
|
||||
import shares from '@/components/m-share/index'
|
||||
import storage from '@/utils/storage.js'
|
||||
import popupGoods from '@/components/m-buy/goods'
|
||||
import { unitPrice } from '@/utils/filters.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
flag: false, //判断接口是否正常请求
|
||||
addr: {
|
||||
id: "",
|
||||
},
|
||||
maskFlag: false, //商品弹框
|
||||
timeStamp: 0,
|
||||
shareFlag: false,
|
||||
data: "",
|
||||
isMaster: true,
|
||||
selectedGoods: "", //选择的商品规格昵称
|
||||
routers: "", //传参数据
|
||||
goodsDetail: "", //商品详情
|
||||
goodsSpec: "",
|
||||
master: "", // 团长
|
||||
PromotionList: "", //优惠集合
|
||||
isGroup: false, //是否拼团
|
||||
isOver: false, //是否结束活动
|
||||
isBuy: false, //当前用户是是否购买
|
||||
};
|
||||
},
|
||||
components: {
|
||||
shares,
|
||||
popupGoods,
|
||||
},
|
||||
watch: {
|
||||
isGroup(val) {
|
||||
if (val) {
|
||||
let timer = setInterval(() => {
|
||||
this.$refs.popupGoods.buyType = "PINTUAN";
|
||||
clearInterval(timer);
|
||||
}, 100);
|
||||
} else {
|
||||
this.$refs.popupGoods.buyType = "";
|
||||
const store = useStore()
|
||||
|
||||
const popupGoodsRef = ref<any>(null)
|
||||
const flag = ref(false)
|
||||
const addr = ref({ id: '' })
|
||||
const maskFlag = ref(false)
|
||||
const timeStamp = ref(0)
|
||||
const shareFlag = ref(false)
|
||||
const data = ref<any>(null)
|
||||
const isMaster = ref(true)
|
||||
const selectedGoods = ref<any>(null)
|
||||
const routers = ref<Record<string, string>>({})
|
||||
const goodsDetail = ref<any>({})
|
||||
const goodsSpec = ref<any>(null)
|
||||
const master = ref<any>(null)
|
||||
const PromotionList = ref<any>(null)
|
||||
const isGroup = ref(false)
|
||||
const isOver = ref(false)
|
||||
const isBuy = ref(false)
|
||||
|
||||
const shareLink = computed(() => {
|
||||
const { sn, sku, goodsId } = routers.value
|
||||
return `/pages/cart/payment/shareOrderGoods?sn=${sn}&sku=${sku}&goodsId=${goodsId}`
|
||||
})
|
||||
|
||||
watch(isGroup, (val) => {
|
||||
if (val) {
|
||||
const timer = setInterval(() => {
|
||||
if (popupGoodsRef.value) {
|
||||
popupGoodsRef.value.buyType = 'PINTUAN'
|
||||
}
|
||||
},
|
||||
},
|
||||
onLoad(options) {
|
||||
this.routers = options;
|
||||
},
|
||||
mounted() {
|
||||
this.init(this.routers.sn, this.routers.sku);
|
||||
},
|
||||
methods: {
|
||||
closeShare() {
|
||||
this.shareFlag = false;
|
||||
},
|
||||
// 这里的话得先跳到商品详情才能购买商品
|
||||
toBuy() {
|
||||
this.maskFlag = true;
|
||||
this.$refs.popupGoods.parentOrder = {
|
||||
...this.master,
|
||||
orderSn: this.routers.sn,
|
||||
};
|
||||
this.$refs.popupGoods.isMask = true;
|
||||
this.$refs.popupGoods.isClose = true;
|
||||
this.$refs.popupGoods.buyType = "PINTUAN";
|
||||
},
|
||||
// 分享
|
||||
share() {
|
||||
this.shareFlag = true;
|
||||
},
|
||||
closePopupBuy(val) {
|
||||
this.maskFlag = false;
|
||||
},
|
||||
// 实例化本页面
|
||||
async init(sn, sku) {
|
||||
let res = await getPinTuanShare(sn, sku);
|
||||
if (res.data.success && res.data.result.promotionGoods) {
|
||||
this.flag = true;
|
||||
this.data = res.data.result;
|
||||
this.selectedGoods = res.data.result.promotionGoods;
|
||||
let endTime = Date.parse(
|
||||
res.data.result.promotionGoods.endTime.replace(/-/g, "/")
|
||||
);
|
||||
// 获取当前剩余的拼团商品时间
|
||||
let timeStamp = Date.parse(new Date(endTime)) / 1000;
|
||||
clearInterval(timer)
|
||||
}, 100)
|
||||
} else if (popupGoodsRef.value) {
|
||||
popupGoodsRef.value.buyType = ''
|
||||
}
|
||||
})
|
||||
|
||||
// 获取当前时间时间戳
|
||||
let dateTime = Date.parse(new Date()) / 1000;
|
||||
onLoad((options) => {
|
||||
routers.value = options || {}
|
||||
})
|
||||
|
||||
this.timeStamp = parseInt(timeStamp - dateTime);
|
||||
onMounted(() => {
|
||||
init(routers.value.sn, routers.value.sku)
|
||||
})
|
||||
|
||||
this.timeStamp <= 0 ? (this.isOver = true) : (this.isOver = false);
|
||||
function hideLoadingIfNeeded() {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
}
|
||||
|
||||
// 获取剩余拼团人数
|
||||
this.master =
|
||||
res.data.result.pintuanMemberVOS.length != 0 &&
|
||||
res.data.result.pintuanMemberVOS.filter((item) => {
|
||||
return item.orderSn == "";
|
||||
})[0];
|
||||
function closeShare() {
|
||||
shareFlag.value = false
|
||||
}
|
||||
|
||||
// 获取当前是否是拼团本人
|
||||
if (
|
||||
storage.getUserInfo(this.routers.sku, this.routers.goodsId).id ==
|
||||
this.master.memberId
|
||||
) {
|
||||
this.isMaster = true;
|
||||
} else {
|
||||
this.isMaster = false;
|
||||
// 获取商品详情
|
||||
this.getGoodsDetail({
|
||||
id: this.routers.sku,
|
||||
goodsId: this.routers.goodsId,
|
||||
});
|
||||
function onCountDownEnd() {
|
||||
isOver.value = true
|
||||
}
|
||||
|
||||
function toBuy() {
|
||||
maskFlag.value = true
|
||||
if (!popupGoodsRef.value) return
|
||||
popupGoodsRef.value.parentOrder = {
|
||||
...master.value,
|
||||
orderSn: routers.value.sn,
|
||||
}
|
||||
popupGoodsRef.value.isMask = true
|
||||
popupGoodsRef.value.isClose = true
|
||||
popupGoodsRef.value.buyType = 'PINTUAN'
|
||||
}
|
||||
|
||||
function share() {
|
||||
shareFlag.value = true
|
||||
}
|
||||
|
||||
function closePopupBuy() {
|
||||
maskFlag.value = false
|
||||
}
|
||||
|
||||
async function init(sn: string, sku: string) {
|
||||
const res = await getPinTuanShare(sn, sku)
|
||||
if (res.data.success && res.data.result.promotionGoods) {
|
||||
flag.value = true
|
||||
data.value = res.data.result
|
||||
selectedGoods.value = res.data.result.promotionGoods
|
||||
const endTime = Date.parse(
|
||||
res.data.result.promotionGoods.endTime.replace(/-/g, '/')
|
||||
)
|
||||
const endTimestamp = Date.parse(new Date(endTime) as any) / 1000
|
||||
const dateTime = Date.parse(new Date() as any) / 1000
|
||||
timeStamp.value = parseInt(String(endTimestamp - dateTime))
|
||||
isOver.value = timeStamp.value <= 0
|
||||
|
||||
master.value =
|
||||
res.data.result.pintuanMemberVOS.length != 0 &&
|
||||
res.data.result.pintuanMemberVOS.filter((item: any) => item.orderSn == '')[0]
|
||||
|
||||
if (
|
||||
storage.getUserInfo(routers.value.sku, routers.value.goodsId).id ==
|
||||
master.value.memberId
|
||||
) {
|
||||
isMaster.value = true
|
||||
} else {
|
||||
isMaster.value = false
|
||||
getGoodsDetail({
|
||||
id: routers.value.sku,
|
||||
goodsId: routers.value.goodsId,
|
||||
})
|
||||
}
|
||||
|
||||
if (storage.getUserInfo().id) {
|
||||
const bought = res.data.result.pintuanMemberVOS.filter(
|
||||
(item: any) => item.memberId == storage.getUserInfo().id
|
||||
)
|
||||
isBuy.value = bought.length != 0
|
||||
}
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '当前拼团单有误!请联系管理员重试',
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function getGoodsDetail(val: { id: string; goodsId: string }) {
|
||||
const { id, goodsId } = val
|
||||
uni.showLoading({ title: '加载中', mask: true })
|
||||
getGoods(id, goodsId).then((response) => {
|
||||
goodsDetail.value = response.data.result.data
|
||||
selectedGoods.value = response.data.result.data
|
||||
goodsSpec.value = response.data.result.specs
|
||||
hideLoadingIfNeeded()
|
||||
PromotionList.value = response.data.result.promotionMap
|
||||
if (PromotionList.value) {
|
||||
Object.keys(PromotionList.value).forEach((item) => {
|
||||
if (item.indexOf('PINTUAN') == 0) {
|
||||
isGroup.value = true
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取当前商品是否已经购买
|
||||
if (storage.getUserInfo().id) {
|
||||
let isBuy = res.data.result.pintuanMemberVOS.filter((item) => {
|
||||
return item.memberId == storage.getUserInfo().id;
|
||||
});
|
||||
isBuy.length != 0 ? (this.isBuy = true) : (this.isBuy = false);
|
||||
}
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: "当前拼团单有误!请联系管理员重试",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
},
|
||||
// 获取商品详情
|
||||
getGoodsDetail(val) {
|
||||
let { id, goodsId } = val;
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
mask: true,
|
||||
});
|
||||
getGoods(id, goodsId).then((response) => {
|
||||
this.goodsDetail = response.data.result.data;
|
||||
this.selectedGoods = response.data.result.data;
|
||||
this.goodsSpec = response.data.result.specs;
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
this.PromotionList = response.data.result.promotionMap;
|
||||
|
||||
// 判断是否拼团活动 如果有则显示拼团活动信息
|
||||
this.PromotionList &&
|
||||
Object.keys(this.PromotionList).forEach((item) => {
|
||||
if (item.indexOf("PINTUAN") == 0) {
|
||||
this.isGroup = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
handleClickHome() {
|
||||
uni.switchTab({
|
||||
url: "/pages/tabbar/home/index",
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
function handleClickHome() {
|
||||
uni.switchTab({ url: '/pages/tabbar/home/index' })
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
¥{{unitPrice(Number(payPrice)) }}
|
||||
</div>
|
||||
<div class="pay-btns">
|
||||
<div v-show="!from" @click="checkOrder">查看{{ this.orderType == "RECHARGE" ? '余额' : '订单' }}</div>
|
||||
<div v-show="!from" @click="checkOrder">查看{{ orderType == "RECHARGE" ? '余额' : '订单' }}</div>
|
||||
<div @click="navigateTo('/pages/tabbar/home/index', 'switch')">回到首页</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -24,73 +24,55 @@
|
||||
</div>
|
||||
|
||||
</template>
|
||||
<script>
|
||||
import goodsRecommend from "@/components/m-goods-recommend";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
checked: false,
|
||||
paymentMethod: "",
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import goodsRecommend from '@/components/m-goods-recommend'
|
||||
import { unitPrice } from '@/utils/filters.js'
|
||||
|
||||
from: "",
|
||||
payPrice: 0,
|
||||
goodsList: [],
|
||||
activeColor: this.$mainColor,
|
||||
};
|
||||
},
|
||||
components: {
|
||||
goodsRecommend,
|
||||
},
|
||||
onLoad(options) {
|
||||
this.paymentMethod = options.paymentMethod || "";
|
||||
this.from = options.from || "";
|
||||
this.payPrice = options.payPrice || 0;
|
||||
this.orderType = options.orderType;
|
||||
const paymentMethod = ref('')
|
||||
const from = ref('')
|
||||
const payPrice = ref<number | string>(0)
|
||||
const orderType = ref('')
|
||||
|
||||
},
|
||||
methods: {
|
||||
paymentTypeFilter(val) {
|
||||
switch (val) {
|
||||
case "WECHAT":
|
||||
return "微信";
|
||||
case "ALIPAY":
|
||||
return "支付宝";
|
||||
case "WALLET":
|
||||
return "余额支付";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
},
|
||||
checkOrder() {
|
||||
/**
|
||||
* 查看订单
|
||||
* 1.充值跳转到明细里面
|
||||
* 2.支付跳转到订单详情
|
||||
*/
|
||||
if (this.orderType == "RECHARGE") {
|
||||
uni.reLaunch({
|
||||
url: `/pages/mine/deposit/operation`,
|
||||
});
|
||||
} else {
|
||||
this.navigateTo("/pages/order/myOrder?status=0");
|
||||
}
|
||||
},
|
||||
onLoad((options) => {
|
||||
paymentMethod.value = options.paymentMethod || ''
|
||||
from.value = options.from || ''
|
||||
payPrice.value = options.payPrice || 0
|
||||
orderType.value = options.orderType || ''
|
||||
})
|
||||
|
||||
navigateTo(url, type) {
|
||||
if (type === "switch") {
|
||||
uni.switchTab({
|
||||
url,
|
||||
});
|
||||
} else {
|
||||
uni.redirectTo({
|
||||
url,
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
function paymentTypeFilter(val: string) {
|
||||
switch (val) {
|
||||
case 'WECHAT':
|
||||
return '微信'
|
||||
case 'ALIPAY':
|
||||
return '支付宝'
|
||||
case 'WALLET':
|
||||
return '余额支付'
|
||||
default:
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
function checkOrder() {
|
||||
if (orderType.value == 'RECHARGE') {
|
||||
uni.reLaunch({
|
||||
url: '/pages/mine/deposit/operation',
|
||||
})
|
||||
} else {
|
||||
navigateTo('/pages/order/myOrder?status=0')
|
||||
}
|
||||
}
|
||||
|
||||
function navigateTo(url: string, type?: string) {
|
||||
if (type === 'switch') {
|
||||
uni.switchTab({ url })
|
||||
} else {
|
||||
uni.redirectTo({ url })
|
||||
}
|
||||
}
|
||||
</script><style scoped lang="scss">
|
||||
.subscribe {
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
@@ -2,21 +2,16 @@
|
||||
<default-page v-if="type" :type="type" title="您的设备已断网" :isBtn="false" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import defaultPage from '@/components/default-page/default-page.vue';
|
||||
export default {
|
||||
components: {
|
||||
defaultPage
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
type: undefined
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
|
||||
}
|
||||
}
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import defaultPage from '@/components/default-page/default-page.vue'
|
||||
|
||||
const type = ref<string>()
|
||||
|
||||
onLoad(() => {
|
||||
type.value = 'msg'
|
||||
})
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
<template>
|
||||
<view class="add-address">
|
||||
<u-form :model="form" ref="uForm" error-type="toast" :rules="rules">
|
||||
<u-form-item label="收货人" label-width="130" prop="name" :border-bottom="true">
|
||||
<up-form
|
||||
:model="form"
|
||||
ref="uForm"
|
||||
error-type="toast"
|
||||
:rules="rules"
|
||||
label-position="left"
|
||||
label-width="180rpx"
|
||||
>
|
||||
<up-form-item label="收货人" label-width="180rpx" prop="name" :border-bottom="true">
|
||||
<u-input
|
||||
v-model="form.name"
|
||||
border="none"
|
||||
@@ -9,9 +16,9 @@
|
||||
clearable
|
||||
placeholder="请输入收货人姓名"
|
||||
/>
|
||||
</u-form-item>
|
||||
</up-form-item>
|
||||
|
||||
<u-form-item label="手机号码" label-width="130" prop="mobile" :border-bottom="true">
|
||||
<up-form-item label="手机号码" label-width="180rpx" prop="mobile" :border-bottom="true">
|
||||
<u-input
|
||||
v-model="form.mobile"
|
||||
type="number"
|
||||
@@ -20,18 +27,18 @@
|
||||
input-align="right"
|
||||
placeholder="请输入收货人手机号码"
|
||||
/>
|
||||
</u-form-item>
|
||||
</up-form-item>
|
||||
|
||||
<u-form-item label="所在区域" label-width="130" prop="___path" :border-bottom="true">
|
||||
<up-form-item label="所在区域" label-width="180rpx" prop="___path" :border-bottom="true">
|
||||
<view class="form-value" @click="showPicker">
|
||||
{{ form.___path || '请选择所在地区' }}
|
||||
</view>
|
||||
<template #right>
|
||||
<u-icon name="arrow-right" color="#ccc" size="16"></u-icon>
|
||||
</template>
|
||||
</u-form-item>
|
||||
</up-form-item>
|
||||
|
||||
<u-form-item class="detailAddress" label="详细地址" label-width="130" prop="detail" :border-bottom="true">
|
||||
<up-form-item class="detailAddress" label="详细地址" label-width="180rpx" prop="detail" :border-bottom="true">
|
||||
<u-input
|
||||
type="textarea"
|
||||
v-model="form.detail"
|
||||
@@ -40,16 +47,16 @@
|
||||
border="none"
|
||||
placeholder="街道楼牌号等"
|
||||
/>
|
||||
</u-form-item>
|
||||
</up-form-item>
|
||||
|
||||
<u-form-item label="地址别名" label-width="130" :border-bottom="false">
|
||||
<up-form-item label="地址别名" label-width="180rpx" :border-bottom="false">
|
||||
<u-input
|
||||
v-model="form.alias"
|
||||
border="none"
|
||||
input-align="right"
|
||||
placeholder="请输入地址别名"
|
||||
/>
|
||||
</u-form-item>
|
||||
</up-form-item>
|
||||
|
||||
<view class="default-row">
|
||||
<u-checkbox
|
||||
@@ -63,7 +70,7 @@
|
||||
</view>
|
||||
|
||||
<view class="saveBtn" @click="save">保存</view>
|
||||
</u-form>
|
||||
</up-form>
|
||||
|
||||
<m-city
|
||||
:provinceData="list"
|
||||
@@ -76,266 +83,208 @@
|
||||
<uniMap v-if="mapFlag" @close="closeMap" @callback="callBackAddress" />
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import { addAddress, editAddress, getAddressDetail } from "@/api/address.js";
|
||||
import city from "@/components/m-city/m-city.vue";
|
||||
import uniMap from "@/components/uniMap";
|
||||
import permision from "@/js_sdk/wa-permission/permission.js";
|
||||
export default {
|
||||
components: {
|
||||
"m-city": city,
|
||||
uniMap,
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed, getCurrentInstance } from 'vue'
|
||||
import { onLoad, onShow, onReady } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { addAddress as addAddressApi, editAddress, getAddressDetail } from '@/api/address.js'
|
||||
import MCity from '@/components/m-city/m-city.vue'
|
||||
import uniMap from '@/components/uniMap'
|
||||
import permision from '@/js_sdk/wa-permission/permission.js'
|
||||
|
||||
const store = useStore()
|
||||
const { proxy } = getCurrentInstance()!
|
||||
|
||||
const lightColor = computed(() => store.getters.lightColor)
|
||||
const mapFlag = ref(false)
|
||||
const routerVal = ref<Record<string, string>>({})
|
||||
const uForm = ref<any>(null)
|
||||
const cityPicker = ref<any>(null)
|
||||
|
||||
const form = reactive<Record<string, any>>({
|
||||
detail: '',
|
||||
name: '',
|
||||
mobile: '',
|
||||
consigneeAddressIdPath: [],
|
||||
consigneeAddressPath: [],
|
||||
___path: '',
|
||||
isDefault: false,
|
||||
})
|
||||
|
||||
const list = ref([
|
||||
{
|
||||
id: '',
|
||||
localName: '请选择',
|
||||
children: [],
|
||||
},
|
||||
onShow() {
|
||||
// 判断当前系统权限定位是否开启
|
||||
},
|
||||
methods: {
|
||||
// 关闭地图
|
||||
closeMap() {
|
||||
this.mapFlag = false;
|
||||
])
|
||||
|
||||
const rules = {
|
||||
name: [
|
||||
{
|
||||
required: true,
|
||||
message: '收货人姓名不能为空',
|
||||
trigger: ['blur', 'change'],
|
||||
},
|
||||
// 打开地图并访问权限
|
||||
clickUniMap() {
|
||||
// #ifdef APP-PLUS
|
||||
if (plus.os.name == "iOS") {
|
||||
// ios系统
|
||||
permision.judgeIosPermission("location")
|
||||
? (this.mapFlag = true)
|
||||
: this.refuseMap();
|
||||
} else {
|
||||
// 安卓
|
||||
this.requestAndroidPermission(
|
||||
"android.permission.ACCESS_FINE_LOCATION"
|
||||
);
|
||||
}
|
||||
// #endif
|
||||
|
||||
// #ifndef APP-PLUS
|
||||
this.mapFlag = true;
|
||||
// #endif
|
||||
],
|
||||
mobile: [
|
||||
{
|
||||
required: true,
|
||||
message: '手机号码不能为空',
|
||||
trigger: ['blur', 'change'],
|
||||
},
|
||||
|
||||
// 如果拒绝权限 提示区设置
|
||||
refuseMap() {
|
||||
uni.showModal({
|
||||
title: "温馨提示",
|
||||
content: "您已拒绝定位,请开启",
|
||||
confirmText: "去设置",
|
||||
success(res) {
|
||||
if (res.confirm) {
|
||||
//打开授权设置
|
||||
// #ifndef MP-WEIXIN
|
||||
uni.getSystemInfo({
|
||||
success(res) {
|
||||
if (res.platform == "ios") {
|
||||
//IOS
|
||||
plus.runtime.openURL("app-settings://");
|
||||
} else if (res.platform == "android") {
|
||||
//安卓
|
||||
let main = plus.android.runtimeMainActivity();
|
||||
let Intent = plus.android.importClass(
|
||||
"android.content.Intent"
|
||||
);
|
||||
let mIntent = new Intent("android.settings.ACTION_SETTINGS");
|
||||
main.startActivity(mIntent);
|
||||
}
|
||||
},
|
||||
});
|
||||
// #endif
|
||||
}
|
||||
},
|
||||
});
|
||||
{
|
||||
validator: (_rule: unknown, value: string) => proxy.$u.test.mobile(value),
|
||||
message: '手机号码不正确',
|
||||
trigger: ['change', 'blur'],
|
||||
},
|
||||
|
||||
// 获取安卓是否拥有地址权限
|
||||
async requestAndroidPermission(permisionID) {
|
||||
var result = await permision.requestAndroidPermission(permisionID);
|
||||
|
||||
if (result == 1) {
|
||||
this.mapFlag = true;
|
||||
} else {
|
||||
this.refuseMap();
|
||||
}
|
||||
],
|
||||
___path: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择所在区域',
|
||||
trigger: ['change'],
|
||||
},
|
||||
|
||||
// 选择地址后数据的回调
|
||||
callBackAddress(val) {
|
||||
console.log(val)
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
|
||||
if (val.regeocode && val) {
|
||||
let address = val.regeocode;
|
||||
this.form.detail = address.formatted_address; //地址详情
|
||||
this.form.___path = val.data.result.name;
|
||||
this.form.consigneeAddressIdPath = val.data.result.id; // 地址id分割
|
||||
this.form.consigneeAddressPath = val.data.result.name; //地址名称, ','分割
|
||||
this.form.lat = val.latitude; //纬度
|
||||
this.form.lon = val.longitude; //经度
|
||||
uni.hideLoading();
|
||||
}
|
||||
|
||||
this.mapFlag = !this.mapFlag; //关闭地图
|
||||
],
|
||||
detail: [
|
||||
{
|
||||
required: true,
|
||||
message: '请填写详细地址',
|
||||
trigger: ['blur', 'change'],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
// 保存当前 地址
|
||||
save() {
|
||||
this.$refs.uForm.validate().then(() => {
|
||||
const params = { ...this.form };
|
||||
delete params.___path;
|
||||
onShow(() => {})
|
||||
|
||||
if (Array.isArray(params.consigneeAddressIdPath)) {
|
||||
params.consigneeAddressIdPath = params.consigneeAddressIdPath.join(",");
|
||||
}
|
||||
if (Array.isArray(params.consigneeAddressPath)) {
|
||||
params.consigneeAddressPath = params.consigneeAddressPath.join(",");
|
||||
}
|
||||
onLoad((option) => {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
routerVal.value = option || {}
|
||||
if (option.id) {
|
||||
getAddressDetail(option.id).then((res) => {
|
||||
const params = res.data.result
|
||||
params.___path = params.consigneeAddressPath
|
||||
Object.assign(form, params)
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
})
|
||||
}
|
||||
uni.hideLoading()
|
||||
})
|
||||
|
||||
if (!params.id) {
|
||||
addAddress(params).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.navigateBack();
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.data.message || "保存失败",
|
||||
icon: "none",
|
||||
});
|
||||
onReady(() => {
|
||||
uForm.value?.setRules(rules)
|
||||
})
|
||||
|
||||
function closeMap() {
|
||||
mapFlag.value = false
|
||||
}
|
||||
|
||||
function refuseMap() {
|
||||
uni.showModal({
|
||||
title: '温馨提示',
|
||||
content: '您已拒绝定位,请开启',
|
||||
confirmText: '去设置',
|
||||
success(res) {
|
||||
if (res.confirm) {
|
||||
// #ifndef MP-WEIXIN
|
||||
uni.getSystemInfo({
|
||||
success(sysRes) {
|
||||
if (sysRes.platform == 'ios') {
|
||||
plus.runtime.openURL('app-settings://')
|
||||
} else if (sysRes.platform == 'android') {
|
||||
const main = plus.android.runtimeMainActivity()
|
||||
const Intent = plus.android.importClass('android.content.Intent')
|
||||
const mIntent = new Intent('android.settings.ACTION_SETTINGS')
|
||||
main.startActivity(mIntent)
|
||||
}
|
||||
});
|
||||
} else {
|
||||
delete params.updateBy;
|
||||
delete params.updateTime;
|
||||
editAddress(params).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.navigateBack();
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.data.message || "保存失败",
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}).catch(() => {});
|
||||
},
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// 三级地址联动回调
|
||||
getpickerParentValue(e) {
|
||||
// 将需要绑定的地址设置为空,并赋值
|
||||
this.form.consigneeAddressIdPath = [];
|
||||
this.form.consigneeAddressPath = [];
|
||||
let name = "";
|
||||
async function requestAndroidPermission(permisionID: string) {
|
||||
const result = await permision.requestAndroidPermission(permisionID)
|
||||
if (result == 1) {
|
||||
mapFlag.value = true
|
||||
} else {
|
||||
refuseMap()
|
||||
}
|
||||
}
|
||||
|
||||
e.forEach((item, index) => {
|
||||
if (item.id) {
|
||||
// 遍历数据
|
||||
this.form.consigneeAddressIdPath.push(item.id);
|
||||
this.form.consigneeAddressPath.push(item.localName);
|
||||
name += item.localName;
|
||||
this.form.___path = name;
|
||||
}
|
||||
if (index == e.length - 1) {
|
||||
//如果是最后一个
|
||||
let _town = item.children.filter((_child) => {
|
||||
return _child.id == item.id;
|
||||
});
|
||||
function callBackAddress(val: any) {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
if (val.regeocode && val) {
|
||||
const address = val.regeocode
|
||||
form.detail = address.formatted_address
|
||||
form.___path = val.data.result.name
|
||||
form.consigneeAddressIdPath = val.data.result.id
|
||||
form.consigneeAddressPath = val.data.result.name
|
||||
form.lat = val.latitude
|
||||
form.lon = val.longitude
|
||||
uni.hideLoading()
|
||||
}
|
||||
mapFlag.value = !mapFlag.value
|
||||
}
|
||||
|
||||
this.form.lat = _town[0].center.split(",")[1];
|
||||
this.form.lon = _town[0].center.split(",")[0];
|
||||
}
|
||||
});
|
||||
},
|
||||
function save() {
|
||||
uForm.value?.validate().then(() => {
|
||||
const params = { ...form }
|
||||
delete params.___path
|
||||
|
||||
// 显示三级地址联动
|
||||
showPicker() {
|
||||
this.$refs.cityPicker.show();
|
||||
},
|
||||
},
|
||||
mounted() {},
|
||||
data() {
|
||||
return {
|
||||
lightColor: this.$lightColor, //高亮颜色
|
||||
mapFlag: false, // 地图选择开
|
||||
routerVal: "",
|
||||
form: {
|
||||
detail: "", //地址详情
|
||||
name: "", //收货人姓名
|
||||
mobile: "", //手机号码
|
||||
consigneeAddressIdPath: [], //地址id
|
||||
consigneeAddressPath: [], //地址名字
|
||||
___path: "", //所在区域
|
||||
isDefault: false, //是否默认地址
|
||||
},
|
||||
// 表单提交校验规则
|
||||
rules: {
|
||||
name: [
|
||||
{
|
||||
required: true,
|
||||
message: "收货人姓名不能为空",
|
||||
trigger: ["blur", "change"],
|
||||
},
|
||||
],
|
||||
mobile: [
|
||||
{
|
||||
required: true,
|
||||
message: "手机号码不能为空",
|
||||
trigger: ["blur", "change"],
|
||||
},
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
return this.$u.test.mobile(value);
|
||||
},
|
||||
message: "手机号码不正确",
|
||||
trigger: ["change", "blur"],
|
||||
},
|
||||
],
|
||||
___path: [
|
||||
{
|
||||
required: true,
|
||||
message: "请选择所在区域",
|
||||
trigger: ["change"],
|
||||
},
|
||||
],
|
||||
detail: [
|
||||
{
|
||||
required: true,
|
||||
message: "请填写详细地址",
|
||||
trigger: ["blur", "change"],
|
||||
},
|
||||
],
|
||||
},
|
||||
list: [
|
||||
{
|
||||
id: "",
|
||||
localName: "请选择",
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
onLoad(option) {
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
this.routerVal = option;
|
||||
// 如果当前是编辑地址,则需要查询出地址详情信息
|
||||
if (option.id) {
|
||||
getAddressDetail(option.id).then((res) => {
|
||||
const params = res.data.result;
|
||||
params.___path = params.consigneeAddressPath;
|
||||
this["form"] = params;
|
||||
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
});
|
||||
if (Array.isArray(params.consigneeAddressIdPath)) {
|
||||
params.consigneeAddressIdPath = params.consigneeAddressIdPath.join(',')
|
||||
}
|
||||
uni.hideLoading();
|
||||
},
|
||||
// 初始化rules必须要在onReady生命周期,因为onLoad生命周期组件可能尚未创建完毕
|
||||
onReady() {
|
||||
this.$refs.uForm.setRules(this.rules);
|
||||
},
|
||||
};
|
||||
if (Array.isArray(params.consigneeAddressPath)) {
|
||||
params.consigneeAddressPath = params.consigneeAddressPath.join(',')
|
||||
}
|
||||
|
||||
if (!params.id) {
|
||||
addAddressApi(params).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.navigateBack()
|
||||
} else {
|
||||
uni.showToast({ title: res.data.message || '保存失败', icon: 'none' })
|
||||
}
|
||||
})
|
||||
} else {
|
||||
delete params.updateBy
|
||||
delete params.updateTime
|
||||
editAddress(params).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.navigateBack()
|
||||
} else {
|
||||
uni.showToast({ title: res.data.message || '保存失败', icon: 'none' })
|
||||
}
|
||||
})
|
||||
}
|
||||
}).catch(() => {})
|
||||
}
|
||||
|
||||
function getpickerParentValue(e: any[]) {
|
||||
form.consigneeAddressIdPath = []
|
||||
form.consigneeAddressPath = []
|
||||
let name = ''
|
||||
e.forEach((item, index) => {
|
||||
if (item.id) {
|
||||
form.consigneeAddressIdPath.push(item.id)
|
||||
form.consigneeAddressPath.push(item.localName)
|
||||
name += item.localName
|
||||
form.___path = name
|
||||
}
|
||||
if (index == e.length - 1) {
|
||||
const _town = item.children.filter((_child: any) => _child.id == item.id)
|
||||
form.lat = _town[0].center.split(',')[1]
|
||||
form.lon = _town[0].center.split(',')[0]
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function showPicker() {
|
||||
cityPicker.value?.show()
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
page {
|
||||
|
||||
@@ -42,126 +42,95 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as API_Trade from "@/api/trade";
|
||||
import * as API_Address from "@/api/address.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
addressList: [], //地址列表
|
||||
showAction: false, //是否显示下栏框
|
||||
removeList: [
|
||||
{
|
||||
text: "确定",
|
||||
},
|
||||
],
|
||||
tips: {
|
||||
text: "确定要删除该收货人信息吗?",
|
||||
},
|
||||
removeId: "", //删除的地址id
|
||||
routerVal: "",
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 1000,
|
||||
},
|
||||
};
|
||||
},
|
||||
onPullDownRefresh() {
|
||||
//下拉刷新
|
||||
this.addressList = [];
|
||||
this.getAddressList();
|
||||
},
|
||||
onLoad: function (val) {
|
||||
this.routerVal = val;
|
||||
},
|
||||
onShow() {
|
||||
this.addressList = [];
|
||||
this.getAddressList();
|
||||
},
|
||||
onHide() {},
|
||||
methods: {
|
||||
async selectAddressData(val) {
|
||||
await API_Trade.setAddressId(val.id, this.routerVal.way);
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad, onShow, onPullDownRefresh } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import * as API_Trade from '@/api/trade'
|
||||
import * as API_Address from '@/api/address.js'
|
||||
|
||||
uni.navigateBack({
|
||||
delta: 1,
|
||||
});
|
||||
},
|
||||
//获取地址列表
|
||||
getAddressList() {
|
||||
uni.showLoading();
|
||||
const store = useStore()
|
||||
|
||||
API_Address.getAddressList(
|
||||
this.params.pageNumber,
|
||||
this.params.pageSize
|
||||
).then((res) => {
|
||||
res.data.result.records.forEach((item) => {
|
||||
item.consigneeAddressPath = item.consigneeAddressPath.split(",");
|
||||
});
|
||||
this.addressList = res.data.result.records;
|
||||
console.log(this.addressList);
|
||||
const addressList = ref<any[]>([])
|
||||
const showAction = ref(false)
|
||||
const removeList = [{ text: '确定' }]
|
||||
const tips = { text: '确定要删除该收货人信息吗?' }
|
||||
const removeId = ref('')
|
||||
const routerVal = ref<Record<string, string>>({})
|
||||
const params = { pageNumber: 1, pageSize: 1000 }
|
||||
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
});
|
||||
},
|
||||
//删除地址
|
||||
removeAddress(id) {
|
||||
this.removeId = id;
|
||||
this.showAction = true;
|
||||
},
|
||||
deleteAddressMessage() {
|
||||
API_Address.deleteAddress(this.removeId).then((res) => {
|
||||
if (res.statusCode == 200) {
|
||||
uni.showToast({
|
||||
icon: "none",
|
||||
title: "删除成功",
|
||||
});
|
||||
this.getAddressList();
|
||||
} else {
|
||||
uni.showToast({
|
||||
icon: "none",
|
||||
title: res.data.message,
|
||||
duration: 2000,
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
//新建。编辑地址
|
||||
addAddress(id) {
|
||||
if (id) {
|
||||
uni.navigateTo({
|
||||
url:
|
||||
"/pages/mine/address/add?id=" +
|
||||
id +
|
||||
"&way=" +
|
||||
this.routerVal.way +
|
||||
"&type=order",
|
||||
});
|
||||
} else {
|
||||
uni.navigateTo({
|
||||
url:
|
||||
"/pages/mine/address/add?way=" + this.routerVal.way + "&type=order",
|
||||
});
|
||||
}
|
||||
},
|
||||
//设为默认地址
|
||||
setDefault(item) {
|
||||
delete item.updateBy;
|
||||
delete item.updateTime;
|
||||
delete item.deleteFlag;
|
||||
onPullDownRefresh(() => {
|
||||
addressList.value = []
|
||||
getAddressList()
|
||||
})
|
||||
|
||||
item.isDefault ? "" : (item.isDefault = !item.isDefault);
|
||||
onLoad((val) => {
|
||||
routerVal.value = val || {}
|
||||
})
|
||||
|
||||
API_Address.editAddress(item).then((res) => {
|
||||
uni.showToast({
|
||||
title: "设置默认地址成功",
|
||||
icon: "none",
|
||||
});
|
||||
this.getAddressList();
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
onShow(() => {
|
||||
addressList.value = []
|
||||
getAddressList()
|
||||
})
|
||||
|
||||
function hideLoadingIfNeeded() {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
}
|
||||
|
||||
async function selectAddressData(val: any) {
|
||||
await API_Trade.setAddressId(val.id, routerVal.value.way)
|
||||
uni.navigateBack({ delta: 1 })
|
||||
}
|
||||
|
||||
function getAddressList() {
|
||||
uni.showLoading()
|
||||
API_Address.getAddressList(params.pageNumber, params.pageSize).then((res) => {
|
||||
res.data.result.records.forEach((item: any) => {
|
||||
item.consigneeAddressPath = item.consigneeAddressPath.split(',')
|
||||
})
|
||||
addressList.value = res.data.result.records
|
||||
hideLoadingIfNeeded()
|
||||
})
|
||||
}
|
||||
|
||||
function removeAddress(id: string) {
|
||||
removeId.value = id
|
||||
showAction.value = true
|
||||
}
|
||||
|
||||
function deleteAddressMessage() {
|
||||
API_Address.deleteAddress(removeId.value).then((res) => {
|
||||
if (res.statusCode == 200) {
|
||||
uni.showToast({ icon: 'none', title: '删除成功' })
|
||||
getAddressList()
|
||||
} else {
|
||||
uni.showToast({ icon: 'none', title: res.data.message, duration: 2000 })
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function addAddress(id: string) {
|
||||
if (id) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/mine/address/add?id=${id}&way=${routerVal.value.way}&type=order`,
|
||||
})
|
||||
} else {
|
||||
uni.navigateTo({
|
||||
url: `/pages/mine/address/add?way=${routerVal.value.way}&type=order`,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function setDefault(item: any) {
|
||||
delete item.updateBy
|
||||
delete item.updateTime
|
||||
delete item.deleteFlag
|
||||
if (!item.isDefault) item.isDefault = true
|
||||
API_Address.editAddress(item).then(() => {
|
||||
uni.showToast({ title: '设置默认地址成功', icon: 'none' })
|
||||
getAddressList()
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<view class="address">
|
||||
<u-empty class="empty" v-if="this.addressList.length === 0" text="暂无收货地址" mode="address"></u-empty>
|
||||
<u-empty class="empty" v-if="addressList.length === 0" text="暂无收货地址" mode="address"></u-empty>
|
||||
<view class="list" >
|
||||
<view class="item c-content" v-for="(item, index) in addressList" :key="index">
|
||||
<view class="basic">
|
||||
@@ -43,116 +43,90 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as API_Address from "@/api/address.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
addressList: [], //地址列表
|
||||
showAction: false, //是否显示下栏框
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad, onShow, onPullDownRefresh, onBackPress } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { tipsToLogin } from '@/utils/filters.js'
|
||||
import * as API_Address from '@/api/address.js'
|
||||
|
||||
removeList: [
|
||||
{
|
||||
text: "确定",
|
||||
},
|
||||
],
|
||||
tips: {
|
||||
text: "确定要删除该收货人信息吗?",
|
||||
},
|
||||
removeId: "", //删除的地址id
|
||||
routerVal: "",
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 1000,
|
||||
},
|
||||
};
|
||||
},
|
||||
// 返回上一级
|
||||
onBackPress(e) {
|
||||
uni.switchTab({
|
||||
url: "/pages/tabbar/user/my",
|
||||
});
|
||||
return true;
|
||||
},
|
||||
onLoad: function (val) {
|
||||
this.routerVal = val;
|
||||
},
|
||||
onPullDownRefresh() {
|
||||
//下拉刷新
|
||||
this.addressList = [];
|
||||
this.getAddressList();
|
||||
},
|
||||
/**
|
||||
* 进入页面检测当前账户是否登录
|
||||
*/
|
||||
onShow() {
|
||||
if (this.tipsToLogin()) {
|
||||
this.getAddressList();
|
||||
const store = useStore()
|
||||
|
||||
const addressList = ref<any[]>([])
|
||||
const showAction = ref(false)
|
||||
const removeList = [{ text: '确定' }]
|
||||
const tips = { text: '确定要删除该收货人信息吗?' }
|
||||
const removeId = ref('')
|
||||
const routerVal = ref<Record<string, string>>({})
|
||||
const params = { pageNumber: 1, pageSize: 1000 }
|
||||
|
||||
onBackPress(() => {
|
||||
uni.switchTab({ url: '/pages/tabbar/user/my' })
|
||||
return true
|
||||
})
|
||||
|
||||
onLoad((val) => {
|
||||
routerVal.value = val || {}
|
||||
})
|
||||
|
||||
onPullDownRefresh(() => {
|
||||
addressList.value = []
|
||||
getAddressList()
|
||||
})
|
||||
|
||||
onShow(() => {
|
||||
if (tipsToLogin()) {
|
||||
getAddressList()
|
||||
}
|
||||
})
|
||||
|
||||
function hideLoadingIfNeeded() {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
}
|
||||
|
||||
function getAddressList() {
|
||||
uni.showLoading()
|
||||
API_Address.getAddressList(params.pageNumber, params.pageSize).then((res) => {
|
||||
res.data.result.records.forEach((item: any) => {
|
||||
item.consigneeAddressPath = item.consigneeAddressPath.split(',')
|
||||
})
|
||||
addressList.value = res.data.result.records
|
||||
hideLoadingIfNeeded()
|
||||
})
|
||||
}
|
||||
|
||||
function removeAddress(id: string) {
|
||||
removeId.value = id
|
||||
showAction.value = true
|
||||
}
|
||||
|
||||
function deleteAddressMessage() {
|
||||
API_Address.deleteAddress(removeId.value).then((res) => {
|
||||
if (res.statusCode == 200) {
|
||||
uni.showToast({ icon: 'none', title: '删除成功' })
|
||||
getAddressList()
|
||||
} else {
|
||||
uni.showToast({ icon: 'none', title: res.data.message, duration: 2000 })
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
//获取地址列表
|
||||
getAddressList() {
|
||||
uni.showLoading();
|
||||
API_Address.getAddressList(
|
||||
this.params.pageNumber,
|
||||
this.params.pageSize
|
||||
).then((res) => {
|
||||
res.data.result.records.forEach((item) => {
|
||||
item.consigneeAddressPath = item.consigneeAddressPath.split(",");
|
||||
});
|
||||
this.addressList = res.data.result.records;
|
||||
})
|
||||
}
|
||||
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
});
|
||||
},
|
||||
//删除地址
|
||||
removeAddress(id) {
|
||||
this.removeId = id;
|
||||
this.showAction = true;
|
||||
},
|
||||
// 删除地址
|
||||
deleteAddressMessage() {
|
||||
API_Address.deleteAddress(this.removeId).then((res) => {
|
||||
if (res.statusCode == 200) {
|
||||
uni.showToast({
|
||||
icon: "none",
|
||||
title: "删除成功",
|
||||
});
|
||||
this.getAddressList();
|
||||
} else {
|
||||
uni.showToast({
|
||||
icon: "none",
|
||||
title: res.data.message,
|
||||
duration: 2000,
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
//新建。编辑地址
|
||||
addAddress(id) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/mine/address/add${id ? "?id=" + id : ""}`,
|
||||
});
|
||||
},
|
||||
//设为默认地址
|
||||
setDefault(item) {
|
||||
delete item.updateBy;
|
||||
delete item.updateTime;
|
||||
delete item.deleteFlag;
|
||||
function addAddress(id?: string) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/mine/address/add${id ? '?id=' + id : ''}`,
|
||||
})
|
||||
}
|
||||
|
||||
item.isDefault ? "" : (item.isDefault = !item.isDefault);
|
||||
|
||||
API_Address.editAddress(item).then(() => {
|
||||
uni.showToast({
|
||||
title: "设置默认地址成功",
|
||||
icon: "none",
|
||||
});
|
||||
this.getAddressList();
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
function setDefault(item: any) {
|
||||
delete item.updateBy
|
||||
delete item.updateTime
|
||||
delete item.deleteFlag
|
||||
if (!item.isDefault) item.isDefault = true
|
||||
API_Address.editAddress(item).then(() => {
|
||||
uni.showToast({ title: '设置默认地址成功', icon: 'none' })
|
||||
getAddressList()
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -20,67 +20,57 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as API_Trade from "@/api/trade";
|
||||
import * as API_Store from "@/api/store.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
storeAddressList: [], //地址列表
|
||||
showAction: false, //是否显示下栏框
|
||||
removeList: [
|
||||
{
|
||||
text: "确定",
|
||||
},
|
||||
],
|
||||
tips: {
|
||||
text: "确定要删除该收货人信息吗?",
|
||||
},
|
||||
removeId: "", //删除的地址id
|
||||
routerVal: "",
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 1000,
|
||||
},
|
||||
};
|
||||
},
|
||||
onPullDownRefresh() {
|
||||
//下拉刷新
|
||||
this.storeAddressList = [];
|
||||
this.getAddressList();
|
||||
},
|
||||
onLoad: function (val) {
|
||||
this.routerVal = val;
|
||||
},
|
||||
onShow() {
|
||||
this.storeAddressList = [];
|
||||
this.getAddressList();
|
||||
},
|
||||
onHide() {},
|
||||
methods: {
|
||||
async selectAddressData(val) {
|
||||
await API_Trade.setStoreAddressId(val.id, this.routerVal.way);
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad, onShow, onPullDownRefresh } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import * as API_Trade from '@/api/trade'
|
||||
import * as API_Store from '@/api/store.js'
|
||||
|
||||
uni.navigateBack({
|
||||
delta: 1,
|
||||
});
|
||||
},
|
||||
//获取地址列表
|
||||
getAddressList() {
|
||||
uni.showLoading();
|
||||
const store = useStore()
|
||||
|
||||
API_Store.getStoreAddress(
|
||||
this.routerVal.storeId,
|
||||
this.params
|
||||
).then((res) => {
|
||||
this.storeAddressList = res.data.result.records;
|
||||
console.log(this.storeAddressList);
|
||||
const storeAddressList = ref<any[]>([])
|
||||
const showAction = ref(false)
|
||||
const removeList = [{ text: '确定' }]
|
||||
const tips = { text: '确定要删除该收货人信息吗?' }
|
||||
const removeId = ref('')
|
||||
const routerVal = ref<Record<string, string>>({})
|
||||
const params = { pageNumber: 1, pageSize: 1000 }
|
||||
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
onPullDownRefresh(() => {
|
||||
storeAddressList.value = []
|
||||
getAddressList()
|
||||
})
|
||||
|
||||
onLoad((val) => {
|
||||
routerVal.value = val || {}
|
||||
})
|
||||
|
||||
onShow(() => {
|
||||
storeAddressList.value = []
|
||||
getAddressList()
|
||||
})
|
||||
|
||||
function hideLoadingIfNeeded() {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
}
|
||||
|
||||
async function selectAddressData(val: any) {
|
||||
await API_Trade.setStoreAddressId(val.id, routerVal.value.way)
|
||||
uni.navigateBack({ delta: 1 })
|
||||
}
|
||||
|
||||
function getAddressList() {
|
||||
uni.showLoading()
|
||||
API_Store.getStoreAddress(routerVal.value.storeId, params).then((res) => {
|
||||
storeAddressList.value = res.data.result.records
|
||||
hideLoadingIfNeeded()
|
||||
})
|
||||
}
|
||||
|
||||
function deleteAddressMessage() {
|
||||
// 保留 action-sheet 回调占位,当前页面无删除入口
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -52,84 +52,64 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getUserRecharge, getWalletLog, getUserWallet } from "@/api/members";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
walletNum: 0,
|
||||
current: 0,
|
||||
swiperCurrent: 0,
|
||||
userInfo: "",
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
order: "desc",
|
||||
},
|
||||
depositData: [],
|
||||
rechargeList: "",
|
||||
walletLogList: "",
|
||||
list: [{ name: "预存款变动明细" }],
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
swiperCurrent(index) {
|
||||
this.swiperCurrent = index;
|
||||
},
|
||||
},
|
||||
async mounted() {
|
||||
this.getWallet();
|
||||
const result = await getUserWallet();
|
||||
this.walletNum = result.data.result.memberWallet;
|
||||
},
|
||||
methods: {
|
||||
isOutgoing(serviceType) {
|
||||
return serviceType === "WALLET_PAY" || serviceType === "WALLET_WITHDRAWAL";
|
||||
},
|
||||
isIncoming(serviceType) {
|
||||
return (
|
||||
serviceType === "WALLET_REFUND" ||
|
||||
serviceType === "WALLET_RECHARGE" ||
|
||||
serviceType === "WALLET_COMMISSION"
|
||||
);
|
||||
},
|
||||
getMoneyClass(serviceType) {
|
||||
if (this.isOutgoing(serviceType)) return "out";
|
||||
if (this.isIncoming(serviceType)) return "in";
|
||||
return "";
|
||||
},
|
||||
formatLogMoney(logItem) {
|
||||
const amount = this.unitPrice(logItem.money);
|
||||
if (this.isOutgoing(logItem.serviceType)) return `-${amount}`;
|
||||
if (this.isIncoming(logItem.serviceType)) return `+${amount}`;
|
||||
return amount;
|
||||
},
|
||||
getRecharge() {
|
||||
getUserRecharge(this.params).then((res) => {
|
||||
if (res.data.success && res.data.result.records.length) {
|
||||
this.depositData.push(...res.data.result.records);
|
||||
}
|
||||
});
|
||||
},
|
||||
getWallet() {
|
||||
getWalletLog(this.params).then((res) => {
|
||||
if (res.data.success && res.data.result.records.length) {
|
||||
this.depositData.push(...res.data.result.records);
|
||||
}
|
||||
});
|
||||
},
|
||||
changed(index) {
|
||||
this.depositData = [];
|
||||
this.swiperCurrent = index;
|
||||
this.params.pageNumber = 1;
|
||||
this.getWallet();
|
||||
},
|
||||
loadMore() {
|
||||
this.params.pageNumber++;
|
||||
this.getWallet();
|
||||
},
|
||||
},
|
||||
};
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { getWalletLog, getUserWallet } from '@/api/members'
|
||||
import { unitPrice } from '@/utils/filters.js'
|
||||
|
||||
const walletNum = ref(0)
|
||||
const swiperCurrent = ref(0)
|
||||
const params = ref({
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
order: 'desc',
|
||||
})
|
||||
const depositData = ref<any[]>([])
|
||||
const list = [{ name: '预存款变动明细' }]
|
||||
|
||||
onMounted(async () => {
|
||||
getWallet()
|
||||
const result = await getUserWallet()
|
||||
walletNum.value = result.data.result.memberWallet
|
||||
})
|
||||
|
||||
function isOutgoing(serviceType: string) {
|
||||
return serviceType === 'WALLET_PAY' || serviceType === 'WALLET_WITHDRAWAL'
|
||||
}
|
||||
|
||||
function isIncoming(serviceType: string) {
|
||||
return (
|
||||
serviceType === 'WALLET_REFUND' ||
|
||||
serviceType === 'WALLET_RECHARGE' ||
|
||||
serviceType === 'WALLET_COMMISSION'
|
||||
)
|
||||
}
|
||||
|
||||
function getMoneyClass(serviceType: string) {
|
||||
if (isOutgoing(serviceType)) return 'out'
|
||||
if (isIncoming(serviceType)) return 'in'
|
||||
return ''
|
||||
}
|
||||
|
||||
function formatLogMoney(logItem: any) {
|
||||
const amount = unitPrice(logItem.money)
|
||||
if (isOutgoing(logItem.serviceType)) return `-${amount}`
|
||||
if (isIncoming(logItem.serviceType)) return `+${amount}`
|
||||
return amount
|
||||
}
|
||||
|
||||
function getWallet() {
|
||||
getWalletLog(params.value).then((res) => {
|
||||
if (res.data.success && res.data.result.records.length) {
|
||||
depositData.value.push(...res.data.result.records)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function loadMore() {
|
||||
params.value.pageNumber++
|
||||
getWallet()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -12,8 +12,7 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {};
|
||||
<script setup lang="ts">
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -38,33 +38,30 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getUserWallet } from "@/api/members";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
walletNum: 0,
|
||||
};
|
||||
},
|
||||
async onShow() {
|
||||
if (this.isLogin("auth")) {
|
||||
let result = await getUserWallet();
|
||||
this.walletNum = result.data.result.memberWallet;
|
||||
} else {
|
||||
this.navigateToLogin("redirectTo");
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
back() {
|
||||
uni.switchTab({
|
||||
url: "/pages/tabbar/user/my",
|
||||
});
|
||||
},
|
||||
navigateTo(url) {
|
||||
uni.navigateTo({ url });
|
||||
},
|
||||
},
|
||||
};
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onShow } from '@dcloudio/uni-app'
|
||||
import { getUserWallet } from '@/api/members'
|
||||
import { isLogin, navigateToLogin, unitPrice } from '@/utils/filters.js'
|
||||
|
||||
const walletNum = ref(0)
|
||||
|
||||
onShow(async () => {
|
||||
if (isLogin('auth')) {
|
||||
const result = await getUserWallet()
|
||||
walletNum.value = result.data.result.memberWallet
|
||||
} else {
|
||||
navigateToLogin('redirectTo')
|
||||
}
|
||||
})
|
||||
|
||||
function back() {
|
||||
uni.switchTab({ url: '/pages/tabbar/user/my' })
|
||||
}
|
||||
|
||||
function navigateTo(url: string) {
|
||||
uni.navigateTo({ url })
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -19,40 +19,30 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { recharge } from "@/api/members";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
price: "",
|
||||
flag: true,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
price(val) {
|
||||
this.flag = !(Number(val) > 0);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
async handlerRecharge() {
|
||||
const amount = Number(this.price);
|
||||
if (!(amount > 0)) {
|
||||
uni.showToast({
|
||||
title: "请输入充值金额",
|
||||
icon: "none",
|
||||
});
|
||||
return;
|
||||
}
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue'
|
||||
import { recharge } from '@/api/members'
|
||||
|
||||
const res = await recharge({ price: amount });
|
||||
if (res.data.success) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/cart/payment/payOrder?orderType=RECHARGE&recharge_sn=${res.data.result.rechargeSn}`,
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
const price = ref('')
|
||||
const flag = ref(true)
|
||||
|
||||
watch(price, (val) => {
|
||||
flag.value = !(Number(val) > 0)
|
||||
})
|
||||
|
||||
async function handlerRecharge() {
|
||||
const amount = Number(price.value)
|
||||
if (!(amount > 0)) {
|
||||
uni.showToast({ title: '请输入充值金额', icon: 'none' })
|
||||
return
|
||||
}
|
||||
const res = await recharge({ price: amount })
|
||||
if (res.data.success) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/cart/payment/payOrder?orderType=RECHARGE&recharge_sn=${res.data.result.rechargeSn}`,
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -25,182 +25,149 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getWithdrawApplyPage, getWithdrawApplyWechatTransferInfo } from "@/api/members";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
loaded: false,
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
order: "desc",
|
||||
},
|
||||
records: [],
|
||||
};
|
||||
},
|
||||
onShow() {
|
||||
this.params.pageNumber = 1;
|
||||
this.records = [];
|
||||
this.loaded = false;
|
||||
this.getData();
|
||||
},
|
||||
methods: {
|
||||
withdrawStatusText(applyStatus) {
|
||||
switch (applyStatus) {
|
||||
case "APPLY":
|
||||
return "申请中";
|
||||
case "VIA_AUDITING":
|
||||
return "审核通过";
|
||||
case "D_VIA_AUDITING":
|
||||
return "分销提现审核通过";
|
||||
case "FAIL_AUDITING":
|
||||
return "审核未通过";
|
||||
case "D_FAIL_AUDITING":
|
||||
return "分销提现审核未通过";
|
||||
case "WAIT_USER_CONFIRM":
|
||||
return "等待用户确认";
|
||||
case "SUCCESS":
|
||||
return "提现成功";
|
||||
case "ERROR":
|
||||
return "提现失败";
|
||||
default:
|
||||
return applyStatus || "";
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onShow } from '@dcloudio/uni-app'
|
||||
import { getWithdrawApplyPage, getWithdrawApplyWechatTransferInfo } from '@/api/members'
|
||||
import { unitPrice } from '@/utils/filters.js'
|
||||
|
||||
const loaded = ref(false)
|
||||
const params = ref({
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
order: 'desc',
|
||||
})
|
||||
const records = ref<any[]>([])
|
||||
|
||||
onShow(() => {
|
||||
params.value.pageNumber = 1
|
||||
records.value = []
|
||||
loaded.value = false
|
||||
getData()
|
||||
})
|
||||
|
||||
function withdrawStatusText(applyStatus: string) {
|
||||
switch (applyStatus) {
|
||||
case 'APPLY':
|
||||
return '申请中'
|
||||
case 'VIA_AUDITING':
|
||||
return '审核通过'
|
||||
case 'D_VIA_AUDITING':
|
||||
return '分销提现审核通过'
|
||||
case 'FAIL_AUDITING':
|
||||
return '审核未通过'
|
||||
case 'D_FAIL_AUDITING':
|
||||
return '分销提现审核未通过'
|
||||
case 'WAIT_USER_CONFIRM':
|
||||
return '等待用户确认'
|
||||
case 'SUCCESS':
|
||||
return '提现成功'
|
||||
case 'ERROR':
|
||||
return '提现失败'
|
||||
default:
|
||||
return applyStatus || ''
|
||||
}
|
||||
}
|
||||
|
||||
function getData() {
|
||||
getWithdrawApplyPage(params.value).then((res) => {
|
||||
loaded.value = true
|
||||
if (res.data.success && res.data.result.records.length != 0) {
|
||||
records.value.push(...res.data.result.records)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function loadMore() {
|
||||
params.value.pageNumber++
|
||||
getData()
|
||||
}
|
||||
|
||||
function confirmWechatReceive(item: any) {
|
||||
const id = item && item.id
|
||||
if (!id) {
|
||||
uni.showToast({ title: '缺少提现记录ID', duration: 2000, icon: 'none' })
|
||||
return
|
||||
}
|
||||
|
||||
uni.showLoading({ title: '加载中' })
|
||||
getWithdrawApplyWechatTransferInfo(id)
|
||||
.then((res) => {
|
||||
if (!res.data || !res.data.success) return
|
||||
|
||||
const info = res.data.result || {}
|
||||
const mchId = info.mchId
|
||||
const wechatPackage = info.wechatPackage
|
||||
let appId = info.appId
|
||||
|
||||
if (typeof wx !== 'undefined' && wx.getAccountInfoSync) {
|
||||
try {
|
||||
const accountInfo = wx.getAccountInfoSync()
|
||||
const mpAppId = accountInfo && accountInfo.miniProgram && accountInfo.miniProgram.appId
|
||||
if (mpAppId) appId = mpAppId
|
||||
} catch (e) {}
|
||||
}
|
||||
},
|
||||
getData() {
|
||||
getWithdrawApplyPage(this.params).then((res) => {
|
||||
this.loaded = true;
|
||||
if (res.data.success) {
|
||||
if (res.data.result.records.length != 0) {
|
||||
this.records.push(...res.data.result.records);
|
||||
}
|
||||
|
||||
if (!mchId || !appId || !wechatPackage) {
|
||||
uni.showToast({ title: '微信确认参数缺失', duration: 2000, icon: 'none' })
|
||||
return
|
||||
}
|
||||
|
||||
const openResultToast = (errMsg?: string) => {
|
||||
if (errMsg === 'requestMerchantTransfer:ok') {
|
||||
uni.showToast({ title: '已唤起确认页面', duration: 2000, icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (errMsg === 'requestMerchantTransfer:cancel') {
|
||||
uni.showToast({ title: '已取消', duration: 2000, icon: 'none' })
|
||||
return
|
||||
}
|
||||
});
|
||||
},
|
||||
loadMore() {
|
||||
this.params.pageNumber++;
|
||||
this.getData();
|
||||
},
|
||||
confirmWechatReceive(item) {
|
||||
const id = item && item.id;
|
||||
if (!id) {
|
||||
uni.showToast({
|
||||
title: "缺少提现记录ID",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
return;
|
||||
title: errMsg ? `唤起失败:${errMsg}` : '唤起失败',
|
||||
duration: 2500,
|
||||
icon: 'none',
|
||||
})
|
||||
}
|
||||
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
getWithdrawApplyWechatTransferInfo(id)
|
||||
.then((res) => {
|
||||
if (!res.data || !res.data.success) return;
|
||||
|
||||
const info = res.data.result || {};
|
||||
const mchId = info.mchId;
|
||||
const wechatPackage = info.wechatPackage;
|
||||
let appId = info.appId;
|
||||
|
||||
if (typeof wx !== "undefined" && wx.getAccountInfoSync) {
|
||||
try {
|
||||
const accountInfo = wx.getAccountInfoSync();
|
||||
const mpAppId = accountInfo && accountInfo.miniProgram && accountInfo.miniProgram.appId;
|
||||
if (mpAppId) appId = mpAppId;
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
if (!mchId || !appId || !wechatPackage) {
|
||||
if (typeof wx !== 'undefined' && wx.getSystemInfoSync) {
|
||||
try {
|
||||
const sys = wx.getSystemInfoSync()
|
||||
if (sys && sys.platform === 'devtools') {
|
||||
uni.showToast({
|
||||
title: "微信确认参数缺失",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const openResultToast = (errMsg) => {
|
||||
if (errMsg === "requestMerchantTransfer:ok") {
|
||||
uni.showToast({
|
||||
title: "已唤起确认页面",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (errMsg === "requestMerchantTransfer:cancel") {
|
||||
uni.showToast({
|
||||
title: "已取消",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
return;
|
||||
}
|
||||
uni.showToast({
|
||||
title: errMsg ? `唤起失败:${errMsg}` : "唤起失败",
|
||||
title: '开发者工具可能不支持,请真机测试',
|
||||
duration: 2500,
|
||||
icon: "none",
|
||||
});
|
||||
};
|
||||
|
||||
if (typeof wx !== "undefined" && wx.getSystemInfoSync) {
|
||||
try {
|
||||
const sys = wx.getSystemInfoSync();
|
||||
if (sys && sys.platform === "devtools") {
|
||||
uni.showToast({
|
||||
title: "开发者工具可能不支持,请真机测试",
|
||||
duration: 2500,
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
} catch (e) {}
|
||||
icon: 'none',
|
||||
})
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
if (typeof wx !== "undefined" && wx.canIUse && wx.canIUse("requestMerchantTransfer")) {
|
||||
wx.requestMerchantTransfer({
|
||||
mchId,
|
||||
appId,
|
||||
package: wechatPackage,
|
||||
success: (r) => {
|
||||
openResultToast(r && (r.errMsg || r.err_msg));
|
||||
},
|
||||
fail: (r) => {
|
||||
openResultToast(r && (r.errMsg || r.err_msg));
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof WeixinJSBridge !== "undefined" && WeixinJSBridge.invoke) {
|
||||
WeixinJSBridge.invoke(
|
||||
"requestMerchantTransfer",
|
||||
{
|
||||
mchId,
|
||||
appId,
|
||||
package: wechatPackage,
|
||||
},
|
||||
(r) => {
|
||||
openResultToast(r && (r.errMsg || r.err_msg));
|
||||
}
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
uni.showToast({
|
||||
title: "请在微信内打开确认收款",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
if (typeof wx !== 'undefined' && wx.canIUse && wx.canIUse('requestMerchantTransfer')) {
|
||||
wx.requestMerchantTransfer({
|
||||
mchId,
|
||||
appId,
|
||||
package: wechatPackage,
|
||||
success: (r: any) => openResultToast(r && (r.errMsg || r.err_msg)),
|
||||
fail: (r: any) => openResultToast(r && (r.errMsg || r.err_msg)),
|
||||
})
|
||||
.finally(() => {
|
||||
uni.hideLoading();
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
return
|
||||
}
|
||||
|
||||
if (typeof WeixinJSBridge !== 'undefined' && WeixinJSBridge.invoke) {
|
||||
WeixinJSBridge.invoke(
|
||||
'requestMerchantTransfer',
|
||||
{ mchId, appId, package: wechatPackage },
|
||||
(r: any) => openResultToast(r && (r.errMsg || r.err_msg))
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
uni.showToast({ title: '请在微信内打开确认收款', duration: 2000, icon: 'none' })
|
||||
})
|
||||
.finally(() => {
|
||||
uni.hideLoading()
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -58,77 +58,68 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getUserWallet, withdrawalApply, withdrawalSettingVO } from "@/api/members";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
price: "",
|
||||
walletNum: 0,
|
||||
minPrice: 0,
|
||||
type: "",
|
||||
connectNumber: "",
|
||||
realName: "",
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
typeLabel() {
|
||||
if (this.type === "ALI") return "支付宝";
|
||||
if (this.type) return "微信";
|
||||
return "--";
|
||||
},
|
||||
},
|
||||
async mounted() {
|
||||
const result = await getUserWallet();
|
||||
const res = await withdrawalSettingVO();
|
||||
this.walletNum = result.data.result.memberWallet;
|
||||
this.minPrice = res.data.result.minPrice;
|
||||
this.type = res.data.result.type;
|
||||
},
|
||||
methods: {
|
||||
cashd() {
|
||||
const amount = Number(this.price);
|
||||
if (!this.$u.test.amount(parseInt(amount))) {
|
||||
uni.showToast({
|
||||
title: "请输入正确金额",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
return;
|
||||
}
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, getCurrentInstance, onMounted } from 'vue'
|
||||
import { getUserWallet, withdrawalApply, withdrawalSettingVO } from '@/api/members'
|
||||
import { unitPrice } from '@/utils/filters.js'
|
||||
|
||||
const params = { price: amount };
|
||||
if (this.type === "ALI") {
|
||||
if (!this.connectNumber || !this.realName) {
|
||||
uni.showToast({
|
||||
title: "请输入真实姓名和第三方登录账号",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
return;
|
||||
}
|
||||
params.connectNumber = this.connectNumber;
|
||||
params.realName = this.realName;
|
||||
}
|
||||
const { proxy } = getCurrentInstance()!
|
||||
|
||||
withdrawalApply(params).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({
|
||||
title: "提现成功!",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
setTimeout(() => {
|
||||
uni.navigateBack({ delta: 1 });
|
||||
}, 1000);
|
||||
}
|
||||
});
|
||||
},
|
||||
handleAll() {
|
||||
this.price = String(this.walletNum || "");
|
||||
},
|
||||
},
|
||||
};
|
||||
const price = ref('')
|
||||
const walletNum = ref(0)
|
||||
const minPrice = ref(0)
|
||||
const type = ref('')
|
||||
const connectNumber = ref('')
|
||||
const realName = ref('')
|
||||
|
||||
const typeLabel = computed(() => {
|
||||
if (type.value === 'ALI') return '支付宝'
|
||||
if (type.value) return '微信'
|
||||
return '--'
|
||||
})
|
||||
|
||||
onMounted(async () => {
|
||||
const result = await getUserWallet()
|
||||
const res = await withdrawalSettingVO()
|
||||
walletNum.value = result.data.result.memberWallet
|
||||
minPrice.value = res.data.result.minPrice
|
||||
type.value = res.data.result.type
|
||||
})
|
||||
|
||||
function cashd() {
|
||||
const amount = Number(price.value)
|
||||
if (!proxy.$u.test.amount(parseInt(String(amount)))) {
|
||||
uni.showToast({ title: '请输入正确金额', duration: 2000, icon: 'none' })
|
||||
return
|
||||
}
|
||||
|
||||
const params: Record<string, any> = { price: amount }
|
||||
if (type.value === 'ALI') {
|
||||
if (!connectNumber.value || !realName.value) {
|
||||
uni.showToast({
|
||||
title: '请输入真实姓名和第三方登录账号',
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
return
|
||||
}
|
||||
params.connectNumber = connectNumber.value
|
||||
params.realName = realName.value
|
||||
}
|
||||
|
||||
withdrawalApply(params).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({ title: '提现成功!', duration: 2000, icon: 'none' })
|
||||
setTimeout(() => {
|
||||
uni.navigateBack({ delta: 1 })
|
||||
}, 1000)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function handleAll() {
|
||||
price.value = String(walletNum.value || '')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
<template>
|
||||
|
||||
<view></view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
<script setup lang="ts">
|
||||
// 占位页,暂无业务逻辑
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
|
||||
@@ -3,160 +3,100 @@
|
||||
<view>
|
||||
<h4>实名认证(请上传真实的个人信息,认证通过后将无法修改)</h4>
|
||||
<view>
|
||||
<u-form :model="ruleForm" label-width="200rpx" ref="uForm">
|
||||
<u-form-item label="姓名" prop="name">
|
||||
<u-input v-model="ruleForm.name" placeholder="请输入您的真实姓名" />
|
||||
</u-form-item>
|
||||
<u-form-item label="身份证" prop="idNumber">
|
||||
<u-input v-model="ruleForm.idNumber" placeholder="请输入身份证号码" />
|
||||
</u-form-item>
|
||||
<u-form-item label="银行开户行" prop="settlementBankBranchName">
|
||||
<u-input v-model="ruleForm.settlementBankBranchName" type="text" placeholder="请输入银行开户行" />
|
||||
</u-form-item>
|
||||
<u-form-item label="银行开户名" prop="settlementBankAccountName">
|
||||
<u-input v-model="ruleForm.settlementBankAccountName" type="text" placeholder="请输入银行开户名" />
|
||||
</u-form-item>
|
||||
<u-form-item label="银行账号" prop="settlementBankAccountNum">
|
||||
<u-input v-model="ruleForm.settlementBankAccountNum" type="text" placeholder="请输入银行账号" />
|
||||
</u-form-item>
|
||||
<!-- <u-form-item label="身份证正面照" prop="name">
|
||||
<u-upload></u-upload>
|
||||
</u-form-item>
|
||||
<u-form-item label="身份证反面照" prop="name">
|
||||
<u-upload></u-upload>
|
||||
</u-form-item>
|
||||
<u-form-item label="手持身份证照" prop="name">
|
||||
<u-upload></u-upload>
|
||||
</u-form-item> -->
|
||||
</u-form>
|
||||
<u-button :customStyle="{'background':$lightColor,'color':'#fff' }" @click="submit">提交</u-button>
|
||||
<up-form
|
||||
:model="formData"
|
||||
label-position="left"
|
||||
label-width="180rpx"
|
||||
ref="uFormRef"
|
||||
>
|
||||
<up-form-item label="姓名" prop="name">
|
||||
<u-input v-model="formData.name" placeholder="请输入您的真实姓名" />
|
||||
</up-form-item>
|
||||
<up-form-item label="身份证" prop="idNumber">
|
||||
<u-input v-model="formData.idNumber" placeholder="请输入身份证号码" />
|
||||
</up-form-item>
|
||||
<up-form-item label="银行开户行" prop="settlementBankBranchName">
|
||||
<u-input v-model="formData.settlementBankBranchName" placeholder="请输入银行开户行" />
|
||||
</up-form-item>
|
||||
<up-form-item label="银行开户名" prop="settlementBankAccountName">
|
||||
<u-input v-model="formData.settlementBankAccountName" placeholder="请输入银行开户名" />
|
||||
</up-form-item>
|
||||
<up-form-item label="银行账号" prop="settlementBankAccountNum">
|
||||
<u-input v-model="formData.settlementBankAccountNum" placeholder="请输入银行账号" />
|
||||
</up-form-item>
|
||||
</up-form>
|
||||
<u-button :customStyle="{ background: lightColor, color: '#fff' }" @click="submitForm">提交</u-button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="tips">
|
||||
<view>您提交的信息正在审核</view>
|
||||
<view>提交认证申请后,工作人员将在三个工作日进行核对完成审核</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import { applyDistribution } from "@/api/goods";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
ruleForm: {
|
||||
name: "",
|
||||
idNumber: "",
|
||||
settlementBankBranchName: "", // 银行开户行
|
||||
settlementBankAccountName: "", //银行开户名
|
||||
settlementBankAccountNum: "", //银行账号
|
||||
},
|
||||
rules: {
|
||||
name: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入姓名",
|
||||
// 可以单个或者同时写两个触发验证方式
|
||||
trigger: "blur",
|
||||
},
|
||||
{
|
||||
// 自定义验证函数,见上说明
|
||||
validator: (rule, value, callback) => {
|
||||
// 上面有说,返回true表示校验通过,返回false表示不通过
|
||||
// this.$u.test.mobile()就是返回true或者false的
|
||||
return this.$u.test.chinese(value);
|
||||
},
|
||||
message: "姓名输入不正确",
|
||||
// 触发器可以同时用blur和change
|
||||
trigger: ["change", "blur"],
|
||||
},
|
||||
],
|
||||
// 银行开户行
|
||||
settlementBankBranchName: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入银行开户行",
|
||||
// 可以单个或者同时写两个触发验证方式
|
||||
trigger: "blur",
|
||||
},
|
||||
], //银行开户名
|
||||
settlementBankAccountName: [
|
||||
{
|
||||
required: true,
|
||||
message: "银行开户名",
|
||||
// 可以单个或者同时写两个触发验证方式
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
//银行账号
|
||||
settlementBankAccountNum: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入银行账号",
|
||||
// 可以单个或者同时写两个触发验证方式
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
idNumber: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入身份证",
|
||||
// 可以单个或者同时写两个触发验证方式
|
||||
trigger: "blur",
|
||||
},
|
||||
{
|
||||
// 自定义验证函数,见上说明
|
||||
validator: (rule, value, callback) => {
|
||||
// 上面有说,返回true表示校验通过,返回false表示不通过
|
||||
// this.$u.test.mobile()就是返回true或者false的
|
||||
return this.$u.test.idCard(value);
|
||||
},
|
||||
message: "身份证号码不正确",
|
||||
// 触发器可以同时用blur和change
|
||||
trigger: ["change", "blur"],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
submit() {
|
||||
this.$refs.uForm.validate((valid) => {
|
||||
if (valid) {
|
||||
applyDistribution(this.ruleForm).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({
|
||||
title: "认证提交成功!",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
uni.navigateBack();
|
||||
}, 500);
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.data.message,
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: "请填写有效信息",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
});
|
||||
<script setup lang="ts">
|
||||
import { reactive, computed, ref, getCurrentInstance } from 'vue'
|
||||
import { onReady } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { applyDistribution } from '@/api/goods'
|
||||
|
||||
const store = useStore()
|
||||
const { proxy } = getCurrentInstance()!
|
||||
|
||||
const lightColor = computed(() => store.getters.lightColor)
|
||||
const uFormRef = ref<any>(null)
|
||||
|
||||
const formData = reactive({
|
||||
name: '',
|
||||
idNumber: '',
|
||||
settlementBankBranchName: '',
|
||||
settlementBankAccountName: '',
|
||||
settlementBankAccountNum: '',
|
||||
})
|
||||
|
||||
const rules = {
|
||||
name: [
|
||||
{ required: true, message: '请输入姓名', trigger: 'blur' },
|
||||
{
|
||||
validator: (_rule: unknown, value: string) => proxy.$u.test.chinese(value),
|
||||
message: '姓名输入不正确',
|
||||
trigger: ['change', 'blur'],
|
||||
},
|
||||
},
|
||||
onReady() {
|
||||
this.$refs.uForm.setRules(this.rules);
|
||||
},
|
||||
};
|
||||
],
|
||||
settlementBankBranchName: [{ required: true, message: '请输入银行开户行', trigger: 'blur' }],
|
||||
settlementBankAccountName: [{ required: true, message: '银行开户名', trigger: 'blur' }],
|
||||
settlementBankAccountNum: [{ required: true, message: '请输入银行账号', trigger: 'blur' }],
|
||||
idNumber: [
|
||||
{ required: true, message: '请输入身份证', trigger: 'blur' },
|
||||
{
|
||||
validator: (_rule: unknown, value: string) => proxy.$u.test.idCard(value),
|
||||
message: '身份证号码不正确',
|
||||
trigger: ['change', 'blur'],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
onReady(() => {
|
||||
uFormRef.value?.setRules(rules)
|
||||
})
|
||||
|
||||
function submitForm() {
|
||||
uFormRef.value?.validate().then(() => {
|
||||
applyDistribution(formData).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({ title: '认证提交成功!', duration: 2000, icon: 'none' })
|
||||
setTimeout(() => uni.navigateBack(), 500)
|
||||
} else {
|
||||
uni.showToast({ title: res.data.message, duration: 2000, icon: 'none' })
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
uni.showToast({ title: '请填写有效信息', duration: 2000, icon: 'none' })
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.wrapper {
|
||||
padding: 32rpx;
|
||||
|
||||
@@ -1,30 +1,38 @@
|
||||
<template>
|
||||
<view class="log-list">
|
||||
<!-- 提现记录 -->
|
||||
<view class="log-way" v-if="cashLogData.length != 0" v-for="(item, index) in cashLogData" :key="index">
|
||||
<view
|
||||
class="log-way"
|
||||
v-if="withdrawLogList.length != 0"
|
||||
v-for="(item, index) in withdrawLogList"
|
||||
:key="'cash-' + index"
|
||||
>
|
||||
<view class="log-item">
|
||||
<view class="log-item-view">
|
||||
<view class="title">{{
|
||||
item.distributionCashStatus == "APPLY"
|
||||
? "待处理"
|
||||
: item.distributionCashStatus == "VIA_AUDITING"
|
||||
? "通过"
|
||||
: "拒绝"
|
||||
item.distributionCashStatus == 'APPLY'
|
||||
? '待处理'
|
||||
: item.distributionCashStatus == 'VIA_AUDITING'
|
||||
? '通过'
|
||||
: '拒绝'
|
||||
}}</view>
|
||||
<view class="price">+{{unitPrice(item.price) }}</view>
|
||||
<view class="price">+{{ unitPrice(item.price) }}</view>
|
||||
</view>
|
||||
<view class="log-item-view">
|
||||
<view>{{ item.createTime }}</view>
|
||||
<view></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 分销业绩 -->
|
||||
<view class="log-way" v-if="achievementData.length != 0" v-for="(item, index) in achievementData" :key="index">
|
||||
|
||||
<view
|
||||
class="log-way"
|
||||
v-if="achievementList.length != 0"
|
||||
v-for="(item, index) in achievementList"
|
||||
:key="'ach-' + index"
|
||||
>
|
||||
<view class="log-item">
|
||||
<view class="log-item-view">
|
||||
<view class="title">{{ item.goodsName }}</view>
|
||||
<view class="price">提成金额:+{{unitPrice(item.rebate) }}</view>
|
||||
<view class="price">提成金额:+{{ unitPrice(item.rebate) }}</view>
|
||||
</view>
|
||||
<view class="log-item-view">
|
||||
<view>创建时间:{{ item.createTime }}</view>
|
||||
@@ -38,101 +46,98 @@
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="empty" v-if="empty">
|
||||
<u-loadmore :status="status" :icon-type="iconType" bg-color="#f7f7f7" />
|
||||
|
||||
<view class="empty" v-if="isEmpty">
|
||||
<u-loadmore :status="loadStatus" :icon-type="iconType" bg-color="#f7f7f7" />
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import { cashLog, distributionOrderList } from "@/api/goods";
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
cashLogData: [], //提现记录数据集合
|
||||
achievementData: [], //分销业绩数据合集,
|
||||
status: "loadmore",
|
||||
iconType: "flower",
|
||||
empty: false,
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
|
||||
type: 0,
|
||||
routers: "",
|
||||
achParams: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
};
|
||||
},
|
||||
onLoad (option) {
|
||||
let title;
|
||||
option.type == 0 ? (title = "分销业绩") : (title = "提现记录");
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad, onReachBottom } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { cashLog, distributionOrderList } from '@/api/goods'
|
||||
import { unitPrice } from '@/utils/filters.js'
|
||||
|
||||
uni.setNavigationBarTitle({
|
||||
title: title, //这是修改后的导航栏文字
|
||||
});
|
||||
this.routers = option;
|
||||
this.type = option.type;
|
||||
option.type == 0 ? this.achievement() : this.history();
|
||||
},
|
||||
mounted () { },
|
||||
onReachBottom () {
|
||||
this.status = "loading";
|
||||
this.type == 0 ? this.achParams.pageNumber++ : this.params.pageNumber++;
|
||||
this.type == 0 ? this.achievement() : this.history();
|
||||
},
|
||||
methods: {
|
||||
// 业绩
|
||||
achievement () {
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
distributionOrderList(this.achParams).then((res) => {
|
||||
if (res.data.success && res.data.result.records.length >= 1) {
|
||||
this.achievementData.push(...res.data.result.records);
|
||||
} else {
|
||||
this.status = "nomore";
|
||||
this.empty = true;
|
||||
}
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
});
|
||||
},
|
||||
// 初始化提现历史
|
||||
history () {
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
cashLog(this.params).then((res) => {
|
||||
if (res.data.success && res.data.result.records.length >= 1) {
|
||||
this.cashLogData.push(...res.data.result.records);
|
||||
} else {
|
||||
this.status = "nomore";
|
||||
this.empty = true;
|
||||
}
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
const store = useStore()
|
||||
|
||||
const withdrawLogList = ref<any[]>([])
|
||||
const achievementList = ref<any[]>([])
|
||||
const loadStatus = ref('loadmore')
|
||||
const iconType = ref('flower')
|
||||
const isEmpty = ref(false)
|
||||
const listType = ref(0)
|
||||
const routeQuery = ref<Record<string, string>>({})
|
||||
|
||||
const withdrawParams = ref({ pageNumber: 1, pageSize: 10 })
|
||||
const achievementParams = ref({ pageNumber: 1, pageSize: 10 })
|
||||
|
||||
onLoad((option) => {
|
||||
const type = Number(option.type ?? 0)
|
||||
listType.value = type
|
||||
routeQuery.value = option || {}
|
||||
uni.setNavigationBarTitle({
|
||||
title: type === 0 ? '分销业绩' : '提现记录',
|
||||
})
|
||||
type === 0 ? fetchAchievementList() : fetchWithdrawLog()
|
||||
})
|
||||
|
||||
onReachBottom(() => {
|
||||
loadStatus.value = 'loading'
|
||||
if (listType.value === 0) {
|
||||
achievementParams.value.pageNumber++
|
||||
fetchAchievementList()
|
||||
} else {
|
||||
withdrawParams.value.pageNumber++
|
||||
fetchWithdrawLog()
|
||||
}
|
||||
})
|
||||
|
||||
function hideLoadingIfNeeded() {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
}
|
||||
|
||||
function fetchAchievementList() {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
distributionOrderList(achievementParams.value).then((res) => {
|
||||
if (res.data.success && res.data.result.records.length >= 1) {
|
||||
achievementList.value.push(...res.data.result.records)
|
||||
} else {
|
||||
loadStatus.value = 'nomore'
|
||||
isEmpty.value = true
|
||||
}
|
||||
hideLoadingIfNeeded()
|
||||
})
|
||||
}
|
||||
|
||||
function fetchWithdrawLog() {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
cashLog(withdrawParams.value).then((res) => {
|
||||
if (res.data.success && res.data.result.records.length >= 1) {
|
||||
withdrawLogList.value.push(...res.data.result.records)
|
||||
} else {
|
||||
loadStatus.value = 'nomore'
|
||||
isEmpty.value = true
|
||||
}
|
||||
hideLoadingIfNeeded()
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.empty {
|
||||
margin: 40rpx 0;
|
||||
}
|
||||
|
||||
.price {
|
||||
color: $main-color;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.log-list {
|
||||
padding: 0 8rpx;
|
||||
overflow: hidden;
|
||||
margin: 20rpx 0;
|
||||
}
|
||||
|
||||
.log-way {
|
||||
margin: 10rpx 0;
|
||||
overflow: hidden;
|
||||
@@ -140,26 +145,17 @@ export default {
|
||||
border-radius: 10rpx;
|
||||
padding: 20rpx 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 30rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.log-item-view {
|
||||
padding: 8rpx 32rpx;
|
||||
display: flex;
|
||||
font-size: 13px;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.log-item-footer {
|
||||
padding: 8rpx 32rpx;
|
||||
display: flex;
|
||||
font-size: 13px;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.log-item-footer,
|
||||
.log-item-footers {
|
||||
padding: 8rpx 32rpx;
|
||||
display: flex;
|
||||
|
||||
@@ -1,18 +1,15 @@
|
||||
<template>
|
||||
<view>
|
||||
|
||||
<view class="nav-list">
|
||||
<view class="total">可提现金额</view>
|
||||
<view class="price">{{unitPrice(distributionData.canRebate) }}</view>
|
||||
<view class="frozen"
|
||||
>冻结金额{{unitPrice(distributionData.commissionFrozen) }}</view
|
||||
>
|
||||
<view class="price">{{ unitPrice(distributionData.canRebate) }}</view>
|
||||
<view class="frozen">冻结金额{{ unitPrice(distributionData.commissionFrozen) }}</view>
|
||||
</view>
|
||||
<view class="nav">
|
||||
<view class="nav-item">
|
||||
<u-icon
|
||||
size="50"
|
||||
@click="handleClick('/pages/mine/distribution/list?id='+distributionData.id+'&name='+distributionData.memberName)"
|
||||
@click="navigateTo(`/pages/mine/distribution/list?id=${distributionData.id}&name=${distributionData.memberName}`)"
|
||||
color="#ff6b35"
|
||||
name="bag-fill"
|
||||
></u-icon>
|
||||
@@ -20,72 +17,54 @@
|
||||
</view>
|
||||
<view
|
||||
class="nav-item"
|
||||
@click="handleClick(`/pages/mine/distribution/history?type=0&id=${distributionData.id}&name=${distributionData.memberName}`)"
|
||||
@click="navigateTo(`/pages/mine/distribution/history?type=0&id=${distributionData.id}&name=${distributionData.memberName}`)"
|
||||
>
|
||||
<u-icon size="50" color="#ff6b35" name="order"></u-icon>
|
||||
<view>分销业绩</view>
|
||||
</view>
|
||||
<view
|
||||
class="nav-item"
|
||||
@click="handleClick('/pages/mine/distribution/history?type=1')"
|
||||
>
|
||||
<view class="nav-item" @click="navigateTo('/pages/mine/distribution/history?type=1')">
|
||||
<u-icon size="50" color="#ff6b35" name="red-packet-fill"></u-icon>
|
||||
<view>提现记录</view>
|
||||
</view>
|
||||
<view
|
||||
class="nav-item"
|
||||
@click="handleClick('/pages/mine/distribution/withdrawal')"
|
||||
>
|
||||
<view class="nav-item" @click="navigateTo('/pages/mine/distribution/withdrawal')">
|
||||
<u-icon size="50" color="#ffc71c" name="rmb-circle-fill"></u-icon>
|
||||
<view>提现</view>
|
||||
</view>
|
||||
|
||||
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onShow } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { distribution } from '@/api/goods'
|
||||
import { unitPrice } from '@/utils/filters.js'
|
||||
|
||||
import { distribution } from "@/api/goods";
|
||||
export default {
|
||||
const store = useStore()
|
||||
const distributionData = ref<Record<string, any>>({})
|
||||
|
||||
data() {
|
||||
return {
|
||||
distributionData: "",
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
handleClick(url) {
|
||||
uni.navigateTo({
|
||||
url,
|
||||
});
|
||||
},
|
||||
queryGoods(src) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/mine/distribution/${src}`,
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 初始化推广商品
|
||||
*/
|
||||
init() {
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
distribution().then((res) => {
|
||||
if (res.data.result) {
|
||||
this.distributionData = res.data.result;
|
||||
}
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
});
|
||||
},
|
||||
},
|
||||
onShow() {
|
||||
this.init();
|
||||
},
|
||||
};
|
||||
onShow(() => {
|
||||
fetchDistributionInfo()
|
||||
})
|
||||
|
||||
function hideLoadingIfNeeded() {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
}
|
||||
|
||||
function navigateTo(url: string) {
|
||||
uni.navigateTo({ url })
|
||||
}
|
||||
|
||||
function fetchDistributionInfo() {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
distribution().then((res) => {
|
||||
if (res.data.result) {
|
||||
distributionData.value = res.data.result
|
||||
}
|
||||
hideLoadingIfNeeded()
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@@ -124,6 +103,5 @@ export default {
|
||||
justify-content: center;
|
||||
gap: 20rpx;
|
||||
width: 33%;
|
||||
// color: #fff;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,104 +1,127 @@
|
||||
<template>
|
||||
<view class="wrapper">
|
||||
<view class="wrapper" :style="themeStyle">
|
||||
<u-tabs
|
||||
:list="list"
|
||||
:list="stepList"
|
||||
:scrollable="false"
|
||||
v-model:current="current"
|
||||
v-model:current="currentStep"
|
||||
:lineColor="lightColor"
|
||||
:activeStyle="{ color: lightColor }"
|
||||
></u-tabs>
|
||||
|
||||
|
||||
|
||||
<!-- 推广人资料 -->
|
||||
<view class="message">
|
||||
<u-form :model="ruleForm" label-width="250rpx" ref="uForm">
|
||||
<u-form-item label="会员昵称" prop="name">
|
||||
<u-input v-model="ruleForm.name" />
|
||||
</u-form-item>
|
||||
<u-form-item label="账户类型" prop="name"> </u-form-item>
|
||||
<u-form-item
|
||||
label="收款人姓名"
|
||||
placeholder="请输入收款人姓名"
|
||||
prop="name"
|
||||
>
|
||||
<u-input v-model="ruleForm.name" />
|
||||
</u-form-item>
|
||||
<u-form-item
|
||||
label="收款账号"
|
||||
placeholder="请输入收款人账号"
|
||||
prop="name"
|
||||
>
|
||||
<u-input v-model="ruleForm.name" />
|
||||
</u-form-item>
|
||||
<u-form-item
|
||||
label="银行名称"
|
||||
placeholder="请输入开户银行支行名称"
|
||||
prop="name"
|
||||
>
|
||||
<u-input v-model="ruleForm.name" />
|
||||
</u-form-item>
|
||||
</u-form>
|
||||
<u-button :customStyle="{'background':$lightColor,'color':'#fff' }" @click="submit">提交</u-button>
|
||||
<view class="feedBack-box">
|
||||
<up-form
|
||||
:model="formData"
|
||||
label-position="top"
|
||||
ref="uFormRef"
|
||||
>
|
||||
<up-form-item label="会员昵称" prop="name">
|
||||
<u-input
|
||||
border="none"
|
||||
class="field-input"
|
||||
v-model="formData.name"
|
||||
:custom-style="fieldInputStyle"
|
||||
/>
|
||||
</up-form-item>
|
||||
<up-form-item label="账户类型" prop="name"></up-form-item>
|
||||
<up-form-item label="收款人姓名" prop="name">
|
||||
<u-input
|
||||
border="none"
|
||||
class="field-input"
|
||||
v-model="formData.name"
|
||||
placeholder="请输入收款人姓名"
|
||||
:custom-style="fieldInputStyle"
|
||||
/>
|
||||
</up-form-item>
|
||||
<up-form-item label="收款账号" prop="name">
|
||||
<u-input
|
||||
border="none"
|
||||
class="field-input"
|
||||
v-model="formData.name"
|
||||
placeholder="请输入收款人账号"
|
||||
:custom-style="fieldInputStyle"
|
||||
/>
|
||||
</up-form-item>
|
||||
<up-form-item label="银行名称" prop="name">
|
||||
<u-input
|
||||
border="none"
|
||||
class="field-input"
|
||||
v-model="formData.name"
|
||||
placeholder="请输入开户银行支行名称"
|
||||
:custom-style="fieldInputStyle"
|
||||
/>
|
||||
</up-form-item>
|
||||
</up-form>
|
||||
</view>
|
||||
|
||||
<view class="submit" @click="submitForm">提交</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
components: {},
|
||||
// 必须要在onReady生命周期,因为onLoad生命周期组件可能尚未创建完毕
|
||||
onReady() {
|
||||
this.$refs.uForm.setRules(this.rules);
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
current:0,
|
||||
lightColor: this.$lightColor,
|
||||
list: [
|
||||
{
|
||||
name: "推广人资料",
|
||||
},
|
||||
{
|
||||
name: "平台审核",
|
||||
},
|
||||
{
|
||||
name: "完成",
|
||||
},
|
||||
],
|
||||
ruleForm: {
|
||||
name: "",
|
||||
radio: "",
|
||||
},
|
||||
rules: {
|
||||
name: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入姓名",
|
||||
// 可以单个或者同时写两个触发验证方式
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed } from 'vue'
|
||||
import { onReady } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { getThemeStyle } from '@/utils/theme'
|
||||
import { fieldInputStyle } from '@/utils/form-style.js'
|
||||
|
||||
const store = useStore()
|
||||
|
||||
const themeStyle = computed(() => getThemeStyle(store.state.theme))
|
||||
const lightColor = computed(() => store.getters.lightColor)
|
||||
const currentStep = ref(0)
|
||||
const uFormRef = ref<any>(null)
|
||||
|
||||
const stepList = [
|
||||
{ name: '推广人资料' },
|
||||
{ name: '平台审核' },
|
||||
{ name: '完成' },
|
||||
]
|
||||
|
||||
const formData = reactive({
|
||||
name: '',
|
||||
radio: '',
|
||||
})
|
||||
|
||||
const rules = {
|
||||
name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
|
||||
}
|
||||
|
||||
onReady(() => {
|
||||
uFormRef.value?.setRules(rules)
|
||||
})
|
||||
|
||||
function submitForm() {
|
||||
uFormRef.value?.validate().catch(() => {
|
||||
uni.showToast({ title: '请填写有效信息', icon: 'none' })
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.menu {
|
||||
height: 88rpx;
|
||||
line-height: 88rpx;
|
||||
background: $main-color;
|
||||
display: flex;
|
||||
> .menu-item {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
color: $light-color;
|
||||
}
|
||||
}
|
||||
.active {
|
||||
color: #fff !important;
|
||||
}
|
||||
.message {
|
||||
padding: 0 32rpx;
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background: #f8f8f8;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '@/pages/passport/entry/seller/entry-form.scss';
|
||||
|
||||
.wrapper {
|
||||
box-sizing: border-box;
|
||||
min-height: 100vh;
|
||||
padding: 20rpx 24rpx 40rpx;
|
||||
background: #f8f8f8;
|
||||
@include seller-entry-form;
|
||||
}
|
||||
|
||||
.feedBack-box {
|
||||
background: #fff;
|
||||
border-radius: 20rpx;
|
||||
padding: 32rpx;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
|
||||
.submit {
|
||||
@include seller-entry-submit;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -58,44 +58,44 @@
|
||||
|
||||
<!-- 导航栏 -->
|
||||
<view class="nav">
|
||||
<view class="nav-item" @click="handleMyGoods(true)" :class="{ checked: params.checked }">已选择</view>
|
||||
<view class="nav-item" @click="handleMyGoods(false)" :class="{ checked: !params.checked }">未选择</view>
|
||||
<view class="nav-item" @click="toggleGoodsTab(true)" :class="{ checked: queryParams.checked }">已选择</view>
|
||||
<view class="nav-item" @click="toggleGoodsTab(false)" :class="{ checked: !queryParams.checked }">未选择</view>
|
||||
|
||||
<!-- <view class="nav-item" @click="popup = !popup">筛选</view> -->
|
||||
</view>
|
||||
<!-- 商品列表 -->
|
||||
|
||||
<view class="goods-list">
|
||||
<scroll-view class="body-view" scroll-y @scrolltolower="renderDate">
|
||||
<scroll-view class="body-view" scroll-y @scrolltolower="loadMore">
|
||||
<block v-for="(item, index) in goodsList" :key="item.id">
|
||||
<u-swipe-action v-if="params.checked" class="distribution-swipe">
|
||||
<u-swipe-action v-if="queryParams.checked" class="distribution-swipe">
|
||||
<u-swipe-action-item
|
||||
:show="item.___selected"
|
||||
@open="openAction(item)"
|
||||
@open="openSwipeAction(item)"
|
||||
:name="index"
|
||||
:options="options"
|
||||
@click="changeActionTab(item)"
|
||||
:options="swipeOptions"
|
||||
@click="confirmUnbindPrompt(item)"
|
||||
>
|
||||
<view class="goods-item">
|
||||
<view class="goods-item-img" @click="handleNavgationGoods(item)">
|
||||
<view class="goods-item-img" @click="navigateToGoods(item)">
|
||||
<u-image width="176rpx" height="176rpx" :src="item.thumbnail"></u-image>
|
||||
</view>
|
||||
<view class="goods-item-desc">
|
||||
<view class="-item-title" @click="handleNavgationGoods(item)">
|
||||
<view class="-item-title" @click="navigateToGoods(item)">
|
||||
{{ item.goodsName }}
|
||||
</view>
|
||||
<view class="-item-price" @click="handleNavgationGoods(item)">
|
||||
<view class="-item-price" @click="navigateToGoods(item)">
|
||||
佣金:
|
||||
<span> ¥{{ unitPrice(item.commission) }}</span>
|
||||
</view>
|
||||
<view class="-item-bottom">
|
||||
<view class="-item-bootom-money" @click="handleNavgationGoods(item)">
|
||||
<view class="-item-bootom-money" @click="navigateToGoods(item)">
|
||||
<view class="-item-yj">
|
||||
<span>¥{{ unitPrice(item.price) }}</span>
|
||||
</view>
|
||||
</view>
|
||||
<view>
|
||||
<view class="click" @click="handleLink(item)">分销商品</view>
|
||||
<view class="click" @click="shareDistributionGoods(item)">分销商品</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -104,25 +104,25 @@
|
||||
</u-swipe-action>
|
||||
|
||||
<view v-else class="goods-item">
|
||||
<view class="goods-item-img" @click="handleNavgationGoods(item)">
|
||||
<view class="goods-item-img" @click="navigateToGoods(item)">
|
||||
<u-image width="176rpx" height="176rpx" :src="item.thumbnail"></u-image>
|
||||
</view>
|
||||
<view class="goods-item-desc">
|
||||
<view class="-item-title" @click="handleNavgationGoods(item)">
|
||||
<view class="-item-title" @click="navigateToGoods(item)">
|
||||
{{ item.goodsName }}
|
||||
</view>
|
||||
<view class="-item-price" @click="handleNavgationGoods(item)">
|
||||
<view class="-item-price" @click="navigateToGoods(item)">
|
||||
佣金:
|
||||
<span> ¥{{ unitPrice(item.commission) }}</span>
|
||||
</view>
|
||||
<view class="-item-bottom">
|
||||
<view class="-item-bootom-money" @click="handleNavgationGoods(item)">
|
||||
<view class="-item-bootom-money" @click="navigateToGoods(item)">
|
||||
<view class="-item-yj">
|
||||
<span>¥{{ unitPrice(item.price) }}</span>
|
||||
</view>
|
||||
</view>
|
||||
<view>
|
||||
<view class="click" @click="handleClickGoods(item)">立即选取</view>
|
||||
<view class="click" @click="selectGoods(item)">立即选取</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -136,210 +136,164 @@
|
||||
</view>
|
||||
</view>
|
||||
<canvas class="canvas-hide" canvas-id="qrcode" />
|
||||
<drawCanvas ref="drawCanvas" v-if="showFlag" :res="res" />
|
||||
<u-modal v-model:show="deleteShow" :confirm-style="{'color':lightColor}" @confirm="delectConfirm" show-cancel-button :content="deleteContent" :async-close="true"></u-modal>
|
||||
<drawCanvas ref="drawCanvasRef" v-if="showPoster" :res="posterData" />
|
||||
<u-modal
|
||||
v-model:show="showUnbindModal"
|
||||
:confirm-style="{ color: lightColor }"
|
||||
@confirm="confirmUnbind"
|
||||
show-cancel-button
|
||||
:content="unbindModalContent"
|
||||
:async-close="true"
|
||||
></u-modal>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { onLoad, onShow } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import {
|
||||
distributionGoods,
|
||||
checkedDistributionGoods,
|
||||
getMpCode,
|
||||
} from "@/api/goods";
|
||||
} from '@/api/goods'
|
||||
import drawCanvas from '@/components/m-canvas'
|
||||
import { unitPrice } from '@/utils/filters.js'
|
||||
|
||||
import drawCanvas from "@/components/m-canvas";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
lightColor: this.$lightColor,
|
||||
deleteContent: "解绑该商品?", //删除显示的信息
|
||||
// 商品栏右侧滑动按钮
|
||||
options: [
|
||||
{
|
||||
text: "解绑",
|
||||
style: {
|
||||
backgroundColor: this.$lightColor, //高亮颜色
|
||||
},
|
||||
},
|
||||
],
|
||||
showFlag: false, //分销分享开关
|
||||
empty: false,
|
||||
popup: false, //弹出层开关
|
||||
active_color: this.$mainColor,
|
||||
current: 0,
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
checked: true,
|
||||
},
|
||||
goodsList: [],
|
||||
|
||||
// 分销分享 实例
|
||||
res: {
|
||||
container: {
|
||||
width: 600,
|
||||
height: 960,
|
||||
background: "#fff",
|
||||
title: "分享背景",
|
||||
},
|
||||
// 分销分享
|
||||
bottom: {
|
||||
img: "",
|
||||
code: "",
|
||||
price: 0,
|
||||
},
|
||||
},
|
||||
|
||||
routers: "",
|
||||
deleteShow: false, //删除模态框
|
||||
goodsVal: false, //分销商铺信息
|
||||
};
|
||||
const store = useStore()
|
||||
const lightColor = computed(() => store.getters.lightColor)
|
||||
const swipeOptions = computed(() => [
|
||||
{
|
||||
text: '解绑',
|
||||
style: { backgroundColor: lightColor.value },
|
||||
},
|
||||
components: {
|
||||
drawCanvas,
|
||||
])
|
||||
|
||||
const unbindModalContent = '解绑该商品?'
|
||||
const showPoster = ref(false)
|
||||
const showUnbindModal = ref(false)
|
||||
const routeQuery = ref<Record<string, string>>({})
|
||||
const selectedGoods = ref<any>(null)
|
||||
const drawCanvasRef = ref<any>(null)
|
||||
|
||||
const queryParams = ref({
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
checked: true,
|
||||
})
|
||||
const goodsList = ref<any[]>([])
|
||||
|
||||
const posterData = ref({
|
||||
container: {
|
||||
width: 600,
|
||||
height: 960,
|
||||
background: '#fff',
|
||||
title: '分享背景',
|
||||
},
|
||||
onLoad(options) {
|
||||
this.routers = options;
|
||||
bottom: {
|
||||
img: '',
|
||||
code: '',
|
||||
price: 0,
|
||||
desc: '',
|
||||
},
|
||||
watch: {},
|
||||
onShow() {
|
||||
this.goodsList = [];
|
||||
this.init();
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 滑动删除
|
||||
*/
|
||||
changeActionTab(val) {
|
||||
this.deleteShow = true;
|
||||
this.goodsVal = val;
|
||||
},
|
||||
})
|
||||
|
||||
/**
|
||||
* 点击解绑商品
|
||||
*/
|
||||
delectConfirm() {
|
||||
checkedDistributionGoods({ id: this.goodsVal.id, checked: false }).then(
|
||||
(res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({
|
||||
title: "此商品解绑成功",
|
||||
duration: 2000,
|
||||
});
|
||||
this.deleteShow = false;
|
||||
this.goodsList = [];
|
||||
this.init();
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
onLoad((options) => {
|
||||
routeQuery.value = options || {}
|
||||
})
|
||||
|
||||
/**
|
||||
* 左滑打开删除
|
||||
*/
|
||||
openAction(val) {
|
||||
this.goodsList.forEach((item) => {
|
||||
item["___selected"] = false;
|
||||
});
|
||||
val["___selected"] = true;
|
||||
},
|
||||
onShow(() => {
|
||||
goodsList.value = []
|
||||
queryParams.value.pageNumber = 1
|
||||
fetchGoodsList()
|
||||
})
|
||||
|
||||
/**
|
||||
* 查看图片
|
||||
*/
|
||||
handleNavgationGoods(val) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/product/goods?id=${val.skuId}&goodsId=${val.goodsId}`,
|
||||
});
|
||||
},
|
||||
function confirmUnbindPrompt(item: any) {
|
||||
showUnbindModal.value = true
|
||||
selectedGoods.value = item
|
||||
}
|
||||
|
||||
async handleLink(goods) {
|
||||
uni.showToast({
|
||||
title: "请请按住保存图片",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
let page = `pages/product/goods`;
|
||||
let scene = `${goods.skuId},${goods.goodsId},${this.routers.id}`;
|
||||
let result = await getMpCode({ page, scene });
|
||||
if (result.data.success) {
|
||||
let callback = result.data.result;
|
||||
this.res.container.title = `${goods.goodsName}`;
|
||||
this.res.bottom.code = `data:image/png;base64,${callback}`;
|
||||
this.res.bottom.price = this.unitPrice(
|
||||
goods.price,
|
||||
"¥"
|
||||
);
|
||||
this.res.bottom.desc = `${goods.goodsName}`;
|
||||
this.res.bottom.img = `${goods.thumbnail}`;
|
||||
function confirmUnbind() {
|
||||
checkedDistributionGoods({ id: selectedGoods.value.id, checked: false }).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({ title: '此商品解绑成功', duration: 2000 })
|
||||
showUnbindModal.value = false
|
||||
goodsList.value = []
|
||||
queryParams.value.pageNumber = 1
|
||||
fetchGoodsList()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (this.showFlag) {
|
||||
this.$refs.drawCanvas.init();
|
||||
}
|
||||
this.showFlag = true;
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: `制作二维码失败!请稍后重试`,
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
},
|
||||
function openSwipeAction(item: any) {
|
||||
goodsList.value.forEach((row) => {
|
||||
row.___selected = false
|
||||
})
|
||||
item.___selected = true
|
||||
}
|
||||
|
||||
change(index) {
|
||||
this.current = index;
|
||||
},
|
||||
// 点击我的选品库
|
||||
handleMyGoods(flag) {
|
||||
this.goodsList = [];
|
||||
this.params.checked = flag;
|
||||
this.init();
|
||||
},
|
||||
function navigateToGoods(item: any) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/product/goods?id=${item.skuId}&goodsId=${item.goodsId}`,
|
||||
})
|
||||
}
|
||||
|
||||
// 选择商品
|
||||
handleClickGoods(val) {
|
||||
checkedDistributionGoods({ id: val.id, checked: true }).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({
|
||||
title: "已添加到我的选品库",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
async function shareDistributionGoods(goods: any) {
|
||||
uni.showToast({ title: '请请按住保存图片', duration: 2000, icon: 'none' })
|
||||
const page = 'pages/product/goods'
|
||||
const scene = `${goods.skuId},${goods.goodsId},${routeQuery.value.id}`
|
||||
const result = await getMpCode({ page, scene })
|
||||
if (result.data.success) {
|
||||
const callback = result.data.result
|
||||
posterData.value.container.title = `${goods.goodsName}`
|
||||
posterData.value.bottom.code = `data:image/png;base64,${callback}`
|
||||
posterData.value.bottom.price = unitPrice(goods.price, '¥')
|
||||
posterData.value.bottom.desc = `${goods.goodsName}`
|
||||
posterData.value.bottom.img = `${goods.thumbnail}`
|
||||
if (showPoster.value) {
|
||||
drawCanvasRef.value?.init()
|
||||
}
|
||||
showPoster.value = true
|
||||
} else {
|
||||
uni.showToast({ title: '制作二维码失败!请稍后重试', duration: 2000, icon: 'none' })
|
||||
}
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
this.goodsList = [];
|
||||
this.init();
|
||||
}, 500);
|
||||
}
|
||||
});
|
||||
},
|
||||
function toggleGoodsTab(isSelected: boolean) {
|
||||
goodsList.value = []
|
||||
queryParams.value.checked = isSelected
|
||||
queryParams.value.pageNumber = 1
|
||||
fetchGoodsList()
|
||||
}
|
||||
|
||||
init() {
|
||||
distributionGoods(this.params).then((res) => {
|
||||
if (res.data.success && res.data.result.records.length >= 1) {
|
||||
res.data.result.records.forEach((item) => {
|
||||
item["___selected"] = false;
|
||||
});
|
||||
this.goodsList.push(...res.data.result.records);
|
||||
}
|
||||
if (this.goodsList.length === 0) {
|
||||
this.empty = true;
|
||||
}
|
||||
});
|
||||
},
|
||||
function selectGoods(item: any) {
|
||||
checkedDistributionGoods({ id: item.id, checked: true }).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({ title: '已添加到我的选品库', duration: 2000, icon: 'none' })
|
||||
setTimeout(() => {
|
||||
goodsList.value = []
|
||||
queryParams.value.pageNumber = 1
|
||||
fetchGoodsList()
|
||||
}, 500)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 底部加载数据
|
||||
*/
|
||||
renderDate() {
|
||||
function fetchGoodsList() {
|
||||
distributionGoods(queryParams.value).then((res) => {
|
||||
if (res.data.success && res.data.result.records.length >= 1) {
|
||||
res.data.result.records.forEach((item: any) => {
|
||||
item.___selected = false
|
||||
})
|
||||
goodsList.value.push(...res.data.result.records)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
this.params.pageNumber += 1;
|
||||
this.init();
|
||||
},
|
||||
|
||||
},
|
||||
};
|
||||
function loadMore() {
|
||||
queryParams.value.pageNumber += 1
|
||||
fetchGoodsList()
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
|
||||
|
||||
@@ -1,129 +1,182 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="withdrawal-list">
|
||||
<view class="title">提现金额</view>
|
||||
<view class="content">
|
||||
<view class="price">
|
||||
<span> ¥</span>
|
||||
<u-input v-model="price" placeholder="" type="number" />
|
||||
</view>
|
||||
|
||||
<view class="all">
|
||||
<view @click="handleAll" :style="{ color: $mainColor }">全部</view>
|
||||
<view style="font-size: 24rpx; color: #999"
|
||||
>可提现金额<span>{{unitPrice(distributionData.canRebate) }}</span
|
||||
>元</view
|
||||
>
|
||||
<view class="wrapper" :style="themeStyle">
|
||||
<view class="feedBack-box">
|
||||
<view class="box-title">提现金额</view>
|
||||
<view class="amount-row">
|
||||
<text class="currency">¥</text>
|
||||
<u-input
|
||||
v-model="price"
|
||||
type="digit"
|
||||
border="none"
|
||||
placeholder="请输入提现金额"
|
||||
class="amount-input"
|
||||
/>
|
||||
</view>
|
||||
<view class="amount-extra">
|
||||
<view class="all-btn" @click="fillAllAmount">全部</view>
|
||||
<view class="balance-tip">
|
||||
可提现金额
|
||||
<text class="balance-value">{{ unitPrice(distributionData.canRebate) }}</text>
|
||||
元
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="submit" @click="cashd">提现</view>
|
||||
<view class="submit" @click="submitWithdraw">提现</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import { distribution, cash } from "@/api/goods";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
price: 0,
|
||||
distributionData: "",
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
methods: {
|
||||
cashd() {
|
||||
this.price = this.price + "";
|
||||
|
||||
|
||||
if (this.$u.test.amount(parseInt(this.price))) {
|
||||
cash({ price: this.price }).then((res) => {
|
||||
if(res.data.success){
|
||||
uni.showToast({
|
||||
title: '提现成功!',
|
||||
duration: 2000,
|
||||
icon:"none"
|
||||
});
|
||||
setTimeout(()=>{
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
});
|
||||
},1000)
|
||||
}
|
||||
});
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: "请输入正确金额",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, getCurrentInstance, onMounted } from 'vue'
|
||||
import { useStore } from '@/store'
|
||||
import { distribution, cash } from '@/api/goods'
|
||||
import { unitPrice } from '@/utils/filters.js'
|
||||
import { getThemeStyle } from '@/utils/theme'
|
||||
|
||||
const store = useStore()
|
||||
const { proxy } = getCurrentInstance()!
|
||||
|
||||
const themeStyle = computed(() => getThemeStyle(store.state.theme))
|
||||
const price = ref('')
|
||||
const distributionData = ref<Record<string, any>>({})
|
||||
|
||||
onMounted(() => {
|
||||
fetchDistributionInfo()
|
||||
})
|
||||
|
||||
function hideLoadingIfNeeded() {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
}
|
||||
|
||||
function fetchDistributionInfo() {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
distribution().then((res) => {
|
||||
if (res.data.result) {
|
||||
distributionData.value = res.data.result
|
||||
}
|
||||
hideLoadingIfNeeded()
|
||||
})
|
||||
}
|
||||
|
||||
function submitWithdraw() {
|
||||
const amount = String(price.value ?? '')
|
||||
if (proxy.$u.test.amount(parseInt(amount))) {
|
||||
cash({ price: amount }).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({ title: '提现成功!', duration: 2000, icon: 'none' })
|
||||
setTimeout(() => {
|
||||
uni.navigateBack({ delta: 1 })
|
||||
}, 1000)
|
||||
}
|
||||
},
|
||||
handleAll() {
|
||||
this.price = this.distributionData.canRebate;
|
||||
},
|
||||
/**
|
||||
* 初始化推广商品
|
||||
*/
|
||||
init() {
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
distribution().then((res) => {
|
||||
if (res.data.result) {
|
||||
this.distributionData = res.data.result;
|
||||
}
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
})
|
||||
} else {
|
||||
uni.showToast({ title: '请输入正确金额', duration: 2000, icon: 'none' })
|
||||
}
|
||||
}
|
||||
|
||||
function fillAllAmount() {
|
||||
price.value = distributionData.value.canRebate ?? ''
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep .u-input__input,
|
||||
.u-input {
|
||||
font-size: 80rpx !important;
|
||||
height: 102rpx !important;
|
||||
|
||||
}
|
||||
::v-deep .u-input__input{
|
||||
height: 100%;
|
||||
font-size: 80rpx;
|
||||
}
|
||||
.content {
|
||||
display: flex;
|
||||
> .price {
|
||||
width: 60%;
|
||||
margin: 20rpx 0;
|
||||
font-size: 80rpx;
|
||||
display: flex;
|
||||
}
|
||||
> .all {
|
||||
justify-content: center;
|
||||
width: 40%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
}
|
||||
}
|
||||
.withdrawal-list {
|
||||
margin: 20rpx 0;
|
||||
background: #fff;
|
||||
padding: 16rpx 32rpx;
|
||||
}
|
||||
.title {
|
||||
font-size: 35rpx;
|
||||
}
|
||||
.submit {
|
||||
margin: 80rpx auto;
|
||||
width: 94%;
|
||||
background: $light-color;
|
||||
height: 90rpx;
|
||||
color: #fff;
|
||||
border-radius: 10rpx;
|
||||
text-align: center;
|
||||
line-height: 90rpx;
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background: #f8f8f8;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '@/pages/passport/entry/seller/entry-form.scss';
|
||||
|
||||
.wrapper {
|
||||
box-sizing: border-box;
|
||||
min-height: 100vh;
|
||||
padding: 20rpx 24rpx 40rpx;
|
||||
background: #f8f8f8;
|
||||
}
|
||||
|
||||
.feedBack-box {
|
||||
background: #fff;
|
||||
border-radius: 20rpx;
|
||||
padding: 32rpx;
|
||||
}
|
||||
|
||||
.box-title {
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.amount-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
margin-top: 24rpx;
|
||||
padding: 16rpx 24rpx;
|
||||
background: #fafafa;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.currency {
|
||||
flex-shrink: 0;
|
||||
margin-right: 16rpx;
|
||||
font-size: 56rpx;
|
||||
font-weight: 600;
|
||||
line-height: 1;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.amount-input {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
:deep(.amount-input .u-input) {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
:deep(.amount-input .u-input__content) {
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
:deep(.amount-input .u-input__content__field-wrapper__field) {
|
||||
height: 72rpx !important;
|
||||
min-height: 72rpx !important;
|
||||
font-size: 56rpx !important;
|
||||
font-weight: 600 !important;
|
||||
color: #333 !important;
|
||||
}
|
||||
|
||||
:deep(.amount-input .u-input__content__field-wrapper__field--placeholder) {
|
||||
font-size: 32rpx !important;
|
||||
font-weight: 400 !important;
|
||||
color: #c0c4cc !important;
|
||||
}
|
||||
|
||||
.amount-extra {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-top: 24rpx;
|
||||
}
|
||||
|
||||
.all-btn {
|
||||
font-size: 28rpx;
|
||||
color: var(--theme-light, #ff6b35);
|
||||
}
|
||||
|
||||
.balance-tip {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.balance-value {
|
||||
margin: 0 4rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.submit {
|
||||
@include seller-entry-submit;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,62 +1,42 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<u-parse :lazy-load="true" :selectable="true" :content="res.content" v-if="res"></u-parse>
|
||||
|
||||
<u-parse :lazy-load="true" :selectable="true" :content="article.content" v-if="article"></u-parse>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { getArticleDetailByType } from "@/api/article";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
res: "",
|
||||
way: {
|
||||
USER_AGREEMENT: {
|
||||
title: "服务协议",
|
||||
type: "USER_AGREEMENT",
|
||||
},
|
||||
PRIVACY_POLICY: {
|
||||
title: "隐私政策",
|
||||
type: "PRIVACY_POLICY",
|
||||
},
|
||||
LICENSE_INFORMATION: {
|
||||
title: "证照信息",
|
||||
type: "LICENSE_INFORMATION",
|
||||
},
|
||||
ABOUT: {
|
||||
title: "关于我们",
|
||||
type: "ABOUT",
|
||||
},
|
||||
STORE_REGISTER: {
|
||||
title: "店铺入驻协议",
|
||||
type: "STORE_REGISTER",
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
mounted() {},
|
||||
onLoad(option) {
|
||||
console.log(this.way)
|
||||
uni.setNavigationBarTitle({
|
||||
title: this.way[option.type].title,
|
||||
});
|
||||
this.init(option);
|
||||
},
|
||||
|
||||
methods: {
|
||||
init(option) {
|
||||
getArticleDetailByType(this.way[option.type].type).then((res) => {
|
||||
if (res.data.success) {
|
||||
this.res = res.data.result;
|
||||
console.log(res)
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { getArticleDetailByType } from '@/api/article'
|
||||
|
||||
const ARTICLE_TYPE_MAP: Record<string, { title: string; type: string }> = {
|
||||
USER_AGREEMENT: { title: '服务协议', type: 'USER_AGREEMENT' },
|
||||
PRIVACY_POLICY: { title: '隐私政策', type: 'PRIVACY_POLICY' },
|
||||
LICENSE_INFORMATION: { title: '证照信息', type: 'LICENSE_INFORMATION' },
|
||||
ABOUT: { title: '关于我们', type: 'ABOUT' },
|
||||
STORE_REGISTER: { title: '店铺入驻协议', type: 'STORE_REGISTER' },
|
||||
}
|
||||
|
||||
const article = ref<any>(null)
|
||||
|
||||
onLoad((option) => {
|
||||
const meta = ARTICLE_TYPE_MAP[option.type]
|
||||
if (!meta) return
|
||||
uni.setNavigationBarTitle({ title: meta.title })
|
||||
fetchArticle(meta.type)
|
||||
})
|
||||
|
||||
function fetchArticle(type: string) {
|
||||
getArticleDetailByType(type).then((res) => {
|
||||
if (res.data.success) {
|
||||
article.value = res.data.result
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.wrapper {
|
||||
padding: 16rpx;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -196,515 +196,356 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// rpx和px的比率
|
||||
var l
|
||||
// 可用窗口高度
|
||||
var wh
|
||||
// 顶部空盒子的高度
|
||||
var mgUpHeight
|
||||
<script setup lang="ts">
|
||||
import { ref, nextTick, getCurrentInstance } from 'vue'
|
||||
import {
|
||||
getTalkMessage,
|
||||
onLoad,
|
||||
onHide,
|
||||
onUnload,
|
||||
onPullDownRefresh,
|
||||
onPageScroll,
|
||||
} from '@dcloudio/uni-app'
|
||||
import {
|
||||
getTalkMessage as fetchTalkMessageApi,
|
||||
getTalkByUser,
|
||||
jumpObtain
|
||||
} from "@/api/im.js";
|
||||
import SocketService from "@/utils/socket_service.js";
|
||||
import storage from "@/utils/storage.js";
|
||||
import {
|
||||
beautifyTime
|
||||
} from "@/utils/filters.js"
|
||||
jumpObtain,
|
||||
} from '@/api/im.js'
|
||||
import SocketService from '@/utils/socket_service.js'
|
||||
import storage from '@/utils/storage.js'
|
||||
import { beautifyTime, unitPrice } from '@/utils/filters.js'
|
||||
import config from '@/config/config.js'
|
||||
import { textReplaceEmoji, emojistwo } from '@/utils/emojis.js';
|
||||
export default {
|
||||
// 页面卸载后清除imGoodId
|
||||
onUnload () {
|
||||
// #ifdef H5
|
||||
uni.setStorageSync("imGoodId", '');
|
||||
// #endif
|
||||
import { textReplaceEmoji, emojistwo } from '@/utils/emojis.js'
|
||||
|
||||
if (this.socketOpen == true) {
|
||||
uni.closeSocket();
|
||||
}
|
||||
},
|
||||
onLoad (options) {
|
||||
// 没有goodsid则不显示 发送商品弹窗
|
||||
this.showHideModel = options.goodsid
|
||||
// 发送后刷新页面不显示 发送商品弹窗 local里面imGoodId不为空显示
|
||||
// #ifdef H5
|
||||
this.localImGoodsId = uni.getStorageSync("imGoodId");
|
||||
// #endif
|
||||
this.resolve = options
|
||||
// 请求商品信息
|
||||
if (this.resolve.goodsid) {
|
||||
this.commodityDetails()
|
||||
}
|
||||
|
||||
var query = uni.getSystemInfoSync()
|
||||
// rpx和px的比率
|
||||
let l: number
|
||||
// 可用窗口高度
|
||||
let wh: number
|
||||
// 顶部空盒子的高度
|
||||
let mgUpHeight: number
|
||||
|
||||
l = query.screenWidth / 750
|
||||
wh = query.windowHeight
|
||||
this.scrollHeight = (query.windowHeight - 44) + "px"
|
||||
this.user = storage.getUserInfo()
|
||||
this.toUser = storage.getTalkToUser()
|
||||
const { proxy } = getCurrentInstance()!
|
||||
|
||||
if (options.talkId) {
|
||||
this.params.talkId = options.talkId;
|
||||
this.getTalkMessage()
|
||||
} else {
|
||||
this.getTalk(options.userId)
|
||||
const socketOpen = ref(false)
|
||||
const showHideModel = ref<string | undefined>(undefined)
|
||||
const localImGoodsId = ref('')
|
||||
const showHide = ref(true)
|
||||
const anData = ref<Record<string, any>>({})
|
||||
const animationData = ref<Record<string, any>>({})
|
||||
const msgList = ref<any[]>([])
|
||||
const oldHeight = ref(0)
|
||||
const params = ref({
|
||||
talkId: '',
|
||||
pageSize: 10,
|
||||
pageNumber: 1,
|
||||
})
|
||||
const msg = ref('')
|
||||
const go = ref(0)
|
||||
const user = ref<Record<string, any>>({})
|
||||
const toUser = ref<Record<string, any>>({})
|
||||
const scrollHeight = ref(0)
|
||||
const ws = new SocketService()
|
||||
const resolve = ref<Record<string, any>>({})
|
||||
const goodListData = ref<Record<string, any>>({})
|
||||
const reconnectCount = ref(0)
|
||||
const inputHeight = ref(0)
|
||||
const isShow = ref(false)
|
||||
|
||||
}
|
||||
|
||||
// this.ws.connect();
|
||||
this.socket();
|
||||
},
|
||||
|
||||
|
||||
|
||||
|
||||
// 页面隐藏
|
||||
onHide () {
|
||||
uni.closeSocket();
|
||||
},
|
||||
onUnload () {
|
||||
uni.closeSocket();
|
||||
},
|
||||
onPullDownRefresh () {
|
||||
this.params.pageNumber = this.params.pageNumber + 1
|
||||
this.getTalkMessage()
|
||||
setTimeout(function () {
|
||||
uni.stopPullDownRefresh();
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
textReplaceEmoji,
|
||||
emojistwo,
|
||||
socketOpen: false, //是否连接
|
||||
storage,
|
||||
fixed: 'fixed',
|
||||
bottom: '50px',
|
||||
width: '100%',
|
||||
showHideModel: undefined,
|
||||
localImGoodsId: '',
|
||||
showHide: true,
|
||||
msgLoad: false,
|
||||
anData: {},
|
||||
animationData: {},
|
||||
msgList: [],
|
||||
oldHeight: 0,
|
||||
params: { //搜索条件
|
||||
talkId: '',
|
||||
pageSize: 10,
|
||||
pageNumber: 1,
|
||||
},
|
||||
goToIndex: 0, // 前往位置
|
||||
msg: "",
|
||||
go: 0,
|
||||
newMessageNum: 0,
|
||||
user: {},
|
||||
toUser: {},
|
||||
scrollHeight: 0,
|
||||
ws: new SocketService(),
|
||||
resolve: {},
|
||||
goodListData: {},
|
||||
count: 0, //判断socket断开连接请求次数
|
||||
inputHeight:0,
|
||||
isShow:false,
|
||||
|
||||
|
||||
}
|
||||
},
|
||||
onPageScroll (e) {
|
||||
|
||||
// #ifdef APP-PLUS
|
||||
uni.hideKeyboard()
|
||||
this.isShow = false
|
||||
// #endif
|
||||
},
|
||||
methods: {
|
||||
navigateToBottom(){
|
||||
// #ifdef H5
|
||||
this.isShow = true
|
||||
this.$refs.inputRef.focus()
|
||||
// #endif
|
||||
|
||||
// #ifdef APP-PLUS
|
||||
this.$nextTick(() => {
|
||||
uni.pageScrollTo({
|
||||
scrollTop: 5000000,
|
||||
duration: 50,
|
||||
success: () => {
|
||||
setTimeout(() => {
|
||||
this.isShow = true
|
||||
}, 200);
|
||||
;
|
||||
},
|
||||
fail: () => { },
|
||||
complete: () => {}
|
||||
});
|
||||
});
|
||||
// #endif
|
||||
|
||||
},
|
||||
|
||||
eventHandle(){
|
||||
|
||||
this.inputHeight = 0
|
||||
this.isShow = false
|
||||
},
|
||||
inputBindFocus(e){
|
||||
if (e.detail.height) {
|
||||
|
||||
|
||||
// #ifdef APP-PLUS
|
||||
// 判断是否是ios
|
||||
if (uni.getSystemInfoSync().platform == 'ios') {
|
||||
this.inputHeight = e.detail.height - 40 //这个高度就是软键盘的高度
|
||||
}else{
|
||||
this.inputHeight = e.detail.height
|
||||
}
|
||||
// #endif
|
||||
|
||||
// #ifndef APP-PLUS
|
||||
this.inputHeight = e.detail.height //这个高度就是软键盘的高度
|
||||
// #endif
|
||||
}
|
||||
},
|
||||
sendMessage () {
|
||||
if (this.msg == "") {
|
||||
return 0;
|
||||
}
|
||||
if (this.socketOpen == false) {
|
||||
return
|
||||
}
|
||||
let msg = {
|
||||
operation_type: "MESSAGE",
|
||||
to: this.toUser.userId,
|
||||
from: this.user.id,
|
||||
message_type: "MESSAGE",
|
||||
context: this.msg,
|
||||
talk_id: this.params.talkId,
|
||||
}
|
||||
let data = JSON.stringify(msg);
|
||||
uni.sendSocketMessage({
|
||||
data: data,
|
||||
});
|
||||
this.msgList.push({
|
||||
"text": this.msg,
|
||||
"my": true,
|
||||
"messageType": 'MESSAGE'
|
||||
})
|
||||
let type = 'down';
|
||||
this.msgGo(type)
|
||||
this.msg = ""
|
||||
},
|
||||
sendGoodsMessage () {
|
||||
let msg = {
|
||||
operation_type: "MESSAGE",
|
||||
to: this.toUser.userId,
|
||||
from: this.user.id,
|
||||
message_type: "GOODS",
|
||||
context: this.goodListData,
|
||||
talk_id: this.params.talkId,
|
||||
}
|
||||
let data = JSON.stringify(msg);
|
||||
uni.sendSocketMessage({
|
||||
data: data
|
||||
});
|
||||
this.msgList.push({
|
||||
"text": JSON.stringify(this.goodListData),
|
||||
"my": true,
|
||||
"messageType": 'GOODS'
|
||||
})
|
||||
this.showHide = false
|
||||
// #ifdef H5
|
||||
uni.setStorageSync("imGoodId", 1111111);
|
||||
// #endif
|
||||
this.$nextTick(() => {
|
||||
uni.pageScrollTo({
|
||||
scrollTop: 2000000,
|
||||
duration: 300
|
||||
});
|
||||
})
|
||||
},
|
||||
socket () {
|
||||
var _this = this;
|
||||
uni.closeSocket();
|
||||
this.socketOpen = false;
|
||||
try {
|
||||
//WebSocket的地址
|
||||
var url = config.baseWsUrl + '/' + storage.getAccessToken();
|
||||
// 连接
|
||||
uni.connectSocket({
|
||||
url: url,
|
||||
});
|
||||
// 监听WebSocket连接已打开
|
||||
uni.onSocketOpen(function (res) {
|
||||
_this.socketOpen = true;
|
||||
});
|
||||
if (!this.socketOpen) {
|
||||
// 监听连接失败
|
||||
|
||||
uni.onSocketError(function (err) {
|
||||
if (this.count < 3) {
|
||||
if (err && err.code != 1000) {
|
||||
_this.socketOpen = true;
|
||||
setTimeout(() => {
|
||||
uni.connectSocket({
|
||||
url: url,
|
||||
});
|
||||
}, 2000)
|
||||
}
|
||||
} else {
|
||||
uni.closeSocket();
|
||||
}
|
||||
this.count++
|
||||
});
|
||||
}
|
||||
// 监听收到信息
|
||||
uni.onSocketMessage(function (res) {
|
||||
res.data = JSON.parse(res.data)
|
||||
console.log(res.data.result);
|
||||
if (res.data.messageResultType == 'MESSAGE') {
|
||||
_this.msgList.push(res.data.result)
|
||||
console.log(_this.msgList)
|
||||
}
|
||||
console.log(res.data)
|
||||
_this.msgGo()
|
||||
})
|
||||
} catch (e) {
|
||||
uni.closeSocket();
|
||||
}
|
||||
// 监听是否断线,断线进行重新连接
|
||||
uni.onSocketClose((res) => {
|
||||
if (res.code != null && res.code != 1000) {
|
||||
this.socket()
|
||||
}
|
||||
})
|
||||
},
|
||||
beautifyTime,
|
||||
//订单详情
|
||||
linkTosOrders (val) {
|
||||
let order = JSON.parse(val)
|
||||
uni.navigateTo({
|
||||
url: '/pages/order/orderDetail?sn=' + order.sn,
|
||||
});
|
||||
|
||||
},
|
||||
// 跳转商品详情页
|
||||
jumpGoodDesc (item) {
|
||||
let info = JSON.parse(item.text)
|
||||
uni.navigateTo({
|
||||
url: `/pages/product/goods?id=${info.id}&goodsId=${info.goodsId}`,
|
||||
});
|
||||
},
|
||||
|
||||
//取消发送
|
||||
cancelModel () {
|
||||
this.showHide = false
|
||||
},
|
||||
// 请求商品详情
|
||||
commodityDetails () {
|
||||
jumpObtain(this.resolve.skuid, this.resolve.goodsid).then((res) => {
|
||||
this.goodListData = res.data.result.data
|
||||
})
|
||||
},
|
||||
// 切换输入法时移动输入框(按照官方的上推页面的原理应该会自动适应不同的键盘高度-->官方bug)
|
||||
goPag (kh) {
|
||||
this.retractBox(0, 250)
|
||||
if (this.keyHeight != 0) {
|
||||
if (kh - this.keyHeight > 0) {
|
||||
this.retractBox(this.keyHeight - kh, 250)
|
||||
}
|
||||
}
|
||||
},
|
||||
// 移动顶部的空盒子
|
||||
messageBoxMove (x, t) {
|
||||
var animation = uni.createAnimation({
|
||||
duration: t,
|
||||
timingFunction: 'linear',
|
||||
})
|
||||
this.animation = animation
|
||||
animation.height(x).step()
|
||||
this.anData = animation.export()
|
||||
},
|
||||
// 保持消息体可见
|
||||
msgGo (type) {
|
||||
const query = uni.createSelectorQuery()
|
||||
// 延时100ms保证是最新的高度
|
||||
setTimeout(() => {
|
||||
// 获取消息体高度
|
||||
query.select('#msgList').boundingClientRect(data => {
|
||||
// 如果超过scorll高度就滚动scorll
|
||||
if (type == 'up') {
|
||||
this.go = data.height - this.oldHeight
|
||||
} else if (type == 'down') {
|
||||
this.go = data.height - wh + 120
|
||||
}
|
||||
// if (this.oldHeight > 0) {
|
||||
// this.go = data.height - this.oldHeight
|
||||
// } else {
|
||||
// // if (data.height - (wh - 32) > 0) {
|
||||
// this.go = data.height - wh + 120
|
||||
// }
|
||||
// 保证键盘第一次拉起时消息体能保持可见
|
||||
var moveY = wh - data.height
|
||||
// 超出页面则缩回空盒子
|
||||
if (moveY - mgUpHeight < 0) {
|
||||
// 小于0则视为0
|
||||
if (moveY < 0) {
|
||||
this.messageBoxMove(0, 200)
|
||||
} else {
|
||||
// 否则缩回盒子对应的高度
|
||||
this.messageBoxMove(moveY, 200)
|
||||
}
|
||||
}
|
||||
uni.pageScrollTo({
|
||||
scrollTop: this.go,
|
||||
duration: 0
|
||||
})
|
||||
this.oldHeight = data.height
|
||||
}).exec();
|
||||
}, 100)
|
||||
},
|
||||
// 回答问题的业务逻辑
|
||||
answer (id) {
|
||||
// 这里应该传入问题的id,模拟就用index代替了
|
||||
|
||||
},
|
||||
// 不建议输入框聚焦时操作此动画
|
||||
ckAdd () {
|
||||
if (!this.showTow) {
|
||||
this.retractBox(-180, 350)
|
||||
} else {
|
||||
this.retractBox(0, 200)
|
||||
}
|
||||
this.showTow = !this.showTow
|
||||
},
|
||||
hideKey () {
|
||||
uni.hideKeyboard()
|
||||
},
|
||||
// 拉起/收回附加栏
|
||||
retractBox (x, t) {
|
||||
var animation = uni.createAnimation({
|
||||
duration: t,
|
||||
timingFunction: 'ease',
|
||||
})
|
||||
this.animation = animation
|
||||
animation.translateY(x).step()
|
||||
this.animationData = animation.export()
|
||||
},
|
||||
async getTalkMessage () {
|
||||
let type = '';
|
||||
await getTalkMessage(this.params).then(res => {
|
||||
if (res.data.success) {
|
||||
if (this.msgList.length >= 10) {
|
||||
this.msgList.unshift(...res.data.result)
|
||||
type = 'up'
|
||||
} else {
|
||||
this.msgList.unshift(...res.data.result)
|
||||
type = 'down'
|
||||
}
|
||||
this.msgList.forEach(item => {
|
||||
if (item.fromUser === this.user.id) {
|
||||
item.my = true
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
console.log(this.msgList);
|
||||
this.msgGo(type)
|
||||
},
|
||||
// 上拉加载
|
||||
touchMoreMessage (e) {
|
||||
if (e.target.scrollTop == 0) {
|
||||
this.params.pageNumber = this.params.pageNumber + 1
|
||||
this.getTalkMessage()
|
||||
}
|
||||
},
|
||||
async getTalk (userId) {
|
||||
getTalkByUser(userId).then(res => {
|
||||
if (res.data.success) {
|
||||
this.toUser = res.data.result
|
||||
this.params.talkId = res.data.result.id
|
||||
this.getTalkMessage()
|
||||
}
|
||||
})
|
||||
},
|
||||
// 处理消息时间是否显示
|
||||
compareTime (index, datetime) {
|
||||
if (datetime == undefined) {
|
||||
return false;
|
||||
}
|
||||
if (typeof datetime == "number") {
|
||||
datetime = this.unixToDate(datetime, "yyyy-MM-dd hh:mm");
|
||||
}
|
||||
|
||||
if (this.msgList[index].is_revoke == 1) {
|
||||
return false;
|
||||
}
|
||||
if (datetime) {
|
||||
datetime = datetime.replace(/-/g, "/");
|
||||
}
|
||||
|
||||
let time = Math.floor(Date.parse(datetime) / 1000);
|
||||
let currTime = Math.floor(new Date().getTime() / 1000);
|
||||
|
||||
// 当前时间5分钟内时间不显示
|
||||
if (currTime - time < 300) return false;
|
||||
// 判断是否是最后一条消息,最后一条消息默认显示时间
|
||||
if (index == this.msgList.length - 1) {
|
||||
return true;
|
||||
}
|
||||
let nextDate
|
||||
if (this.msgList[index + 1] && this.msgList[index + 1].createTime) {
|
||||
nextDate = this.msgList[index + 1].createTime.replace(/-/g, "/");
|
||||
if (nextDate - datetime < 300) return false;
|
||||
}
|
||||
|
||||
return !(
|
||||
this.unixToDate(new Date(datetime), "{y}-{m}-{d} {h}:{i}") ==
|
||||
this.unixToDate(new Date(nextDate), "{y}-{m}-{d} {h}:{i}")
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* 将unix时间戳转换为指定格式
|
||||
* @param unix 时间戳【秒】
|
||||
* @param format 转换格式
|
||||
* @returns {*|string}
|
||||
*/
|
||||
unixToDate (unix, format) {
|
||||
if (!unix) return unix;
|
||||
let _format = format || "yyyy-MM-dd hh:mm:ss";
|
||||
const d = new Date(unix);
|
||||
const o = {
|
||||
"M+": d.getMonth() + 1,
|
||||
"d+": d.getDate(),
|
||||
"h+": d.getHours(),
|
||||
"m+": d.getMinutes(),
|
||||
"s+": d.getSeconds(),
|
||||
"q+": Math.floor((d.getMonth() + 3) / 3),
|
||||
S: d.getMilliseconds(),
|
||||
};
|
||||
if (/(y+)/.test(_format))
|
||||
_format = _format.replace(
|
||||
RegExp.$1,
|
||||
(d.getFullYear() + "").substr(4 - RegExp.$1.length)
|
||||
);
|
||||
for (const k in o)
|
||||
if (new RegExp("(" + k + ")").test(_format))
|
||||
_format = _format.replace(
|
||||
RegExp.$1,
|
||||
RegExp.$1.length === 1 ?
|
||||
o[k] :
|
||||
("00" + o[k]).substr(("" + o[k]).length)
|
||||
);
|
||||
return _format;
|
||||
},
|
||||
onLoad((options: Record<string, string | undefined> = {}) => {
|
||||
showHideModel.value = options.goodsid
|
||||
// #ifdef H5
|
||||
localImGoodsId.value = uni.getStorageSync('imGoodId')
|
||||
// #endif
|
||||
resolve.value = options
|
||||
if (resolve.value.goodsid) {
|
||||
commodityDetails()
|
||||
}
|
||||
|
||||
const query = uni.getSystemInfoSync()
|
||||
l = query.screenWidth / 750
|
||||
wh = query.windowHeight
|
||||
scrollHeight.value = query.windowHeight - 44 + 'px'
|
||||
user.value = storage.getUserInfo()
|
||||
toUser.value = storage.getTalkToUser()
|
||||
|
||||
if (options.talkId) {
|
||||
params.value.talkId = options.talkId
|
||||
fetchTalkMessages()
|
||||
} else {
|
||||
getTalk(options.userId!)
|
||||
}
|
||||
|
||||
socket()
|
||||
})
|
||||
|
||||
onHide(() => {
|
||||
uni.closeSocket()
|
||||
})
|
||||
|
||||
onUnload(() => {
|
||||
// #ifdef H5
|
||||
uni.setStorageSync('imGoodId', '')
|
||||
// #endif
|
||||
uni.closeSocket()
|
||||
})
|
||||
|
||||
onPullDownRefresh(() => {
|
||||
params.value.pageNumber = params.value.pageNumber + 1
|
||||
fetchTalkMessages()
|
||||
setTimeout(() => {
|
||||
uni.stopPullDownRefresh()
|
||||
}, 1000)
|
||||
})
|
||||
|
||||
onPageScroll(() => {
|
||||
// #ifdef APP-PLUS
|
||||
uni.hideKeyboard()
|
||||
isShow.value = false
|
||||
// #endif
|
||||
})
|
||||
|
||||
function navigateToBottom() {
|
||||
// #ifdef H5
|
||||
isShow.value = true
|
||||
;(proxy as any).$refs.inputRef?.focus()
|
||||
// #endif
|
||||
|
||||
// #ifdef APP-PLUS
|
||||
nextTick(() => {
|
||||
uni.pageScrollTo({
|
||||
scrollTop: 5000000,
|
||||
duration: 50,
|
||||
success: () => {
|
||||
setTimeout(() => {
|
||||
isShow.value = true
|
||||
}, 200)
|
||||
},
|
||||
fail: () => {},
|
||||
complete: () => {},
|
||||
})
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
|
||||
function eventHandle() {
|
||||
inputHeight.value = 0
|
||||
isShow.value = false
|
||||
}
|
||||
|
||||
function inputBindFocus(e: any) {
|
||||
if (e.detail.height) {
|
||||
// #ifdef APP-PLUS
|
||||
if (uni.getSystemInfoSync().platform == 'ios') {
|
||||
inputHeight.value = e.detail.height - 40
|
||||
} else {
|
||||
inputHeight.value = e.detail.height
|
||||
}
|
||||
// #endif
|
||||
|
||||
// #ifndef APP-PLUS
|
||||
inputHeight.value = e.detail.height
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
|
||||
function sendMessage() {
|
||||
if (msg.value == '') {
|
||||
return 0
|
||||
}
|
||||
if (socketOpen.value == false) {
|
||||
return
|
||||
}
|
||||
const payload = {
|
||||
operation_type: 'MESSAGE',
|
||||
to: toUser.value.userId,
|
||||
from: user.value.id,
|
||||
message_type: 'MESSAGE',
|
||||
context: msg.value,
|
||||
talk_id: params.value.talkId,
|
||||
}
|
||||
const data = JSON.stringify(payload)
|
||||
uni.sendSocketMessage({
|
||||
data: data,
|
||||
})
|
||||
msgList.value.push({
|
||||
text: msg.value,
|
||||
my: true,
|
||||
messageType: 'MESSAGE',
|
||||
})
|
||||
const type = 'down'
|
||||
msgGo(type)
|
||||
msg.value = ''
|
||||
}
|
||||
|
||||
function sendGoodsMessage() {
|
||||
const payload = {
|
||||
operation_type: 'MESSAGE',
|
||||
to: toUser.value.userId,
|
||||
from: user.value.id,
|
||||
message_type: 'GOODS',
|
||||
context: goodListData.value,
|
||||
talk_id: params.value.talkId,
|
||||
}
|
||||
const data = JSON.stringify(payload)
|
||||
uni.sendSocketMessage({
|
||||
data: data,
|
||||
})
|
||||
msgList.value.push({
|
||||
text: JSON.stringify(goodListData.value),
|
||||
my: true,
|
||||
messageType: 'GOODS',
|
||||
})
|
||||
showHide.value = false
|
||||
// #ifdef H5
|
||||
uni.setStorageSync('imGoodId', 1111111)
|
||||
// #endif
|
||||
nextTick(() => {
|
||||
uni.pageScrollTo({
|
||||
scrollTop: 2000000,
|
||||
duration: 300,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function socket() {
|
||||
uni.closeSocket()
|
||||
socketOpen.value = false
|
||||
try {
|
||||
const url = config.baseWsUrl + '/' + storage.getAccessToken()
|
||||
uni.connectSocket({
|
||||
url: url,
|
||||
})
|
||||
uni.onSocketOpen(function () {
|
||||
socketOpen.value = true
|
||||
})
|
||||
if (!socketOpen.value) {
|
||||
uni.onSocketError(function (err: any) {
|
||||
if (reconnectCount.value < 3) {
|
||||
if (err && err.code != 1000) {
|
||||
socketOpen.value = true
|
||||
setTimeout(() => {
|
||||
uni.connectSocket({
|
||||
url: url,
|
||||
})
|
||||
}, 2000)
|
||||
}
|
||||
} else {
|
||||
uni.closeSocket()
|
||||
}
|
||||
reconnectCount.value++
|
||||
})
|
||||
}
|
||||
uni.onSocketMessage(function (res) {
|
||||
const data = JSON.parse(res.data as string)
|
||||
console.log(data.result)
|
||||
if (data.messageResultType == 'MESSAGE') {
|
||||
msgList.value.push(data.result)
|
||||
console.log(msgList.value)
|
||||
}
|
||||
console.log(data)
|
||||
msgGo()
|
||||
})
|
||||
} catch (e) {
|
||||
uni.closeSocket()
|
||||
}
|
||||
uni.onSocketClose((res) => {
|
||||
if (res.code != null && res.code != 1000) {
|
||||
socket()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function linkTosOrders(val: string) {
|
||||
const order = JSON.parse(val)
|
||||
uni.navigateTo({
|
||||
url: '/pages/order/orderDetail?sn=' + order.sn,
|
||||
})
|
||||
}
|
||||
|
||||
function jumpGoodDesc(item: any) {
|
||||
const info = JSON.parse(item.text)
|
||||
uni.navigateTo({
|
||||
url: `/pages/product/goods?id=${info.id}&goodsId=${info.goodsId}`,
|
||||
})
|
||||
}
|
||||
|
||||
function cancelModel() {
|
||||
showHide.value = false
|
||||
}
|
||||
|
||||
function commodityDetails() {
|
||||
jumpObtain(resolve.value.skuid, resolve.value.goodsid).then((res) => {
|
||||
goodListData.value = res.data.result.data
|
||||
})
|
||||
}
|
||||
|
||||
function messageBoxMove(x: number, t: number) {
|
||||
const animation = uni.createAnimation({
|
||||
duration: t,
|
||||
timingFunction: 'linear',
|
||||
})
|
||||
animation.height(x).step()
|
||||
anData.value = animation.export()
|
||||
}
|
||||
|
||||
function msgGo(type?: string) {
|
||||
const query = uni.createSelectorQuery()
|
||||
setTimeout(() => {
|
||||
query
|
||||
.select('#msgList')
|
||||
.boundingClientRect((data: any) => {
|
||||
if (type == 'up') {
|
||||
go.value = data.height - oldHeight.value
|
||||
} else if (type == 'down') {
|
||||
go.value = data.height - wh + 120
|
||||
}
|
||||
const moveY = wh - data.height
|
||||
if (moveY - mgUpHeight < 0) {
|
||||
if (moveY < 0) {
|
||||
messageBoxMove(0, 200)
|
||||
} else {
|
||||
messageBoxMove(moveY, 200)
|
||||
}
|
||||
}
|
||||
uni.pageScrollTo({
|
||||
scrollTop: go.value,
|
||||
duration: 0,
|
||||
})
|
||||
oldHeight.value = data.height
|
||||
})
|
||||
.exec()
|
||||
}, 100)
|
||||
}
|
||||
|
||||
async function fetchTalkMessages() {
|
||||
let type = ''
|
||||
await fetchTalkMessageApi(params.value).then((res) => {
|
||||
if (res.data.success) {
|
||||
if (msgList.value.length >= 10) {
|
||||
msgList.value.unshift(...res.data.result)
|
||||
type = 'up'
|
||||
} else {
|
||||
msgList.value.unshift(...res.data.result)
|
||||
type = 'down'
|
||||
}
|
||||
msgList.value.forEach((item) => {
|
||||
if (item.fromUser === user.value.id) {
|
||||
item.my = true
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
console.log(msgList.value)
|
||||
msgGo(type)
|
||||
}
|
||||
|
||||
function getTalk(userId: string) {
|
||||
getTalkByUser(userId).then((res) => {
|
||||
if (res.data.success) {
|
||||
toUser.value = res.data.result
|
||||
params.value.talkId = res.data.result.id
|
||||
fetchTalkMessages()
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -9,12 +9,12 @@
|
||||
:border="false"
|
||||
:auto-back="true"
|
||||
></u-navbar>
|
||||
<scroll-view class="list-scroll-content" scroll-y @scrolltolower="loadData(tabIndex)">
|
||||
<scroll-view class="list-scroll-content" scroll-y @scrolltolower="fetchTalkList">
|
||||
|
||||
<!-- 消息列表 -->
|
||||
<div class="iconBox">
|
||||
<view class="icon-list">
|
||||
<view class="icon-item" @click="cleanUnread()">
|
||||
<view class="icon-item" @click="clearUnreadMessages()">
|
||||
<div class="bag bag1">
|
||||
<u-icon name="trash" size="50" color="#fff"></u-icon>
|
||||
</div>
|
||||
@@ -28,7 +28,7 @@
|
||||
</view>
|
||||
</view>
|
||||
</div>
|
||||
<u-search class="nav-search" v-model="userName" clearabled @change="userTalkList()" placeholder="搜索用户"
|
||||
<u-search class="nav-search" v-model="userName" clearabled @change="fetchTalkList()" placeholder="搜索用户"
|
||||
:show-action="false"></u-search>
|
||||
<view class="talk-view" :key="index" v-for="(item, index) in talkList">
|
||||
<view>
|
||||
@@ -65,85 +65,80 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getTalkList, clearmeaager } from "@/api/im.js";
|
||||
import storage from "@/utils/storage.js";
|
||||
import { beautifyTime } from "@/utils/filters.js"
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
storage,
|
||||
count: {
|
||||
loadStatus: "more",
|
||||
},
|
||||
talkList: [], //聊天列表
|
||||
userName: '',
|
||||
pointData: {}, //累计获取 未输入 集合
|
||||
};
|
||||
},
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onShow, onPullDownRefresh, onReachBottom } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { getTalkList, clearmeaager } from '@/api/im.js'
|
||||
import storage from '@/utils/storage.js'
|
||||
import { beautifyTime } from '@/utils/filters.js'
|
||||
|
||||
onShow () {
|
||||
this.userTalkList();
|
||||
},
|
||||
onPullDownRefresh () {
|
||||
this.userTalkList()
|
||||
console.log('下拉事件');
|
||||
setTimeout(function () {
|
||||
uni.stopPullDownRefresh();
|
||||
}, 1000);
|
||||
},
|
||||
/**
|
||||
* 触底加载
|
||||
*/
|
||||
onReachBottom () {
|
||||
this.userTalkList();
|
||||
},
|
||||
methods: {
|
||||
beautifyTime,
|
||||
onclickToTalkInfo (val) {
|
||||
storage.setTalkToUser(val)
|
||||
uni.navigateTo({
|
||||
url:
|
||||
"/pages/mine/im/index?talkId=" + val.id,
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 获取聊天列表
|
||||
*/
|
||||
userTalkList () {
|
||||
let params = {
|
||||
userName: this.userName,
|
||||
}
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
getTalkList(params).then((res) => {
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
if (res.data.success) {
|
||||
this.talkList = res.data.result;
|
||||
console.log(this.talkList, 'this.talkListthis.talkList');
|
||||
}
|
||||
});
|
||||
},
|
||||
navigateTo (url) {
|
||||
uni.navigateTo({
|
||||
url,
|
||||
});
|
||||
},
|
||||
cleanUnread () {
|
||||
clearmeaager().then((res) => {
|
||||
console.log(res);
|
||||
if (res.data.code == 200) {
|
||||
this.userTalkList();
|
||||
uni.showToast({
|
||||
icon: "none",
|
||||
title: res.data.message,
|
||||
});
|
||||
}
|
||||
const store = useStore()
|
||||
|
||||
const talkList = ref<any[]>([])
|
||||
const userName = ref('')
|
||||
|
||||
onShow(() => {
|
||||
fetchTalkList()
|
||||
})
|
||||
|
||||
onPullDownRefresh(() => {
|
||||
fetchTalkList()
|
||||
console.log('下拉事件')
|
||||
setTimeout(() => {
|
||||
uni.stopPullDownRefresh()
|
||||
}, 1000)
|
||||
})
|
||||
|
||||
onReachBottom(() => {
|
||||
fetchTalkList()
|
||||
})
|
||||
|
||||
function hideLoadingIfNeeded() {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
}
|
||||
|
||||
function onclickToTalkInfo(val: any) {
|
||||
storage.setTalkToUser(val)
|
||||
uni.navigateTo({
|
||||
url: '/pages/mine/im/index?talkId=' + val.id,
|
||||
})
|
||||
}
|
||||
|
||||
function fetchTalkList() {
|
||||
const params = {
|
||||
userName: userName.value,
|
||||
}
|
||||
uni.showLoading({
|
||||
title: '加载中',
|
||||
})
|
||||
getTalkList(params).then((res) => {
|
||||
hideLoadingIfNeeded()
|
||||
if (res.data.success) {
|
||||
talkList.value = res.data.result
|
||||
console.log(talkList.value, 'this.talkListthis.talkList')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function navigateTo(url: string) {
|
||||
uni.navigateTo({
|
||||
url,
|
||||
})
|
||||
}
|
||||
|
||||
function clearUnreadMessages() {
|
||||
clearmeaager().then((res) => {
|
||||
console.log(res)
|
||||
if (res.data.code == 200) {
|
||||
fetchTalkList()
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: res.data.message,
|
||||
})
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -1,183 +1,98 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<view class="list-cell b-b m-t" hover-class="cell-hover" :hover-stay-time="50">
|
||||
<u-row gutter="12" justify="start" @click="navigateTo('/pages/msgTips/sysMsg/index')">
|
||||
<u-col span="2" class="uCol" style="text-align:center;">
|
||||
<image class="img" src="/static/mine/setting.png"></image>
|
||||
</u-col>
|
||||
<u-col span="7">
|
||||
<p class="tit_title">系统消息</p>
|
||||
<p class="tit_tips">查看系统消息</p>
|
||||
</u-col>
|
||||
<u-col span="3">
|
||||
<view class="cell-more">
|
||||
<u-tag size="mini" v-if="no_read.system_num>0" shape="circle" mode="dark" type="error" :text="no_read.system_num"></u-tag>
|
||||
<span class="yticon icon-you"></span>
|
||||
</view>
|
||||
</u-col>
|
||||
</u-row>
|
||||
</view>
|
||||
<!-- <view class="list-cell b-b m-t" hover-class="cell-hover" :hover-stay-time="50">
|
||||
<u-row gutter="12" justify="start" @click="navigateTo('/pages/msgTips/packagemsg/index')">
|
||||
<u-col span="2" class="uCol" style="text-align:center;">
|
||||
<image class="img" src="/static/mine/logistics.png"></image>
|
||||
|
||||
</u-col>
|
||||
<u-col span="7">
|
||||
<p class="tit_title">物流消息</p>
|
||||
<p class="tit_tips">查看物流消息</p>
|
||||
</u-col>
|
||||
<u-col span="3">
|
||||
<view class="cell-more">
|
||||
|
||||
<u-tag v-if="no_read.logistics_num>0" shape="circle" mode="dark" type="warning" :text="no_read.logistics_num"></u-tag>
|
||||
<span class="yticon icon-you"></span>
|
||||
</view>
|
||||
</u-col>
|
||||
</u-row>
|
||||
</view> -->
|
||||
</view>
|
||||
<view class="container">
|
||||
<view class="list-cell b-b m-t" hover-class="cell-hover" :hover-stay-time="50">
|
||||
<u-row gutter="12" justify="start" @click="navigateTo('/pages/mine/msgTips/sysMsg/index')">
|
||||
<u-col span="2" class="uCol" style="text-align: center">
|
||||
<image class="img" src="/static/mine/setting.png"></image>
|
||||
</u-col>
|
||||
<u-col span="7">
|
||||
<p class="tit_title">系统消息</p>
|
||||
<p class="tit_tips">查看系统消息</p>
|
||||
</u-col>
|
||||
<u-col span="3">
|
||||
<view class="cell-more">
|
||||
<u-tag
|
||||
size="mini"
|
||||
v-if="unreadCount.system_num > 0"
|
||||
shape="circle"
|
||||
mode="dark"
|
||||
type="error"
|
||||
:text="String(unreadCount.system_num)"
|
||||
></u-tag>
|
||||
<span class="yticon icon-you"></span>
|
||||
</view>
|
||||
</u-col>
|
||||
</u-row>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapMutations
|
||||
} from "vuex";
|
||||
import * as API_Message from "@/api/members.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
no_read: ''
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
this.GET_NoReadMessageNum();
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(["logout"]),
|
||||
navigateTo(url) {
|
||||
uni.navigateTo({
|
||||
url
|
||||
});
|
||||
},
|
||||
/** 获取未读消息数量信息 */
|
||||
GET_NoReadMessageNum() {
|
||||
API_Message.getNoReadMessageNum().then(response => {
|
||||
this.no_read = response.data
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { getNoReadMessageNum } from '@/api/members.js'
|
||||
|
||||
const unreadCount = ref<Record<string, number>>({ system_num: 0 })
|
||||
|
||||
onLoad(() => {
|
||||
fetchUnreadCount()
|
||||
})
|
||||
|
||||
function navigateTo(url: string) {
|
||||
uni.navigateTo({ url })
|
||||
}
|
||||
|
||||
function fetchUnreadCount() {
|
||||
getNoReadMessageNum().then((response) => {
|
||||
unreadCount.value = response.data || { system_num: 0 }
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang='scss'>
|
||||
.uCol {
|
||||
display: flex;
|
||||
justify-content: center !important;
|
||||
}
|
||||
|
||||
.img {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
|
||||
}
|
||||
|
||||
.container {
|
||||
background: #f9f9f9;
|
||||
}
|
||||
|
||||
::v-deep .u-col-2 {
|
||||
height: 60px;
|
||||
line-height: 60px;
|
||||
text-align: center !important;
|
||||
|
||||
}
|
||||
|
||||
.qicon {
|
||||
text-align: center;
|
||||
display: block;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.redBox {
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
line-height: 1.5em;
|
||||
font-size: 12px;
|
||||
min-width: 1.5em;
|
||||
min-height: 1.5em;
|
||||
|
||||
background: #ed6533;
|
||||
border-radius: 50%;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.tit_title {
|
||||
color: $u-main-color;
|
||||
}
|
||||
|
||||
.tit_tips {
|
||||
color: $u-tips-color;
|
||||
}
|
||||
|
||||
.u-col-3 {
|
||||
text-align: right !important;
|
||||
padding-right: 20rpx !important;
|
||||
}
|
||||
|
||||
.list-cell {
|
||||
background: #fff;
|
||||
align-items: baseline;
|
||||
padding: 20rpx 0;
|
||||
line-height: 60rpx;
|
||||
|
||||
background: #fff;
|
||||
justify-content: center;
|
||||
|
||||
&.log-out-btn {
|
||||
margin-top: 40rpx;
|
||||
|
||||
.cell-tit {
|
||||
color: $uni-color-primary;
|
||||
text-align: center;
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.cell-hover {
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
&.b-b:after {
|
||||
left: 30rpx;
|
||||
}
|
||||
|
||||
&.m-t {
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
|
||||
.cell-more {
|
||||
/* margin-top: 10rpx; */
|
||||
height: 60rpx;
|
||||
text-align: right;
|
||||
/* display: flex;
|
||||
justify-content: center; //这个是X轴居中
|
||||
align-items: center; //这个是 Y轴居中 */
|
||||
font-size: $font-lg;
|
||||
color: $font-color-light;
|
||||
/* width: 100rpx; */
|
||||
}
|
||||
|
||||
.cell-tit {
|
||||
flex: 1;
|
||||
font-size: $font-base + 2rpx;
|
||||
color: $font-color-dark;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
.cell-tip {
|
||||
font-size: $font-base;
|
||||
color: $font-color-light;
|
||||
}
|
||||
}
|
||||
<style scoped lang="scss">
|
||||
.uCol {
|
||||
display: flex;
|
||||
justify-content: center !important;
|
||||
}
|
||||
.img {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
}
|
||||
.container {
|
||||
background: #f9f9f9;
|
||||
}
|
||||
::v-deep .u-col-2 {
|
||||
height: 60px;
|
||||
line-height: 60px;
|
||||
text-align: center !important;
|
||||
}
|
||||
.tit_title {
|
||||
color: $u-main-color;
|
||||
}
|
||||
.tit_tips {
|
||||
color: $u-tips-color;
|
||||
}
|
||||
.u-col-3 {
|
||||
text-align: right !important;
|
||||
padding-right: 20rpx !important;
|
||||
}
|
||||
.list-cell {
|
||||
background: #fff;
|
||||
align-items: baseline;
|
||||
padding: 20rpx 0;
|
||||
line-height: 60rpx;
|
||||
justify-content: center;
|
||||
&.cell-hover {
|
||||
background: #fafafa;
|
||||
}
|
||||
&.m-t {
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
.cell-more {
|
||||
height: 60rpx;
|
||||
text-align: right;
|
||||
font-size: $font-lg;
|
||||
color: $font-color-light;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,99 +1,113 @@
|
||||
<template>
|
||||
<view class="container " style="font-size: 13px;">
|
||||
<block v-for="(row, index) in messageList" :key="index">
|
||||
<view class="msgItem">
|
||||
<div class="msgMsg">
|
||||
<div class="bagbar">{{$u.timeFormat(row.send_time, 'yyyy-mm-dd')}}</div>
|
||||
</div>
|
||||
<u-card @click="goDetail(row.sn,row.logi_id,row.ship_no)" :title="title" title-color="#666666" title-size="24" sub-title-color="#666666" sub-title-size="24" :border="false" :sub-title=row.status>
|
||||
<template #body>
|
||||
<view class="msg-body">
|
||||
<image class="msgImg" :src="row.goods_img" mode=""></image>
|
||||
<view class="msgView">
|
||||
<view>{{row.goodsName}}</view>
|
||||
<view class="msgNum">订单号:{{row.sn}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</u-card>
|
||||
</view>
|
||||
</block>
|
||||
<uni-load-more :status="loadStatus"></uni-load-more>
|
||||
<view class="container" style="font-size: 13px">
|
||||
<block v-for="(row, index) in messageList" :key="index">
|
||||
<view class="msgItem">
|
||||
<div class="msgMsg">
|
||||
<div class="bagbar">{{ formatSendTime(row.send_time) }}</div>
|
||||
</div>
|
||||
<u-card
|
||||
@click="navigateToLogisticsDetail(row.sn, row.logi_id, row.ship_no)"
|
||||
:title="pageTitle"
|
||||
title-color="#666666"
|
||||
title-size="24"
|
||||
sub-title-color="#666666"
|
||||
sub-title-size="24"
|
||||
:border="false"
|
||||
:sub-title="row.status"
|
||||
>
|
||||
<template #body>
|
||||
<view class="msg-body">
|
||||
<image class="msgImg" :src="row.goods_img" mode=""></image>
|
||||
<view class="msgView">
|
||||
<view>{{ row.goodsName }}</view>
|
||||
<view class="msgNum">订单号:{{ row.sn }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</u-card>
|
||||
</view>
|
||||
</block>
|
||||
<uni-load-more :status="loadStatus"></uni-load-more>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as API_Message from "@/api/message.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
messageList: [],
|
||||
title: "物流更新通知",
|
||||
subTitle: "运输中",
|
||||
loadStatus:'more',
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
loadStatus:'more'
|
||||
};
|
||||
},
|
||||
onLoad(){
|
||||
this.GET_LogisticsList(true);
|
||||
},
|
||||
onReachBottom() {
|
||||
this.params.pageNumber++
|
||||
this.GET_LogisticsList(false)
|
||||
},
|
||||
methods: {
|
||||
goDetail(sn,logi_id,ship_no){
|
||||
uni.navigateTo({
|
||||
url:'/pages/msgTips/packagemsg/logisticsDetail?order_sn=' + sn +'&logi_id='+logi_id+'&ship_no='+ship_no,
|
||||
})
|
||||
},
|
||||
//获取物流消息
|
||||
GET_LogisticsList(reset){
|
||||
if (reset) {
|
||||
this.params.pageNumber = 1
|
||||
}
|
||||
uni.showLoading({
|
||||
title:"加载中"
|
||||
})
|
||||
API_Message.getLogisticsMessages(this.params).then(async response => {
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() }
|
||||
const { data } = response
|
||||
if (!data || !data.length) {
|
||||
this.messageList.push(...data.data)
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, getCurrentInstance } from 'vue'
|
||||
import { onLoad, onReachBottom } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import * as API_Message from '@/api/message.js'
|
||||
|
||||
const store = useStore()
|
||||
const { proxy } = getCurrentInstance()!
|
||||
|
||||
const messageList = ref<any[]>([])
|
||||
const pageTitle = '物流更新通知'
|
||||
const loadStatus = ref('more')
|
||||
const queryParams = ref({ pageNumber: 1, pageSize: 10 })
|
||||
|
||||
onLoad(() => {
|
||||
fetchLogisticsList(true)
|
||||
})
|
||||
|
||||
onReachBottom(() => {
|
||||
queryParams.value.pageNumber++
|
||||
fetchLogisticsList(false)
|
||||
})
|
||||
|
||||
function hideLoadingIfNeeded() {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
}
|
||||
|
||||
function formatSendTime(time: number) {
|
||||
return proxy.$u.timeFormat(time, 'yyyy-mm-dd')
|
||||
}
|
||||
|
||||
function extractRecords(res: any) {
|
||||
if (Array.isArray(res?.result?.records)) return res.result.records
|
||||
if (Array.isArray(res?.result)) return res.result
|
||||
if (Array.isArray(res?.data)) return res.data
|
||||
return []
|
||||
}
|
||||
|
||||
function navigateToLogisticsDetail(sn: string, logiId: string, shipNo: string) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/mine/msgTips/packageMsg/logisticsDetail?order_sn=${sn}&logi_id=${logiId}&ship_no=${shipNo}`,
|
||||
})
|
||||
}
|
||||
|
||||
function fetchLogisticsList(reset: boolean) {
|
||||
if (reset) {
|
||||
queryParams.value.pageNumber = 1
|
||||
messageList.value = []
|
||||
loadStatus.value = 'more'
|
||||
}
|
||||
};
|
||||
uni.showLoading({ title: '加载中' })
|
||||
API_Message.getLogisticsMessages(queryParams.value).then((response) => {
|
||||
hideLoadingIfNeeded()
|
||||
const records = extractRecords(response.data)
|
||||
if (records.length) {
|
||||
messageList.value.push(...records)
|
||||
} else {
|
||||
loadStatus.value = 'noMore'
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang='scss'>
|
||||
.ddnumber {
|
||||
color: $u-tips-color;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
.msg-body{
|
||||
display: flex;
|
||||
background-color: rgba(102, 110, 232, 0.0470588235294118);
|
||||
|
||||
|
||||
.msgImg{
|
||||
width: 160rpx;
|
||||
height: 160rpx;
|
||||
}
|
||||
.msgView{
|
||||
margin-left: 20rpx;
|
||||
.msgNum:last-child{
|
||||
margin-top: 60rpx;
|
||||
}
|
||||
}
|
||||
|
||||
<style scoped lang="scss">
|
||||
.msg-body {
|
||||
display: flex;
|
||||
background-color: rgba(102, 110, 232, 0.0470588235294118);
|
||||
.msgImg {
|
||||
width: 160rpx;
|
||||
height: 160rpx;
|
||||
}
|
||||
.msgView {
|
||||
margin-left: 20rpx;
|
||||
.msgNum:last-child {
|
||||
margin-top: 60rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
.bagbar {
|
||||
display: inline;
|
||||
@@ -103,13 +117,8 @@ export default {
|
||||
padding: 10rpx 20rpx;
|
||||
background: $u-info-disabled;
|
||||
}
|
||||
.storeImg {
|
||||
width: 100%;
|
||||
height: 100rpx;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
.container {
|
||||
background: #F9F9F9;
|
||||
background: #f9f9f9;
|
||||
min-height: 100vh;
|
||||
}
|
||||
.msgMsg {
|
||||
@@ -119,12 +128,8 @@ export default {
|
||||
.msgItem {
|
||||
padding: 1em 0;
|
||||
}
|
||||
view{
|
||||
font-size: 13px;
|
||||
color: #666666;
|
||||
view {
|
||||
font-size: 13px;
|
||||
color: #666666;
|
||||
}
|
||||
u-card{
|
||||
font-size: 13px;
|
||||
color: #666666;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -2,21 +2,23 @@
|
||||
<view class="logistics-detail">
|
||||
<view class="card">
|
||||
<view class="card-title">
|
||||
<span>{{ logiList.shipper }}</span>快递 <span>{{ logiList.logisticCode }}</span>
|
||||
<span>{{ logisticsInfo.shipper }}</span>快递 <span>{{ logisticsInfo.logisticCode }}</span>
|
||||
</view>
|
||||
<view class="time-line">
|
||||
<u-time-line v-if="logiList.traces && logiList.traces.length != 0">
|
||||
<u-time-line-item nodeTop="2" v-for="(item, index) in logiList.traces" :key="index">
|
||||
<!-- 此处自定义了左边内容,用一个图标替代 -->
|
||||
<template v-slot:node >
|
||||
<view v-if="index == logiList.traces.length - 1" class="u-node" :style="{ background: $lightColor }" style="padding: 0 4px">
|
||||
<!-- 此处为uView的icon组件 -->
|
||||
<u-time-line v-if="logisticsInfo.traces && logisticsInfo.traces.length != 0">
|
||||
<u-time-line-item nodeTop="2" v-for="(item, index) in logisticsInfo.traces" :key="index">
|
||||
<template #node>
|
||||
<view
|
||||
v-if="index == logisticsInfo.traces.length - 1"
|
||||
class="u-node"
|
||||
:style="{ background: lightColor }"
|
||||
style="padding: 0 4px"
|
||||
>
|
||||
<u-icon name="pushpin-fill" color="#fff" :size="24"></u-icon>
|
||||
</view>
|
||||
</template>
|
||||
<template v-slot:content>
|
||||
<template #content>
|
||||
<view>
|
||||
<!-- <view class="u-order-title">待取件</view> -->
|
||||
<view class="u-order-desc">{{ item.AcceptStation }}</view>
|
||||
<view class="u-order-time">{{ item.AcceptTime }}</view>
|
||||
</view>
|
||||
@@ -29,32 +31,26 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getExpress } from "@/api/trade.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
express: "",
|
||||
resData: {
|
||||
title: "物流详情",
|
||||
},
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { getExpress } from '@/api/trade.js'
|
||||
|
||||
logiList: "",
|
||||
activeStep: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
init(sn) {
|
||||
getExpress(sn).then((res) => {
|
||||
this.logiList = res.data.result;
|
||||
});
|
||||
},
|
||||
},
|
||||
onLoad(option) {
|
||||
let sn = option.order_sn;
|
||||
this.init(sn);
|
||||
},
|
||||
};
|
||||
const store = useStore()
|
||||
|
||||
const lightColor = computed(() => store.getters.lightColor)
|
||||
const logisticsInfo = ref<Record<string, any>>({})
|
||||
|
||||
onLoad((option) => {
|
||||
fetchLogistics(option.order_sn)
|
||||
})
|
||||
|
||||
function fetchLogistics(orderSn: string) {
|
||||
getExpress(orderSn).then((res) => {
|
||||
logisticsInfo.value = res.data.result || {}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@@ -79,9 +75,6 @@ export default {
|
||||
padding: 16rpx 32rpx;
|
||||
}
|
||||
}
|
||||
.u-order-title {
|
||||
font-weight: bold;
|
||||
}
|
||||
.u-order-desc {
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
|
||||
@@ -30,20 +30,11 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapMutations } from "vuex";
|
||||
export default {
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(["logout"]),
|
||||
|
||||
}
|
||||
};
|
||||
<script setup lang="ts">
|
||||
// 占位页,后续接入客服消息
|
||||
</script>
|
||||
|
||||
<style scoped lang='scss'>
|
||||
<style scoped lang="scss">
|
||||
.msgTime {
|
||||
font-size: 13px;
|
||||
}
|
||||
@@ -56,11 +47,6 @@ page {
|
||||
vertical-align: middle;
|
||||
border-radius: 0.4em;
|
||||
}
|
||||
.qicon {
|
||||
text-align: center;
|
||||
display: block;
|
||||
font-size: 20px;
|
||||
}
|
||||
.redBox {
|
||||
padding: 10rpx 12rpx;
|
||||
display: inline-block;
|
||||
@@ -71,7 +57,6 @@ page {
|
||||
height: 1em;
|
||||
background: #ed6533;
|
||||
border-radius: 50%;
|
||||
|
||||
color: #fff;
|
||||
}
|
||||
.tit_title,
|
||||
@@ -92,25 +77,14 @@ page {
|
||||
}
|
||||
.list-cell {
|
||||
align-items: baseline;
|
||||
padding: 20rpx 30rpx;
|
||||
padding: 20rpx 30rpx;
|
||||
line-height: 60rpx;
|
||||
position: relative;
|
||||
background: #fff;
|
||||
justify-content: center;
|
||||
&.log-out-btn {
|
||||
margin-top: 40rpx;
|
||||
.cell-tit {
|
||||
color: $uni-color-primary;
|
||||
text-align: center;
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
&.cell-hover {
|
||||
background: #fafafa;
|
||||
}
|
||||
&.b-b:after {
|
||||
left: 30rpx;
|
||||
}
|
||||
&.m-t {
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
@@ -119,22 +93,12 @@ page {
|
||||
margin-top: 10rpx;
|
||||
height: 60rpx;
|
||||
display: flex;
|
||||
justify-content: center; //这个是X轴居中
|
||||
align-items: center; //这个是 Y轴居中
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
align-self: baseline;
|
||||
font-size: $font-lg;
|
||||
color: $font-color-light;
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
.cell-tit {
|
||||
flex: 1;
|
||||
font-size: $font-base + 2rpx;
|
||||
color: $font-color-dark;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
.cell-tip {
|
||||
font-size: $font-base;
|
||||
color: $font-color-light;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -2,17 +2,15 @@
|
||||
<view class="container">
|
||||
<block v-for="(row, index) in messageList" :key="index">
|
||||
<view class="msgItem">
|
||||
<div class="is_read">
|
||||
<!-- {{row.is_read}} -->
|
||||
<span v-if="row.is_read"></span>
|
||||
<span v-else class="red">·</span>
|
||||
|
||||
</div>
|
||||
<div class="msgMsg">{{$u.timeFormat(row.send_time, 'yyyy-mm-dd')}}</div>
|
||||
<u-card :title="title" :title-size="35" :border="false">
|
||||
<div class="is_read">
|
||||
<span v-if="row.is_read"></span>
|
||||
<span v-else class="red">·</span>
|
||||
</div>
|
||||
<div class="msgMsg">{{ formatSendTime(row.send_time) }}</div>
|
||||
<u-card :title="pageTitle" :title-size="35" :border="false">
|
||||
<template #body>
|
||||
<view class="u-body-item u-flex u-row-between u-p-b-0">
|
||||
<view class="u-body-item-title u-line-2">{{row.content}}</view>
|
||||
<view class="u-body-item-title u-line-2">{{ row.content }}</view>
|
||||
</view>
|
||||
</template>
|
||||
</u-card>
|
||||
@@ -22,74 +20,85 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapMutations } from "vuex";
|
||||
import * as API_Message from "@/api/message.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: "系统消息",
|
||||
subTitle: "未读",
|
||||
finished: false,
|
||||
loadStatus: "more",
|
||||
params: {
|
||||
pageNumber: 0,
|
||||
pageSize: 5
|
||||
},
|
||||
messageList: []
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
this.GET_MessageList(true);
|
||||
},
|
||||
onReachBottom() {
|
||||
this.params.pageNumber++;
|
||||
this.GET_MessageList(false);
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(["logout"]),
|
||||
|
||||
/** 获取站内消息 */
|
||||
GET_MessageList(reset) {
|
||||
if (reset) {
|
||||
this.params.pageNumber = 1;
|
||||
this.messageList = [];
|
||||
}
|
||||
uni.showLoading({
|
||||
title: "加载中"
|
||||
});
|
||||
API_Message.getMessages(this.params).then(async response => {
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
const { data } = response;
|
||||
if (!data || !data.length) {
|
||||
this.messageList.push(...data.data);
|
||||
this.handleReadPageMessages();
|
||||
}
|
||||
});
|
||||
},
|
||||
/** 设置消息已读 **/
|
||||
handleReadPageMessages() {
|
||||
const ids = this.messageList.map(item => item.id).join(",");
|
||||
API_Message.messageMarkAsRead(ids).then(async () => {});
|
||||
}
|
||||
<script setup lang="ts">
|
||||
import { ref, getCurrentInstance } from 'vue'
|
||||
import { onLoad, onReachBottom } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import * as API_Message from '@/api/message.js'
|
||||
|
||||
const store = useStore()
|
||||
const { proxy } = getCurrentInstance()!
|
||||
|
||||
const pageTitle = '系统消息'
|
||||
const loadStatus = ref('more')
|
||||
const queryParams = ref({ pageNumber: 1, pageSize: 5 })
|
||||
const messageList = ref<any[]>([])
|
||||
|
||||
onLoad(() => {
|
||||
fetchMessageList(true)
|
||||
})
|
||||
|
||||
onReachBottom(() => {
|
||||
queryParams.value.pageNumber++
|
||||
fetchMessageList(false)
|
||||
})
|
||||
|
||||
function hideLoadingIfNeeded() {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
}
|
||||
|
||||
function formatSendTime(time: number) {
|
||||
return proxy.$u.timeFormat(time, 'yyyy-mm-dd')
|
||||
}
|
||||
|
||||
function extractRecords(res: any) {
|
||||
if (Array.isArray(res?.result?.records)) return res.result.records
|
||||
if (Array.isArray(res?.result)) return res.result
|
||||
if (Array.isArray(res?.data)) return res.data
|
||||
return []
|
||||
}
|
||||
|
||||
function fetchMessageList(reset: boolean) {
|
||||
if (reset) {
|
||||
queryParams.value.pageNumber = 1
|
||||
messageList.value = []
|
||||
loadStatus.value = 'more'
|
||||
}
|
||||
};
|
||||
uni.showLoading({ title: '加载中' })
|
||||
API_Message.getMessages(queryParams.value).then((response) => {
|
||||
hideLoadingIfNeeded()
|
||||
const res = response.data
|
||||
const records = extractRecords(res)
|
||||
if (records.length) {
|
||||
messageList.value.push(...records)
|
||||
markPageMessagesAsRead()
|
||||
} else {
|
||||
loadStatus.value = 'noMore'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function markPageMessagesAsRead() {
|
||||
const ids = messageList.value.map((item) => item.id).join(',')
|
||||
if (!ids) return
|
||||
API_Message.messageMarkAsRead(ids)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang='scss'>
|
||||
.is_read{
|
||||
position: absolute;
|
||||
right: 25px;
|
||||
top: 80rpx;
|
||||
z-index: 999;
|
||||
<style scoped lang="scss">
|
||||
.is_read {
|
||||
position: absolute;
|
||||
right: 25px;
|
||||
top: 80rpx;
|
||||
z-index: 999;
|
||||
}
|
||||
.container {
|
||||
background: #f9f9f9;
|
||||
min-height: 100vh;
|
||||
}
|
||||
.red{
|
||||
color: coral;
|
||||
font-size: 100rpx;
|
||||
.red {
|
||||
color: coral;
|
||||
font-size: 100rpx;
|
||||
}
|
||||
.msgMsg {
|
||||
text-align: center;
|
||||
@@ -99,4 +108,4 @@ export default {
|
||||
padding: 1em 0;
|
||||
position: relative;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
:activeStyle="{ color: lightColor }"
|
||||
class="collect-tabs"
|
||||
:list="navList"
|
||||
:scrollable="true"
|
||||
:scrollable="false"
|
||||
v-model:current="tabCurrentIndex"
|
||||
></u-tabs>
|
||||
</view>
|
||||
@@ -22,278 +22,238 @@
|
||||
</u-navbar>
|
||||
<view class="collect-body">
|
||||
<!-- 显示商品栏 -->
|
||||
<view v-if="tabCurrentIndex == 0" class="tab-content">
|
||||
<scroll-view class="list-scroll-content" scroll-y>
|
||||
<u-empty style="margin-top: 40rpx" text="暂无收藏商品数据" mode="favor" v-if="goodsEmpty"></u-empty>
|
||||
<template v-else>
|
||||
<u-swipe-action
|
||||
v-for="(item, index) in goodList"
|
||||
:key="index"
|
||||
class="collect-swipe"
|
||||
<view v-if="tabCurrentIndex === 0" class="tab-content">
|
||||
<u-empty style="margin-top: 40rpx" text="暂无收藏商品数据" mode="favor" v-if="goodsEmpty"></u-empty>
|
||||
<template v-else>
|
||||
<u-swipe-action
|
||||
v-for="(item, index) in goodsList"
|
||||
:key="item.skuId || item.goodsId || index"
|
||||
class="collect-swipe"
|
||||
>
|
||||
<u-swipe-action-item
|
||||
@open="openSwipeItem(item, 'goods')"
|
||||
:show="item.selected"
|
||||
:options="swipeOptions"
|
||||
@click="removeGoodsCollection(item, index)"
|
||||
:name="index"
|
||||
>
|
||||
<u-swipe-action-item
|
||||
@open="openLeftChange(item, 'goods')"
|
||||
:show="item.selected"
|
||||
:options="LeftOptions"
|
||||
@click="clickGoodsSwiperAction(item, index)"
|
||||
:name="index"
|
||||
>
|
||||
<view class="goods" @click="goGoodsDetail(item)">
|
||||
<u-image width="131rpx" height="131rpx" :src="item.image" mode="aspectFit">
|
||||
<template #loading><u-loading></u-loading></template>
|
||||
</u-image>
|
||||
<view class="goods-intro">
|
||||
<view class="goods-name">{{ item.goodsName }}</view>
|
||||
<view class="goods-sn">{{ item.goods_sn }}</view>
|
||||
<view class="goods-price">¥{{ unitPrice(item.price) }}</view>
|
||||
</view>
|
||||
<view class="goods" @click="goGoodsDetail(item)">
|
||||
<u-image width="131rpx" height="131rpx" :src="item.image" mode="aspectFit">
|
||||
<template #loading><u-loading-icon></u-loading-icon></template>
|
||||
</u-image>
|
||||
<view class="goods-intro">
|
||||
<view class="goods-name">{{ item.goodsName }}</view>
|
||||
<view class="goods-sn">{{ item.goods_sn }}</view>
|
||||
<view class="goods-price">¥{{ unitPrice(item.price) }}</view>
|
||||
</view>
|
||||
</u-swipe-action-item>
|
||||
</u-swipe-action>
|
||||
</template>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</u-swipe-action-item>
|
||||
</u-swipe-action>
|
||||
</template>
|
||||
</view>
|
||||
<!-- 显示收藏的店铺栏 -->
|
||||
<view v-else class="tab-content">
|
||||
<scroll-view class="list-scroll-content" scroll-y>
|
||||
<u-empty style="margin-top: 40rpx" text="暂无收藏店铺数据" mode="favor" v-if="storeEmpty"></u-empty>
|
||||
<template v-else>
|
||||
<u-swipe-action
|
||||
v-for="(item, index) in storeList"
|
||||
:key="index"
|
||||
class="collect-swipe"
|
||||
<u-empty style="margin-top: 40rpx" text="暂无收藏店铺数据" mode="favor" v-if="storeEmpty"></u-empty>
|
||||
<template v-else>
|
||||
<u-swipe-action
|
||||
v-for="(item, index) in storeList"
|
||||
:key="item.id || index"
|
||||
class="collect-swipe"
|
||||
>
|
||||
<u-swipe-action-item
|
||||
@open="openSwipeItem(item, 'store')"
|
||||
:show="item.selected"
|
||||
:options="swipeOptions"
|
||||
@click="removeStoreCollection(item)"
|
||||
:name="index"
|
||||
>
|
||||
<u-swipe-action-item
|
||||
@open="openLeftChange(item, 'store')"
|
||||
:show="item.selected"
|
||||
:options="LeftOptions"
|
||||
@click="clickStoreSwiperAction(item)"
|
||||
:name="index"
|
||||
>
|
||||
<view class="store" @click="goStoreMainPage(item.id)">
|
||||
<view class="intro">
|
||||
<view class="store-logo">
|
||||
<u-image width="102rpx" height="102rpx" :src="item.storeLogo" :alt="item.storeName"
|
||||
mode="aspectFit">
|
||||
<template #loading><u-loading></u-loading></template>
|
||||
</u-image>
|
||||
</view>
|
||||
<view class="store-name">
|
||||
<view>{{ item.storeName }}</view>
|
||||
<u-tag size="mini" type="error" :color="$mainColor" v-if="item.selfOperated"
|
||||
text="自营" mode="plain" shape="circle" />
|
||||
</view>
|
||||
<view class="store-collect">
|
||||
<view>进店逛逛</view>
|
||||
</view>
|
||||
<view class="store" @click="goStoreMainPage(item.id)">
|
||||
<view class="intro">
|
||||
<view class="store-logo">
|
||||
<u-image width="102rpx" height="102rpx" :src="item.storeLogo" :alt="item.storeName"
|
||||
mode="aspectFit">
|
||||
<template #loading><u-loading-icon></u-loading-icon></template>
|
||||
</u-image>
|
||||
</view>
|
||||
<view class="store-name">
|
||||
<view>{{ item.storeName }}</view>
|
||||
<u-tag size="mini" type="error" :color="mainColor" v-if="item.selfOperated"
|
||||
text="自营" mode="plain" shape="circle" />
|
||||
</view>
|
||||
<view class="store-collect">
|
||||
<view>进店逛逛</view>
|
||||
</view>
|
||||
</view>
|
||||
</u-swipe-action-item>
|
||||
</u-swipe-action>
|
||||
</template>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</u-swipe-action-item>
|
||||
</u-swipe-action>
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getGoodsCollection,
|
||||
getStoreCollection,
|
||||
deleteGoodsCollection,
|
||||
deleteStoreCollection,
|
||||
} from "@/api/members.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
lightColor:this.$lightColor,
|
||||
// 商品左滑侧边栏
|
||||
LeftOptions: [{
|
||||
text: "取消",
|
||||
style: {
|
||||
backgroundColor: this.$lightColor,
|
||||
},
|
||||
}, ],
|
||||
tabCurrentIndex: 0, //tab的下标默认为0,也就是说会默认请求商品
|
||||
navList: [
|
||||
//tab显示数据
|
||||
{
|
||||
name: "商品(0)",
|
||||
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "店铺(0)",
|
||||
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
goodsEmpty: false, //商品数据是否为空
|
||||
storeEmpty: false, //店铺数据是否为空
|
||||
goodList: [], //商品集合
|
||||
storeList: [], //店铺集合
|
||||
};
|
||||
},
|
||||
onShow() {
|
||||
this.fetchReloadOrNextPage('reload')
|
||||
},
|
||||
onReachBottom() {
|
||||
this.fetchReloadOrNextPage('next')
|
||||
},
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { onShow, onReachBottom, onPullDownRefresh } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { unitPrice } from '@/utils/filters.js'
|
||||
import {
|
||||
getGoodsCollection,
|
||||
getStoreCollection,
|
||||
deleteGoodsCollection,
|
||||
deleteStoreCollection,
|
||||
} from '@/api/members.js'
|
||||
|
||||
methods: {
|
||||
// 刷新或者下一页
|
||||
fetchReloadOrNextPage(type) {
|
||||
if(type == 'next'){
|
||||
this.navList[this.tabCurrentIndex].params.pageNumber ++;
|
||||
if (this.tabCurrentIndex == 0) {
|
||||
this.getGoodList();
|
||||
} else {
|
||||
this.getStoreList();
|
||||
}
|
||||
const store = useStore()
|
||||
|
||||
const lightColor = computed(() => store.getters.lightColor)
|
||||
const mainColor = computed(() => store.getters.mainColor)
|
||||
|
||||
const swipeOptions = computed(() => [
|
||||
{
|
||||
text: '取消',
|
||||
style: { backgroundColor: lightColor.value },
|
||||
},
|
||||
])
|
||||
|
||||
const tabCurrentIndex = ref(0)
|
||||
const navList = ref([
|
||||
{ name: '商品(0)', params: { pageNumber: 1, pageSize: 10 } },
|
||||
{ name: '店铺(0)', params: { pageNumber: 1, pageSize: 10 } },
|
||||
])
|
||||
const goodsEmpty = ref(false)
|
||||
const storeEmpty = ref(false)
|
||||
const goodsList = ref<any[]>([])
|
||||
const storeList = ref<any[]>([])
|
||||
|
||||
onShow(() => {
|
||||
reloadOrLoadMore('reload')
|
||||
})
|
||||
|
||||
onReachBottom(() => {
|
||||
reloadOrLoadMore('next')
|
||||
})
|
||||
|
||||
onPullDownRefresh(() => {
|
||||
if (tabCurrentIndex.value === 0) {
|
||||
navList.value[0].params.pageNumber = 1
|
||||
goodsList.value = []
|
||||
fetchGoodsList()
|
||||
} else {
|
||||
navList.value[1].params.pageNumber = 1
|
||||
storeList.value = []
|
||||
fetchStoreList()
|
||||
}
|
||||
})
|
||||
|
||||
function hideLoadingIfNeeded() {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
}
|
||||
|
||||
function reloadOrLoadMore(type: 'reload' | 'next') {
|
||||
if (type === 'next') {
|
||||
navList.value[tabCurrentIndex.value].params.pageNumber++
|
||||
if (tabCurrentIndex.value === 0) {
|
||||
fetchGoodsList()
|
||||
} else {
|
||||
fetchStoreList()
|
||||
}
|
||||
return
|
||||
}
|
||||
navList.value[0].params.pageNumber = 1
|
||||
navList.value[1].params.pageNumber = 1
|
||||
goodsEmpty.value = false
|
||||
storeEmpty.value = false
|
||||
goodsList.value = []
|
||||
storeList.value = []
|
||||
fetchGoodsList()
|
||||
fetchStoreList()
|
||||
}
|
||||
|
||||
function openSwipeItem(val: any, type: 'goods' | 'store') {
|
||||
const targetList = type === 'goods' ? goodsList.value : storeList.value
|
||||
targetList.forEach((item) => {
|
||||
item.selected = false
|
||||
})
|
||||
val.selected = true
|
||||
}
|
||||
|
||||
function removeGoodsCollection(val: any) {
|
||||
deleteGoodsCollection(val.skuId).then((res) => {
|
||||
if (res.statusCode === 200) {
|
||||
goodsList.value = []
|
||||
navList.value[0].params.pageNumber = 1
|
||||
fetchGoodsList()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function removeStoreCollection(val: any) {
|
||||
deleteStoreCollection(val.id).then((res) => {
|
||||
if (res.statusCode === 200) {
|
||||
storeList.value = []
|
||||
navList.value[1].params.pageNumber = 1
|
||||
fetchStoreList()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function goGoodsDetail(val: any) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/product/goods?id=${val.skuId}&goodsId=${val.goodsId}`,
|
||||
})
|
||||
}
|
||||
|
||||
function goStoreMainPage(id: string) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/product/shopPage?id=${id}`,
|
||||
})
|
||||
}
|
||||
|
||||
function fetchGoodsList() {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
getGoodsCollection(navList.value[0].params, 'GOODS')
|
||||
.then((res) => {
|
||||
hideLoadingIfNeeded()
|
||||
uni.stopPullDownRefresh()
|
||||
if (res.data.success) {
|
||||
const data = res.data.result
|
||||
navList.value[0].name = `商品(${data.total})`
|
||||
goodsEmpty.value = data.total === 0
|
||||
if (data.records?.length) {
|
||||
const records = data.records.map((item: any) => ({ ...item, selected: false }))
|
||||
goodsList.value.push(...records)
|
||||
}
|
||||
else{
|
||||
this.navList[0].params.pageNumber = 1;
|
||||
this.navList[1].params.pageNumber = 1;
|
||||
this.goodList = [];
|
||||
this.storeList = [];
|
||||
this.getGoodList();
|
||||
this.getStoreList();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 打开商品左侧取消收藏
|
||||
*/
|
||||
openLeftChange(val, type) {
|
||||
const way = type === "goods" ? this.goodList : this.storeList;
|
||||
way.forEach((item) => {
|
||||
item.selected = false;
|
||||
});
|
||||
val.selected = true;
|
||||
},
|
||||
|
||||
/**
|
||||
* 点击商品左侧取消收藏
|
||||
*/
|
||||
clickGoodsSwiperAction(val) {
|
||||
deleteGoodsCollection(val.skuId).then((res) => {
|
||||
if (res.statusCode == 200) {
|
||||
this.storeList = [];
|
||||
this.goodList = [];
|
||||
this.getGoodList();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 点击店铺左侧取消收藏
|
||||
*/
|
||||
clickStoreSwiperAction(val) {
|
||||
deleteStoreCollection(val.id).then((res) => {
|
||||
if (res.statusCode == 200) {
|
||||
this.storeList = [];
|
||||
this.getStoreList();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 查看商品详情
|
||||
*/
|
||||
goGoodsDetail(val) {
|
||||
//商品详情
|
||||
uni.navigateTo({
|
||||
url: "/pages/product/goods?id=" + val.skuId + "&goodsId=" + val.goodsId,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 查看店铺详情
|
||||
*/
|
||||
goStoreMainPage(id) {
|
||||
//店铺主页
|
||||
uni.navigateTo({
|
||||
url: "/pages/product/shopPage?id=" + id,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取商品集合
|
||||
*/
|
||||
getGoodList() {
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
getGoodsCollection(this.navList[0].params, "GOODS").then((res) => {
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
uni.stopPullDownRefresh();
|
||||
if (res.data.success) {
|
||||
let data = res.data.result;
|
||||
data.selected = false;
|
||||
this.navList[0].name = `商品(${data.total})`;
|
||||
|
||||
if (data.total == 0) {
|
||||
this.goodsEmpty = true;
|
||||
} else if (data.total < 10) {
|
||||
this.goodsLoad = "noMore";
|
||||
this.goodList.push(...data.records);
|
||||
} else {
|
||||
this.goodList.push(...data.records);
|
||||
if (data.total.length < 10) this.goodsLoad = "noMore";
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取店铺集合
|
||||
*/
|
||||
getStoreList() {
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
getStoreCollection(this.navList[1].params, "STORE").then((res) => {
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
uni.stopPullDownRefresh();
|
||||
if (res.data.success) {
|
||||
let data = res.data.result;
|
||||
data.selected = false;
|
||||
this.navList[1].name = `店铺(${data.total})`;
|
||||
if (data.total == 0) {
|
||||
this.storeEmpty = true;
|
||||
} else if (data.total < 10) {
|
||||
|
||||
this.storeList.push(...data.records);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 下拉刷新时
|
||||
*/
|
||||
onPullDownRefresh() {
|
||||
if (this.tabCurrentIndex == 0) {
|
||||
this.navList[0].params.pageNumber = 1;
|
||||
this.goodList = [];
|
||||
this.getGoodList();
|
||||
} else {
|
||||
this.navList[1].params.pageNumber = 1;
|
||||
this.storeList = [];
|
||||
this.getStoreList();
|
||||
}
|
||||
},
|
||||
};
|
||||
})
|
||||
.catch(() => {
|
||||
hideLoadingIfNeeded()
|
||||
uni.stopPullDownRefresh()
|
||||
})
|
||||
}
|
||||
|
||||
function fetchStoreList() {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
getStoreCollection(navList.value[1].params, 'STORE')
|
||||
.then((res) => {
|
||||
hideLoadingIfNeeded()
|
||||
uni.stopPullDownRefresh()
|
||||
if (res.data.success) {
|
||||
const data = res.data.result
|
||||
navList.value[1].name = `店铺(${data.total})`
|
||||
storeEmpty.value = data.total === 0
|
||||
if (data.records?.length) {
|
||||
const records = data.records.map((item: any) => ({ ...item, selected: false }))
|
||||
storeList.value.push(...records)
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
hideLoadingIfNeeded()
|
||||
uni.stopPullDownRefresh()
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@@ -324,15 +284,18 @@
|
||||
|
||||
.collect-body {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.list-scroll-content {
|
||||
height: 100%;
|
||||
:deep(.u-tabs),
|
||||
:deep(.u-tabs__wrapper),
|
||||
:deep(.u-tabs__wrapper__scroll-view-wrapper),
|
||||
:deep(.u-tabs__wrapper__scroll-view),
|
||||
:deep(.u-tabs__wrapper__nav) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,14 +7,14 @@
|
||||
:auto-back="true"
|
||||
>
|
||||
<template #right>
|
||||
<div class="light-color edit" @click="isEdit = !isEdit">{{ !isEdit ? '编辑' : '完成'}}</div>
|
||||
<view class="light-color edit" @click="isEdit = !isEdit">{{ !isEdit ? '编辑' : '完成'}}</view>
|
||||
</template>
|
||||
</u-navbar>
|
||||
<view class="tracks-tip">
|
||||
<u-icon name="volume" color="#f9ae3d" size="19"></u-icon>
|
||||
<text class="tracks-tip-text">右划删除浏览记录</text>
|
||||
</view>
|
||||
<u-empty text="暂无历史记录" style="margin-top:200rpx;" mode="history" v-if="whetherEmpty"></u-empty>
|
||||
<u-empty text="暂无历史记录" style="margin-top:200rpx;" mode="history" v-if="isEmpty"></u-empty>
|
||||
<view v-else class="tracks-list">
|
||||
<block v-for="(item, index) in trackList" :key="index">
|
||||
<view
|
||||
@@ -26,9 +26,9 @@
|
||||
<u-swipe-action-item
|
||||
:show="item.show"
|
||||
:name="index"
|
||||
@click="delTracks"
|
||||
@open="open"
|
||||
:options="options"
|
||||
@click="deleteTracks"
|
||||
@open="openSwipe"
|
||||
:options="swipeOptions"
|
||||
>
|
||||
<view class="myTracks-item">
|
||||
<u-checkbox-group v-if="isEdit" class="store-line-check">
|
||||
@@ -37,7 +37,7 @@
|
||||
shape="circle"
|
||||
:active-color="lightColor"
|
||||
v-model:checked="item.checked"
|
||||
@change="checkboxChangeDP(item)"
|
||||
@change="onTrackCheckChange(item)"
|
||||
></u-checkbox>
|
||||
</u-checkbox-group>
|
||||
<view class="myTracks-item-img" @click.stop="navigateToDetail(item)">
|
||||
@@ -56,7 +56,7 @@
|
||||
</u-swipe-action>
|
||||
<view class="myTracks-divider"></view>
|
||||
</block>
|
||||
<view v-if="isEdit" class="submit" @click="handleClickDeleteSelected">
|
||||
<view v-if="isEdit" class="submit" @click="deleteSelectedTracks">
|
||||
删除所选
|
||||
</view>
|
||||
</view>
|
||||
@@ -64,172 +64,147 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
myTrackList,
|
||||
deleteHistoryListId
|
||||
} from "@/api/members.js";
|
||||
import { getStoreBaseInfo } from "@/api/store.js";
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { onShow, onReachBottom, onPullDownRefresh } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { unitPrice } from '@/utils/filters.js'
|
||||
import { myTrackList, deleteHistoryListId } from '@/api/members.js'
|
||||
import { getStoreBaseInfo } from '@/api/store.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
isEdit:false,
|
||||
whetherEmpty: false, //是否数据为空
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
order: "desc",
|
||||
sort: "updateTime",
|
||||
},
|
||||
lightColor:this.$lightColor,
|
||||
options: [{
|
||||
text: '删除',
|
||||
style: {
|
||||
backgroundColor: '#dd524d'
|
||||
}
|
||||
}],
|
||||
trackList: [], //足迹列表
|
||||
storeNameMap: {},
|
||||
};
|
||||
},
|
||||
const store = useStore()
|
||||
const lightColor = computed(() => store.getters.lightColor)
|
||||
|
||||
/**
|
||||
* 滑到底部加载下一页数据
|
||||
*/
|
||||
onReachBottom() {
|
||||
this.params.pageNumber++;
|
||||
this.getList();
|
||||
},
|
||||
onShow() {
|
||||
this.params.pageNumber = 1
|
||||
this.trackList = [];
|
||||
this.getList();
|
||||
},
|
||||
onPullDownRefresh() {
|
||||
this.trackList = [];
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
getStoreName(item) {
|
||||
return item.storeName || this.storeNameMap[item.storeId] || "";
|
||||
},
|
||||
async enrichStoreNames(records) {
|
||||
const storeIds = [
|
||||
...new Set(
|
||||
records
|
||||
.filter((item) => !item.storeName && item.storeId)
|
||||
.map((item) => item.storeId)
|
||||
),
|
||||
].filter((storeId) => !this.storeNameMap[storeId]);
|
||||
const isEdit = ref(false)
|
||||
const isEmpty = ref(false)
|
||||
const params = ref({
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
order: 'desc',
|
||||
sort: 'updateTime',
|
||||
})
|
||||
const swipeOptions = [{ text: '删除', style: { backgroundColor: '#dd524d' } }]
|
||||
const trackList = ref<any[]>([])
|
||||
const storeNameMap = ref<Record<string, string>>({})
|
||||
|
||||
await Promise.all(
|
||||
storeIds.map(async (storeId) => {
|
||||
try {
|
||||
const res = await getStoreBaseInfo(storeId);
|
||||
const name = res.data?.result?.storeName;
|
||||
if (name) {
|
||||
this.storeNameMap[storeId] = name;
|
||||
}
|
||||
} catch (e) {
|
||||
// ignore
|
||||
}
|
||||
})
|
||||
);
|
||||
},
|
||||
checkboxChangeDP(val){
|
||||
console.log(val)
|
||||
},
|
||||
// 删除所选的数据
|
||||
handleClickDeleteSelected(val){
|
||||
const ids = this.trackList.filter(item=>item.checked).map(item=>item.goodsId);
|
||||
if(!ids.length){
|
||||
uni.showToast({
|
||||
title:"请选择删除数据",
|
||||
icon:"none"
|
||||
})
|
||||
}else{
|
||||
this.delTracks(0,ids)
|
||||
onReachBottom(() => {
|
||||
params.value.pageNumber++
|
||||
fetchTrackList()
|
||||
})
|
||||
|
||||
onShow(() => {
|
||||
params.value.pageNumber = 1
|
||||
trackList.value = []
|
||||
fetchTrackList()
|
||||
})
|
||||
|
||||
onPullDownRefresh(() => {
|
||||
params.value.pageNumber = 1
|
||||
trackList.value = []
|
||||
fetchTrackList()
|
||||
})
|
||||
|
||||
function getStoreName(item: any) {
|
||||
return item.storeName || storeNameMap.value[item.storeId] || ''
|
||||
}
|
||||
|
||||
async function enrichStoreNames(records: any[]) {
|
||||
const storeIds = [
|
||||
...new Set(
|
||||
records
|
||||
.filter((item) => !item.storeName && item.storeId)
|
||||
.map((item) => item.storeId)
|
||||
),
|
||||
].filter((storeId) => !storeNameMap.value[storeId])
|
||||
|
||||
await Promise.all(
|
||||
storeIds.map(async (storeId) => {
|
||||
try {
|
||||
const res = await getStoreBaseInfo(storeId)
|
||||
const name = res.data?.result?.storeName
|
||||
if (name) {
|
||||
storeNameMap.value[storeId] = name
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 导航到店铺
|
||||
*/
|
||||
navigateToStore(val) {
|
||||
uni.navigateTo({
|
||||
url: "/pages/product/shopPage?id=" + val.storeId,
|
||||
});
|
||||
},
|
||||
open(index) {
|
||||
// 先将正在被操作的swipeAction标记为打开状态,否则由于props的特性限制,
|
||||
// 原本为'false',再次设置为'false'会无效
|
||||
this.trackList[index].show = true;
|
||||
this.trackList.map((val, idx) => {
|
||||
if (index != idx) this.trackList[idx].show = false;
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 跳转详情
|
||||
*/
|
||||
navigateToDetail(item) {
|
||||
uni.navigateTo({
|
||||
url: "/pages/product/goods?id=" + item.id + "&goodsId=" + item.goodsId,
|
||||
});
|
||||
},
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取我的足迹列表
|
||||
*/
|
||||
getList() {
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
myTrackList(this.params).then(async (res) => {
|
||||
uni.stopPullDownRefresh();
|
||||
uni.hideLoading();
|
||||
if (res.statusCode == 200) {
|
||||
const records = res.data.result.records || [];
|
||||
records.forEach((item) => {
|
||||
item.show = false;
|
||||
item.checked = false;
|
||||
});
|
||||
function onTrackCheckChange(_val: any) {
|
||||
// 勾选状态由 v-model:checked 维护
|
||||
}
|
||||
|
||||
if (!records.length) {
|
||||
if (this.trackList.length === 0) {
|
||||
this.whetherEmpty = true;
|
||||
}
|
||||
} else {
|
||||
await this.enrichStoreNames(records);
|
||||
this.trackList.push(...records);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
function deleteSelectedTracks() {
|
||||
const ids = trackList.value.filter((item) => item.checked).map((item) => item.goodsId)
|
||||
if (!ids.length) {
|
||||
uni.showToast({ title: '请选择删除数据', icon: 'none' })
|
||||
return
|
||||
}
|
||||
deleteTracks(0, ids)
|
||||
}
|
||||
|
||||
function navigateToStore(val: any) {
|
||||
uni.navigateTo({ url: `/pages/product/shopPage?id=${val.storeId}` })
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除足迹
|
||||
*/
|
||||
delTracks(e, ids) {
|
||||
const index = typeof e === 'object' ? (e.name ?? e.index) : e;
|
||||
const goodsId = ids || this.trackList[index]?.goodsId;
|
||||
if (!goodsId) return;
|
||||
deleteHistoryListId(goodsId).then((res) => {
|
||||
if (res.data.code == 200) {
|
||||
this.trackList = [];
|
||||
this.params.pageNumber = 1
|
||||
this.getList();
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.data.message,
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
function openSwipe(index: number) {
|
||||
trackList.value[index].show = true
|
||||
trackList.value.forEach((val, idx) => {
|
||||
if (index !== idx) val.show = false
|
||||
})
|
||||
}
|
||||
|
||||
function navigateToDetail(item: any) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/product/goods?id=${item.id}&goodsId=${item.goodsId}`,
|
||||
})
|
||||
}
|
||||
|
||||
function fetchTrackList() {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
myTrackList(params.value).then(async (res) => {
|
||||
uni.stopPullDownRefresh()
|
||||
uni.hideLoading()
|
||||
if (res.statusCode === 200) {
|
||||
const records = res.data.result.records || []
|
||||
records.forEach((item: any) => {
|
||||
item.show = false
|
||||
item.checked = false
|
||||
})
|
||||
|
||||
if (!records.length) {
|
||||
if (trackList.value.length === 0) {
|
||||
isEmpty.value = true
|
||||
}
|
||||
} else {
|
||||
isEmpty.value = false
|
||||
await enrichStoreNames(records)
|
||||
trackList.value.push(...records)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function deleteTracks(e: any, ids?: any) {
|
||||
const index = typeof e === 'object' ? (e.name ?? e.index) : e
|
||||
const goodsId = ids || trackList.value[index]?.goodsId
|
||||
if (!goodsId) return
|
||||
deleteHistoryListId(goodsId).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
trackList.value = []
|
||||
params.value.pageNumber = 1
|
||||
fetchTrackList()
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.data.message,
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -1,249 +1,245 @@
|
||||
<template>
|
||||
<view class="content">
|
||||
<view class="portrait-box">
|
||||
<image src="/static/pointTrade/point_bg_1.png" mode=""></image>
|
||||
<image class="point-img" src="/static/pointTrade/tradehall.png" />
|
||||
<view class="position-point">
|
||||
|
||||
|
||||
</view>
|
||||
</view>
|
||||
<view class="point-summary">
|
||||
<view class="point-summary-item">
|
||||
<text>累计获得:</text>
|
||||
<text class="pcolor">{{ pointData.totalPoint || 0 }}</text>
|
||||
</view>
|
||||
<view class="point-summary-divider"></view>
|
||||
<view class="point-summary-item">
|
||||
<text>剩余积分:</text>
|
||||
<text class="pcolor">{{ pointData.point || 0 }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<div class="point-list">
|
||||
<view class="point-item" v-for="(item, index) in pointList" :key="index">
|
||||
<view class="point-item-left">
|
||||
<view class="point-label">{{ item.content }}</view>
|
||||
<view class="point-item-time">{{ item.createTime }}</view>
|
||||
</view>
|
||||
<view class="point-item-value" :class="[item.pointType == 'INCREASE' ? 'plus' : 'reduce']">
|
||||
<text>{{ item.pointType == "INCREASE" ? "+" : "-" }}</text>{{ item.variablePoint }}
|
||||
</view>
|
||||
</view>
|
||||
<uni-load-more :status="count.loadStatus"></uni-load-more>
|
||||
</div>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getPointsData } from "@/api/members.js";
|
||||
import { getMemberPointSum } from "@/api/members.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
count: {
|
||||
loadStatus: "more",
|
||||
},
|
||||
pointList: [], //积分数据集合
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
pointData: {}, //累计获取 未输入 集合
|
||||
};
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
this.initPointData();
|
||||
this.getList();
|
||||
},
|
||||
|
||||
/**
|
||||
* 触底加载
|
||||
*/
|
||||
onReachBottom() {
|
||||
this.params.pageNumber++;
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 获取积分数据
|
||||
*/
|
||||
getList() {
|
||||
let params = this.params;
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
getPointsData(params).then((res) => {
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
if (res.data.success) {
|
||||
let data = res.data.result.records;
|
||||
if (data.length < 10) {
|
||||
this.count["loadStatus"] = "noMore";
|
||||
this.pointList.push(...data);
|
||||
} else {
|
||||
this.pointList.push(...data);
|
||||
if (data.length < 10) this.count["loadStatus"] = "noMore";
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获得累计积分使用
|
||||
*/
|
||||
initPointData() {
|
||||
getMemberPointSum().then((res) => {
|
||||
this.pointData = res.data.result;
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.point-list {
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
.title {
|
||||
height: 80rpx;
|
||||
text-align: center;
|
||||
line-height: 80rpx;
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
.plus{
|
||||
color: $light-color;
|
||||
font-weight: bold;
|
||||
}
|
||||
.reduce{
|
||||
color: $weChat-color;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.point-item {
|
||||
width: 100%;
|
||||
min-height: 130rpx;
|
||||
padding: 24rpx 20rpx;
|
||||
background: #ffffff;
|
||||
font-size: $font-sm;
|
||||
border-bottom: 1px solid $border-color-light;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
|
||||
.point-item-left {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
line-height: 40rpx;
|
||||
}
|
||||
|
||||
.point-item-time {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.point-item-value {
|
||||
flex-shrink: 0;
|
||||
width: 100rpx;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.point-summary {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-height: 100rpx;
|
||||
padding: 28rpx 0;
|
||||
background: #ffffff;
|
||||
border-radius: 0 0 20rpx 20rpx;
|
||||
margin: 0 20rpx;
|
||||
font-size: 26rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
.point-summary-item {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.point-summary-divider {
|
||||
width: 1px;
|
||||
height: 48rpx;
|
||||
background: $border-color-light;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.pcolor {
|
||||
color: $light-color;
|
||||
margin-left: 8rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
background: #f9f9f9;
|
||||
}
|
||||
|
||||
.more {
|
||||
text-align: right;
|
||||
color: $u-tips-color;
|
||||
font-size: 24rpx;
|
||||
padding-right: 40rpx !important;
|
||||
}
|
||||
|
||||
.portrait-box {
|
||||
background-color: $main-color;
|
||||
height: 250rpx;
|
||||
background: linear-gradient(91deg, $light-color 1%, $aider-light-color 99%);
|
||||
border-radius: 20rpx 20rpx 0 0;
|
||||
margin: 20rpx 20rpx 0;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: #ffffff;
|
||||
|
||||
> image:first-child {
|
||||
width: 263rpx;
|
||||
height: 250rpx;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
transform: rotateY(180deg);
|
||||
}
|
||||
|
||||
.position-point {
|
||||
position: absolute;
|
||||
right: -2rpx;
|
||||
top: 0;
|
||||
|
||||
.apply-point {
|
||||
margin-top: 30rpx;
|
||||
text-align: center;
|
||||
line-height: 40rpx;
|
||||
font-size: $font-sm;
|
||||
color: #ffffff;
|
||||
width: 142rpx;
|
||||
height: 40rpx;
|
||||
background: rgba(#ffffff, 0.2);
|
||||
border-radius: 20rpx 0px 0px 20rpx;
|
||||
}
|
||||
}
|
||||
.point-img {
|
||||
height: 108rpx;
|
||||
width: 108rpx;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
.point {
|
||||
font-size: 56rpx;
|
||||
}
|
||||
|
||||
}
|
||||
.point-label {
|
||||
font-weight: bold;
|
||||
margin-bottom: 10rpx;
|
||||
color: #666666;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<view class="content">
|
||||
<view class="portrait-box">
|
||||
<image src="/static/pointTrade/point_bg_1.png" mode=""></image>
|
||||
<image class="point-img" src="/static/pointTrade/tradehall.png" />
|
||||
<view class="position-point">
|
||||
|
||||
|
||||
</view>
|
||||
</view>
|
||||
<view class="point-summary">
|
||||
<view class="point-summary-item">
|
||||
<text>累计获得:</text>
|
||||
<text class="pcolor">{{ pointSummary.totalPoint || 0 }}</text>
|
||||
</view>
|
||||
<view class="point-summary-divider"></view>
|
||||
<view class="point-summary-item">
|
||||
<text>剩余积分:</text>
|
||||
<text class="pcolor">{{ pointSummary.point || 0 }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="point-list">
|
||||
<view class="point-item" v-for="(item, index) in pointList" :key="index">
|
||||
<view class="point-item-left">
|
||||
<view class="point-label">{{ item.content }}</view>
|
||||
<view class="point-item-time">{{ item.createTime }}</view>
|
||||
</view>
|
||||
<view class="point-item-value" :class="[item.pointType == 'INCREASE' ? 'plus' : 'reduce']">
|
||||
<text>{{ item.pointType == "INCREASE" ? "+" : "-" }}</text>{{ item.variablePoint }}
|
||||
</view>
|
||||
</view>
|
||||
<uni-load-more :status="loadStatus"></uni-load-more>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad, onReachBottom } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { getPointsData, getMemberPointSum } from '@/api/members.js'
|
||||
|
||||
const store = useStore()
|
||||
|
||||
const loadStatus = ref('more')
|
||||
const pointList = ref<any[]>([])
|
||||
const params = ref({ pageNumber: 1, pageSize: 10 })
|
||||
const pointSummary = ref<Record<string, any>>({})
|
||||
|
||||
onLoad(() => {
|
||||
fetchPointSummary()
|
||||
fetchPointLogList()
|
||||
})
|
||||
|
||||
onReachBottom(() => {
|
||||
params.value.pageNumber++
|
||||
fetchPointLogList()
|
||||
})
|
||||
|
||||
function hideLoadingIfNeeded() {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
}
|
||||
|
||||
function fetchPointLogList() {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
getPointsData(params.value).then((res) => {
|
||||
hideLoadingIfNeeded()
|
||||
if (res.data.success) {
|
||||
const data = res.data.result.records || []
|
||||
if (data.length < params.value.pageSize) {
|
||||
loadStatus.value = 'noMore'
|
||||
}
|
||||
pointList.value.push(...data)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function fetchPointSummary() {
|
||||
getMemberPointSum().then((res) => {
|
||||
pointSummary.value = res.data.result
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page,
|
||||
.content {
|
||||
min-height: 100vh;
|
||||
background: #f9f9f9;
|
||||
}
|
||||
|
||||
.content {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.point-list {
|
||||
margin-top: 20rpx;
|
||||
background: #f9f9f9;
|
||||
min-height: calc(100vh - 390rpx);
|
||||
padding-bottom: 24rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.title {
|
||||
height: 80rpx;
|
||||
text-align: center;
|
||||
line-height: 80rpx;
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
.plus{
|
||||
color: $light-color;
|
||||
font-weight: bold;
|
||||
}
|
||||
.reduce{
|
||||
color: $weChat-color;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.point-item {
|
||||
width: 100%;
|
||||
min-height: 130rpx;
|
||||
padding: 24rpx 20rpx;
|
||||
background: #ffffff;
|
||||
font-size: $font-sm;
|
||||
border-bottom: 1px solid $border-color-light;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
|
||||
.point-item-left {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
line-height: 40rpx;
|
||||
}
|
||||
|
||||
.point-item-time {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.point-item-value {
|
||||
flex-shrink: 0;
|
||||
width: 100rpx;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.point-summary {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-height: 100rpx;
|
||||
padding: 28rpx 0;
|
||||
background: #ffffff;
|
||||
border-radius: 0 0 20rpx 20rpx;
|
||||
margin: 0 20rpx;
|
||||
font-size: 26rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
.point-summary-item {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.point-summary-divider {
|
||||
width: 1px;
|
||||
height: 48rpx;
|
||||
background: $border-color-light;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.pcolor {
|
||||
color: $light-color;
|
||||
margin-left: 8rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.more {
|
||||
text-align: right;
|
||||
color: $u-tips-color;
|
||||
font-size: 24rpx;
|
||||
padding-right: 40rpx !important;
|
||||
}
|
||||
|
||||
.portrait-box {
|
||||
background-color: $main-color;
|
||||
height: 250rpx;
|
||||
background: linear-gradient(91deg, $light-color 1%, $aider-light-color 99%);
|
||||
border-radius: 20rpx 20rpx 0 0;
|
||||
margin: 20rpx 20rpx 0;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: #ffffff;
|
||||
|
||||
> image:first-child {
|
||||
width: 263rpx;
|
||||
height: 250rpx;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
transform: rotateY(180deg);
|
||||
}
|
||||
|
||||
.position-point {
|
||||
position: absolute;
|
||||
right: -2rpx;
|
||||
top: 0;
|
||||
|
||||
.apply-point {
|
||||
margin-top: 30rpx;
|
||||
text-align: center;
|
||||
line-height: 40rpx;
|
||||
font-size: $font-sm;
|
||||
color: #ffffff;
|
||||
width: 142rpx;
|
||||
height: 40rpx;
|
||||
background: rgba(#ffffff, 0.2);
|
||||
border-radius: 20rpx 0px 0px 20rpx;
|
||||
}
|
||||
}
|
||||
.point-img {
|
||||
height: 108rpx;
|
||||
width: 108rpx;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
.point {
|
||||
font-size: 56rpx;
|
||||
}
|
||||
|
||||
}
|
||||
.point-label {
|
||||
font-weight: bold;
|
||||
margin-bottom: 10rpx;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.point-list .uni-load-more {
|
||||
background: #f9f9f9;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
<u-cell-group class="cell-group" :border="false">
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<u-cell v-if="IosWhether" is-link title="去评分" @click="checkStar"></u-cell>
|
||||
<u-cell v-if="showIosRating" is-link title="去评分" @click="openAppStoreRating"></u-cell>
|
||||
<u-cell is-link title="功能介绍" @click="navigateTo('/pages/mine/set/versionFunctionList')"></u-cell>
|
||||
<u-cell is-link title="检查更新" @click="checkUpdate"></u-cell>
|
||||
<!-- #endif -->
|
||||
@@ -40,93 +40,72 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import APPUpdate from "@/plugins/APPUpdate";
|
||||
import config from "@/config/config";
|
||||
import { getAppVersion } from "@/api/message.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
config,
|
||||
IosWhether: false,
|
||||
editionHistory: [],
|
||||
versionData: {},
|
||||
localVersion: "",
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 5,
|
||||
},
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
// #ifdef APP-PLUS
|
||||
const platform = uni.getSystemInfoSync().platform;
|
||||
if (platform === "android") {
|
||||
this.params.type = 0;
|
||||
} else {
|
||||
this.IosWhether = true;
|
||||
this.params.type = 1;
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import APPUpdate from '@/plugins/APPUpdate'
|
||||
import config from '@/config/config'
|
||||
import { getAppVersion } from '@/api/message.js'
|
||||
|
||||
const showIosRating = ref(false)
|
||||
const versionData = ref<Record<string, any>>({})
|
||||
const localVersion = ref<Record<string, any>>({})
|
||||
const params = ref<Record<string, any>>({ pageNumber: 1, pageSize: 5 })
|
||||
|
||||
onLoad(() => {
|
||||
// #ifdef APP-PLUS
|
||||
const platform = uni.getSystemInfoSync().platform
|
||||
if (platform === 'android') {
|
||||
params.value.type = 0
|
||||
} else {
|
||||
showIosRating.value = true
|
||||
params.value.type = 1
|
||||
}
|
||||
fetchRemoteVersion(platform)
|
||||
|
||||
plus.runtime.getProperty(plus.runtime.appid, (inf) => {
|
||||
localVersion.value = {
|
||||
versionCode: inf.version.replace(/\./g, ''),
|
||||
version: inf.version,
|
||||
}
|
||||
this.getVersion(platform);
|
||||
})
|
||||
// #endif
|
||||
|
||||
plus.runtime.getProperty(plus.runtime.appid, (inf) => {
|
||||
this.localVersion = {
|
||||
versionCode: inf.version.replace(/\./g, ""),
|
||||
version: inf.version,
|
||||
};
|
||||
});
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN
|
||||
const accountInfo = wx.getAccountInfoSync()
|
||||
localVersion.value = {
|
||||
versionCode: accountInfo.miniProgram.version.replace(/\./g, ''),
|
||||
version: accountInfo.miniProgram.version,
|
||||
envVersion: accountInfo.miniProgram.envVersion,
|
||||
}
|
||||
// #endif
|
||||
})
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
const accountInfo = wx.getAccountInfoSync();
|
||||
this.version_number = accountInfo.miniProgram.version;
|
||||
this.localVersion = {
|
||||
versionCode: accountInfo.miniProgram.version.replace(/\./g, ""),
|
||||
version: accountInfo.miniProgram.version,
|
||||
envVersion: accountInfo.miniProgram.envVersion,
|
||||
};
|
||||
// #endif
|
||||
},
|
||||
async function fetchRemoteVersion(platform: string) {
|
||||
const type = platform === 'android' ? 'ANDROID' : 'IOS'
|
||||
const res = await getAppVersion(type)
|
||||
if (res.data.success) {
|
||||
versionData.value = res.data.result
|
||||
}
|
||||
}
|
||||
|
||||
methods: {
|
||||
async getVersion(platform) {
|
||||
let type;
|
||||
platform == "android" ? (type = "ANDROID") : (type = "IOS");
|
||||
function navigateTo(url: string) {
|
||||
uni.navigateTo({ url })
|
||||
}
|
||||
|
||||
let res = await getAppVersion(type);
|
||||
if (res.data.success) {
|
||||
this.versionData = res.data.result;
|
||||
}
|
||||
},
|
||||
function openAppStoreRating() {
|
||||
plus.runtime.launchApplication({
|
||||
action: `itms-apps://itunes.apple.com/app/${config.iosAppId}?action=write-review`,
|
||||
})
|
||||
}
|
||||
|
||||
navigateTo(url) {
|
||||
uni.navigateTo({
|
||||
url,
|
||||
});
|
||||
},
|
||||
|
||||
checkStar() {
|
||||
plus.runtime.launchApplication({
|
||||
action: `itms-apps://itunes.apple.com/app/${config.iosAppId}?action=write-review`,
|
||||
});
|
||||
},
|
||||
|
||||
checkUpdate() {
|
||||
if (
|
||||
this.versionData.version.replace(/\./g, "") <
|
||||
this.localVersion.versionCode
|
||||
) {
|
||||
APPUpdate();
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: "当前版本已是最新版",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
function checkUpdate() {
|
||||
if (versionData.value.version?.replace(/\./g, '') < localVersion.value.versionCode) {
|
||||
APPUpdate()
|
||||
} else {
|
||||
uni.showToast({ title: '当前版本已是最新版', duration: 2000, icon: 'none' })
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
<view class="box-title">猜你想问</view>
|
||||
<view
|
||||
class="feedBack-item"
|
||||
:class="{ active: feedBack.type == item.value }"
|
||||
@click="handleClick(index)"
|
||||
v-for="(item, index) in list"
|
||||
:class="{ active: feedbackForm.type == item.value }"
|
||||
@click="selectFeedbackType(index)"
|
||||
v-for="(item, index) in feedbackTypeList"
|
||||
:key="index"
|
||||
>
|
||||
{{ item.text }}
|
||||
@@ -15,11 +15,11 @@
|
||||
|
||||
<view class="feedBack-box">
|
||||
<view class="box-title">问题反馈
|
||||
<text class="box-tag" v-if="feedBack.type">@{{ list.find(item => item.value == feedBack.type).text }}</text>
|
||||
<text class="box-tag" v-if="feedbackForm.type">@{{ feedbackTypeList.find(item => item.value == feedbackForm.type)?.text }}</text>
|
||||
</view>
|
||||
<u-textarea
|
||||
class="field-textarea"
|
||||
v-model="feedBack.context"
|
||||
v-model="feedbackForm.context"
|
||||
placeholder="请输入反馈信息"
|
||||
border="none"
|
||||
height="240"
|
||||
@@ -39,7 +39,7 @@
|
||||
<view class="box-title">手机号</view>
|
||||
<u-input
|
||||
class="field-input"
|
||||
v-model="feedBack.mobile"
|
||||
v-model="feedbackForm.mobile"
|
||||
type="number"
|
||||
maxlength="11"
|
||||
border="none"
|
||||
@@ -48,98 +48,69 @@
|
||||
></u-input>
|
||||
</view>
|
||||
|
||||
<view class="submit" @click="submit()">提交</view>
|
||||
<view class="submit" @click="submitFeedback">提交</view>
|
||||
</view>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import storage from "@/utils/storage.js";
|
||||
import config from "@/config/config";
|
||||
import { feedBack } from "@/api/members.js";
|
||||
import { handleUploadAfterRead } from "@/utils/uploadHelper.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
storage,
|
||||
config,
|
||||
feedBack: {
|
||||
type: "FUNCTION",
|
||||
context: "",
|
||||
mobile: "",
|
||||
},
|
||||
inputStyle: {
|
||||
background: "#fafafa",
|
||||
borderRadius: "12rpx",
|
||||
padding: "0 24rpx",
|
||||
height: "80rpx",
|
||||
},
|
||||
uploadFileList: [],
|
||||
list: [
|
||||
{ text: "功能相关", value: "FUNCTION" },
|
||||
{ text: "优化反馈", value: "OPTIMIZE" },
|
||||
{ text: "其他", value: "OTHER" },
|
||||
],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 点击反馈内容
|
||||
handleClick(index) {
|
||||
this.feedBack["type"] = this.list[index].value;
|
||||
},
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, getCurrentInstance } from 'vue'
|
||||
import { feedBack as submitFeedBackApi } from '@/api/members.js'
|
||||
import { handleUploadAfterRead } from '@/utils/uploadHelper.js'
|
||||
|
||||
onUploadAfterRead(event) {
|
||||
handleUploadAfterRead(event, this.uploadFileList, (urls) => {
|
||||
this.feedBack.images = urls.join(",");
|
||||
});
|
||||
},
|
||||
const { proxy } = getCurrentInstance()!
|
||||
|
||||
/**
|
||||
* 提交意见反馈
|
||||
*/
|
||||
submit() {
|
||||
if (!this.feedBack.type) {
|
||||
uni.showToast({
|
||||
title: "请填写反馈类型",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!this.feedBack.context) {
|
||||
uni.showToast({
|
||||
title: "请填写反馈信息",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (this.feedBack.mobile && !this.$u.test.mobile(this.feedBack.mobile)) {
|
||||
uni.showToast({
|
||||
title: "请填写您的正确手机号",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
return false;
|
||||
}
|
||||
/** 提交 */
|
||||
feedBack(this.feedBack).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({
|
||||
title: "提交成功!",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
setTimeout(() => {
|
||||
uni.navigateBack({
|
||||
delta: 1,
|
||||
});
|
||||
}, 500);
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
const feedbackForm = reactive({
|
||||
type: 'FUNCTION',
|
||||
context: '',
|
||||
mobile: '',
|
||||
images: '',
|
||||
})
|
||||
const inputStyle = {
|
||||
background: '#fafafa',
|
||||
borderRadius: '12rpx',
|
||||
padding: '0 24rpx',
|
||||
height: '80rpx',
|
||||
}
|
||||
const uploadFileList = ref<any[]>([])
|
||||
const feedbackTypeList = [
|
||||
{ text: '功能相关', value: 'FUNCTION' },
|
||||
{ text: '优化反馈', value: 'OPTIMIZE' },
|
||||
{ text: '其他', value: 'OTHER' },
|
||||
]
|
||||
|
||||
function selectFeedbackType(index: number) {
|
||||
feedbackForm.type = feedbackTypeList[index].value
|
||||
}
|
||||
|
||||
function onUploadAfterRead(event: any) {
|
||||
handleUploadAfterRead(event, uploadFileList.value, (urls) => {
|
||||
feedbackForm.images = urls.join(',')
|
||||
})
|
||||
}
|
||||
|
||||
function submitFeedback() {
|
||||
if (!feedbackForm.type) {
|
||||
uni.showToast({ title: '请填写反馈类型', duration: 2000, icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (!feedbackForm.context) {
|
||||
uni.showToast({ title: '请填写反馈信息', duration: 2000, icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (feedbackForm.mobile && !proxy.$u.test.mobile(feedbackForm.mobile)) {
|
||||
uni.showToast({ title: '请填写您的正确手机号', duration: 2000, icon: 'none' })
|
||||
return
|
||||
}
|
||||
submitFeedBackApi(feedbackForm).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({ title: '提交成功!', duration: 2000, icon: 'none' })
|
||||
setTimeout(() => {
|
||||
uni.navigateBack({ delta: 1 })
|
||||
}, 500)
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -5,48 +5,54 @@
|
||||
<view>点击修改头像</view>
|
||||
</view>
|
||||
|
||||
<u-form :model="form" ref="uForm" class="form">
|
||||
<u-form-item label="昵称" label-width="150" :border-bottom="true">
|
||||
<up-form
|
||||
:model="form"
|
||||
ref="uForm"
|
||||
class="form"
|
||||
label-position="left"
|
||||
label-width="180rpx"
|
||||
>
|
||||
<up-form-item label="昵称" label-width="180rpx" :border-bottom="true">
|
||||
<u-input
|
||||
v-model="form.nickName"
|
||||
border="none"
|
||||
input-align="right"
|
||||
placeholder="请输入昵称"
|
||||
/>
|
||||
</u-form-item>
|
||||
</up-form-item>
|
||||
|
||||
<u-form-item label="性别" label-width="150" :border-bottom="true">
|
||||
<up-form-item label="性别" label-width="180rpx" :border-bottom="true">
|
||||
<view class="sex-row">
|
||||
<u-radio-group v-model="form.sex" :active-color="lightColor" :gap="40">
|
||||
<u-radio name="1" label="男" shape="circle"></u-radio>
|
||||
<u-radio name="0" label="女" shape="circle"></u-radio>
|
||||
</u-radio-group>
|
||||
</view>
|
||||
</u-form-item>
|
||||
</up-form-item>
|
||||
|
||||
<u-form-item label="生日" label-width="150" :border-bottom="true">
|
||||
<up-form-item label="生日" label-width="180rpx" :border-bottom="true">
|
||||
<view class="form-value" @click="showBirthday = true">
|
||||
{{ birthday || '请选择出生日期' }}
|
||||
</view>
|
||||
<template #right>
|
||||
<u-icon name="arrow-right" color="#ccc" size="16"></u-icon>
|
||||
</template>
|
||||
</u-form-item>
|
||||
</up-form-item>
|
||||
|
||||
<u-form-item label="城市" label-width="150" :border-bottom="true">
|
||||
<up-form-item label="城市" label-width="180rpx" :border-bottom="true">
|
||||
<view class="form-value" @click="clickRegion">
|
||||
{{ form.___path || '请选择城市' }}
|
||||
{{ form.regionPath || '请选择城市' }}
|
||||
</view>
|
||||
<template #right>
|
||||
<u-icon name="arrow-right" color="#ccc" size="16"></u-icon>
|
||||
</template>
|
||||
</u-form-item>
|
||||
</up-form-item>
|
||||
|
||||
<u-form-item label="手机号" label-width="150" :border-bottom="false">
|
||||
<up-form-item label="手机号" label-width="180rpx" :border-bottom="false">
|
||||
<view v-if="form.mobile" class="form-value">{{ form.mobile }}</view>
|
||||
<view v-else class="bind-mobile" @click="navigateTo(form.username)">绑定手机号码</view>
|
||||
</u-form-item>
|
||||
</u-form>
|
||||
<view v-else class="bind-mobile" @click="navigateToBindMobile(form.username)">绑定手机号码</view>
|
||||
</up-form-item>
|
||||
</up-form>
|
||||
|
||||
<view class="bottom">
|
||||
<view class="submit" @click="submit">保存</view>
|
||||
@@ -74,152 +80,135 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { saveUserInfo } from "@/api/members.js";
|
||||
import { upload } from "@/api/common.js";
|
||||
import storage from "@/utils/storage.js";
|
||||
import city from "@/components/m-city/m-city.vue";
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed } from 'vue'
|
||||
import { onShow } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { quiteLoginOut } from '@/utils/filters.js'
|
||||
import { saveUserInfo } from '@/api/members.js'
|
||||
import { upload } from '@/api/common.js'
|
||||
import storage from '@/utils/storage.js'
|
||||
import MCity from '@/components/m-city/m-city.vue'
|
||||
|
||||
function parseBirthdayTimestamp(str) {
|
||||
if (!str) {
|
||||
return Date.now();
|
||||
}
|
||||
const timestamp = Date.parse(String(str).replace(/-/g, "/"));
|
||||
return Number.isFinite(timestamp) ? timestamp : Date.now();
|
||||
function parseBirthdayTimestamp(str?: string) {
|
||||
if (!str) return Date.now()
|
||||
const timestamp = Date.parse(String(str).replace(/-/g, '/'))
|
||||
return Number.isFinite(timestamp) ? timestamp : Date.now()
|
||||
}
|
||||
|
||||
function formatBirthday(timestamp) {
|
||||
const date = new Date(timestamp);
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, "0");
|
||||
const day = String(date.getDate()).padStart(2, "0");
|
||||
return `${year}-${month}-${day}`;
|
||||
function formatBirthday(timestamp: number) {
|
||||
const date = new Date(timestamp)
|
||||
const year = date.getFullYear()
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0')
|
||||
const day = String(date.getDate()).padStart(2, '0')
|
||||
return `${year}-${month}-${day}`
|
||||
}
|
||||
|
||||
export default {
|
||||
components: { "m-city": city },
|
||||
data() {
|
||||
const userInfo = storage.getUserInfo() || {};
|
||||
return {
|
||||
lightColor: this.$lightColor,
|
||||
form: {
|
||||
nickName: userInfo.nickName || "",
|
||||
birthday: userInfo.birthday || "",
|
||||
face: userInfo.face || "/static/missing-face.png",
|
||||
regionId: [],
|
||||
region: userInfo.region || [],
|
||||
sex: userInfo.sex != null ? String(userInfo.sex) : "1",
|
||||
___path: userInfo.region,
|
||||
mobile: userInfo.mobile,
|
||||
username: userInfo.username,
|
||||
},
|
||||
birthday: userInfo.birthday || "",
|
||||
birthdayValue: parseBirthdayTimestamp(userInfo.birthday),
|
||||
minBirthdayDate: new Date("1950-01-01").getTime(),
|
||||
maxBirthdayDate: Date.now(),
|
||||
region: [
|
||||
{
|
||||
id: "",
|
||||
localName: "请选择",
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
showBirthday: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
getPickerParentValue(e) {
|
||||
this.form.region = [];
|
||||
this.form.regionId = [];
|
||||
let name = "";
|
||||
const store = useStore()
|
||||
const lightColor = computed(() => store.getters.lightColor)
|
||||
|
||||
e.forEach((item, index) => {
|
||||
if (item.id) {
|
||||
this.form.region.push(item.localName);
|
||||
this.form.regionId.push(item.id);
|
||||
if (index == e.length - 1) {
|
||||
name += item.localName;
|
||||
} else {
|
||||
name += item.localName + ",";
|
||||
}
|
||||
this.form.___path = name;
|
||||
}
|
||||
});
|
||||
},
|
||||
const userInfo = storage.getUserInfo() || {}
|
||||
const form = reactive<Record<string, any>>({
|
||||
nickName: userInfo.nickName || '',
|
||||
birthday: userInfo.birthday || '',
|
||||
face: userInfo.face || '/static/missing-face.png',
|
||||
regionId: [],
|
||||
region: userInfo.region || [],
|
||||
sex: userInfo.sex != null ? String(userInfo.sex) : '1',
|
||||
regionPath: userInfo.region,
|
||||
mobile: userInfo.mobile,
|
||||
username: userInfo.username,
|
||||
})
|
||||
const birthday = ref(userInfo.birthday || '')
|
||||
const birthdayValue = ref(parseBirthdayTimestamp(userInfo.birthday))
|
||||
const minBirthdayDate = new Date('1950-01-01').getTime()
|
||||
const maxBirthdayDate = Date.now()
|
||||
const region = ref([{ id: '', localName: '请选择', children: [] }])
|
||||
const showBirthday = ref(false)
|
||||
const cityPicker = ref<any>(null)
|
||||
|
||||
clickRegion() {
|
||||
this.$refs.cityPicker.show();
|
||||
},
|
||||
function getPickerParentValue(selected: any[]) {
|
||||
form.region = []
|
||||
form.regionId = []
|
||||
let name = ''
|
||||
selected.forEach((item, index) => {
|
||||
if (item.id) {
|
||||
form.region.push(item.localName)
|
||||
form.regionId.push(item.id)
|
||||
name += index === selected.length - 1 ? item.localName : `${item.localName},`
|
||||
form.regionPath = name
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
submit() {
|
||||
delete this.form.___path;
|
||||
const params = JSON.parse(JSON.stringify(this.form));
|
||||
saveUserInfo(params).then((res) => {
|
||||
if (res.statusCode == 200) {
|
||||
storage.setUserInfo(res.data.result);
|
||||
uni.navigateBack();
|
||||
}
|
||||
});
|
||||
},
|
||||
function clickRegion() {
|
||||
cityPicker.value?.show()
|
||||
}
|
||||
|
||||
changeFace() {
|
||||
uni.chooseImage({
|
||||
success: (chooseImageRes) => {
|
||||
const tempFilePaths = chooseImageRes.tempFilePaths;
|
||||
uni.uploadFile({
|
||||
url: upload,
|
||||
filePath: tempFilePaths[0],
|
||||
name: "file",
|
||||
header: {
|
||||
accessToken: storage.getAccessToken(),
|
||||
},
|
||||
success: (uploadFileRes) => {
|
||||
const data = JSON.parse(uploadFileRes.data);
|
||||
this.form.face = data.result;
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
function submit() {
|
||||
const params = JSON.parse(JSON.stringify(form))
|
||||
delete params.regionPath
|
||||
saveUserInfo(params).then((res) => {
|
||||
if (res.statusCode === 200) {
|
||||
storage.setUserInfo(res.data.result)
|
||||
uni.navigateBack()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
selectTime(e) {
|
||||
const timestamp = typeof e?.value === "number" ? e.value : this.birthdayValue;
|
||||
const formatted = formatBirthday(timestamp);
|
||||
this.birthdayValue = timestamp;
|
||||
this.form.birthday = formatted;
|
||||
this.birthday = formatted;
|
||||
this.showBirthday = false;
|
||||
},
|
||||
function changeFace() {
|
||||
uni.chooseImage({
|
||||
success: (chooseImageRes) => {
|
||||
uni.uploadFile({
|
||||
url: upload,
|
||||
filePath: chooseImageRes.tempFilePaths[0],
|
||||
name: 'file',
|
||||
header: { accessToken: storage.getAccessToken() },
|
||||
success: (uploadFileRes) => {
|
||||
const data = JSON.parse(uploadFileRes.data)
|
||||
form.face = data.result
|
||||
},
|
||||
})
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
closeBirthdayPicker() {
|
||||
this.showBirthday = false;
|
||||
},
|
||||
function selectTime(e: any) {
|
||||
const timestamp = typeof e?.value === 'number' ? e.value : birthdayValue.value
|
||||
const formatted = formatBirthday(timestamp)
|
||||
birthdayValue.value = timestamp
|
||||
form.birthday = formatted
|
||||
birthday.value = formatted
|
||||
showBirthday.value = false
|
||||
}
|
||||
|
||||
navigateTo(username) {
|
||||
uni.navigateTo({
|
||||
url: "/pages/mine/set/securityCenter/bindMobile?username=" + username,
|
||||
});
|
||||
},
|
||||
function closeBirthdayPicker() {
|
||||
showBirthday.value = false
|
||||
}
|
||||
|
||||
syncUserInfo() {
|
||||
const userInfo = storage.getUserInfo() || {};
|
||||
this.form.nickName = userInfo.nickName || "";
|
||||
this.form.birthday = userInfo.birthday || "";
|
||||
this.form.face = userInfo.face || "/static/missing-face.png";
|
||||
this.form.region = userInfo.region || [];
|
||||
this.form.sex = userInfo.sex != null ? String(userInfo.sex) : "1";
|
||||
this.form.___path = userInfo.region;
|
||||
this.form.mobile = userInfo.mobile;
|
||||
this.form.username = userInfo.username;
|
||||
this.birthday = userInfo.birthday || "";
|
||||
this.birthdayValue = parseBirthdayTimestamp(userInfo.birthday);
|
||||
},
|
||||
},
|
||||
function navigateToBindMobile(username: string) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/mine/set/securityCenter/bindMobile?username=${username}`,
|
||||
})
|
||||
}
|
||||
|
||||
onShow() {
|
||||
this.syncUserInfo();
|
||||
},
|
||||
};
|
||||
function syncUserInfo() {
|
||||
const latest = storage.getUserInfo() || {}
|
||||
form.nickName = latest.nickName || ''
|
||||
form.birthday = latest.birthday || ''
|
||||
form.face = latest.face || '/static/missing-face.png'
|
||||
form.region = latest.region || []
|
||||
form.sex = latest.sex != null ? String(latest.sex) : '1'
|
||||
form.regionPath = latest.region
|
||||
form.mobile = latest.mobile
|
||||
form.username = latest.username
|
||||
birthday.value = latest.birthday || ''
|
||||
birthdayValue.value = parseBirthdayTimestamp(latest.birthday)
|
||||
}
|
||||
|
||||
onShow(() => {
|
||||
syncUserInfo()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -1,227 +1,211 @@
|
||||
<template>
|
||||
<view class="box">
|
||||
<view class="box-tips">
|
||||
<h2 class='h2'>
|
||||
绑定手机号码
|
||||
</h2>
|
||||
<h2 class="h2">绑定手机号码</h2>
|
||||
<view class="verification"></view>
|
||||
</view>
|
||||
<view class="form">
|
||||
<u-form :model="codeForm" ref="validateCodeForm">
|
||||
<view v-if="!validateFlage">
|
||||
<u-form-item label-width="120" label="手机号" prop="mobile">
|
||||
<up-form
|
||||
:model="codeForm"
|
||||
ref="validateCodeForm"
|
||||
label-position="left"
|
||||
label-width="180rpx"
|
||||
>
|
||||
<view v-if="!phoneVerified">
|
||||
<up-form-item label-width="180rpx" label="手机号" prop="mobile">
|
||||
<u-input maxlength="11" v-model="codeForm.mobile" placeholder="请输入您的手机号" />
|
||||
</u-form-item>
|
||||
|
||||
<u-form-item class="sendCode" label-width="120" prop="code" label="验证码">
|
||||
<u-input v-model="codeForm.code" placeholder="请输入验证码" />
|
||||
<u-code unique-key="page-edit" :seconds="seconds" @end="end" @start="start"
|
||||
ref="uCode" @change="codeChange"></u-code>
|
||||
<view @tap="getCode" class="text-tips">{{ tips }}</view>
|
||||
</u-form-item>
|
||||
</up-form-item>
|
||||
|
||||
<view class="submit" @click="validatePhone">绑定</view>
|
||||
<myVerification keep-running @send="verification" class="verification" ref="verification"
|
||||
business="BIND_MOBILE" />
|
||||
<up-form-item class="sendCode" label-width="180rpx" prop="code" label="验证码">
|
||||
<u-input v-model="codeForm.code" placeholder="请输入验证码" />
|
||||
<u-code
|
||||
unique-key="page-edit"
|
||||
:seconds="seconds"
|
||||
@end="onCodeCountdownEnd"
|
||||
@start="onCodeCountdownStart"
|
||||
ref="uCodeRef"
|
||||
@change="onCodeTextChange"
|
||||
></u-code>
|
||||
<view @tap="requestSmsCode" class="text-tips">{{ codeTips }}</view>
|
||||
</up-form-item>
|
||||
|
||||
<view class="submit" @click="submitBindMobile">绑定</view>
|
||||
<myVerification
|
||||
keep-running
|
||||
@send="onVerificationPassed"
|
||||
class="verification"
|
||||
ref="verificationRef"
|
||||
business="BIND_MOBILE"
|
||||
/>
|
||||
</view>
|
||||
</u-form>
|
||||
</up-form>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
sendMobile,
|
||||
bindMobile
|
||||
} from "@/api/login";
|
||||
import { getUserInfo } from "@/api/members.js";
|
||||
import storage from "@/utils/storage.js";
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, watch, getCurrentInstance } from 'vue'
|
||||
import { onLoad, onReady } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { sendMobile, bindMobile } from '@/api/login'
|
||||
import { getUserInfo } from '@/api/members.js'
|
||||
import storage from '@/utils/storage.js'
|
||||
import MyVerification from '@/components/verification/verification.vue'
|
||||
|
||||
import myVerification from "@/components/verification/verification.vue"; //验证
|
||||
import uuid from "@/utils/uuid.modified.js";
|
||||
export default {
|
||||
components: {
|
||||
myVerification,
|
||||
const store = useStore()
|
||||
const { proxy } = getCurrentInstance()!
|
||||
|
||||
const phoneVerified = ref(false)
|
||||
const verificationPassed = ref(false)
|
||||
const codeForm = reactive({
|
||||
mobile: '',
|
||||
code: '',
|
||||
username: '',
|
||||
})
|
||||
const codeTips = ref('')
|
||||
const seconds = 69
|
||||
|
||||
const validateCodeForm = ref<any>(null)
|
||||
const uCodeRef = ref<any>(null)
|
||||
const verificationRef = ref<any>(null)
|
||||
|
||||
const codeRules = {
|
||||
mobile: [
|
||||
{
|
||||
validator: (_rule: any, value: string) => proxy.$u.test.mobile(value),
|
||||
message: '手机号码不正确',
|
||||
trigger: ['blur'],
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
uuid,
|
||||
validateFlage: false, //是否进行了手机号验证
|
||||
step: 0, //当前验证步骤
|
||||
flage: false, //是否验证码验证
|
||||
codeForm: {
|
||||
mobile: "", //手机号
|
||||
code: "", //验证码
|
||||
username: "", //用户名
|
||||
},
|
||||
tips: "", //提示
|
||||
seconds: 69, // 60s等待时间
|
||||
|
||||
// 验证码登录校验
|
||||
codeRules: {
|
||||
mobile: [{
|
||||
validator: (rule, value, callback) => {
|
||||
return this.$u.test.mobile(value);
|
||||
},
|
||||
message: "手机号码不正确",
|
||||
trigger: ["blur"],
|
||||
}, ],
|
||||
code: [{
|
||||
min: 4,
|
||||
max: 6,
|
||||
required: true,
|
||||
message: "请输入验证码",
|
||||
trigger: ["blur"],
|
||||
}, ],
|
||||
},
|
||||
};
|
||||
},
|
||||
onLoad(options) {
|
||||
this.codeForm.username = options.username;
|
||||
},
|
||||
onReady() {
|
||||
// 必须要在onReady生命周期,因为onLoad生命周期组件可能尚未创建完毕
|
||||
this.$refs.validateCodeForm.setRules(this.codeRules);
|
||||
},
|
||||
watch: {
|
||||
flage(val) {
|
||||
if (val) {
|
||||
if (this.$refs.uCode.canGetCode) {
|
||||
uni.showLoading({
|
||||
title: "正在获取验证码",
|
||||
});
|
||||
sendMobile(this.codeForm.mobile, "BIND_MOBILE").then((res) => {
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
// 这里此提示会被this.start()方法中的提示覆盖
|
||||
if (res.data.success) {
|
||||
this.$refs.uCode.start();
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.data.message,
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
this.flage = false;
|
||||
this.$refs.verification.getCode();
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.$u.toast("请倒计时结束后再发送");
|
||||
}
|
||||
}
|
||||
},
|
||||
],
|
||||
code: [
|
||||
{
|
||||
min: 4,
|
||||
max: 6,
|
||||
required: true,
|
||||
message: '请输入验证码',
|
||||
trigger: ['blur'],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
methods: {
|
||||
// 验证码验证
|
||||
verification(val) {
|
||||
this.flage = val == this.$store.state.verificationKey ? true : false;
|
||||
},
|
||||
onLoad((options) => {
|
||||
codeForm.username = options?.username || ''
|
||||
})
|
||||
|
||||
// 验证手机号
|
||||
validatePhone() {
|
||||
this.$refs.validateCodeForm.validate((valid) => {
|
||||
if (valid) {
|
||||
bindMobile(this.codeForm).then((res) => {
|
||||
if (res.data.success) {
|
||||
this.validateFlage = !this.validateFlage;
|
||||
// 获取最新的用户信息并更新缓存
|
||||
getUserInfo().then(userRes => {
|
||||
if (userRes.data.success) {
|
||||
storage.setUserInfo(userRes.data.result);
|
||||
}
|
||||
// 显示成功提示
|
||||
uni.showToast({
|
||||
title: "绑定成功!",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
// 返回上一页
|
||||
setTimeout(() => {
|
||||
uni.navigateBack({
|
||||
delta: 1,
|
||||
});
|
||||
}, 1000);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
onReady(() => {
|
||||
validateCodeForm.value?.setRules(codeRules)
|
||||
})
|
||||
|
||||
codeChange(text) {
|
||||
this.tips = text;
|
||||
},
|
||||
end() {
|
||||
|
||||
this.flage = false;
|
||||
this.$refs.verification.getCode()
|
||||
},
|
||||
|
||||
/**获取验证码 */
|
||||
getCode() {
|
||||
if (this.tips == "重新获取") {
|
||||
this.$refs.verification.error(); //发送
|
||||
}
|
||||
if (!this.$u.test.mobile(this.codeForm.mobile)) {
|
||||
uni.showToast({
|
||||
title: "请输入正确手机号",
|
||||
icon: "none",
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!this.flage) {
|
||||
this.$refs.verification.error(); //发送
|
||||
return false;
|
||||
}
|
||||
},
|
||||
start() {
|
||||
this.$u.toast("验证码已发送");
|
||||
this.flage = true;
|
||||
|
||||
this.$refs.verification.hide();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import url("@/pages/passport/login.scss");
|
||||
|
||||
::v-deep .u-form-item {
|
||||
margin: 40rpx 0;
|
||||
watch(verificationPassed, (val) => {
|
||||
if (!val) return
|
||||
if (!uCodeRef.value?.canGetCode) {
|
||||
proxy.$u.toast('请倒计时结束后再发送')
|
||||
return
|
||||
}
|
||||
|
||||
.sendCode {
|
||||
::v-deep .u-form-item--right__content__slot {
|
||||
display: flex;
|
||||
uni.showLoading({ title: '正在获取验证码' })
|
||||
sendMobile(codeForm.mobile, 'BIND_MOBILE').then((res) => {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
if (res.data.success) {
|
||||
uCodeRef.value?.start()
|
||||
} else {
|
||||
uni.showToast({ title: res.data.message, duration: 2000, icon: 'none' })
|
||||
verificationPassed.value = false
|
||||
verificationRef.value?.getCode()
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
.h2 {
|
||||
font-size: 40rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
function onVerificationPassed(val: string) {
|
||||
verificationPassed.value = val === store.state.verificationKey
|
||||
}
|
||||
|
||||
page {
|
||||
background: #fff;
|
||||
}
|
||||
function submitBindMobile() {
|
||||
validateCodeForm.value?.validate((valid: boolean) => {
|
||||
if (!valid) return
|
||||
bindMobile(codeForm).then((res) => {
|
||||
if (res.data.success) {
|
||||
phoneVerified.value = true
|
||||
getUserInfo().then((userRes) => {
|
||||
if (userRes.data.success) {
|
||||
storage.setUserInfo(userRes.data.result)
|
||||
}
|
||||
uni.showToast({ title: '绑定成功!', duration: 2000, icon: 'none' })
|
||||
setTimeout(() => {
|
||||
uni.navigateBack({ delta: 1 })
|
||||
}, 1000)
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
.box {
|
||||
padding: 80rpx 0;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
function onCodeTextChange(text: string) {
|
||||
codeTips.value = text
|
||||
}
|
||||
|
||||
.submit {
|
||||
background: $light-color;
|
||||
}
|
||||
function onCodeCountdownEnd() {
|
||||
verificationPassed.value = false
|
||||
verificationRef.value?.getCode()
|
||||
}
|
||||
|
||||
.box-tips {
|
||||
margin: 0 72rpx;
|
||||
function requestSmsCode() {
|
||||
if (codeTips.value === '重新获取') {
|
||||
verificationRef.value?.error()
|
||||
}
|
||||
if (!proxy.$u.test.mobile(codeForm.mobile)) {
|
||||
uni.showToast({ title: '请输入正确手机号', icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (!verificationPassed.value) {
|
||||
verificationRef.value?.error()
|
||||
}
|
||||
}
|
||||
|
||||
.verification {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
margin-top: 10rpx;
|
||||
function onCodeCountdownStart() {
|
||||
proxy.$u.toast('验证码已发送')
|
||||
verificationPassed.value = true
|
||||
verificationRef.value?.hide()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import url("@/pages/passport/login.scss");
|
||||
|
||||
::v-deep .u-form-item {
|
||||
margin: 40rpx 0;
|
||||
}
|
||||
|
||||
.sendCode {
|
||||
::v-deep .u-form-item__body__right__content__slot {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
.h2 {
|
||||
font-size: 40rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
page {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.box {
|
||||
padding: 80rpx 0;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
|
||||
.submit {
|
||||
background: $light-color;
|
||||
}
|
||||
|
||||
.box-tips {
|
||||
margin: 0 72rpx;
|
||||
}
|
||||
|
||||
.verification {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,160 +1,99 @@
|
||||
<template>
|
||||
<view class="box">
|
||||
<view class="box-tips">
|
||||
<h2 class='h2'>
|
||||
{{verificationTitle.title}}
|
||||
</h2>
|
||||
<view class="verification">{{verificationTitle.desc}}</view>
|
||||
<h2 class="h2">{{ verificationTitle.title }}</h2>
|
||||
<view class="verification">{{ verificationTitle.desc }}</view>
|
||||
</view>
|
||||
<view class="form">
|
||||
<u-form :model="codeForm" ref="validateCodeForm">
|
||||
<u-form-item label-width="120" label="旧密码">
|
||||
<u-input type="password" v-model="oldPassword" placeholder="请输入您的旧密码" />
|
||||
</u-form-item>
|
||||
<up-form
|
||||
:model="codeForm"
|
||||
ref="validateCodeForm"
|
||||
label-position="left"
|
||||
label-width="180rpx"
|
||||
>
|
||||
<up-form-item label-width="180rpx" label="旧密码">
|
||||
<u-input type="password" v-model="oldPassword" placeholder="请输入您的旧密码" />
|
||||
</up-form-item>
|
||||
|
||||
<u-form-item label-width="120" label="密码">
|
||||
<u-input type="password" v-model="password" placeholder="请输入您的密码" />
|
||||
</u-form-item>
|
||||
<up-form-item label-width="180rpx" label="密码">
|
||||
<u-input type="password" v-model="password" placeholder="请输入您的密码" />
|
||||
</up-form-item>
|
||||
|
||||
<u-form-item label-width="120" label="确认密码">
|
||||
<u-input type="password" v-model="newPassword" placeholder="请再次输入您的密码" />
|
||||
</u-form-item>
|
||||
<up-form-item label-width="180rpx" label="确认密码">
|
||||
<u-input type="password" v-model="confirmPassword" placeholder="请再次输入您的密码" />
|
||||
</up-form-item>
|
||||
|
||||
<view class="submit" @click="updatePassword">修改密码</view>
|
||||
</u-form>
|
||||
<view class="submit" @click="updatePassword">修改密码</view>
|
||||
</up-form>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
resetByMobile,
|
||||
modifyPass
|
||||
} from "@/api/login";
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import { modifyPass } from '@/api/login'
|
||||
import { md5 } from '@/utils/md5.js'
|
||||
|
||||
import {
|
||||
md5
|
||||
} from "@/utils/md5.js"; // md5
|
||||
import myVerification from "@/components/verification/verification.vue"; //验证
|
||||
import uuid from "@/utils/uuid.modified.js";
|
||||
export default {
|
||||
components: {
|
||||
myVerification,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
uuid,
|
||||
validateFlage: false, //是否进行了手机号验证
|
||||
verificationTitle: {
|
||||
title: "修改密码",
|
||||
desc: "请验证并输入密码",
|
||||
},
|
||||
step: 0, //当前验证步骤
|
||||
flage: false, //是否验证码验证
|
||||
const verificationTitle = {
|
||||
title: '修改密码',
|
||||
desc: '请验证并输入密码',
|
||||
}
|
||||
const codeForm = reactive({ mobile: '', code: '' })
|
||||
const oldPassword = ref('')
|
||||
const password = ref('')
|
||||
const confirmPassword = ref('')
|
||||
|
||||
codeForm: {
|
||||
mobile: "", //手机号
|
||||
code: "", //验证码
|
||||
},
|
||||
newPassword: "", //新密码
|
||||
password: "", //密码
|
||||
oldPassword: '', //旧密码
|
||||
tips: "", //提示
|
||||
seconds: 69, // 60s等待时间
|
||||
|
||||
// 验证码登录校验
|
||||
codeRules: {
|
||||
mobile: [{
|
||||
validator: (rule, value, callback) => {
|
||||
return this.$u.test.mobile(value);
|
||||
},
|
||||
message: "手机号码不正确",
|
||||
trigger: ["blur"],
|
||||
}, ],
|
||||
code: [{
|
||||
min: 4,
|
||||
max: 6,
|
||||
required: true,
|
||||
message: "请输入验证码",
|
||||
trigger: ["blur"],
|
||||
}, ],
|
||||
},
|
||||
};
|
||||
},
|
||||
onReady() {
|
||||
// 必须要在onReady生命周期,因为onLoad生命周期组件可能尚未创建完毕
|
||||
this.$refs.validateCodeForm.setRules(this.codeRules);
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 修改密码
|
||||
updatePassword() {
|
||||
if(this.password !== this.newPassword){
|
||||
uni.showToast({
|
||||
title: "两次输入密码不一致!",
|
||||
icon: "none",
|
||||
});
|
||||
return;
|
||||
}
|
||||
modifyPass({
|
||||
password: md5(this.oldPassword),
|
||||
newPassword: md5(this.newPassword),
|
||||
}).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({
|
||||
title: "修改成功!",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
setTimeout(() => {
|
||||
uni.navigateBack({
|
||||
delta: 1,
|
||||
});
|
||||
}, 1000);
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import url("@/pages/passport/login.scss");
|
||||
|
||||
::v-deep .u-form-item {
|
||||
margin: 40rpx 0;
|
||||
function updatePassword() {
|
||||
if (password.value !== confirmPassword.value) {
|
||||
uni.showToast({ title: '两次输入密码不一致!', icon: 'none' })
|
||||
return
|
||||
}
|
||||
|
||||
.sendCode {
|
||||
::v-deep .u-form-item--right__content__slot {
|
||||
display: flex;
|
||||
modifyPass({
|
||||
password: md5(oldPassword.value),
|
||||
newPassword: md5(password.value),
|
||||
}).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({ title: '修改成功!', duration: 2000, icon: 'none' })
|
||||
setTimeout(() => {
|
||||
uni.navigateBack({ delta: 1 })
|
||||
}, 1000)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
.h2 {
|
||||
font-size: 40rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
<style lang="scss" scoped>
|
||||
@import url("@/pages/passport/login.scss");
|
||||
|
||||
page {
|
||||
background: #fff;
|
||||
}
|
||||
::v-deep .u-form-item {
|
||||
margin: 40rpx 0;
|
||||
}
|
||||
|
||||
.box {
|
||||
padding: 80rpx 0;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
.h2 {
|
||||
font-size: 40rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.submit {
|
||||
background: $light-color;
|
||||
}
|
||||
page {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.box-tips {
|
||||
margin: 0 72rpx;
|
||||
}
|
||||
.box {
|
||||
padding: 80rpx 0;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
|
||||
.verification {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
.submit {
|
||||
background: $light-color;
|
||||
}
|
||||
|
||||
.box-tips {
|
||||
margin: 0 72rpx;
|
||||
}
|
||||
|
||||
.verification {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,281 +1,238 @@
|
||||
<template>
|
||||
<view class="box">
|
||||
<view class="box-tips">
|
||||
<h2 class='h2'>
|
||||
{{verificationTitle[validateFlage==false ? 0 : 1].title}}
|
||||
</h2>
|
||||
<view class="verification">{{verificationTitle[step].desc}}</view>
|
||||
<h2 class="h2">{{ verificationTitle[phoneVerified ? 1 : 0].title }}</h2>
|
||||
<view class="verification">{{ verificationTitle[step].desc }}</view>
|
||||
</view>
|
||||
<view class="form">
|
||||
<u-form :model="codeForm" ref="validateCodeForm">
|
||||
<view v-if="!validateFlage">
|
||||
<u-form-item label-width="120" label="手机号" prop="mobile">
|
||||
<up-form
|
||||
:model="codeForm"
|
||||
ref="validateCodeForm"
|
||||
label-position="left"
|
||||
label-width="180rpx"
|
||||
>
|
||||
<view v-if="!phoneVerified">
|
||||
<up-form-item label-width="180rpx" label="手机号" prop="mobile">
|
||||
<u-input maxlength="11" v-model="codeForm.mobile" placeholder="请输入您的手机号" />
|
||||
</u-form-item>
|
||||
</up-form-item>
|
||||
|
||||
<u-form-item class="sendCode" label-width="120" prop="code" label="验证码">
|
||||
<up-form-item class="sendCode" label-width="180rpx" prop="code" label="验证码">
|
||||
<u-input v-model="codeForm.code" placeholder="请输入验证码" />
|
||||
<u-code unique-key="page-edit" :seconds="seconds" @end="end" @start="start"
|
||||
ref="uCode" @change="codeChange"></u-code>
|
||||
<view @tap="getCode" class="text-tips">{{ tips }}</view>
|
||||
</u-form-item>
|
||||
<u-code
|
||||
unique-key="page-edit"
|
||||
:seconds="seconds"
|
||||
@end="onCodeCountdownEnd"
|
||||
@start="onCodeCountdownStart"
|
||||
ref="uCodeRef"
|
||||
@change="onCodeTextChange"
|
||||
></u-code>
|
||||
<view @tap="requestSmsCode" class="text-tips">{{ codeTips }}</view>
|
||||
</up-form-item>
|
||||
|
||||
<view class="submit" @click="validatePhone">验证</view>
|
||||
<myVerification keep-running @send="verification" class="verification" ref="verification"
|
||||
business="FIND_USER" />
|
||||
<view class="submit" @click="verifyMobile">验证</view>
|
||||
<myVerification
|
||||
keep-running
|
||||
@send="onVerificationPassed"
|
||||
class="verification"
|
||||
ref="verificationRef"
|
||||
business="FIND_USER"
|
||||
/>
|
||||
</view>
|
||||
<view v-if="validateFlage">
|
||||
<u-form-item label-width="120" label="密码">
|
||||
<view v-if="phoneVerified">
|
||||
<up-form-item label-width="180rpx" label="密码">
|
||||
<u-input type="password" v-model="password" placeholder="请输入您的密码" />
|
||||
</u-form-item>
|
||||
</up-form-item>
|
||||
|
||||
<u-form-item label-width="120" label="确认密码">
|
||||
<u-input type="password" v-model="newPassword" placeholder="请再次输入您的密码" />
|
||||
</u-form-item>
|
||||
<up-form-item label-width="180rpx" label="确认密码">
|
||||
<u-input type="password" v-model="confirmPassword" placeholder="请再次输入您的密码" />
|
||||
</up-form-item>
|
||||
|
||||
<view class="submit" @click="updatePassword">修改密码</view>
|
||||
</view>
|
||||
</u-form>
|
||||
</up-form>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
sendMobile,
|
||||
resetByMobile,
|
||||
resetPassword
|
||||
} from "@/api/login";
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, watch, getCurrentInstance } from 'vue'
|
||||
import { onReady } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { isLogin } from '@/utils/filters.js'
|
||||
import { sendMobile, resetByMobile, resetPassword } from '@/api/login'
|
||||
import { md5 } from '@/utils/md5.js'
|
||||
import MyVerification from '@/components/verification/verification.vue'
|
||||
|
||||
import {
|
||||
md5
|
||||
} from "@/utils/md5.js"; // md5
|
||||
import myVerification from "@/components/verification/verification.vue"; //验证
|
||||
import uuid from "@/utils/uuid.modified.js";
|
||||
export default {
|
||||
components: {
|
||||
myVerification,
|
||||
const store = useStore()
|
||||
const { proxy } = getCurrentInstance()!
|
||||
|
||||
const phoneVerified = ref(false)
|
||||
const verificationPassed = ref(false)
|
||||
const verificationTitle = [
|
||||
{ title: '安全验证', desc: '请输入当前手机号进行安全验证' },
|
||||
{ title: '修改密码', desc: '请输入新密码' },
|
||||
]
|
||||
const step = ref(0)
|
||||
const codeForm = reactive({ mobile: '', code: '' })
|
||||
const password = ref('')
|
||||
const confirmPassword = ref('')
|
||||
const codeTips = ref('')
|
||||
const seconds = 69
|
||||
|
||||
const validateCodeForm = ref<any>(null)
|
||||
const uCodeRef = ref<any>(null)
|
||||
const verificationRef = ref<any>(null)
|
||||
|
||||
const codeRules = {
|
||||
mobile: [
|
||||
{
|
||||
validator: (_rule: any, value: string) => proxy.$u.test.mobile(value),
|
||||
message: '手机号码不正确',
|
||||
trigger: ['blur'],
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
uuid,
|
||||
validateFlage: false, //是否进行了手机号验证
|
||||
verificationTitle: [{
|
||||
title: "安全验证",
|
||||
desc: "请输入当前手机号进行安全验证",
|
||||
},
|
||||
{
|
||||
title: "修改密码",
|
||||
desc: "请输入新密码",
|
||||
},
|
||||
],
|
||||
step: 0, //当前验证步骤
|
||||
flage: false, //是否验证码验证
|
||||
|
||||
codeForm: {
|
||||
mobile: "", //手机号
|
||||
code: "", //验证码
|
||||
},
|
||||
newPassword: "", //新密码
|
||||
password: "", //密码
|
||||
tips: "", //提示
|
||||
seconds: 69, // 60s等待时间
|
||||
|
||||
// 验证码登录校验
|
||||
codeRules: {
|
||||
mobile: [{
|
||||
validator: (rule, value, callback) => {
|
||||
return this.$u.test.mobile(value);
|
||||
},
|
||||
message: "手机号码不正确",
|
||||
trigger: ["blur"],
|
||||
}, ],
|
||||
code: [{
|
||||
min: 4,
|
||||
max: 6,
|
||||
required: true,
|
||||
message: "请输入验证码",
|
||||
trigger: ["blur"],
|
||||
}, ],
|
||||
},
|
||||
};
|
||||
],
|
||||
code: [
|
||||
{
|
||||
min: 4,
|
||||
max: 6,
|
||||
required: true,
|
||||
message: '请输入验证码',
|
||||
trigger: ['blur'],
|
||||
},
|
||||
onReady() {
|
||||
// 必须要在onReady生命周期,因为onLoad生命周期组件可能尚未创建完毕
|
||||
this.$refs.validateCodeForm.setRules(this.codeRules);
|
||||
},
|
||||
watch: {
|
||||
flage(val) {
|
||||
if (val) {
|
||||
],
|
||||
}
|
||||
|
||||
if (this.$refs.uCode.canGetCode) {
|
||||
uni.showLoading({
|
||||
title: "正在获取验证码",
|
||||
});
|
||||
sendMobile(this.codeForm.mobile, "FIND_USER").then((res) => {
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
// 这里此提示会被this.start()方法中的提示覆盖
|
||||
if (res.data.success) {
|
||||
this.$refs.uCode.start();
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.data.message,
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
this.flage = false;
|
||||
this.$refs.verification.getCode();
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.$u.toast("请倒计时结束后再发送");
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
onReady(() => {
|
||||
validateCodeForm.value?.setRules(codeRules)
|
||||
})
|
||||
|
||||
methods: {
|
||||
// 修改密码
|
||||
updatePassword() {
|
||||
if(this.password !== this.newPassword){
|
||||
uni.showToast({
|
||||
title: "两次输入密码不一致!",
|
||||
icon: "none",
|
||||
});
|
||||
return;
|
||||
}
|
||||
resetPassword({
|
||||
password: md5(this.password),
|
||||
}).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({
|
||||
title: "修改成功!",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
setTimeout(() => {
|
||||
uni.navigateBack({
|
||||
delta: 1,
|
||||
});
|
||||
}, 1000);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 验证码验证
|
||||
verification(val) {
|
||||
this.flage = val == this.$store.state.verificationKey ? true : false;
|
||||
},
|
||||
|
||||
// 验证手机号
|
||||
validatePhone() {
|
||||
this.$refs.validateCodeForm.validate((valid) => {
|
||||
if (valid) {
|
||||
resetByMobile(this.codeForm).then((res) => {
|
||||
if (res.data.success) {
|
||||
this.validateFlage = !this.validateFlage;
|
||||
// 登录成功
|
||||
uni.showToast({
|
||||
title: "验证成功!",
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
codeChange(text) {
|
||||
this.tips = text;
|
||||
},
|
||||
end() {
|
||||
|
||||
this.flage = false;
|
||||
this.$refs.verification.getCode()
|
||||
},
|
||||
|
||||
/**判断是否是当前用户的手机号 */
|
||||
isUserPhone() {
|
||||
let flage = false;
|
||||
let user = this.isLogin();
|
||||
if (user.mobile != this.codeForm.mobile) {
|
||||
uni.showToast({
|
||||
title: "请输入当前绑定手机号",
|
||||
icon: "none",
|
||||
});
|
||||
flage = false;
|
||||
} else {
|
||||
flage = true;
|
||||
}
|
||||
|
||||
return flage;
|
||||
},
|
||||
/**获取验证码 */
|
||||
getCode() {
|
||||
if (this.isUserPhone()) {
|
||||
if (this.tips == "重新获取") {
|
||||
this.$refs.verification.error(); //发送
|
||||
}
|
||||
if (!this.$u.test.mobile(this.codeForm.mobile)) {
|
||||
uni.showToast({
|
||||
title: "请输入正确手机号",
|
||||
icon: "none",
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!this.flage) {
|
||||
this.$refs.verification.error(); //发送
|
||||
return false;
|
||||
}
|
||||
}
|
||||
},
|
||||
start() {
|
||||
this.$u.toast("验证码已发送");
|
||||
this.flage = true;
|
||||
|
||||
this.$refs.verification.hide();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import url("@/pages/passport/login.scss");
|
||||
|
||||
::v-deep .u-form-item {
|
||||
margin: 40rpx 0;
|
||||
watch(verificationPassed, (val) => {
|
||||
if (!val) return
|
||||
if (!uCodeRef.value?.canGetCode) {
|
||||
proxy.$u.toast('请倒计时结束后再发送')
|
||||
return
|
||||
}
|
||||
|
||||
.sendCode {
|
||||
::v-deep .u-form-item--right__content__slot {
|
||||
display: flex;
|
||||
uni.showLoading({ title: '正在获取验证码' })
|
||||
sendMobile(codeForm.mobile, 'FIND_USER').then((res) => {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
if (res.data.success) {
|
||||
uCodeRef.value?.start()
|
||||
} else {
|
||||
uni.showToast({ title: res.data.message, duration: 2000, icon: 'none' })
|
||||
verificationPassed.value = false
|
||||
verificationRef.value?.getCode()
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
.h2 {
|
||||
font-size: 40rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
function onVerificationPassed(val: string) {
|
||||
verificationPassed.value = val === store.state.verificationKey
|
||||
}
|
||||
|
||||
page {
|
||||
background: #fff;
|
||||
function updatePassword() {
|
||||
if (password.value !== confirmPassword.value) {
|
||||
uni.showToast({ title: '两次输入密码不一致!', icon: 'none' })
|
||||
return
|
||||
}
|
||||
resetPassword({ password: md5(password.value) }).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({ title: '修改成功!', duration: 2000, icon: 'none' })
|
||||
setTimeout(() => {
|
||||
uni.navigateBack({ delta: 1 })
|
||||
}, 1000)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
.box {
|
||||
padding: 80rpx 0;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
function verifyMobile() {
|
||||
validateCodeForm.value?.validate((valid: boolean) => {
|
||||
if (!valid) return
|
||||
resetByMobile(codeForm).then((res) => {
|
||||
if (res.data.success) {
|
||||
phoneVerified.value = true
|
||||
uni.showToast({ title: '验证成功!', icon: 'none' })
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
.submit {
|
||||
background: $light-color;
|
||||
}
|
||||
function onCodeTextChange(text: string) {
|
||||
codeTips.value = text
|
||||
}
|
||||
|
||||
.box-tips {
|
||||
margin: 0 72rpx;
|
||||
}
|
||||
function onCodeCountdownEnd() {
|
||||
verificationPassed.value = false
|
||||
verificationRef.value?.getCode()
|
||||
}
|
||||
|
||||
.verification {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
margin-top: 10rpx;
|
||||
function isCurrentUserPhone() {
|
||||
const user = isLogin()
|
||||
if (user?.mobile !== codeForm.mobile) {
|
||||
uni.showToast({ title: '请输入当前绑定手机号', icon: 'none' })
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
function requestSmsCode() {
|
||||
if (!isCurrentUserPhone()) return
|
||||
if (codeTips.value === '重新获取') {
|
||||
verificationRef.value?.error()
|
||||
}
|
||||
if (!proxy.$u.test.mobile(codeForm.mobile)) {
|
||||
uni.showToast({ title: '请输入正确手机号', icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (!verificationPassed.value) {
|
||||
verificationRef.value?.error()
|
||||
}
|
||||
}
|
||||
|
||||
function onCodeCountdownStart() {
|
||||
proxy.$u.toast('验证码已发送')
|
||||
verificationPassed.value = true
|
||||
verificationRef.value?.hide()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import url("@/pages/passport/login.scss");
|
||||
|
||||
::v-deep .u-form-item {
|
||||
margin: 40rpx 0;
|
||||
}
|
||||
|
||||
.sendCode {
|
||||
::v-deep .u-form-item__body__right__content__slot {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
.h2 {
|
||||
font-size: 40rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
page {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.box {
|
||||
padding: 80rpx 0;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
|
||||
.submit {
|
||||
background: $light-color;
|
||||
}
|
||||
|
||||
.box-tips {
|
||||
margin: 0 72rpx;
|
||||
}
|
||||
|
||||
.verification {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<u-cell-group>
|
||||
<u-cell class="border-top" :isLink="false" title="面容登录">
|
||||
<template #right-icon>
|
||||
<u-switch @change="faceSwitchChange" active-color="#1abc9c" size="40" v-model="checked"></u-switch>
|
||||
<u-switch @change="onFaceSwitchChange" active-color="#1abc9c" size="40" v-model="enabled"></u-switch>
|
||||
</template>
|
||||
</u-cell>
|
||||
</u-cell-group>
|
||||
@@ -12,74 +12,65 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import storage from "@/utils/storage.js";
|
||||
import { setBiolofy } from "@/api/passport.js";
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import storage from '@/utils/storage.js'
|
||||
import { setBiolofy } from '@/api/passport.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
lightColor: this.$lightColor,
|
||||
checked: true,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
faceSwitchChange(value) {
|
||||
if (value === true) {
|
||||
const res = uni.getSystemInfoSync();
|
||||
plus.device.getInfo({
|
||||
success: function (e) {
|
||||
let params = {
|
||||
mobile_type: res.model,
|
||||
secret_key: e.uuid,
|
||||
};
|
||||
setBiolofy(params).then((res) => {
|
||||
if (res.statusCode === 200) {
|
||||
storage.setFaceLogin(true);
|
||||
}
|
||||
});
|
||||
},
|
||||
fail: function (e) {
|
||||
//plus.nativeUI.toast('获取设备信息错误:' + JSON.stringify(e));
|
||||
console.error("getDeviceInfo failed: " + JSON.stringify(e));
|
||||
},
|
||||
});
|
||||
} else {
|
||||
storage.setFaceLogin(false);
|
||||
const enabled = ref(false)
|
||||
|
||||
onLoad(() => {
|
||||
// #ifdef APP-PLUS
|
||||
uni.checkIsSupportSoterAuthentication({
|
||||
success(res) {
|
||||
if (!res.supportMode.find((e) => e === 'facial')) {
|
||||
plus.nativeUI.toast('此设备不支持面部识别')
|
||||
uni.navigateBack()
|
||||
}
|
||||
uni.checkIsSoterEnrolledInDevice({
|
||||
checkAuthMode: 'facial',
|
||||
success(_res) {
|
||||
if (!_res.isEnrolled) {
|
||||
plus.nativeUI.toast('此设备未录入面部信息')
|
||||
uni.navigateBack()
|
||||
}
|
||||
},
|
||||
fail() {
|
||||
uni.navigateBack()
|
||||
},
|
||||
})
|
||||
},
|
||||
},
|
||||
onLoad() {
|
||||
// #ifdef APP-PLUS
|
||||
uni.checkIsSupportSoterAuthentication({
|
||||
success(res) {
|
||||
if (!res.supportMode.find((e) => e === "facial")) {
|
||||
plus.nativeUI.toast("此设备不支持面部识别");
|
||||
uni.navigateBack();
|
||||
}
|
||||
uni.checkIsSoterEnrolledInDevice({
|
||||
checkAuthMode: "facial",
|
||||
success(_res) {
|
||||
if (!_res.isEnrolled) {
|
||||
plus.nativeUI.toast("此设备未录入面部信息");
|
||||
uni.navigateBack();
|
||||
}
|
||||
},
|
||||
fail(_err) {
|
||||
// plus.nativeUI.toast(JSON.stringify(_err));
|
||||
uni.navigateBack();
|
||||
},
|
||||
});
|
||||
fail() {
|
||||
uni.navigateBack()
|
||||
},
|
||||
})
|
||||
enabled.value = storage.getFaceLogin() || false
|
||||
// #endif
|
||||
})
|
||||
|
||||
function onFaceSwitchChange(value: boolean) {
|
||||
if (value) {
|
||||
const systemInfo = uni.getSystemInfoSync()
|
||||
plus.device.getInfo({
|
||||
success(e) {
|
||||
setBiolofy({
|
||||
mobile_type: systemInfo.model,
|
||||
secret_key: e.uuid,
|
||||
}).then((res) => {
|
||||
if (res.statusCode === 200) {
|
||||
storage.setFaceLogin(true)
|
||||
}
|
||||
})
|
||||
},
|
||||
fail(err) {
|
||||
// plus.nativeUI.toast(JSON.stringify(err));
|
||||
uni.navigateBack();
|
||||
console.error('getDeviceInfo failed: ' + JSON.stringify(err))
|
||||
},
|
||||
});
|
||||
this.checked = storage.getFaceLogin() || false;
|
||||
// #endif
|
||||
},
|
||||
};
|
||||
})
|
||||
} else {
|
||||
storage.setFaceLogin(false)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<u-cell-group>
|
||||
<u-cell class="border-top" :isLink="false" title="指纹登录">
|
||||
<template #right-icon>
|
||||
<u-switch @change="fingerSwitchChange" :active-color="lightColor" size="40" v-model="checked"></u-switch>
|
||||
<u-switch @change="onFingerSwitchChange" :active-color="lightColor" size="40" v-model="enabled"></u-switch>
|
||||
</template>
|
||||
</u-cell>
|
||||
</u-cell-group>
|
||||
@@ -12,60 +12,57 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import storage from "@/utils/storage.js";
|
||||
import { setBiolofy } from "@/api/passport.js";
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import storage from '@/utils/storage.js'
|
||||
import { setBiolofy } from '@/api/passport.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
lightColor: this.$lightColor,
|
||||
checked: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
fingerSwitchChange(value) {
|
||||
if (value === true) {
|
||||
const res = uni.getSystemInfoSync();
|
||||
plus.device.getInfo({
|
||||
success: function (e) {
|
||||
let params = {
|
||||
mobile_type: res.model,
|
||||
secret_key: e.uuid,
|
||||
};
|
||||
setBiolofy(params).then((res) => {
|
||||
if (res.statusCode === 200) {
|
||||
storage.setFingerLogin(true);
|
||||
}
|
||||
});
|
||||
},
|
||||
fail: function (e) {
|
||||
console.error("getDeviceInfo failed: " + JSON.stringify(e));
|
||||
},
|
||||
});
|
||||
} else {
|
||||
storage.setFingerLogin(false);
|
||||
}
|
||||
},
|
||||
},
|
||||
onLoad() {
|
||||
// #ifdef APP-PLUS
|
||||
if (!plus.fingerprint.isSupport()) {
|
||||
plus.nativeUI.toast("此设备不支持指纹识别");
|
||||
uni.navigateBack();
|
||||
}
|
||||
if (!plus.fingerprint.isKeyguardSecure()) {
|
||||
plus.nativeUI.toast("此设备未设置密码锁屏");
|
||||
uni.navigateBack();
|
||||
}
|
||||
if (!plus.fingerprint.isEnrolledFingerprints()) {
|
||||
plus.nativeUI.toast("此设备未录入指纹");
|
||||
uni.navigateBack();
|
||||
}
|
||||
this.checked = storage.getFingerLogin() || false;
|
||||
// #endif
|
||||
},
|
||||
};
|
||||
const store = useStore()
|
||||
const lightColor = computed(() => store.getters.lightColor)
|
||||
const enabled = ref(false)
|
||||
|
||||
onLoad(() => {
|
||||
// #ifdef APP-PLUS
|
||||
if (!plus.fingerprint.isSupport()) {
|
||||
plus.nativeUI.toast('此设备不支持指纹识别')
|
||||
uni.navigateBack()
|
||||
}
|
||||
if (!plus.fingerprint.isKeyguardSecure()) {
|
||||
plus.nativeUI.toast('此设备未设置密码锁屏')
|
||||
uni.navigateBack()
|
||||
}
|
||||
if (!plus.fingerprint.isEnrolledFingerprints()) {
|
||||
plus.nativeUI.toast('此设备未录入指纹')
|
||||
uni.navigateBack()
|
||||
}
|
||||
enabled.value = storage.getFingerLogin() || false
|
||||
// #endif
|
||||
})
|
||||
|
||||
function onFingerSwitchChange(value: boolean) {
|
||||
if (value) {
|
||||
const systemInfo = uni.getSystemInfoSync()
|
||||
plus.device.getInfo({
|
||||
success(e) {
|
||||
setBiolofy({
|
||||
mobile_type: systemInfo.model,
|
||||
secret_key: e.uuid,
|
||||
}).then((res) => {
|
||||
if (res.statusCode === 200) {
|
||||
storage.setFingerLogin(true)
|
||||
}
|
||||
})
|
||||
},
|
||||
fail(err) {
|
||||
console.error('getDeviceInfo failed: ' + JSON.stringify(err))
|
||||
},
|
||||
})
|
||||
} else {
|
||||
storage.setFingerLogin(false)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@@ -2,56 +2,44 @@
|
||||
<view class="securityCenter">
|
||||
<u-cell-group>
|
||||
<u-cell title="修改密码" @click="navigateTo('/pages/mine/set/securityCenter/updatePwdTab')"></u-cell>
|
||||
<u-cell title="注销账户" @click="zhuxiao"></u-cell>
|
||||
<u-cell title="注销账户" @click="confirmAccountDeletion"></u-cell>
|
||||
</u-cell-group>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
mobile: "", //存储手机号
|
||||
};
|
||||
},
|
||||
<script setup lang="ts">
|
||||
function navigateTo(url: string) {
|
||||
uni.navigateTo({ url })
|
||||
}
|
||||
|
||||
methods: {
|
||||
zhuxiao(){
|
||||
|
||||
uni.showModal({
|
||||
title: "警告",
|
||||
content: "您确定要注销当前账号吗?",
|
||||
confirmText: "确定注销",
|
||||
confirmColor: "#FF0000",
|
||||
cancelText: "取消",
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
uni.showModal({
|
||||
title: "谨慎操作",
|
||||
content: "再次向您确认,您确定要注销当前账号吗?",
|
||||
confirmText: "坚持注销",
|
||||
confirmColor: "#FF0000",
|
||||
cancelText: "取消",
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
uni.showToast({
|
||||
title: "您的注销申请已经提交,待管理员审核后。会自动注销当前账号",
|
||||
duration: 10000,
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
function confirmAccountDeletion() {
|
||||
uni.showModal({
|
||||
title: '警告',
|
||||
content: '您确定要注销当前账号吗?',
|
||||
confirmText: '确定注销',
|
||||
confirmColor: '#FF0000',
|
||||
cancelText: '取消',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
uni.showModal({
|
||||
title: '谨慎操作',
|
||||
content: '再次向您确认,您确定要注销当前账号吗?',
|
||||
confirmText: '坚持注销',
|
||||
confirmColor: '#FF0000',
|
||||
cancelText: '取消',
|
||||
success: (confirmRes) => {
|
||||
if (confirmRes.confirm) {
|
||||
uni.showToast({
|
||||
title: '您的注销申请已经提交,待管理员审核后。会自动注销当前账号',
|
||||
duration: 10000,
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
},
|
||||
navigateTo(url) {
|
||||
uni.navigateTo({
|
||||
url: url,
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -7,22 +7,10 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
mobile: "", //存储手机号
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
navigateTo(url) {
|
||||
uni.navigateTo({
|
||||
url: url,
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
<script setup lang="ts">
|
||||
function navigateTo(url: string) {
|
||||
uni.navigateTo({ url })
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -38,112 +38,95 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import config from "@/config/config";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
config,
|
||||
userImage: config.defaultUserPhoto,
|
||||
isCertificate: false,
|
||||
userInfo: {},
|
||||
fileSizeString: "0B",
|
||||
};
|
||||
},
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onShow } from '@dcloudio/uni-app'
|
||||
import config from '@/config/config'
|
||||
import { isLogin, tipsToLogin, quiteLoginOut, logoff } from '@/utils/filters.js'
|
||||
|
||||
methods: {
|
||||
navigateTo(url) {
|
||||
if (url == "/pages/set/securityCenter/securityCenter") {
|
||||
url += `?mobile=${this.userInfo.mobile}`;
|
||||
}
|
||||
uni.navigateTo({
|
||||
url: url,
|
||||
});
|
||||
},
|
||||
const userImage = config.defaultUserPhoto
|
||||
const userInfo = ref<Record<string, any>>({})
|
||||
const fileSizeString = ref('0B')
|
||||
|
||||
getCacheSize() {
|
||||
let that = this;
|
||||
plus.cache.calculate(function (size) {
|
||||
let sizeCache = parseInt(size);
|
||||
if (sizeCache == 0) {
|
||||
that.fileSizeString = "0B";
|
||||
} else if (sizeCache < 1024) {
|
||||
that.fileSizeString = sizeCache + "B";
|
||||
} else if (sizeCache < 1048576) {
|
||||
that.fileSizeString = (sizeCache / 1024).toFixed(2) + "KB";
|
||||
} else if (sizeCache < 1073741824) {
|
||||
that.fileSizeString = (sizeCache / 1048576).toFixed(2) + "MB";
|
||||
} else {
|
||||
that.fileSizeString = (sizeCache / 1073741824).toFixed(2) + "GB";
|
||||
}
|
||||
});
|
||||
},
|
||||
onShow(() => {
|
||||
userInfo.value = isLogin() || {}
|
||||
// #ifdef APP-PLUS
|
||||
getCacheSize()
|
||||
// #endif
|
||||
})
|
||||
|
||||
checkUserInfo() {
|
||||
if (this.isLogin("auth")) {
|
||||
this.navigateTo("/pages/mine/set/personMsg");
|
||||
} else {
|
||||
this.tipsToLogin();
|
||||
}
|
||||
},
|
||||
function navigateTo(url: string) {
|
||||
if (url === '/pages/mine/set/securityCenter/securityCenter') {
|
||||
url += `?mobile=${userInfo.value.mobile || ''}`
|
||||
}
|
||||
uni.navigateTo({ url })
|
||||
}
|
||||
|
||||
clearCache() {
|
||||
let that = this;
|
||||
let os = plus.os.name;
|
||||
if (os == "Android") {
|
||||
let main = plus.android.runtimeMainActivity();
|
||||
let sdRoot = main.getCacheDir();
|
||||
let files = plus.android.invoke(sdRoot, "listFiles");
|
||||
let len = files.length;
|
||||
for (let i = 0; i < len; i++) {
|
||||
let filePath = "" + files[i];
|
||||
plus.io.resolveLocalFileSystemURL(
|
||||
filePath,
|
||||
function (entry) {
|
||||
if (entry.isDirectory) {
|
||||
entry.removeRecursively(
|
||||
function () {
|
||||
uni.showToast({
|
||||
title: "缓存清理完成",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
that.getCacheSize();
|
||||
},
|
||||
function () {}
|
||||
);
|
||||
} else {
|
||||
entry.remove();
|
||||
}
|
||||
},
|
||||
function () {
|
||||
uni.showToast({
|
||||
title: "文件路径读取失败",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
} else {
|
||||
plus.cache.clear(function () {
|
||||
uni.showToast({
|
||||
title: "缓存清理完成",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
that.getCacheSize();
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
onShow() {
|
||||
this.userInfo = this.isLogin();
|
||||
// #ifdef APP-PLUS
|
||||
this.getCacheSize();
|
||||
// #endif
|
||||
},
|
||||
};
|
||||
function getCacheSize() {
|
||||
// #ifdef APP-PLUS
|
||||
plus.cache.calculate((size) => {
|
||||
const sizeCache = parseInt(String(size))
|
||||
if (sizeCache === 0) {
|
||||
fileSizeString.value = '0B'
|
||||
} else if (sizeCache < 1024) {
|
||||
fileSizeString.value = `${sizeCache}B`
|
||||
} else if (sizeCache < 1048576) {
|
||||
fileSizeString.value = `${(sizeCache / 1024).toFixed(2)}KB`
|
||||
} else if (sizeCache < 1073741824) {
|
||||
fileSizeString.value = `${(sizeCache / 1048576).toFixed(2)}MB`
|
||||
} else {
|
||||
fileSizeString.value = `${(sizeCache / 1073741824).toFixed(2)}GB`
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
|
||||
function checkUserInfo() {
|
||||
if (isLogin('auth')) {
|
||||
navigateTo('/pages/mine/set/personMsg')
|
||||
} else {
|
||||
tipsToLogin()
|
||||
}
|
||||
}
|
||||
|
||||
function clearCache() {
|
||||
// #ifdef APP-PLUS
|
||||
const os = plus.os.name
|
||||
if (os === 'Android') {
|
||||
const main = plus.android.runtimeMainActivity()
|
||||
const sdRoot = main.getCacheDir()
|
||||
const files = plus.android.invoke(sdRoot, 'listFiles')
|
||||
const len = files.length
|
||||
for (let i = 0; i < len; i++) {
|
||||
const filePath = `${files[i]}`
|
||||
plus.io.resolveLocalFileSystemURL(
|
||||
filePath,
|
||||
(entry) => {
|
||||
if (entry.isDirectory) {
|
||||
entry.removeRecursively(
|
||||
() => {
|
||||
uni.showToast({ title: '缓存清理完成', duration: 2000, icon: 'none' })
|
||||
getCacheSize()
|
||||
},
|
||||
() => {}
|
||||
)
|
||||
} else {
|
||||
entry.remove()
|
||||
}
|
||||
},
|
||||
() => {
|
||||
uni.showToast({ title: '文件路径读取失败', duration: 2000, icon: 'none' })
|
||||
}
|
||||
)
|
||||
}
|
||||
} else {
|
||||
plus.cache.clear(() => {
|
||||
uni.showToast({ title: '缓存清理完成', duration: 2000, icon: 'none' })
|
||||
getCacheSize()
|
||||
})
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -1,58 +1,45 @@
|
||||
<template>
|
||||
<div>
|
||||
<u-collapse v-if="versionData.length !=0">
|
||||
<u-collapse-item class="version-item" :title="item.versionName" v-for="(item, index) in versionData" :key="index">
|
||||
<!-- {{item.body}} -->
|
||||
|
||||
{{item.content}}
|
||||
<u-collapse v-if="versionList.length !== 0">
|
||||
<u-collapse-item
|
||||
class="version-item"
|
||||
:title="item.versionName"
|
||||
v-for="(item, index) in versionList"
|
||||
:key="index"
|
||||
>
|
||||
{{ item.content }}
|
||||
</u-collapse-item>
|
||||
|
||||
</u-collapse>
|
||||
<u-empty class="empty" v-else text="暂无版本信息" mode="list"></u-empty>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getAppVersionList } from "@/api/message";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
versionData: [],
|
||||
appType: "",
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
const platform = uni.getSystemInfoSync().platform;
|
||||
/**
|
||||
* 获取是否是安卓
|
||||
*/
|
||||
if (platform === "android") {
|
||||
this.appType = "ANDROID";
|
||||
} else {
|
||||
this.IosWhether = true;
|
||||
this.appType = "IOS";
|
||||
}
|
||||
this.getVersionList();
|
||||
},
|
||||
methods: {
|
||||
async getVersionList() {
|
||||
let res = await getAppVersionList(this.appType, this.params);
|
||||
if (res.data.success) {
|
||||
this.versionData = res.data.result.records;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { getAppVersionList } from '@/api/message'
|
||||
|
||||
const versionList = ref<any[]>([])
|
||||
const appType = ref('')
|
||||
const params = { pageNumber: 1, pageSize: 10 }
|
||||
|
||||
onLoad(() => {
|
||||
const platform = uni.getSystemInfoSync().platform
|
||||
appType.value = platform === 'android' ? 'ANDROID' : 'IOS'
|
||||
fetchVersionList()
|
||||
})
|
||||
|
||||
async function fetchVersionList() {
|
||||
const res = await getAppVersionList(appType.value, params)
|
||||
if (res.data.success) {
|
||||
versionList.value = res.data.result.records
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.version-item{
|
||||
padding: 10rpx;
|
||||
background: #fff;
|
||||
.version-item {
|
||||
padding: 10rpx;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
<view class="date-card">
|
||||
<div class="box">
|
||||
<div class="circle-box">
|
||||
<div class="cricle" @click="signIn()">
|
||||
<span v-if="!ifSign" :class="{ active: signFlag || ifSign }">签到</span>
|
||||
<span v-else :class="{ active: signFlag || ifSign }"
|
||||
:style="ifSign ? 'transform: rotateY(0deg);' : ''">已签</span>
|
||||
<div class="cricle" @click="handleSignIn()">
|
||||
<span v-if="!hasSignedToday" :class="{ active: signAnimating || hasSignedToday }">签到</span>
|
||||
<span v-else :class="{ active: signAnimating || hasSignedToday }"
|
||||
:style="hasSignedToday ? 'transform: rotateY(0deg);' : ''">已签</span>
|
||||
</div>
|
||||
</div>
|
||||
<text class="tips">坚持每天连续签到可以获多重奖励哦</text>
|
||||
@@ -22,19 +22,19 @@
|
||||
<view class="week">
|
||||
<text v-for="item in weekArr" :key="item.id">{{ item }}</text>
|
||||
</view>
|
||||
<view class="date" v-for="obj in dataObj" :key="obj.id">
|
||||
<view class="item" v-for="item in obj" :key="item.id" :class="item == '' ? 'hide' : ''"
|
||||
<view class="date" v-for="(obj, rowIndex) in calendarRows" :key="rowIndex">
|
||||
<view class="item" v-for="(item, dayIndex) in obj" :key="dayIndex" :class="item == '' ? 'hide' : ''"
|
||||
:animation="item == currentDay ? animationData : ''">
|
||||
<view class="just" :class="signArr.indexOf(item) != -1 ? 'active' : ''">
|
||||
<view class="just" :class="signedDays.indexOf(item) != -1 ? 'active' : ''">
|
||||
<view class="top">{{ item }} </view>
|
||||
<view class="bottom">
|
||||
<u-icon name="error" v-if="item <= currentDay" size="24" color="#999"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
<view class="back" :class="signArr.indexOf(item) != -1 ? 'active' : ''" :style="
|
||||
signArr.indexOf(item) != -1 && ifSign
|
||||
<view class="back" :class="signedDays.indexOf(item) != -1 ? 'active' : ''" :style="
|
||||
signedDays.indexOf(item) != -1 && hasSignedToday
|
||||
? 'transform: rotateY(0deg);'
|
||||
: signArr.indexOf(item) != -1 && item != currentDay
|
||||
: signedDays.indexOf(item) != -1 && item != currentDay
|
||||
? 'transform: rotateY(0deg);'
|
||||
: ''
|
||||
">
|
||||
@@ -47,11 +47,11 @@
|
||||
</view>
|
||||
</view>
|
||||
</div>
|
||||
<view class="mask" :class="{ show: maskFlag, trans: transFlag }" ref="mask">
|
||||
<view class="mask" :class="{ show: showSuccessMask, trans: maskClosing }" ref="mask">
|
||||
<view class="mask-header">
|
||||
<text class="close"></text>
|
||||
<text>签到成功</text>
|
||||
<text class="close" @click="close">×</text>
|
||||
<text class="close" @click="closeSuccessMask">×</text>
|
||||
</view>
|
||||
<view class="mask-con">
|
||||
<u-icon size="120" style="margin: 50rpx 0" :color="aiderLightColor" name="checkmark"></u-icon>
|
||||
@@ -61,231 +61,147 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { sign, signTime } from "@/api/point.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
aiderLightColor:this.$aiderLightColor,
|
||||
signFlag: false,
|
||||
animationData: {},
|
||||
maskFlag: false, //
|
||||
transFlag: false, //动画
|
||||
weekArr: ["日", "一", "二", "三", "四", "五", "六"], //周数组
|
||||
dateArr: [], //每个月的天数
|
||||
monthArr: [
|
||||
//实例化每个月
|
||||
"1月",
|
||||
"2月",
|
||||
"3月",
|
||||
"4月",
|
||||
"5月",
|
||||
"6月",
|
||||
"7月",
|
||||
"8月",
|
||||
"9月",
|
||||
"10月",
|
||||
"11月",
|
||||
"12月",
|
||||
], //今天一个月英文
|
||||
currentMonth: "", //当月
|
||||
currentMonthIndex: "", //当月
|
||||
currentYear: "", //今年
|
||||
currentDay: "", //今天
|
||||
currentWeek: "", //获取当月一号是周几
|
||||
dataObj: [], //一个月有多少天这个获取
|
||||
signArr: [], //本月签到过的天数 该参数用于请求接口后获取当月都哪天签到了
|
||||
signAll: [], //所有签到数据
|
||||
ifSign: false, //今天是否签到
|
||||
};
|
||||
},
|
||||
async onLoad() {
|
||||
//获取签到数据
|
||||
var response = await signTime(
|
||||
new Date().getFullYear() + "" + this.makeUp(new Date().getMonth() + 1)
|
||||
);
|
||||
this.signAll = response.data.result;
|
||||
//获取展示数据
|
||||
this.getDate();
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 补0
|
||||
*/
|
||||
makeUp(val) {
|
||||
if (val >= 10) {
|
||||
return val;
|
||||
} else {
|
||||
return "0" + val;
|
||||
}
|
||||
},
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { sign, signTime } from '@/api/point.js'
|
||||
|
||||
/**
|
||||
* 点击签到
|
||||
*/
|
||||
async signIn() {
|
||||
await sign().then((response) => {
|
||||
if (this.ifSign) return;
|
||||
if (this.signFlag) return;
|
||||
if (response.data.code != 200) {
|
||||
uni.showToast({
|
||||
title: response.data.message,
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
const store = useStore()
|
||||
const aiderLightColor = computed(() => store.getters.aiderLightColor)
|
||||
|
||||
return false;
|
||||
}
|
||||
var that = this;
|
||||
var animation = uni.createAnimation({
|
||||
duration: 200,
|
||||
timingFunction: "linear",
|
||||
});
|
||||
this.signArr.push(this.currentDay);
|
||||
this.animation = animation;
|
||||
animation.rotateY(0).step();
|
||||
this.animationData = animation.export();
|
||||
const signAnimating = ref(false)
|
||||
const animationData = ref({})
|
||||
const showSuccessMask = ref(false)
|
||||
const maskClosing = ref(false)
|
||||
const weekArr = ['日', '一', '二', '三', '四', '五', '六']
|
||||
const monthLabels = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
|
||||
const currentMonth = ref('')
|
||||
const currentMonthIndex = ref(0)
|
||||
const currentYear = ref(0)
|
||||
const currentDay = ref(0)
|
||||
const calendarRows = ref<any[][]>([])
|
||||
const signedDays = ref<number[]>([])
|
||||
const signRecords = ref<any[]>([])
|
||||
const hasSignedToday = ref(false)
|
||||
|
||||
setTimeout(
|
||||
function () {
|
||||
that.signFlag = true;
|
||||
this.maskFlag = true;
|
||||
this.ifSign = !this.ifSign;
|
||||
animation.rotateY(0).step();
|
||||
this.animationData = animation.export();
|
||||
}.bind(this),
|
||||
200
|
||||
);
|
||||
});
|
||||
},
|
||||
onLoad(async () => {
|
||||
const response = await signTime(
|
||||
`${new Date().getFullYear()}${padZero(new Date().getMonth() + 1)}`
|
||||
)
|
||||
signRecords.value = response.data.result
|
||||
buildCalendar()
|
||||
})
|
||||
|
||||
/**
|
||||
* 签到成功后关闭弹窗
|
||||
*/
|
||||
close() {
|
||||
var that = this;
|
||||
this.maskFlag = false;
|
||||
this.transFlag = true;
|
||||
setTimeout(() => {
|
||||
that.transFlag = false;
|
||||
}, 500);
|
||||
},
|
||||
function padZero(val: number) {
|
||||
return val >= 10 ? String(val) : `0${val}`
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取今天时间
|
||||
*
|
||||
*/
|
||||
getDate() {
|
||||
var date = new Date(),
|
||||
index = date.getMonth(),
|
||||
curDay = null;
|
||||
this.currentYear = date.getFullYear();
|
||||
this.currentMonth = this.monthArr[index];
|
||||
this.currentMonthIndex = index + 1;
|
||||
this.currentDay = date.getDate();
|
||||
if (this.currentDay == this.signArr[this.signArr.length - 1]) {
|
||||
this.ifSign = true;
|
||||
}
|
||||
curDay = this.getWeekByDay(this.currentYear + "-" + (index + 1) + "-1");
|
||||
this.getMonthDays(index, curDay);
|
||||
this.curentSignData();
|
||||
},
|
||||
async function handleSignIn() {
|
||||
if (hasSignedToday.value || signAnimating.value) return
|
||||
|
||||
/**
|
||||
* 获取当前已经签到的时间
|
||||
*/
|
||||
curentSignData() {
|
||||
var date = new Date(),
|
||||
index = date.getMonth(),
|
||||
curDay = null;
|
||||
this.signArr = [];
|
||||
for (var i = 0; i < this.signAll.length; i++) {
|
||||
var item = this.signAll[i];
|
||||
item.createTime = item.createTime.split(" ")[0];
|
||||
var itemVal = item.createTime.split("-");
|
||||
if (
|
||||
Number(itemVal[0]) === Number(this.currentYear) &&
|
||||
Number(itemVal[1]) === Number(this.currentMonthIndex)
|
||||
) {
|
||||
this.signArr.push(Number(itemVal[2]));
|
||||
}
|
||||
if (
|
||||
Number(itemVal[0]) === Number(date.getFullYear()) &&
|
||||
Number(itemVal[1]) === Number(index + 1) &&
|
||||
Number(itemVal[2]) === Number(date.getDate())
|
||||
) {
|
||||
this.ifSign = true;
|
||||
}
|
||||
}
|
||||
},
|
||||
const response = await sign()
|
||||
if (response.data.code !== 200) {
|
||||
uni.showToast({
|
||||
title: response.data.message,
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
/**
|
||||
* 循环出当前月份的时间
|
||||
* 例子:
|
||||
* "","","","","","",1,
|
||||
* 2 ,3 ,4 ,5 ,6 ,7 ,8,
|
||||
* ...依次向下排
|
||||
*/
|
||||
getMonthDays(index, day) {
|
||||
//day 当月1号是周几
|
||||
this.dateArr = [];
|
||||
this.dataObj = [];
|
||||
for (var i = 0; i < day; i++) {
|
||||
this.dateArr.push("");
|
||||
}
|
||||
if (
|
||||
index == 0 ||
|
||||
index == 2 ||
|
||||
index == 4 ||
|
||||
index == 6 ||
|
||||
index == 7 ||
|
||||
index == 9 ||
|
||||
index == 11
|
||||
) {
|
||||
for (let i = 1; i < 32; i++) {
|
||||
this.dateArr.push(i);
|
||||
}
|
||||
}
|
||||
if (index == 3 || index == 5 || index == 8 || index == 10) {
|
||||
for (let i = 1; i < 31; i++) {
|
||||
this.dateArr.push(i);
|
||||
}
|
||||
}
|
||||
if (index == 1) {
|
||||
if (
|
||||
(this.currentYear % 4 == 0 && this.currentYear % 100 != 0) ||
|
||||
this.currentYear % 400 == 0
|
||||
) {
|
||||
for (let i = 1; i < 30; i++) {
|
||||
this.dateArr.push(i);
|
||||
}
|
||||
} else {
|
||||
for (let i = 1; i < 29; i++) {
|
||||
this.dateArr.push(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (var y = 0; y < 10; y++) {
|
||||
if (this.dateArr.length > 7) {
|
||||
this.dataObj.push(this.dateArr.splice(0, 7));
|
||||
} else {
|
||||
for (let i = 0; i < 7 - this.dateArr.length; i++) {
|
||||
this.dateArr.push("");
|
||||
}
|
||||
}
|
||||
}
|
||||
this.dataObj.push(this.dateArr);
|
||||
},
|
||||
const animation = uni.createAnimation({ duration: 200, timingFunction: 'linear' })
|
||||
signedDays.value.push(currentDay.value)
|
||||
animation.rotateY(0).step()
|
||||
animationData.value = animation.export()
|
||||
|
||||
/**
|
||||
* 获取当前月份有几周
|
||||
*/
|
||||
getWeekByDay(dayValue) {
|
||||
var day = new Date(Date.parse(dayValue.replace(/-/g, "/"))).getDay(); //将日期值格式化
|
||||
return day;
|
||||
},
|
||||
},
|
||||
};
|
||||
setTimeout(() => {
|
||||
signAnimating.value = true
|
||||
showSuccessMask.value = true
|
||||
hasSignedToday.value = true
|
||||
animation.rotateY(0).step()
|
||||
animationData.value = animation.export()
|
||||
}, 200)
|
||||
}
|
||||
|
||||
function closeSuccessMask() {
|
||||
showSuccessMask.value = false
|
||||
maskClosing.value = true
|
||||
setTimeout(() => {
|
||||
maskClosing.value = false
|
||||
}, 500)
|
||||
}
|
||||
|
||||
function buildCalendar() {
|
||||
const date = new Date()
|
||||
const monthIndex = date.getMonth()
|
||||
currentYear.value = date.getFullYear()
|
||||
currentMonth.value = monthLabels[monthIndex]
|
||||
currentMonthIndex.value = monthIndex + 1
|
||||
currentDay.value = date.getDate()
|
||||
syncSignedDays()
|
||||
const firstWeekDay = getWeekByDay(`${currentYear.value}-${monthIndex + 1}-1`)
|
||||
buildMonthDays(monthIndex, firstWeekDay)
|
||||
}
|
||||
|
||||
function syncSignedDays() {
|
||||
const date = new Date()
|
||||
const monthIndex = date.getMonth()
|
||||
signedDays.value = []
|
||||
hasSignedToday.value = false
|
||||
|
||||
signRecords.value.forEach((item) => {
|
||||
const datePart = item.createTime.split(' ')[0]
|
||||
const parts = datePart.split('-')
|
||||
if (
|
||||
Number(parts[0]) === currentYear.value &&
|
||||
Number(parts[1]) === currentMonthIndex.value
|
||||
) {
|
||||
signedDays.value.push(Number(parts[2]))
|
||||
}
|
||||
if (
|
||||
Number(parts[0]) === date.getFullYear() &&
|
||||
Number(parts[1]) === monthIndex + 1 &&
|
||||
Number(parts[2]) === date.getDate()
|
||||
) {
|
||||
hasSignedToday.value = true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function buildMonthDays(monthIndex: number, firstWeekDay: number) {
|
||||
const daysInRow: any[] = []
|
||||
const rows: any[][] = []
|
||||
for (let i = 0; i < firstWeekDay; i++) {
|
||||
daysInRow.push('')
|
||||
}
|
||||
|
||||
const isLongMonth = [0, 2, 4, 6, 7, 9, 11].includes(monthIndex)
|
||||
const isFebruary = monthIndex === 1
|
||||
let totalDays = isLongMonth ? 31 : 30
|
||||
if (isFebruary) {
|
||||
const year = currentYear.value
|
||||
const isLeap = (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0
|
||||
totalDays = isLeap ? 29 : 28
|
||||
}
|
||||
|
||||
for (let day = 1; day <= totalDays; day++) {
|
||||
daysInRow.push(day)
|
||||
}
|
||||
|
||||
while (daysInRow.length) {
|
||||
const row = daysInRow.splice(0, 7)
|
||||
while (row.length < 7) {
|
||||
row.push('')
|
||||
}
|
||||
rows.push(row)
|
||||
}
|
||||
calendarRows.value = rows
|
||||
}
|
||||
|
||||
function getWeekByDay(dayValue: string) {
|
||||
return new Date(Date.parse(dayValue.replace(/-/g, '/'))).getDay()
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
page {
|
||||
|
||||
@@ -185,6 +185,8 @@ page {
|
||||
}
|
||||
|
||||
.goods-list-wrap {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding-bottom: 40rpx;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,8 +6,8 @@
|
||||
:scrollable="false"
|
||||
v-model:current="current"
|
||||
@change="change"
|
||||
:lineColor="$lightColor"
|
||||
:activeStyle="{ color: $lightColor }"
|
||||
:lineColor="lightColor"
|
||||
:activeStyle="{ color: lightColor }"
|
||||
></u-tabs>
|
||||
</view>
|
||||
<div class="u-tabs-search">
|
||||
@@ -194,279 +194,199 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import uniLoadMore from "@/components/uni-load-more/uni-load-more.vue";
|
||||
import { getAfterSaleList, cancelAfterSale } from "@/api/after-sale.js";
|
||||
import { getOrderList } from "@/api/order.js";
|
||||
import storage from "@/utils/storage";
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed } from 'vue'
|
||||
import { onLoad, onPullDownRefresh } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { unitPrice, serviceStatusList, parseGoodsImageUrl } from '@/utils/filters.js'
|
||||
import { getAfterSaleList, cancelAfterSale } from '@/api/after-sale.js'
|
||||
import { getOrderList } from '@/api/order.js'
|
||||
import storage from '@/utils/storage'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
uniLoadMore,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
list: [
|
||||
//tab表头
|
||||
const store = useStore()
|
||||
const lightColor = computed(() => store.getters.lightColor)
|
||||
|
||||
const list = [
|
||||
{ name: '售后申请' },
|
||||
{ name: '申请中' },
|
||||
{ name: '申请记录' },
|
||||
]
|
||||
|
||||
const current = ref(0)
|
||||
const tipsShow = ref(false)
|
||||
const cancelShow = ref(false)
|
||||
const selectedOrder = ref<any>(null)
|
||||
const orderList = ref<any[]>([])
|
||||
const params = reactive<Record<string, any>>({
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
sort: 'createTime',
|
||||
flowPrice: 0,
|
||||
order: 'desc',
|
||||
})
|
||||
const logParams = reactive<Record<string, any>>({
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
})
|
||||
const status = ref('loadmore')
|
||||
const keywords = ref('')
|
||||
|
||||
onLoad((options) => {
|
||||
orderList.value = []
|
||||
params.pageNumber = 1
|
||||
if (options?.orderSn) params.keywords = options.orderSn
|
||||
searchOrderList(current.value)
|
||||
})
|
||||
|
||||
onPullDownRefresh(() => {
|
||||
change(current.value)
|
||||
})
|
||||
|
||||
function hideLoadingIfNeeded() {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
}
|
||||
|
||||
function getGoodsName(sku: any) {
|
||||
return sku.goodsName || sku.name || ''
|
||||
}
|
||||
|
||||
function getGoodsImage(goods: any, order: any, index: number) {
|
||||
let image = goods.image || goods.goodsImage || goods.thumbnail
|
||||
if (!image && order.groupImages) {
|
||||
const images = String(order.groupImages).split(',')
|
||||
image = images[index] || images[0]
|
||||
}
|
||||
return parseGoodsImageUrl(image)
|
||||
}
|
||||
|
||||
function submitSearchOrderList(tabIndex: number) {
|
||||
params.pageNumber = 1
|
||||
logParams.pageNumber = 1
|
||||
orderList.value = []
|
||||
searchOrderList(tabIndex)
|
||||
}
|
||||
|
||||
function clear(tabIndex: number) {
|
||||
params.pageNumber = 1
|
||||
logParams.pageNumber = 1
|
||||
params.keywords = ''
|
||||
orderList.value = []
|
||||
searchOrderList(tabIndex)
|
||||
}
|
||||
|
||||
function change(e: number | { index: number }) {
|
||||
const index = typeof e === 'object' && e != null ? e.index : e
|
||||
current.value = index
|
||||
Object.assign(params, { pageNumber: 1, pageSize: 10 })
|
||||
orderList.value = []
|
||||
searchOrderList(index)
|
||||
uni.stopPullDownRefresh()
|
||||
}
|
||||
|
||||
function searchOrderList(index: number) {
|
||||
if (index == 0) {
|
||||
if (keywords.value) params.keywords = keywords.value
|
||||
fetchOrderList()
|
||||
} else {
|
||||
Object.assign(logParams, {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
sort: 'createTime',
|
||||
order: 'desc',
|
||||
})
|
||||
if (index === 1) {
|
||||
logParams.serviceStatus = 'APPLY'
|
||||
}
|
||||
if (keywords.value) logParams.keywords = keywords.value
|
||||
orderList.value = []
|
||||
fetchAfterSaleLogList()
|
||||
}
|
||||
}
|
||||
|
||||
function fetchOrderList() {
|
||||
uni.showLoading({ title: '加载中', mask: true })
|
||||
getOrderList(params).then((res) => {
|
||||
hideLoadingIfNeeded()
|
||||
const records = res.data.result.records
|
||||
if (records.length > 0) {
|
||||
orderList.value = orderList.value.concat(records)
|
||||
params.pageNumber += 1
|
||||
}
|
||||
status.value = records.length < 10 ? 'nomore' : 'loading'
|
||||
})
|
||||
}
|
||||
|
||||
function close(order: any, _sku: any) {
|
||||
selectedOrder.value = order
|
||||
cancelShow.value = true
|
||||
}
|
||||
|
||||
async function closeService() {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
const res = await cancelAfterSale(selectedOrder.value.sn)
|
||||
if (res.data.success) {
|
||||
uni.showToast({ title: '取消成功!', duration: 2000, icon: 'none' })
|
||||
}
|
||||
orderList.value = []
|
||||
searchOrderList(current.value)
|
||||
hideLoadingIfNeeded()
|
||||
}
|
||||
|
||||
function afterDetails(order: any, _sku?: any) {
|
||||
uni.navigateTo({ url: './applyDetail?sn=' + order.sn })
|
||||
}
|
||||
|
||||
function fetchAfterSaleLogList() {
|
||||
getAfterSaleList(logParams).then((res) => {
|
||||
const afterSaleLogList = res.data.result.records
|
||||
afterSaleLogList.forEach((item: any) => {
|
||||
item.orderItems = [
|
||||
{
|
||||
name: "售后申请",
|
||||
image: item.goodsImage,
|
||||
skuId: item.skuId,
|
||||
name: item.goodsName,
|
||||
num: item.num,
|
||||
price: item.flowPrice,
|
||||
},
|
||||
{
|
||||
name: "申请中",
|
||||
},
|
||||
{
|
||||
name: "申请记录",
|
||||
},
|
||||
],
|
||||
current: 0, //当前表头索引
|
||||
tipsShow: false, //提示开关
|
||||
cancelShow: false, //取消显示开关
|
||||
selectedOrder: "", //选中的order
|
||||
orderList: [], //订单集合
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
sort: "createTime",
|
||||
flowPrice: 0,
|
||||
order: "desc",
|
||||
},
|
||||
]
|
||||
})
|
||||
orderList.value = orderList.value.concat(afterSaleLogList)
|
||||
status.value = afterSaleLogList.length < 10 ? 'nomore' : 'loading'
|
||||
})
|
||||
}
|
||||
|
||||
logParams: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
status: "loadmore",
|
||||
keywords: "", // 搜索订单sn
|
||||
};
|
||||
},
|
||||
onLoad(options) {
|
||||
this.orderList = [];
|
||||
this.params.pageNumber = 1;
|
||||
if (options.orderSn) this.params.keywords = options.orderSn;
|
||||
this.searchOrderList(this.current);
|
||||
},
|
||||
onPullDownRefresh() {
|
||||
this.change(this.current);
|
||||
},
|
||||
methods: {
|
||||
getGoodsName(sku) {
|
||||
return sku.goodsName || sku.name || "";
|
||||
},
|
||||
getGoodsImage(goods, order, index) {
|
||||
let image = goods.image || goods.goodsImage || goods.thumbnail;
|
||||
if (!image && order.groupImages) {
|
||||
const images = String(order.groupImages).split(",");
|
||||
image = images[index] || images[0];
|
||||
}
|
||||
return this.parseGoodsImageUrl(image);
|
||||
},
|
||||
/**
|
||||
* 点击搜索执行搜索
|
||||
*/
|
||||
submitSearchOrderList(current) {
|
||||
this.params.pageNumber = 1;
|
||||
this.logParams.pageNumber = 1;
|
||||
this.orderList = [];
|
||||
this.searchOrderList(current);
|
||||
},
|
||||
// 清空
|
||||
clear(current){
|
||||
this.params.pageNumber = 1;
|
||||
this.logParams.pageNumber = 1;
|
||||
this.params.keywords = ''
|
||||
this.orderList = [];
|
||||
this.searchOrderList(current);
|
||||
},
|
||||
/**
|
||||
* 切换tab页时,初始化数据
|
||||
*/
|
||||
change(e) {
|
||||
const index = typeof e === 'object' && e != null ? e.index : e;
|
||||
this.current = index;
|
||||
this.params = {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
};
|
||||
this.orderList = [];
|
||||
//如果是2 则读取售后申请记录列表
|
||||
this.searchOrderList(index);
|
||||
uni.stopPullDownRefresh();
|
||||
},
|
||||
function applyService(sn: string, order: any, sku: any) {
|
||||
storage.setAfterSaleData({ ...order, ...sku })
|
||||
uni.navigateTo({ url: `/pages/order/afterSales/afterSalesSelect?sn=${sn}` })
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索初始化
|
||||
* 根据当前tab传值的索引进行更改
|
||||
*/
|
||||
searchOrderList(index) {
|
||||
if (index == 0) {
|
||||
this.keywords ? (this.params.keywords = this.keywords) : "";
|
||||
this.getOrderList();
|
||||
} else {
|
||||
this.logParams = {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
};
|
||||
if (index === 1) {
|
||||
this.logParams.serviceStatus = "APPLY";
|
||||
}
|
||||
this.keywords ? (this.logParams.keywords = this.keywords) : "";
|
||||
this.orderList = [];
|
||||
this.getAfterSaleLogList();
|
||||
}
|
||||
},
|
||||
function onExpress(order: any, sku: any) {
|
||||
sku.storeName = order.storeName
|
||||
storage.setAfterSaleData({ ...order, ...sku })
|
||||
uni.navigateTo({ url: `./afterSalesDetailExpress?serviceSn=${order.sn}` })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订单列表
|
||||
*/
|
||||
getOrderList() {
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
mask: true,
|
||||
});
|
||||
getOrderList(this.params).then((res) => {
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
const orderList = res.data.result.records;
|
||||
if (orderList.length > 0) {
|
||||
this.orderList = this.orderList.concat(orderList);
|
||||
this.params.pageNumber += 1;
|
||||
}
|
||||
if (orderList.length < 10) {
|
||||
this.status = "nomore";
|
||||
} else {
|
||||
this.status = "loading";
|
||||
}
|
||||
});
|
||||
},
|
||||
function onDetail(goods: any, sku: any) {
|
||||
if (current.value == 0) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/product/goods?id=${sku.skuId}&goodsId=${sku.goodsId || sku.goodsId}`,
|
||||
})
|
||||
} else {
|
||||
uni.navigateTo({
|
||||
url: `/pages/product/goods?id=${goods.skuId}&goodsId=${goods.goodsId || goods.goodsId}`,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
close(order, sku) {
|
||||
console.log(order, sku);
|
||||
this.selectedOrder = order;
|
||||
this.cancelShow = true;
|
||||
},
|
||||
|
||||
async closeService() {
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
console.log(this.selectedOrder);
|
||||
let res = await cancelAfterSale(this.selectedOrder.sn);
|
||||
if (res.data.success) {
|
||||
uni.showToast({
|
||||
title: "取消成功!",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
this.orderList = [];
|
||||
this.searchOrderList(this.current);
|
||||
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
},
|
||||
|
||||
/**
|
||||
* 售后详情
|
||||
*/
|
||||
afterDetails(order) {
|
||||
uni.navigateTo({
|
||||
url: "./applyDetail?sn=" + order.sn,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 申请记录列表
|
||||
*/
|
||||
getAfterSaleLogList() {
|
||||
getAfterSaleList(this.logParams).then((res) => {
|
||||
let afterSaleLogList = res.data.result.records;
|
||||
|
||||
afterSaleLogList.forEach((item) => {
|
||||
item.orderItems = [
|
||||
{
|
||||
image: item.goodsImage,
|
||||
skuId: item.skuId,
|
||||
name: item.goodsName,
|
||||
num: item.num,
|
||||
price: item.flowPrice,
|
||||
},
|
||||
];
|
||||
});
|
||||
|
||||
this.orderList = this.orderList.concat(afterSaleLogList);
|
||||
|
||||
if (afterSaleLogList.length < 10) {
|
||||
this.status = "nomore";
|
||||
} else {
|
||||
this.status = "loading";
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 申请售后
|
||||
*/
|
||||
applyService(sn, order, sku) {
|
||||
let data = {
|
||||
...order,
|
||||
...sku,
|
||||
};
|
||||
storage.setAfterSaleData(data);
|
||||
uni.navigateTo({
|
||||
url: `/pages/order/afterSales/afterSalesSelect?sn=${sn}`,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 提交物流信息
|
||||
*/
|
||||
onExpress(order, sku) {
|
||||
sku.storeName = order.storeName;
|
||||
let data = {
|
||||
...order,
|
||||
...sku,
|
||||
};
|
||||
|
||||
storage.setAfterSaleData(data);
|
||||
uni.navigateTo({
|
||||
url: `./afterSalesDetailExpress?serviceSn=${order.sn}`,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 查看详情
|
||||
*/
|
||||
onDetail(goods, sku) {
|
||||
// 售后申请
|
||||
if (this.current == 0) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/product/goods?id=${sku.skuId}&goodsId=${
|
||||
sku.goodsId || sku.goodsId
|
||||
}`,
|
||||
});
|
||||
} else {
|
||||
uni.navigateTo({
|
||||
url: `/pages/product/goods?id=${goods.skuId}&goodsId=${
|
||||
goods.goodsId || goods.goodsId
|
||||
}`,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 底部加载数据
|
||||
*/
|
||||
renderDate() {
|
||||
if (this.current === 0) {
|
||||
this.params.pageNumber += 1;
|
||||
this.getOrderList();
|
||||
} else {
|
||||
this.logParams.pageNumber += 1;
|
||||
this.getAfterSaleLogList();
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
function renderDate() {
|
||||
if (current.value === 0) {
|
||||
params.pageNumber += 1
|
||||
fetchOrderList()
|
||||
} else {
|
||||
logParams.pageNumber += 1
|
||||
fetchAfterSaleLogList()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
<template>
|
||||
<view class="page-wrap">
|
||||
<scroll-view scroll-y class="page-scroll">
|
||||
<u-form :model="form" ref="uForm">
|
||||
<up-form
|
||||
:model="form"
|
||||
ref="uForm"
|
||||
label-position="left"
|
||||
label-width="180rpx"
|
||||
>
|
||||
<view class="after-sales-goods-detail-view">
|
||||
<view class="header">
|
||||
<view>
|
||||
@@ -58,7 +63,7 @@
|
||||
<u-icon name="arrow-right" color="#ccc" size="16"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
<u-form-item label="申请说明" label-width="150" :border-bottom="false" class="desc-item">
|
||||
<up-form-item label="申请说明" label-width="180rpx" :border-bottom="false" class="desc-item">
|
||||
<u-input
|
||||
v-model="form.problemDesc"
|
||||
type="textarea"
|
||||
@@ -67,54 +72,54 @@
|
||||
height="120"
|
||||
placeholder="请描述申请售后的说明"
|
||||
/>
|
||||
</u-form-item>
|
||||
</up-form-item>
|
||||
</view>
|
||||
|
||||
<!-- 退款方式 / 银行信息 -->
|
||||
<view class="opt-view form-block">
|
||||
<u-form-item label="退款方式" label-width="150" :border-bottom="true">
|
||||
<up-form-item label="退款方式" label-width="180rpx" :border-bottom="true">
|
||||
<view class="form-value">{{
|
||||
applyInfo.refundWay == 'ORIGINAL' ? '原路退回' : '账号退款'
|
||||
}}</view>
|
||||
</u-form-item>
|
||||
</up-form-item>
|
||||
<template v-if="
|
||||
applyInfo.accountType === 'BANK_TRANSFER' &&
|
||||
applyInfo.applyRefundPrice != 0
|
||||
">
|
||||
<u-form-item label="银行开户行" label-width="150" :border-bottom="true">
|
||||
<up-form-item label="银行开户行" label-width="180rpx" :border-bottom="true">
|
||||
<u-input
|
||||
v-model="form.bankDepositName"
|
||||
border="none"
|
||||
input-align="right"
|
||||
placeholder="请输入银行开户行"
|
||||
/>
|
||||
</u-form-item>
|
||||
<u-form-item label="银行开户名" label-width="150" :border-bottom="true">
|
||||
</up-form-item>
|
||||
<up-form-item label="银行开户名" label-width="180rpx" :border-bottom="true">
|
||||
<u-input
|
||||
v-model="form.bankAccountName"
|
||||
border="none"
|
||||
input-align="right"
|
||||
placeholder="请输入银行开户名"
|
||||
/>
|
||||
</u-form-item>
|
||||
<u-form-item label="银行账号" label-width="150" :border-bottom="true" class="bank-account-item">
|
||||
</up-form-item>
|
||||
<up-form-item label="银行账号" label-width="180rpx" :border-bottom="true" class="bank-account-item">
|
||||
<u-input
|
||||
v-model="form.bankAccountNumber"
|
||||
border="none"
|
||||
input-align="right"
|
||||
placeholder="请输入银行账号"
|
||||
/>
|
||||
</u-form-item>
|
||||
</up-form-item>
|
||||
</template>
|
||||
|
||||
<u-form-item
|
||||
<up-form-item
|
||||
v-if="form.serviceType !== 'RETURN_MONEY'"
|
||||
label="返回方式"
|
||||
label-width="150"
|
||||
label-width="180rpx"
|
||||
:border-bottom="false"
|
||||
>
|
||||
<view class="form-value">快递至第三方卖家</view>
|
||||
</u-form-item>
|
||||
</up-form-item>
|
||||
</view>
|
||||
|
||||
<!-- 上传凭证 -->
|
||||
@@ -133,7 +138,7 @@
|
||||
|
||||
<view class="opt-tip">提交服务单后,售后专员可能与您电话沟通,请保持手机畅通</view>
|
||||
</view>
|
||||
</u-form>
|
||||
</up-form>
|
||||
</scroll-view>
|
||||
|
||||
<view class="submit-view">
|
||||
@@ -142,7 +147,7 @@
|
||||
ripple
|
||||
shape="circle"
|
||||
v-if="applyInfo.refundWay"
|
||||
:custom-style="{ backgroundColor: $lightColor, width: '100%' }"
|
||||
:custom-style="{ backgroundColor: lightColor, width: '100%' }"
|
||||
@click="onSubmit"
|
||||
>提交申请</u-button>
|
||||
</view>
|
||||
@@ -158,246 +163,214 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getAfterSaleReason,
|
||||
applyReturn,
|
||||
getAfterSaleInfo,
|
||||
} from "@/api/after-sale";
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed, getCurrentInstance } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { unitPrice, parseGoodsImageUrl } from '@/utils/filters.js'
|
||||
import { getAfterSaleReason, applyReturn, getAfterSaleInfo } from '@/api/after-sale'
|
||||
import { handleUploadAfterRead } from '@/utils/uploadHelper.js'
|
||||
import storage from '@/utils/storage.js'
|
||||
|
||||
import city from "@/components/m-city/m-city";
|
||||
import { handleUploadAfterRead } from "@/utils/uploadHelper.js";
|
||||
import storage from "@/utils/storage.js";
|
||||
export default {
|
||||
component: {
|
||||
city,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
storage,
|
||||
list: [{ id: "", localName: "请选择", children: [] }],
|
||||
fileList: [],
|
||||
sn: "",
|
||||
sku: {},
|
||||
typeValue: 0,
|
||||
value: "",
|
||||
type: "textarea",
|
||||
border: true,
|
||||
//退款原因 弹出框
|
||||
reasonSelectShow: false,
|
||||
reasonList: [],
|
||||
applyInfo: {},
|
||||
form: {
|
||||
orderItemSn: "", // 订单sn
|
||||
skuId: "",
|
||||
reason: "", //退款原因
|
||||
problemDesc: "", //退款说明
|
||||
images: [], //图片凭证
|
||||
num: 1, //退货数量
|
||||
goodsId: "", //商品id
|
||||
accountType: "",
|
||||
applyRefundPrice: "",
|
||||
refundWay: "",
|
||||
serviceType: "", //申请类型
|
||||
},
|
||||
};
|
||||
},
|
||||
const store = useStore()
|
||||
const { proxy } = getCurrentInstance()!
|
||||
const $u = proxy!.$u
|
||||
|
||||
/**
|
||||
* 判断当前内容并生成数据
|
||||
*/
|
||||
onLoad(options) {
|
||||
let navTitle = "申请售后";
|
||||
this.form.serviceType = "RETURN_GOODS";
|
||||
if (options.value == 1) {
|
||||
navTitle = "申请退货";
|
||||
this.form.serviceType = "RETURN_GOODS";
|
||||
const lightColor = computed(() => store.getters.lightColor)
|
||||
|
||||
const fileList = ref<any[]>([])
|
||||
const sn = ref('')
|
||||
const sku = ref<any>({})
|
||||
const reasonSelectShow = ref(false)
|
||||
const reasonList = ref<any[]>([])
|
||||
const applyInfo = ref<any>({})
|
||||
const uToast = ref<any>(null)
|
||||
|
||||
const form = reactive({
|
||||
orderItemSn: '',
|
||||
skuId: '',
|
||||
reason: '',
|
||||
problemDesc: '',
|
||||
images: [] as string[],
|
||||
num: 1,
|
||||
goodsId: '',
|
||||
accountType: '',
|
||||
applyRefundPrice: '',
|
||||
refundWay: '',
|
||||
serviceType: 'RETURN_GOODS',
|
||||
bankDepositName: '',
|
||||
bankAccountName: '',
|
||||
bankAccountNumber: '',
|
||||
})
|
||||
|
||||
onLoad((options) => {
|
||||
let navTitle = '申请售后'
|
||||
form.serviceType = 'RETURN_GOODS'
|
||||
if (options?.value == '1') {
|
||||
navTitle = '申请退货'
|
||||
form.serviceType = 'RETURN_GOODS'
|
||||
}
|
||||
if (options?.value == '2') {
|
||||
navTitle = '申请换货'
|
||||
form.serviceType = 'EXCHANGE_GOODS'
|
||||
}
|
||||
if (options?.value == '3') {
|
||||
navTitle = '申请退款'
|
||||
form.serviceType = 'RETURN_MONEY'
|
||||
}
|
||||
uni.setNavigationBarTitle({ title: navTitle })
|
||||
sn.value = options?.sn || ''
|
||||
sku.value = storage.getAfterSaleData()
|
||||
form.orderItemSn = options?.sn || ''
|
||||
form.skuId = sku.value.skuId
|
||||
form.num = sku.value.num
|
||||
form.goodsId = sku.value.goodsId
|
||||
fetchReasonActions(form.serviceType)
|
||||
init(options?.sn || '')
|
||||
})
|
||||
|
||||
function hideLoadingIfNeeded() {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
}
|
||||
|
||||
function getGoodsName(item: any) {
|
||||
return item.goodsName || item.name || ''
|
||||
}
|
||||
|
||||
function getGoodsImage(item: any) {
|
||||
const image = item.image || item.goodsImage || item.thumbnail
|
||||
return parseGoodsImageUrl(image)
|
||||
}
|
||||
|
||||
function gotoGoodsDetail(goodsId: string) {
|
||||
if (!goodsId) return
|
||||
uni.navigateTo({
|
||||
url: `/pages/product/goods?id=${form.skuId}&goodsId=${goodsId}`,
|
||||
})
|
||||
}
|
||||
|
||||
async function fetchReasonActions(serviceType: string) {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
await getAfterSaleReason(serviceType).then((res) => {
|
||||
if (res.data.success) {
|
||||
reasonList.value = res.data.result.map((item: any) => ({
|
||||
value: item.id,
|
||||
label: item.reason,
|
||||
}))
|
||||
}
|
||||
if (options.value == 2) {
|
||||
navTitle = "申请换货";
|
||||
this.form.serviceType = "EXCHANGE_GOODS";
|
||||
}
|
||||
if (options.value == 3) {
|
||||
navTitle = "申请退款";
|
||||
this.form.serviceType = "RETURN_MONEY";
|
||||
}
|
||||
this.typeValue = options.value;
|
||||
uni.setNavigationBarTitle({
|
||||
title: navTitle, //此处写页面的title
|
||||
});
|
||||
this.sn = options.sn;
|
||||
this.sku = storage.getAfterSaleData();;
|
||||
})
|
||||
hideLoadingIfNeeded()
|
||||
}
|
||||
|
||||
this.form.orderItemSn = options.sn;
|
||||
this.form.skuId = this.sku.skuId;
|
||||
this.form.num = this.sku.num;
|
||||
this.form.goodsId = this.sku.goodsId;
|
||||
this.getReasonActions(this.form.serviceType);
|
||||
|
||||
this.init(options.sn);
|
||||
},
|
||||
methods: {
|
||||
getGoodsName(item) {
|
||||
return item.goodsName || item.name || "";
|
||||
},
|
||||
getGoodsImage(item) {
|
||||
const image = item.image || item.goodsImage || item.thumbnail;
|
||||
return this.parseGoodsImageUrl(image);
|
||||
},
|
||||
gotoGoodsDetail(goodsId) {
|
||||
if (!goodsId) return;
|
||||
uni.navigateTo({
|
||||
url: `/pages/product/goods?id=${this.form.skuId}&goodsId=${goodsId}`,
|
||||
});
|
||||
},
|
||||
/** 获取申请原因下拉框数据 */
|
||||
async getReasonActions(serviceType) {
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
await getAfterSaleReason(serviceType).then((res) => {
|
||||
if (res.data.success) {
|
||||
let action = [];
|
||||
res.data.result.forEach((item) => {
|
||||
action.push({
|
||||
value: item.id,
|
||||
label: item.reason,
|
||||
});
|
||||
});
|
||||
|
||||
this.reasonList = action;
|
||||
}
|
||||
});
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
},
|
||||
//打开地区选择器
|
||||
showCitySelect() {
|
||||
this.$refs.cityPicker.show();
|
||||
},
|
||||
|
||||
// 初始化数据
|
||||
init(sn) {
|
||||
getAfterSaleInfo(sn).then((response) => {
|
||||
if (response.data.code == 400) {
|
||||
uni.showToast({
|
||||
title: response.data.message,
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
} else {
|
||||
this.applyInfo = response.data.result;
|
||||
|
||||
this.form.accountType = response.data.result.accountType;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
openReasonPicker() {
|
||||
if (!this.reasonList.length) {
|
||||
uni.showToast({
|
||||
title: "暂无可选原因",
|
||||
icon: "none",
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.reasonSelectShow = true;
|
||||
},
|
||||
|
||||
//退款原因
|
||||
reasonSelectConfirm(val) {
|
||||
const selected = val?.value?.[0] || val?.[0];
|
||||
if (selected) {
|
||||
this.form.reason = selected.label || selected.text || "";
|
||||
}
|
||||
},
|
||||
|
||||
//修改申请数量
|
||||
valChange(e) {
|
||||
this.form.num = e.value;
|
||||
},
|
||||
onUploadAfterRead(event) {
|
||||
handleUploadAfterRead(event, this.fileList, (urls) => {
|
||||
this.form.images = urls;
|
||||
});
|
||||
},
|
||||
showToast(message, type = "error") {
|
||||
const text = message || (type === "success" ? "操作成功" : "操作失败");
|
||||
if (this.$refs.uToast) {
|
||||
this.$refs.uToast.show({ message: text, type });
|
||||
return;
|
||||
}
|
||||
function init(orderItemSn: string) {
|
||||
getAfterSaleInfo(orderItemSn).then((response) => {
|
||||
if (response.data.code == 400) {
|
||||
uni.showToast({
|
||||
title: text,
|
||||
icon: type === "success" ? "success" : "none",
|
||||
});
|
||||
},
|
||||
//提交申请
|
||||
onSubmit() {
|
||||
//提交申请前检测参数
|
||||
if (!this.handleCheckParams()) {
|
||||
return;
|
||||
}
|
||||
title: response.data.message,
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
} else {
|
||||
applyInfo.value = response.data.result
|
||||
form.accountType = response.data.result.accountType
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
this.form.accountType = this.applyInfo.accountType;
|
||||
this.form.refundWay = this.applyInfo.refundWay;
|
||||
this.form.applyRefundPrice = this.applyInfo.applyRefundPrice;
|
||||
function openReasonPicker() {
|
||||
if (!reasonList.value.length) {
|
||||
uni.showToast({ title: '暂无可选原因', icon: 'none' })
|
||||
return
|
||||
}
|
||||
reasonSelectShow.value = true
|
||||
}
|
||||
|
||||
applyReturn(this.sn, this.form).then((resp) => {
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
if (resp.data.success) {
|
||||
this.showToast("提交成功", "success");
|
||||
uni.redirectTo({
|
||||
url: "/pages/order/afterSales/applySuccess",
|
||||
});
|
||||
} else {
|
||||
this.showToast(resp.data.message || "提交失败", "error");
|
||||
}
|
||||
});
|
||||
},
|
||||
//检测提交参数
|
||||
handleCheckParams() {
|
||||
if (this.$u.test.isEmpty(this.form.reason)) {
|
||||
this.showToast("请选择退款原因");
|
||||
return false;
|
||||
}
|
||||
if (this.$u.test.isEmpty(this.form.problemDesc)) {
|
||||
this.showToast("请输入退款说明");
|
||||
return false;
|
||||
}
|
||||
function reasonSelectConfirm(val: any) {
|
||||
const selected = val?.value?.[0] || val?.[0]
|
||||
if (selected) {
|
||||
form.reason = selected.label || selected.text || ''
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
this.applyInfo.accountType === "BANK_TRANSFER" &&
|
||||
this.applyInfo.applyRefundPrice != 0
|
||||
) {
|
||||
if (this.$u.test.isEmpty(this.form.bankDepositName)) {
|
||||
this.showToast("请输入银行开户行");
|
||||
return false;
|
||||
}
|
||||
if (this.$u.test.isEmpty(this.form.bankAccountName)) {
|
||||
this.showToast("请输入银行开户名");
|
||||
return false;
|
||||
}
|
||||
if (this.$u.test.isEmpty(this.form.bankAccountNumber)) {
|
||||
this.showToast("请输入银行账号");
|
||||
return false;
|
||||
}
|
||||
if (this.$u.test.chinese(this.form.bankAccountName) === false) {
|
||||
this.showToast("银行开户名需为中文");
|
||||
return false;
|
||||
}
|
||||
if (this.$u.test.chinese(this.form.bankDepositName) === false) {
|
||||
this.showToast("银行开户行需为中文");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
function valChange(e: { value: number }) {
|
||||
form.num = e.value
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
},
|
||||
};
|
||||
function onUploadAfterRead(event: any) {
|
||||
handleUploadAfterRead(event, fileList.value, (urls) => {
|
||||
form.images = urls
|
||||
})
|
||||
}
|
||||
|
||||
function showToast(message: string, type = 'error') {
|
||||
const text = message || (type === 'success' ? '操作成功' : '操作失败')
|
||||
if (uToast.value) {
|
||||
uToast.value.show({ message: text, type })
|
||||
return
|
||||
}
|
||||
uni.showToast({
|
||||
title: text,
|
||||
icon: type === 'success' ? 'success' : 'none',
|
||||
})
|
||||
}
|
||||
|
||||
function onSubmit() {
|
||||
if (!validateFormParams()) return
|
||||
|
||||
uni.showLoading({ title: '加载中' })
|
||||
form.accountType = applyInfo.value.accountType
|
||||
form.refundWay = applyInfo.value.refundWay
|
||||
form.applyRefundPrice = applyInfo.value.applyRefundPrice
|
||||
|
||||
applyReturn(sn.value, form).then((resp) => {
|
||||
hideLoadingIfNeeded()
|
||||
if (resp.data.success) {
|
||||
showToast('提交成功', 'success')
|
||||
uni.redirectTo({ url: '/pages/order/afterSales/applySuccess' })
|
||||
} else {
|
||||
showToast(resp.data.message || '提交失败', 'error')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function validateFormParams() {
|
||||
if ($u.test.isEmpty(form.reason)) {
|
||||
showToast('请选择退款原因')
|
||||
return false
|
||||
}
|
||||
if ($u.test.isEmpty(form.problemDesc)) {
|
||||
showToast('请输入退款说明')
|
||||
return false
|
||||
}
|
||||
|
||||
if (
|
||||
applyInfo.value.accountType === 'BANK_TRANSFER' &&
|
||||
applyInfo.value.applyRefundPrice != 0
|
||||
) {
|
||||
if ($u.test.isEmpty(form.bankDepositName)) {
|
||||
showToast('请输入银行开户行')
|
||||
return false
|
||||
}
|
||||
if ($u.test.isEmpty(form.bankAccountName)) {
|
||||
showToast('请输入银行开户名')
|
||||
return false
|
||||
}
|
||||
if ($u.test.isEmpty(form.bankAccountNumber)) {
|
||||
showToast('请输入银行账号')
|
||||
return false
|
||||
}
|
||||
if ($u.test.chinese(form.bankAccountName) === false) {
|
||||
showToast('银行开户名需为中文')
|
||||
return false
|
||||
}
|
||||
if ($u.test.chinese(form.bankDepositName) === false) {
|
||||
showToast('银行开户行需为中文')
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
<template>
|
||||
<view class="mp-iphonex-bottom content">
|
||||
<u-form :model="form" ref="uForm">
|
||||
<up-form
|
||||
:model="form"
|
||||
ref="uForm"
|
||||
label-position="left"
|
||||
label-width="180rpx"
|
||||
>
|
||||
<view class="after-sales-goods-detail-view">
|
||||
<view class="header">
|
||||
<view>
|
||||
@@ -29,32 +34,32 @@
|
||||
<!-- 上传凭证 -->
|
||||
<view class="opt-view">
|
||||
<view class="img-title" style="font-size: 30rpx">填写物流信息</view>
|
||||
<u-form-item label="返回方式" :label-width="150">
|
||||
<up-form-item label="返回方式" label-width="180rpx">
|
||||
<div style="width: 100%; text-align: right;">快递至第三方卖家</div>
|
||||
</u-form-item>
|
||||
<u-form-item label="快递公司" :label-width="150">
|
||||
</up-form-item>
|
||||
<up-form-item label="快递公司" label-width="180rpx">
|
||||
<div style="width: 100%; text-align: right;" @click="companySelectShow = true">
|
||||
{{ form.courierCompany || '请选择快递公司' }}
|
||||
</div>
|
||||
</u-form-item>
|
||||
<u-form-item label="快递单号" :label-width="150">
|
||||
</up-form-item>
|
||||
<up-form-item label="快递单号" label-width="180rpx">
|
||||
<u-input input-align="right" v-model="form.logisticsNo" placeholder="请输入快递单号"/>
|
||||
</u-form-item>
|
||||
<u-form-item label="发货时间" :label-width="150">
|
||||
</up-form-item>
|
||||
<up-form-item label="发货时间" label-width="180rpx">
|
||||
<div style="width: 100%; text-align: right;" @click="timeshow = true">{{
|
||||
form.mDeliverTime || '请选择发货时间'
|
||||
}}
|
||||
</div>
|
||||
</u-form-item>
|
||||
</up-form-item>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<view class="submit-view">
|
||||
<u-button ripple :customStyle="{'background':$lightColor,'color':'#fff' }" shape="circle" @click="onSubmit">
|
||||
<u-button ripple :customStyle="{ background: lightColor, color: '#fff' }" shape="circle" @click="onSubmit">
|
||||
提交申请
|
||||
</u-button>
|
||||
</view>
|
||||
</u-form>
|
||||
</up-form>
|
||||
<u-select mode="single-column" :list="companyList" v-model:show="companySelectShow"
|
||||
@confirm="companySelectConfirm"></u-select>
|
||||
<u-calendar v-model:show="timeshow" :mode="'date'" @change="onTimeChange"></u-calendar>
|
||||
@@ -62,124 +67,98 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {getLogistics} from "@/api/address.js";
|
||||
import {fillShipInfo} from "@/api/after-sale.js";
|
||||
import storage from "@/utils/storage";
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { unitPrice } from '@/utils/filters.js'
|
||||
import { getLogistics } from '@/api/address.js'
|
||||
import { fillShipInfo } from '@/api/after-sale.js'
|
||||
import storage from '@/utils/storage'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
//快递公司 弹出框
|
||||
companySelectShow: false,
|
||||
companyList: [], //快递公司集合
|
||||
timeshow: false, //发货时间
|
||||
form: {
|
||||
courierCompany: "", //快递公司
|
||||
logisticsId: "", //快递公司ID
|
||||
logisticsNo: "", //快递单号
|
||||
mDeliverTime: "", //发货时间
|
||||
},
|
||||
serviceDetail: {}, //服务详情
|
||||
sku: {}, //sku信息
|
||||
};
|
||||
},
|
||||
onLoad(options) {
|
||||
const store = useStore()
|
||||
const lightColor = computed(() => store.getters.lightColor)
|
||||
|
||||
this.sku = storage.getAfterSaleData();
|
||||
let navTitle = "服务单详情";
|
||||
uni.setNavigationBarTitle({
|
||||
title: navTitle, //此处写页面的title
|
||||
});
|
||||
this.serviceDetail.sn = options.serviceSn;
|
||||
this.Logistics();
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 确认快递公司
|
||||
*/
|
||||
companySelectConfirm(e) {
|
||||
this.form.logisticsId = e[0].value;
|
||||
this.form.courierCompany = e[0].label;
|
||||
},
|
||||
const companySelectShow = ref(false)
|
||||
const companyList = ref<any[]>([])
|
||||
const timeshow = ref(false)
|
||||
const form = reactive({
|
||||
courierCompany: '',
|
||||
logisticsId: '',
|
||||
logisticsNo: '',
|
||||
mDeliverTime: '',
|
||||
})
|
||||
const serviceDetail = reactive<{ sn: string }>({ sn: '' })
|
||||
const sku = ref<any>({})
|
||||
const uToast = ref<any>(null)
|
||||
|
||||
/**
|
||||
* 获取快递公司
|
||||
*/
|
||||
Logistics() {
|
||||
getLogistics().then((res) => {
|
||||
if (res.data.success) {
|
||||
res.data.result.forEach((item, index) => {
|
||||
this.companyList[index] = {
|
||||
value: item.id,
|
||||
label: item.name,
|
||||
};
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
onLoad((options) => {
|
||||
sku.value = storage.getAfterSaleData()
|
||||
uni.setNavigationBarTitle({ title: '服务单详情' })
|
||||
serviceDetail.sn = options?.serviceSn || ''
|
||||
fetchLogisticsList()
|
||||
})
|
||||
|
||||
/**
|
||||
* 更改时间
|
||||
*/
|
||||
onTimeChange(e) {
|
||||
this.form.mDeliverTime = e.result;
|
||||
},
|
||||
function hideLoadingIfNeeded() {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击提交
|
||||
*/
|
||||
onSubmit() {
|
||||
delete this.form.courierCompany;
|
||||
function companySelectConfirm(e: any[]) {
|
||||
form.logisticsId = e[0].value
|
||||
form.courierCompany = e[0].label
|
||||
}
|
||||
|
||||
if (this.form.logisticsId == "") {
|
||||
this.$refs.uToast.show({
|
||||
title: "请选择快递公司",
|
||||
type: "error",
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (this.form.logisticsNo == "") {
|
||||
this.$refs.uToast.show({
|
||||
title: "请填写快递单号",
|
||||
type: "error",
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (this.form.mDeliverTime == "") {
|
||||
this.$refs.uToast.show({
|
||||
title: "请选择发货时间",
|
||||
type: "error",
|
||||
});
|
||||
return;
|
||||
}
|
||||
function fetchLogisticsList() {
|
||||
getLogistics().then((res) => {
|
||||
if (res.data.success) {
|
||||
companyList.value = res.data.result.map((item: any) => ({
|
||||
value: item.id,
|
||||
label: item.name,
|
||||
}))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
mask: true,
|
||||
});
|
||||
fillShipInfo(this.serviceDetail.sn, this.form).then((res) => {
|
||||
if (this.$store.state.isShowToast) {
|
||||
uni.hideLoading()
|
||||
}
|
||||
;
|
||||
if (res.statusCode === 200) {
|
||||
this.$refs.uToast.show({
|
||||
title: "提交成功",
|
||||
type: "success",
|
||||
back: true,
|
||||
url: "/pages/order/afterSales/afterSales",
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
gotoGoodsDetail(sku) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/product/goods?id=${sku.skuId}&goodsId=${sku.goodsId}`,
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
function onTimeChange(e: { result: string }) {
|
||||
form.mDeliverTime = e.result
|
||||
}
|
||||
|
||||
function onSubmit() {
|
||||
const submitForm = { ...form }
|
||||
delete submitForm.courierCompany
|
||||
|
||||
if (form.logisticsId == '') {
|
||||
uToast.value?.show({ title: '请选择快递公司', type: 'error' })
|
||||
return
|
||||
}
|
||||
if (form.logisticsNo == '') {
|
||||
uToast.value?.show({ title: '请填写快递单号', type: 'error' })
|
||||
return
|
||||
}
|
||||
if (form.mDeliverTime == '') {
|
||||
uToast.value?.show({ title: '请选择发货时间', type: 'error' })
|
||||
return
|
||||
}
|
||||
|
||||
uni.showLoading({ title: '加载中', mask: true })
|
||||
fillShipInfo(serviceDetail.sn, submitForm).then((res) => {
|
||||
hideLoadingIfNeeded()
|
||||
if (res.statusCode === 200) {
|
||||
uToast.value?.show({
|
||||
title: '提交成功',
|
||||
type: 'success',
|
||||
back: true,
|
||||
url: '/pages/order/afterSales/afterSales',
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function gotoGoodsDetail(item: any) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/product/goods?id=${item.skuId}&goodsId=${item.goodsId}`,
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -57,59 +57,51 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getAfterSaleInfo } from "@/api/after-sale";
|
||||
import storage from "@/utils/storage";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
sn: "",
|
||||
sku: {}, //sku
|
||||
applyInfo:""
|
||||
};
|
||||
},
|
||||
onLoad(options) {
|
||||
this.sn = options.sn;
|
||||
this.sku = storage.getAfterSaleData();
|
||||
// 查看当前商品是否支持退款退货
|
||||
this.init()
|
||||
},
|
||||
methods: {
|
||||
getGoodsName(item) {
|
||||
return item.goodsName || item.name || "";
|
||||
},
|
||||
getGoodsImage(item) {
|
||||
const image = item.image || item.goodsImage || item.thumbnail;
|
||||
return this.parseGoodsImageUrl(image);
|
||||
},
|
||||
// 初始化数据
|
||||
init() {
|
||||
getAfterSaleInfo(this.sn).then((response) => {
|
||||
if (response.data.success) {
|
||||
this.applyInfo = response.data.result;
|
||||
}
|
||||
});
|
||||
},
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { unitPrice, parseGoodsImageUrl } from '@/utils/filters.js'
|
||||
import { getAfterSaleInfo } from '@/api/after-sale'
|
||||
import storage from '@/utils/storage'
|
||||
|
||||
/**
|
||||
* 选择退货流程
|
||||
*/
|
||||
onSelect(value) {
|
||||
uni.redirectTo({
|
||||
url: `./afterSalesDetail?sn=${this.sn}&value=${value}`,
|
||||
});
|
||||
},
|
||||
const sn = ref('')
|
||||
const sku = ref<any>({})
|
||||
const applyInfo = ref<any>({})
|
||||
|
||||
/**
|
||||
* 跳转到商品信息
|
||||
*/
|
||||
navigateToGoodsDetail(id) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/product/goods?id=${id}&goodsId=${goodsId}`,
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
onLoad((options) => {
|
||||
sn.value = options?.sn || ''
|
||||
sku.value = storage.getAfterSaleData()
|
||||
init()
|
||||
})
|
||||
|
||||
function getGoodsName(item: any) {
|
||||
return item.goodsName || item.name || ''
|
||||
}
|
||||
|
||||
function getGoodsImage(item: any) {
|
||||
const image = item.image || item.goodsImage || item.thumbnail
|
||||
return parseGoodsImageUrl(image)
|
||||
}
|
||||
|
||||
function init() {
|
||||
getAfterSaleInfo(sn.value).then((response) => {
|
||||
if (response.data.success) {
|
||||
applyInfo.value = response.data.result
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function onSelect(value: number) {
|
||||
uni.redirectTo({
|
||||
url: `./afterSalesDetail?sn=${sn.value}&value=${value}`,
|
||||
})
|
||||
}
|
||||
|
||||
function navigateToGoodsDetail(skuId: string) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/product/goods?id=${skuId}&goodsId=${sku.value.goodsId}`,
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
</view>
|
||||
<view class="goods-info">
|
||||
<view class="info-box">
|
||||
<view class="goods-item-view" @click="navgiateToGoodsDetail(serviceDetail)">
|
||||
<view class="goods-item-view" @click="navigateToGoodsDetail(serviceDetail)">
|
||||
<view class="goods-img">
|
||||
<u-image
|
||||
border-radius="6"
|
||||
@@ -184,198 +184,184 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import {
|
||||
unitPrice,
|
||||
parseGoodsImageUrl,
|
||||
serviceStatusList,
|
||||
secrecyMobile,
|
||||
unixToDate,
|
||||
} from '@/utils/filters.js'
|
||||
import {
|
||||
getServiceDetail,
|
||||
getStoreAfterSaleAddress,
|
||||
getAfterSaleLog,
|
||||
getAfterSaleReason,
|
||||
} from "@/api/after-sale.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
reason: "", //申请原因
|
||||
serviceTypeList: {
|
||||
// 售后类型
|
||||
CANCEL: "取消",
|
||||
RETURN_GOODS: "退货",
|
||||
EXCHANGE_GOODS: "换货",
|
||||
RETURN_MONEY: "退款",
|
||||
},
|
||||
serviceDetail: {}, // 售后详情
|
||||
logs: [], //日志
|
||||
goodsList: [], //商品列表
|
||||
storeAfterSaleAddress: {}, //售后地址
|
||||
refundShow: false, //退款开关
|
||||
accountShow: false, //账户显示
|
||||
bankShow: false, //银行显示
|
||||
sn: "", //订单sn
|
||||
};
|
||||
},
|
||||
onLoad(options) {
|
||||
uni.setNavigationBarTitle({
|
||||
title: "服务单详情",
|
||||
});
|
||||
this.sn = options.sn;
|
||||
this.loadDetail();
|
||||
this.getAddress();
|
||||
this.getLog(options.sn);
|
||||
},
|
||||
methods: {
|
||||
statusFilter(val) {
|
||||
switch (val) {
|
||||
case "APPLY":
|
||||
return "售后服务申请成功,等待商家审核";
|
||||
case "PASS":
|
||||
return "售后服务申请审核通过";
|
||||
case "REFUSE":
|
||||
return "售后服务申请已被商家拒绝,如有疑问请及时联系商家";
|
||||
case "FULL_COURIER":
|
||||
return "申请售后的商品已经寄出,等待商家收货";
|
||||
case "STOCK_IN":
|
||||
return "商家已将售后商品入库";
|
||||
case "WAIT_FOR_MANUAL":
|
||||
return "等待平台进行人工退款";
|
||||
case "REFUNDING":
|
||||
return "商家退款中,请您耐心等待";
|
||||
case "COMPLETED":
|
||||
return "售后服务已完成,感谢您的支持";
|
||||
case "ERROR_EXCEPTION":
|
||||
return "系统生成新订单异常,等待商家手动创建新订单";
|
||||
case "CLOSED":
|
||||
return "售后服务已关闭";
|
||||
case "WAIT_REFUND":
|
||||
return "等待平台进行退款";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
},
|
||||
refundWayFilter(val) {
|
||||
switch (val) {
|
||||
case "OFFLINE":
|
||||
return "账户退款";
|
||||
case "ORIGINAL":
|
||||
return "原路退回";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
},
|
||||
accountTypeFilter(val) {
|
||||
switch (val) {
|
||||
case "WEIXINPAY":
|
||||
return "微信";
|
||||
case "ALIPAY":
|
||||
return "支付宝";
|
||||
case "BANK_TRANSFER":
|
||||
return "银行卡";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 点击图片放大或保存
|
||||
*/
|
||||
preview(urls, index) {
|
||||
uni.previewImage({
|
||||
current: index,
|
||||
urls: urls,
|
||||
longPressActions: {
|
||||
itemList: ["保存图片"],
|
||||
success: function (data) {},
|
||||
fail: function (err) {},
|
||||
},
|
||||
});
|
||||
},
|
||||
} from '@/api/after-sale.js'
|
||||
|
||||
/**
|
||||
* 获取地址信息
|
||||
*/
|
||||
getAddress() {
|
||||
getStoreAfterSaleAddress(this.sn).then((res) => {
|
||||
if (res.data.success) {
|
||||
this.storeAfterSaleAddress = res.data.result;
|
||||
}
|
||||
});
|
||||
const store = useStore()
|
||||
|
||||
const reason = ref('')
|
||||
const serviceTypeList: Record<string, string> = {
|
||||
CANCEL: '取消',
|
||||
RETURN_GOODS: '退货',
|
||||
EXCHANGE_GOODS: '换货',
|
||||
RETURN_MONEY: '退款',
|
||||
}
|
||||
const serviceDetail = ref<any>(null)
|
||||
const logs = ref<any[]>([])
|
||||
const storeAfterSaleAddress = ref<any>({})
|
||||
const refundShow = ref(false)
|
||||
const accountShow = ref(false)
|
||||
const bankShow = ref(false)
|
||||
const sn = ref('')
|
||||
|
||||
onLoad((options) => {
|
||||
uni.setNavigationBarTitle({ title: '服务单详情' })
|
||||
sn.value = options?.sn || ''
|
||||
loadDetail()
|
||||
fetchAddress()
|
||||
fetchLog(sn.value)
|
||||
})
|
||||
|
||||
function hideLoadingIfNeeded() {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
}
|
||||
|
||||
function statusFilter(val: string) {
|
||||
switch (val) {
|
||||
case 'APPLY':
|
||||
return '售后服务申请成功,等待商家审核'
|
||||
case 'PASS':
|
||||
return '售后服务申请审核通过'
|
||||
case 'REFUSE':
|
||||
return '售后服务申请已被商家拒绝,如有疑问请及时联系商家'
|
||||
case 'FULL_COURIER':
|
||||
return '申请售后的商品已经寄出,等待商家收货'
|
||||
case 'STOCK_IN':
|
||||
return '商家已将售后商品入库'
|
||||
case 'WAIT_FOR_MANUAL':
|
||||
return '等待平台进行人工退款'
|
||||
case 'REFUNDING':
|
||||
return '商家退款中,请您耐心等待'
|
||||
case 'COMPLETED':
|
||||
return '售后服务已完成,感谢您的支持'
|
||||
case 'ERROR_EXCEPTION':
|
||||
return '系统生成新订单异常,等待商家手动创建新订单'
|
||||
case 'CLOSED':
|
||||
return '售后服务已关闭'
|
||||
case 'WAIT_REFUND':
|
||||
return '等待平台进行退款'
|
||||
default:
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
function refundWayFilter(val: string) {
|
||||
switch (val) {
|
||||
case 'OFFLINE':
|
||||
return '账户退款'
|
||||
case 'ORIGINAL':
|
||||
return '原路退回'
|
||||
default:
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
function accountTypeFilter(val: string) {
|
||||
switch (val) {
|
||||
case 'WEIXINPAY':
|
||||
return '微信'
|
||||
case 'ALIPAY':
|
||||
return '支付宝'
|
||||
case 'BANK_TRANSFER':
|
||||
return '银行卡'
|
||||
default:
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
function preview(urls: string[], index: number) {
|
||||
uni.previewImage({
|
||||
current: index,
|
||||
urls,
|
||||
longPressActions: {
|
||||
itemList: ['保存图片'],
|
||||
success: () => {},
|
||||
fail: () => {},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取日志
|
||||
*/
|
||||
getLog(sn) {
|
||||
getAfterSaleLog(sn).then((res) => {
|
||||
this.logs = res.data.result;
|
||||
});
|
||||
},
|
||||
function fetchAddress() {
|
||||
getStoreAfterSaleAddress(sn.value).then((res) => {
|
||||
if (res.data.success) {
|
||||
storeAfterSaleAddress.value = res.data.result
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取申请原因
|
||||
*/
|
||||
getReasonList(serviceType) {
|
||||
getAfterSaleReason(serviceType).then((res) => {
|
||||
if (res.data.success) {
|
||||
// 1357583466371219456
|
||||
this.reason = this.serviceDetail.reason;
|
||||
}
|
||||
});
|
||||
},
|
||||
function fetchLog(serviceSn: string) {
|
||||
getAfterSaleLog(serviceSn).then((res) => {
|
||||
logs.value = res.data.result
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化详情
|
||||
*/
|
||||
loadDetail() {
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
getServiceDetail(this.sn).then((res) => {
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
this.serviceDetail = res.data.result;
|
||||
if (
|
||||
this.serviceDetail.serviceType == "RETURN_GOODS" ||
|
||||
this.serviceDetail.serviceType === "RETURN_MONEY"
|
||||
) {
|
||||
this.refundShow = true;
|
||||
}
|
||||
function fetchReasonList(serviceType: string) {
|
||||
getAfterSaleReason(serviceType).then((res) => {
|
||||
if (res.data.success) {
|
||||
reason.value = serviceDetail.value.reason
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
this.accountShow =
|
||||
(this.serviceDetail.serviceType === "RETURN_GOODS" ||
|
||||
this.serviceDetail.serviceType === "ORDER_CANCEL") &&
|
||||
this.serviceDetail.refundWay === "OFFLINE";
|
||||
function loadDetail() {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
getServiceDetail(sn.value).then((res) => {
|
||||
hideLoadingIfNeeded()
|
||||
serviceDetail.value = res.data.result
|
||||
if (
|
||||
serviceDetail.value.serviceType == 'RETURN_GOODS' ||
|
||||
serviceDetail.value.serviceType === 'RETURN_MONEY'
|
||||
) {
|
||||
refundShow.value = true
|
||||
}
|
||||
|
||||
this.bankShow =
|
||||
this.serviceDetail.accountType === "BANK_TRANSFER" &&
|
||||
this.serviceDetail.refundWay === "OFFLINE" &&
|
||||
((this.serviceDetail.serviceType === "RETURN_GOODS") |
|
||||
(this.serviceDetail.serviceType === "ORDER_CANCEL") ||
|
||||
this.serviceDetail.serviceType === "RETURN_MONEY");
|
||||
accountShow.value =
|
||||
(serviceDetail.value.serviceType === 'RETURN_GOODS' ||
|
||||
serviceDetail.value.serviceType === 'ORDER_CANCEL') &&
|
||||
serviceDetail.value.refundWay === 'OFFLINE'
|
||||
|
||||
this.getReasonList(this.serviceDetail.serviceType);
|
||||
});
|
||||
},
|
||||
bankShow.value =
|
||||
serviceDetail.value.accountType === 'BANK_TRANSFER' &&
|
||||
serviceDetail.value.refundWay === 'OFFLINE' &&
|
||||
((serviceDetail.value.serviceType === 'RETURN_GOODS') |
|
||||
(serviceDetail.value.serviceType === 'ORDER_CANCEL') ||
|
||||
serviceDetail.value.serviceType === 'RETURN_MONEY')
|
||||
|
||||
/**
|
||||
* 访问商品详情
|
||||
*/
|
||||
navgiateToGoodsDetail(item) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/product/goods?id=${item.id}&goodsId=${item.goodsId}`,
|
||||
});
|
||||
},
|
||||
fetchReasonList(serviceDetail.value.serviceType)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 进度
|
||||
*/
|
||||
onProgress() {
|
||||
uni.navigateTo({
|
||||
url: `./applyProgress?sn=${
|
||||
this.serviceDetail.sn
|
||||
}&createTime=${encodeURIComponent(this.serviceDetail.createTime)}
|
||||
&logs=${encodeURIComponent(JSON.stringify(this.logs))}&serviceStatus=${
|
||||
this.serviceDetail.serviceStatus
|
||||
}`,
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
function navigateToGoodsDetail(item: any) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/product/goods?id=${item.id}&goodsId=${item.goodsId}`,
|
||||
})
|
||||
}
|
||||
|
||||
function onProgress() {
|
||||
uni.navigateTo({
|
||||
url: `./applyProgress?sn=${
|
||||
serviceDetail.value.sn
|
||||
}&createTime=${encodeURIComponent(serviceDetail.value.createTime)}
|
||||
&logs=${encodeURIComponent(JSON.stringify(logs.value))}&serviceStatus=${
|
||||
serviceDetail.value.serviceStatus
|
||||
}`,
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -35,54 +35,50 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
sn: "", //sn
|
||||
createTime: "", //创建时间
|
||||
logList: [], //日志集合
|
||||
serviceStatus: "", //订单状态
|
||||
};
|
||||
},
|
||||
onLoad(options) {
|
||||
this.sn = options.sn;
|
||||
this.createTime = decodeURIComponent(options.createTime);
|
||||
this.serviceStatus = this.statusFilter(options.serviceStatus);
|
||||
this.logList = JSON.parse(decodeURIComponent(options.logs));
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
|
||||
},
|
||||
methods: {
|
||||
statusFilter(val) {
|
||||
switch (val) {
|
||||
case "APPLY":
|
||||
return "售后服务申请成功,等待商家审核";
|
||||
case "PASS":
|
||||
return "售后服务申请审核通过";
|
||||
case "REFUSE":
|
||||
return "售后服务申请已被商家拒绝,如有疑问请及时联系商家";
|
||||
case "FULL_COURIER":
|
||||
return "申请售后的商品已经寄出,等待商家收货";
|
||||
case "STOCK_IN":
|
||||
return "商家已将售后商品入库";
|
||||
case "WAIT_FOR_MANUAL":
|
||||
return "等待平台进行人工退款";
|
||||
case "REFUNDING":
|
||||
return "商家退款中,请您耐心等待";
|
||||
case "COMPLETED":
|
||||
return "售后服务已完成,感谢您的支持";
|
||||
case "ERROR_EXCEPTION":
|
||||
return "系统生成新订单异常,等待商家手动创建新订单";
|
||||
case "CLOSED":
|
||||
return "售后服务已关闭";
|
||||
case "WAIT_REFUND":
|
||||
return "等待平台进行退款";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
const sn = ref('')
|
||||
const createTime = ref('')
|
||||
const logList = ref<any[]>([])
|
||||
const serviceStatus = ref('')
|
||||
|
||||
function statusFilter(val: string) {
|
||||
switch (val) {
|
||||
case 'APPLY':
|
||||
return '售后服务申请成功,等待商家审核'
|
||||
case 'PASS':
|
||||
return '售后服务申请审核通过'
|
||||
case 'REFUSE':
|
||||
return '售后服务申请已被商家拒绝,如有疑问请及时联系商家'
|
||||
case 'FULL_COURIER':
|
||||
return '申请售后的商品已经寄出,等待商家收货'
|
||||
case 'STOCK_IN':
|
||||
return '商家已将售后商品入库'
|
||||
case 'WAIT_FOR_MANUAL':
|
||||
return '等待平台进行人工退款'
|
||||
case 'REFUNDING':
|
||||
return '商家退款中,请您耐心等待'
|
||||
case 'COMPLETED':
|
||||
return '售后服务已完成,感谢您的支持'
|
||||
case 'ERROR_EXCEPTION':
|
||||
return '系统生成新订单异常,等待商家手动创建新订单'
|
||||
case 'CLOSED':
|
||||
return '售后服务已关闭'
|
||||
case 'WAIT_REFUND':
|
||||
return '等待平台进行退款'
|
||||
default:
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
onLoad((options) => {
|
||||
sn.value = options.sn || ''
|
||||
createTime.value = decodeURIComponent(options.createTime || '')
|
||||
serviceStatus.value = statusFilter(options.serviceStatus || '')
|
||||
logList.value = JSON.parse(decodeURIComponent(options.logs || '[]'))
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -21,31 +21,18 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 跳转到售后服务
|
||||
*/
|
||||
navigateToAfterSales() {
|
||||
uni.redirectTo({
|
||||
url: "/pages/order/afterSales/afterSales",
|
||||
});
|
||||
},
|
||||
<script setup lang="ts">
|
||||
function navigateToAfterSales() {
|
||||
uni.redirectTo({
|
||||
url: '/pages/order/afterSales/afterSales',
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转到首页
|
||||
*/
|
||||
navigateToHome() {
|
||||
uni.switchTab({
|
||||
url: "/pages/tabbar/home/index",
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
function navigateToHome() {
|
||||
uni.switchTab({
|
||||
url: '/pages/tabbar/home/index',
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -57,137 +57,112 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import storage from "@/utils/storage.js";
|
||||
import { getOrderDetail } from "@/api/order.js";
|
||||
import { getComplainReason, addComplain } from "@/api/after-sale.js";
|
||||
import { handleUploadAfterRead } from "@/utils/uploadHelper.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
storage,
|
||||
uploadFileList: [],
|
||||
orderStatusMap: {
|
||||
//订单状态列表
|
||||
UNDELIVERED: "待发货",
|
||||
PARTS_DELIVERED: "部分发货",
|
||||
UNPAID: "未付款",
|
||||
PAID: "已付款",
|
||||
DELIVERED: "已发货",
|
||||
CANCELLED: "已取消",
|
||||
COMPLETE: "已完成",
|
||||
TAKE: "已完成",
|
||||
},
|
||||
complainValue: "", //投诉内容
|
||||
complainShow: false, //投诉主题开关
|
||||
complainTopic: "", //投诉抱怨话题
|
||||
complainList: [], // 投诉列表
|
||||
images: [], //投诉内容图片
|
||||
order: "", //订单
|
||||
orderGoodsList: "", //订单商品
|
||||
orderDetail: "", //订单详情
|
||||
sn: "",
|
||||
skuId: "", //商品skuid
|
||||
};
|
||||
},
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { getOrderDetail } from '@/api/order.js'
|
||||
import { getComplainReason, addComplain } from '@/api/after-sale.js'
|
||||
import { handleUploadAfterRead } from '@/utils/uploadHelper.js'
|
||||
import { unitPrice } from '@/utils/filters.js'
|
||||
|
||||
onLoad(option) {
|
||||
this.loadData(option.sn);
|
||||
this.sn = option.sn;
|
||||
this.skuId = option.skuId;
|
||||
this.getReasion();
|
||||
},
|
||||
const store = useStore()
|
||||
|
||||
methods: {
|
||||
onUploadAfterRead(event) {
|
||||
handleUploadAfterRead(event, this.uploadFileList, (urls) => {
|
||||
this.images = urls;
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 提交
|
||||
*/
|
||||
handleSubmit() {
|
||||
if(!this.images.length && !this.complainValue){
|
||||
uni.showToast({
|
||||
title:'请上传图片凭证和投诉内容',
|
||||
icon:'none'
|
||||
const orderStatusMap: Record<string, string> = {
|
||||
UNDELIVERED: '待发货',
|
||||
PARTS_DELIVERED: '部分发货',
|
||||
UNPAID: '未付款',
|
||||
PAID: '已付款',
|
||||
DELIVERED: '已发货',
|
||||
CANCELLED: '已取消',
|
||||
COMPLETE: '已完成',
|
||||
TAKE: '已完成',
|
||||
}
|
||||
|
||||
const uploadFileList = ref<any[]>([])
|
||||
const complainValue = ref('')
|
||||
const complainShow = ref(false)
|
||||
const complainTopic = ref('')
|
||||
const complainList = ref<any[]>([])
|
||||
const images = ref<string[]>([])
|
||||
const order = ref<Record<string, any>>({})
|
||||
const orderGoodsList = ref<any[]>([])
|
||||
const sn = ref('')
|
||||
const skuId = ref('')
|
||||
|
||||
onLoad((option) => {
|
||||
loadData(option.sn)
|
||||
sn.value = option.sn
|
||||
skuId.value = option.skuId
|
||||
getReasion()
|
||||
})
|
||||
|
||||
function onUploadAfterRead(event: any) {
|
||||
handleUploadAfterRead(event, uploadFileList.value, (urls) => {
|
||||
images.value = urls
|
||||
})
|
||||
}
|
||||
|
||||
function handleSubmit() {
|
||||
if (!images.value.length && !complainValue.value) {
|
||||
uni.showToast({
|
||||
title: '请上传图片凭证和投诉内容',
|
||||
icon: 'none',
|
||||
})
|
||||
return
|
||||
}
|
||||
const goods = orderGoodsList.value.filter((item) => item.skuId == skuId.value)
|
||||
const data = {
|
||||
complainTopic: complainTopic.value,
|
||||
content: complainValue.value,
|
||||
goodsId: goods[0].goodsId,
|
||||
images: images.value,
|
||||
orderSn: sn.value,
|
||||
skuId: skuId.value,
|
||||
}
|
||||
addComplain(data).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({
|
||||
title: '提交成功!',
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
setTimeout(() => {
|
||||
uni.redirectTo({
|
||||
url: '/pages/order/complain/complainList',
|
||||
})
|
||||
return
|
||||
}, 1000)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
// 循环出商品
|
||||
let goods = this.orderGoodsList.filter((item) => {
|
||||
return item.skuId == this.skuId;
|
||||
});
|
||||
//数据赋值
|
||||
let data = {
|
||||
complainTopic: this.complainTopic, //投诉主题,
|
||||
content: this.complainValue, //投诉内容
|
||||
goodsId: goods[0].goodsId, //商品id
|
||||
images: this.images, //图片
|
||||
orderSn: this.sn, //订单号
|
||||
skuId: this.skuId, //skuid
|
||||
};
|
||||
addComplain(data).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({
|
||||
title: "提交成功!",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
function getReasion() {
|
||||
getComplainReason().then((res) => {
|
||||
if (res.data.result.length >= 1) {
|
||||
res.data.result.forEach((item: any) => {
|
||||
complainList.value.push({
|
||||
value: item.reason,
|
||||
label: item.reason,
|
||||
})
|
||||
})
|
||||
complainTopic.value = res.data.result[0].reason
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
uni.redirectTo({
|
||||
url: "/pages/order/complain/complainList",
|
||||
});
|
||||
}, 1000);
|
||||
}
|
||||
});
|
||||
},
|
||||
function loadData(orderSn: string) {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
getOrderDetail(orderSn).then((res) => {
|
||||
const result = res.data.result
|
||||
order.value = result.order
|
||||
orderGoodsList.value = result.orderItems
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取投诉原因
|
||||
*/
|
||||
getReasion() {
|
||||
getComplainReason().then((res) => {
|
||||
if (res.data.result.length >= 1) {
|
||||
res.data.result.forEach((item) => {
|
||||
let way = {
|
||||
value: item.reason,
|
||||
label: item.reason,
|
||||
};
|
||||
this.complainList.push(way);
|
||||
});
|
||||
this.complainTopic = res.data.result[0].reason;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 加载订单详情
|
||||
*/
|
||||
loadData(sn) {
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
getOrderDetail(sn).then((res) => {
|
||||
const order = res.data.result;
|
||||
this.order = order.order;
|
||||
this.orderGoodsList = order.orderItems;
|
||||
this.orderDetail = res.data.result;
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 确认投诉
|
||||
*/
|
||||
confirmComplain(e) {
|
||||
this.complainTopic = e[0].label;
|
||||
},
|
||||
},
|
||||
};
|
||||
function confirmComplain(e: any[]) {
|
||||
complainTopic.value = e[0].label
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
<span>{{ complaint.content }}</span>
|
||||
</view>
|
||||
</view>
|
||||
<view class="speak-way" v-else>暂无对话</view>
|
||||
<view class="speak-way" v-else>暂无对话</view>
|
||||
<div v-if="complainDetail.complainStatus!='COMPLETE'">
|
||||
<view class="tips">回复对话</view>
|
||||
<view class="cell-item complain-content">
|
||||
@@ -42,7 +42,7 @@
|
||||
<u-input type="textarea" height="70rpx" auto-height v-model="complainValue" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="submit-btn" @click="handleSubmit">回复</view>
|
||||
<view class="submit-btn" @click="handleSubmit">回复</view>
|
||||
</div>
|
||||
<view class="tips">平台仲裁</view>
|
||||
<u-cell-group>
|
||||
@@ -51,99 +51,91 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getComplainDetail, communication } from "@/api/after-sale";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
complainId: "",
|
||||
complainValue: "", //回复内容
|
||||
complainDetail: "", //投诉详情
|
||||
statusData: {
|
||||
NEW: "新投诉",
|
||||
NO_APPLY: "未申请",
|
||||
APPLYING: "申请中",
|
||||
COMPLETE: "已完成",
|
||||
EXPIRED: "已失效",
|
||||
CANCEL: "已取消",
|
||||
WAIT_ARBITRATION:"等待仲裁"
|
||||
},
|
||||
};
|
||||
},
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { getComplainDetail, communication } from '@/api/after-sale'
|
||||
|
||||
onLoad(option) {
|
||||
this.complainId = option.id;
|
||||
this.init(option.id);
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 点击图片放大或保存
|
||||
*/
|
||||
preview(urls, index) {
|
||||
uni.previewImage({
|
||||
current: index,
|
||||
urls: urls,
|
||||
longPressActions: {
|
||||
itemList: ["保存图片"],
|
||||
success: function (data) {},
|
||||
fail: function (err) {},
|
||||
},
|
||||
});
|
||||
},
|
||||
handleSubmit() {
|
||||
if (!this.complainValue) {
|
||||
uni.showToast({
|
||||
title: "请输入回复内容",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
return;
|
||||
}
|
||||
let params = {
|
||||
content: this.complainValue,
|
||||
complainId: this.complainId,
|
||||
};
|
||||
communication(params).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({
|
||||
title: "回复成功",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
this.complainValue = '';
|
||||
this.init(this.complainId);
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.data.message,
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
});
|
||||
const store = useStore()
|
||||
|
||||
const complainId = ref('')
|
||||
const complainValue = ref('')
|
||||
const complainDetail = ref<Record<string, any>>({})
|
||||
const statusData: Record<string, string> = {
|
||||
NEW: '新投诉',
|
||||
NO_APPLY: '未申请',
|
||||
APPLYING: '申请中',
|
||||
COMPLETE: '已完成',
|
||||
EXPIRED: '已失效',
|
||||
CANCEL: '已取消',
|
||||
WAIT_ARBITRATION: '等待仲裁',
|
||||
}
|
||||
|
||||
onLoad((option) => {
|
||||
complainId.value = option.id
|
||||
init(option.id)
|
||||
})
|
||||
|
||||
function preview(urls: string[], index: number) {
|
||||
uni.previewImage({
|
||||
current: index,
|
||||
urls,
|
||||
longPressActions: {
|
||||
itemList: ['保存图片'],
|
||||
success: () => {},
|
||||
fail: () => {},
|
||||
},
|
||||
/**
|
||||
* 初始化投诉详情
|
||||
*/
|
||||
init(id) {
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
getComplainDetail(id).then((res) => {
|
||||
if (res.data.success) {
|
||||
this.complainDetail = res.data.result;
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.data.message,
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
function handleSubmit() {
|
||||
if (!complainValue.value) {
|
||||
uni.showToast({
|
||||
title: '请输入回复内容',
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
return
|
||||
}
|
||||
const params = {
|
||||
content: complainValue.value,
|
||||
complainId: complainId.value,
|
||||
}
|
||||
communication(params).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({
|
||||
title: '回复成功',
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
complainValue.value = ''
|
||||
init(complainId.value)
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.data.message,
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function init(id: string) {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
getComplainDetail(id).then((res) => {
|
||||
if (res.data.success) {
|
||||
complainDetail.value = res.data.result
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.data.message,
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
}
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.row {
|
||||
|
||||
@@ -1,181 +1,239 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="seller-view" v-for="(item, index) in complaionData" :key="index">
|
||||
<view class="seller-info u-flex u-row-between">
|
||||
<view class="seller-name">
|
||||
<view class="name">{{ item.storeName }}</view>
|
||||
</view>
|
||||
<view class="order-sn">{{ statusData[item.complainStatus] }}</view>
|
||||
</view>
|
||||
<u-line color="#DCDFE6"></u-line>
|
||||
<view class="goods-item-view">
|
||||
<view class="goods-img" @click="handleToGoods(item)">
|
||||
<u-image border-radius="6" width="131rpx" height="131rpx" :src="item.goodsImage"></u-image>
|
||||
</view>
|
||||
<view class="goods-info" @click="handleToGoods(item)">
|
||||
<view class="goods-title u-line-2">{{ item.goodsName }}</view>
|
||||
<view class="goods-price">
|
||||
¥{{unitPrice(item.goodsPrice) }}
|
||||
<!-- <span>+{{ '1' }}积分</span> -->
|
||||
</view>
|
||||
</view>
|
||||
<view class="goods-num">
|
||||
<view>x{{ item.num }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="complain-item-view">
|
||||
<view class="complain-time"> {{ item.createTime }} </view>
|
||||
<view class="complain-speak"> {{ item.complainTopic }} </view>
|
||||
</view>
|
||||
<view class="complain-btn">
|
||||
<u-tag mode="plain" @click="handleClear(item)" class="complain-tag" text="撤销投诉" type="info"
|
||||
v-if="item.complainStatus === 'APPLYING' || item.complainStatus === 'NEW'" />
|
||||
<u-tag mode="plain" @click="handleInfo(item)" class="complain-tag" text="投诉详情" type="info" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<u-empty v-if="empty" :style="{'marginTop':complaionDetail.total == 0 ? '200rpx':'0rpx'}" class="empty" style="" text="暂无投诉列表" mode="list"></u-empty>
|
||||
|
||||
<u-modal show-cancel-button @confirm="handleClearConfirm" v-model:show="show" :content="content"></u-modal>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getComplain, clearComplain } from "@/api/after-sale";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
statusData: {
|
||||
NEW: "新投诉",
|
||||
NO_APPLY: "未申请",
|
||||
APPLYING: "申请中",
|
||||
COMPLETE: "已完成",
|
||||
EXPIRED: "已失效",
|
||||
CANCEL: "已取消",
|
||||
WAIT_ARBITRATION:"等待仲裁"
|
||||
},
|
||||
show: false,
|
||||
content: "是否撤销投诉?",
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
},
|
||||
complaionDetail: "", //返回的整个response
|
||||
complaionData: [], //投诉列表
|
||||
empty: false,
|
||||
checkComplainData: "", //存储投诉信息
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
/**
|
||||
* 触底加载
|
||||
*/
|
||||
onReachBottom() {
|
||||
if (
|
||||
this.complaionDetail &&
|
||||
this.complaionDetail.total < this.params.pageNumber * this.params.pageSize
|
||||
) {
|
||||
this.params.pageNumber++;
|
||||
this.init();
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 点击跳转到商品
|
||||
handleToGoods(val) {
|
||||
uni.navigateTo({
|
||||
url: "/pages/product/goods?id=" + val.skuId + "&goodsId=" + val.goodsId,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 点击撤销投诉
|
||||
*/
|
||||
handleClear(val) {
|
||||
this.show = true;
|
||||
this.checkComplainData = val;
|
||||
},
|
||||
/**
|
||||
* 执行撤销
|
||||
*/
|
||||
handleClearConfirm() {
|
||||
clearComplain(this.checkComplainData.id).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({
|
||||
title: "撤销成功",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
this.complaionData = [];
|
||||
this.params.pageNumber = 1;
|
||||
this.init();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 查看详情
|
||||
*/
|
||||
handleInfo(val) {
|
||||
uni.navigateTo({
|
||||
url: "./complainInfo?id=" + val.id,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 初始化投诉列表
|
||||
*/
|
||||
init() {
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
getComplain(this.params).then((res) => {
|
||||
this.complaionDetail = res.data.result;
|
||||
if (res.data.result.records.length >= 1) {
|
||||
this.complaionData.push(...res.data.result.records);
|
||||
} else {
|
||||
this.empty = true;
|
||||
}
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "../goods.scss";
|
||||
|
||||
.complain-item-view {
|
||||
border-bottom: 2rpx solid #f5f7fa;
|
||||
border-top: 2rpx solid #f5f7fa;
|
||||
padding: 20rpx 30rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.complain-time {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
::v-deep .seller-name {
|
||||
width: auto !important;
|
||||
}
|
||||
.complain-btn {
|
||||
padding: 20rpx 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
margin-right: 30rpx;
|
||||
}
|
||||
.complain-tag {
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
.empty {
|
||||
margin-top: 40rpx;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<view>
|
||||
<view class="seller-view" v-for="(item, index) in complaionData" :key="index">
|
||||
<view class="seller-info u-flex u-row-between">
|
||||
<view class="seller-name">
|
||||
<view class="name">{{ item.storeName }}</view>
|
||||
</view>
|
||||
<view class="order-sn">{{ statusData[item.complainStatus] }}</view>
|
||||
</view>
|
||||
<u-line color="#DCDFE6"></u-line>
|
||||
<view class="goods-item-view">
|
||||
<view class="goods-img" @click="handleToGoods(item)">
|
||||
<u-image radius="6rpx" width="131rpx" height="131rpx" :src="item.goodsImage"></u-image>
|
||||
</view>
|
||||
<view class="goods-info" @click="handleToGoods(item)">
|
||||
<view class="goods-title u-line-2">{{ item.goodsName }}</view>
|
||||
<view class="goods-price">
|
||||
¥{{unitPrice(item.goodsPrice) }}
|
||||
<!-- <span>+{{ '1' }}积分</span> -->
|
||||
</view>
|
||||
</view>
|
||||
<view class="goods-num">
|
||||
<view>x{{ item.num }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="complain-item-view">
|
||||
<view class="complain-time"> {{ item.createTime }} </view>
|
||||
<view class="complain-speak"> {{ item.complainTopic }} </view>
|
||||
</view>
|
||||
<view class="complain-btn">
|
||||
<u-tag plain @click="handleClear(item)" class="complain-tag" text="撤销投诉" type="info"
|
||||
v-if="item.complainStatus === 'APPLYING' || item.complainStatus === 'NEW'" />
|
||||
<u-tag plain @click="handleInfo(item)" class="complain-tag" text="投诉详情" type="info" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<u-empty v-if="empty" :style="{'marginTop':complaionDetail.total == 0 ? '200rpx':'0rpx'}" class="empty" style="" text="暂无投诉列表" mode="list"></u-empty>
|
||||
|
||||
<u-modal show-cancel-button @confirm="handleClearConfirm" v-model:show="show" :content="content"></u-modal>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad, onReachBottom } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { unitPrice } from '@/utils/filters.js'
|
||||
import { getComplain, clearComplain } from '@/api/after-sale'
|
||||
|
||||
const store = useStore()
|
||||
|
||||
const statusData: Record<string, string> = {
|
||||
NEW: '新投诉',
|
||||
NO_APPLY: '未申请',
|
||||
APPLYING: '申请中',
|
||||
COMPLETE: '已完成',
|
||||
EXPIRED: '已失效',
|
||||
CANCEL: '已取消',
|
||||
WAIT_ARBITRATION: '等待仲裁',
|
||||
}
|
||||
|
||||
const show = ref(false)
|
||||
const content = ref('是否撤销投诉?')
|
||||
const params = ref({ pageNumber: 1, pageSize: 20 })
|
||||
const complaionDetail = ref<any>(null)
|
||||
const complaionData = ref<any[]>([])
|
||||
const empty = ref(false)
|
||||
const checkComplainData = ref<any>(null)
|
||||
|
||||
onLoad(() => {
|
||||
init()
|
||||
})
|
||||
|
||||
onReachBottom(() => {
|
||||
if (
|
||||
complaionDetail.value &&
|
||||
complaionDetail.value.total > params.value.pageNumber * params.value.pageSize
|
||||
) {
|
||||
params.value.pageNumber++
|
||||
init()
|
||||
}
|
||||
})
|
||||
|
||||
function handleToGoods(val: any) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/product/goods?id=' + val.skuId + '&goodsId=' + val.goodsId,
|
||||
})
|
||||
}
|
||||
|
||||
function handleClear(val: any) {
|
||||
show.value = true
|
||||
checkComplainData.value = val
|
||||
}
|
||||
|
||||
function handleClearConfirm() {
|
||||
clearComplain(checkComplainData.value.id).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({
|
||||
title: '撤销成功',
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
complaionData.value = []
|
||||
params.value.pageNumber = 1
|
||||
init()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function handleInfo(val: any) {
|
||||
uni.navigateTo({
|
||||
url: './complainInfo?id=' + val.id,
|
||||
})
|
||||
}
|
||||
|
||||
function hideLoadingIfNeeded() {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
}
|
||||
|
||||
function init() {
|
||||
uni.showLoading({
|
||||
title: '加载中',
|
||||
})
|
||||
getComplain(params.value).then((res) => {
|
||||
complaionDetail.value = res.data.result
|
||||
if (res.data.result.records.length >= 1) {
|
||||
complaionData.value.push(...res.data.result.records)
|
||||
} else {
|
||||
empty.value = true
|
||||
}
|
||||
hideLoadingIfNeeded()
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.seller-view {
|
||||
background-color: #fff;
|
||||
margin: 20rpx 0;
|
||||
}
|
||||
|
||||
.seller-info {
|
||||
height: 70rpx;
|
||||
padding: 0 20rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.seller-name {
|
||||
width: auto;
|
||||
min-width: 0;
|
||||
font-size: 33rpx;
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
height: 90rpx;
|
||||
}
|
||||
|
||||
.name {
|
||||
margin-left: 15rpx;
|
||||
margin-top: -2rpx;
|
||||
font-size: 28rpx;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.order-sn {
|
||||
color: #ff0000;
|
||||
font-size: 26rpx;
|
||||
flex-shrink: 0;
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
|
||||
.goods-item-view {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 10rpx 30rpx;
|
||||
}
|
||||
|
||||
.goods-img {
|
||||
width: 131rpx;
|
||||
height: 131rpx;
|
||||
flex: 0 0 131rpx;
|
||||
}
|
||||
|
||||
.goods-info {
|
||||
padding-left: 30rpx;
|
||||
min-width: 0;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.goods-title {
|
||||
margin-bottom: 10rpx;
|
||||
color: $font-color-dark;
|
||||
}
|
||||
|
||||
.goods-price {
|
||||
font-size: 28rpx;
|
||||
margin-bottom: 10rpx;
|
||||
color: #ff5a10;
|
||||
}
|
||||
|
||||
.goods-num {
|
||||
text-align: center;
|
||||
flex: 0 0 60rpx;
|
||||
width: 60rpx;
|
||||
color: $main-color;
|
||||
}
|
||||
|
||||
.complain-item-view {
|
||||
border-bottom: 2rpx solid #f5f7fa;
|
||||
border-top: 2rpx solid #f5f7fa;
|
||||
padding: 20rpx 30rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.complain-time {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
.complain-btn {
|
||||
padding: 20rpx 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
margin-right: 30rpx;
|
||||
}
|
||||
.complain-tag {
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
.empty {
|
||||
margin-top: 40rpx;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -45,34 +45,24 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getPackage } from "@/api/trade.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
order: {},
|
||||
logisticsList: [],
|
||||
}
|
||||
},
|
||||
components: {
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
onLoad(option) {
|
||||
let sn = option.order_sn;
|
||||
this.tracesList(sn);
|
||||
},
|
||||
mounted() {
|
||||
},
|
||||
methods: {
|
||||
tracesList(sn) {
|
||||
getPackage(sn).then((res) => {
|
||||
if(res.data.success){
|
||||
this.logisticsList = res.data.result;
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { getPackage } from '@/api/trade.js'
|
||||
|
||||
const logisticsList = ref<any[]>([])
|
||||
|
||||
onLoad((option) => {
|
||||
const sn = option.order_sn
|
||||
if (sn) fetchLogistics(sn)
|
||||
})
|
||||
|
||||
function fetchLogistics(sn: string) {
|
||||
getPackage(sn).then((res) => {
|
||||
if (res.data.success) {
|
||||
logisticsList.value = res.data.result
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style >
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
<view class="img">
|
||||
<!-- 循环出商家回复评价的图片 -->
|
||||
<u-image width="140rpx" height="140rpx" v-if="comment.replyImage" v-for="(replyImg, replyIndex) in splitImg(comment.replyImage)" :src="replyImg" :key="replyIndex"
|
||||
@click="preview(splitImg( comment.replyImage), index)">
|
||||
@click="preview(splitImg(comment.replyImage), replyIndex)">
|
||||
</u-image>
|
||||
</view>
|
||||
</view>
|
||||
@@ -40,56 +40,46 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import configs from '@/config/config'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
configs,
|
||||
userImage:configs.defaultUserPhoto,
|
||||
|
||||
comment: {}, //评论信息
|
||||
gradeList: {
|
||||
//评价grade
|
||||
GOOD: "好评",
|
||||
MODERATE: "中评",
|
||||
WORSE: "差评",
|
||||
haveImage: "有图",
|
||||
},
|
||||
};
|
||||
},
|
||||
onLoad(options) {
|
||||
this.comment = JSON.parse(decodeURIComponent(options.comment));
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 切割图像
|
||||
*/
|
||||
splitImg(val) {
|
||||
if (val && val.split(",")) {
|
||||
return val.split(",");
|
||||
} else if (val) {
|
||||
return val;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
const userImage = configs.defaultUserPhoto
|
||||
|
||||
const comment = ref<Record<string, any>>({})
|
||||
const gradeList: Record<string, string> = {
|
||||
GOOD: '好评',
|
||||
MODERATE: '中评',
|
||||
WORSE: '差评',
|
||||
haveImage: '有图',
|
||||
}
|
||||
|
||||
onLoad((options) => {
|
||||
comment.value = JSON.parse(decodeURIComponent(options.comment))
|
||||
})
|
||||
|
||||
function splitImg(val: string) {
|
||||
if (val && val.split(',')) {
|
||||
return val.split(',')
|
||||
} else if (val) {
|
||||
return val
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
function preview(urls: string[] | false, index: number) {
|
||||
if (!urls) return
|
||||
uni.previewImage({
|
||||
current: index,
|
||||
urls: Array.isArray(urls) ? urls : [urls],
|
||||
longPressActions: {
|
||||
itemList: ['保存图片'],
|
||||
success: () => {},
|
||||
fail: () => {},
|
||||
},
|
||||
/**
|
||||
* 点击图片放大或保存
|
||||
*/
|
||||
preview(urls, index) {
|
||||
uni.previewImage({
|
||||
current: index,
|
||||
urls: urls,
|
||||
longPressActions: {
|
||||
itemList: ["保存图片"],
|
||||
success: function (data) {},
|
||||
fail: function (err) {},
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -8,8 +8,9 @@
|
||||
:inactiveStyle="{ color: '#333' }"
|
||||
v-model:current="current"
|
||||
class="utabs"
|
||||
:lineColor="$lightColor"
|
||||
:activeStyle="{ color: $lightColor }"
|
||||
:lineColor="lightColor"
|
||||
:activeStyle="{ color: lightColor }"
|
||||
:bg-color="'#ffffff'"
|
||||
></u-tabs>
|
||||
</view>
|
||||
<swiper class="swiper-box" :current="current" @change="changeSwiper" duration="500">
|
||||
@@ -38,7 +39,7 @@
|
||||
<view class="btn-view u-row-between" v-if="current == 2">
|
||||
<view class="description">
|
||||
<view class="text title">
|
||||
<u-read-more ref="uReadMore" :color="$lightColor" text-indent="0">
|
||||
<u-read-more ref="uReadMore" :color="lightColor" text-indent="0">
|
||||
<rich-text :nodes="'评论内容:' + order.content || ''"></rich-text>
|
||||
</u-read-more>
|
||||
</view>
|
||||
@@ -78,209 +79,144 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getOrderList } from "@/api/order.js";
|
||||
import { getComments } from "@/api/members.js";
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed, watch } from 'vue'
|
||||
import { onShow } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { getOrderList } from '@/api/order.js'
|
||||
import { getComments } from '@/api/members.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
list: [
|
||||
//顶部tab
|
||||
const store = useStore()
|
||||
const lightColor = computed(() => store.getters.lightColor)
|
||||
|
||||
const list = [
|
||||
{ name: '全部订单' },
|
||||
{ name: '待评价' },
|
||||
{ name: '已评价' },
|
||||
]
|
||||
|
||||
const gradeList: Record<string, string> = {
|
||||
GOOD: '好评',
|
||||
MODERATE: '中评',
|
||||
WORSE: '差评',
|
||||
haveImage: '有图',
|
||||
}
|
||||
|
||||
const groupCommentStatusWay: Record<string, string> = {
|
||||
NEW: '新订单,不能进行评论',
|
||||
UNFINISHED: '未完成评论',
|
||||
WAIT_CHASE: '待追评的评论信息',
|
||||
FINISHED: '已经完成评论',
|
||||
}
|
||||
|
||||
const current = ref(0)
|
||||
const orderList = ref<any[]>([])
|
||||
const params = reactive<Record<string, any>>({
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
loadStatus: 'more',
|
||||
})
|
||||
|
||||
onShow(() => {
|
||||
orderList.value = []
|
||||
params.pageNumber = 1
|
||||
current.value = 0
|
||||
loadData()
|
||||
})
|
||||
|
||||
watch(current, (val) => {
|
||||
params.pageNumber = 1
|
||||
params.loadStatus = 'more'
|
||||
orderList.value = []
|
||||
|
||||
if (val == 0) {
|
||||
delete params.commentStatus
|
||||
loadData()
|
||||
} else if (val == 1) {
|
||||
params.commentStatus = 'UNFINISHED'
|
||||
orderList.value = []
|
||||
loadData()
|
||||
} else {
|
||||
params.commentStatus = 'FINISHED'
|
||||
orderList.value = []
|
||||
loadComments()
|
||||
}
|
||||
})
|
||||
|
||||
function preview(urls: string[], index: number) {
|
||||
uni.previewImage({
|
||||
current: index,
|
||||
urls,
|
||||
longPressActions: {
|
||||
itemList: ['保存图片'],
|
||||
success: () => {},
|
||||
fail: () => {},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
function changeSwiper(e: any) {
|
||||
current.value = e.target.current
|
||||
}
|
||||
|
||||
function loadData() {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
getOrderList(params).then((res) => {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
const records = res.data.result.records
|
||||
if (records.length < 10) {
|
||||
params.loadStatus = 'noMore'
|
||||
}
|
||||
if (records.length > 0) {
|
||||
orderList.value = orderList.value.concat(records)
|
||||
params.pageNumber += 1
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function talkCommont(sku: any) {
|
||||
uni.navigateTo({
|
||||
url: `./releaseEvaluate?sn=${sku.sn}&sku=${encodeURIComponent(JSON.stringify(sku))}`,
|
||||
})
|
||||
}
|
||||
|
||||
function loadComments() {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
getComments(params).then((res) => {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
const records = res.data.result.records
|
||||
if (records.length < 10) {
|
||||
params.loadStatus = 'noMore'
|
||||
}
|
||||
records.forEach((item: any) => {
|
||||
item.orderItems = [
|
||||
{
|
||||
name: "全部订单",
|
||||
image: item.goodsImage,
|
||||
name: item.goodsName,
|
||||
goodsId: item.goodsId,
|
||||
skuId: item.skuId,
|
||||
},
|
||||
{
|
||||
name: "待评价",
|
||||
},
|
||||
{
|
||||
name: "已评价",
|
||||
},
|
||||
],
|
||||
gradeList: {
|
||||
//评论表
|
||||
GOOD: "好评",
|
||||
MODERATE: "中评",
|
||||
WORSE: "差评",
|
||||
haveImage: "有图",
|
||||
},
|
||||
groupCommentStatusWay: {
|
||||
NEW: "新订单,不能进行评论",
|
||||
UNFINISHED: "未完成评论",
|
||||
WAIT_CHASE: "待追评的评论信息",
|
||||
FINISHED: "已经完成评论",
|
||||
},
|
||||
current: 0, //当前tabIndex
|
||||
orderList: [], //商品集合
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
loadStatus: "more",
|
||||
},
|
||||
};
|
||||
},
|
||||
]
|
||||
})
|
||||
orderList.value = orderList.value.concat(records)
|
||||
params.pageNumber += 1
|
||||
})
|
||||
}
|
||||
|
||||
onShow() {
|
||||
this.orderList = [];
|
||||
this.params.pageNumber = 1;
|
||||
this.current = 0
|
||||
this.loadData()
|
||||
},
|
||||
watch: {
|
||||
/**
|
||||
* 切换current
|
||||
* 更改页面并重新加载数据
|
||||
*/
|
||||
current(val) {
|
||||
this.params.pageNumber = 1;
|
||||
this.params.loadStatus = "more";
|
||||
this.orderList = [];
|
||||
//重新读取数据
|
||||
function renderData(index: number) {
|
||||
if (params.loadStatus == 'noMore') return
|
||||
if (index == 0) {
|
||||
loadData()
|
||||
} else {
|
||||
loadComments()
|
||||
}
|
||||
}
|
||||
|
||||
if (val == 0) {
|
||||
delete this.params.commentStatus
|
||||
this.loadData();
|
||||
} else if (val == 1) {
|
||||
this.params.commentStatus = "UNFINISHED";
|
||||
this.orderList = [];
|
||||
this.loadData();
|
||||
} else {
|
||||
this.params.commentStatus = "FINISHED";
|
||||
this.orderList = [];
|
||||
return this.loadComments();
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
/**
|
||||
* 判断当前店铺是否有可评价的商品
|
||||
*/
|
||||
commentStatus(val) {
|
||||
if (this.current == 2) {
|
||||
return true;
|
||||
} else {
|
||||
let show;
|
||||
val.orderItems &&
|
||||
val.orderItems.forEach((item) => {
|
||||
if (item.commentStatus == "UNFINISHED") {
|
||||
show = true;
|
||||
} else {
|
||||
show = false;
|
||||
}
|
||||
});
|
||||
|
||||
return show;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 点击图片放大或保存
|
||||
*/
|
||||
preview(urls, index) {
|
||||
uni.previewImage({
|
||||
current: index,
|
||||
urls: urls,
|
||||
longPressActions: {
|
||||
itemList: ["保存图片"],
|
||||
success: function (data) {},
|
||||
fail: function (err) {},
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 点击swiper
|
||||
*/
|
||||
changeSwiper(e) {
|
||||
this.current = e.target.current;
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取订单数据
|
||||
*/
|
||||
loadData() {
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
getOrderList(this.params).then((res) => {
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
const orderList = res.data.result.records;
|
||||
if (orderList.length < 10) {
|
||||
this.params.loadStatus = "noMore";
|
||||
}
|
||||
if (orderList.length > 0) {
|
||||
this.orderList = this.orderList.concat(orderList);
|
||||
this.params.pageNumber += 1;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 发表评价
|
||||
*/
|
||||
talkCommont(sku) {
|
||||
console.log(sku);
|
||||
uni.navigateTo({
|
||||
url: `./releaseEvaluate?sn=${sku.sn}&sku=${encodeURIComponent(
|
||||
JSON.stringify(sku)
|
||||
)}`,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 加载已评价数据
|
||||
*/
|
||||
loadComments() {
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
getComments(this.params).then((res) => {
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
let orderList = res.data.result.records;
|
||||
if (orderList.length < 10) {
|
||||
this.params.loadStatus = "noMore";
|
||||
}
|
||||
orderList.forEach((item) => {
|
||||
item.orderItems = [
|
||||
{
|
||||
image: item.goodsImage,
|
||||
name: item.goodsName,
|
||||
goodsId: item.goodsId,
|
||||
skuId: item.skuId,
|
||||
},
|
||||
];
|
||||
});
|
||||
this.orderList = this.orderList.concat(orderList);
|
||||
this.params.pageNumber += 1;
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 滑到底部加载数据
|
||||
*/
|
||||
renderData(index) {
|
||||
if (this.params.loadStatus == "noMore") return;
|
||||
if (index == 0) {
|
||||
this.loadData();
|
||||
} else {
|
||||
this.loadComments();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 评价详情
|
||||
*/
|
||||
onDetail(comment) {
|
||||
uni.navigateTo({
|
||||
url:
|
||||
"./evaluateDetail?comment=" +
|
||||
encodeURIComponent(JSON.stringify(comment)),
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
function onDetail(comment: any) {
|
||||
uni.navigateTo({
|
||||
url: './evaluateDetail?comment=' + encodeURIComponent(JSON.stringify(comment)),
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
page {
|
||||
@@ -310,6 +246,7 @@ page {
|
||||
.u-tabs-box {
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
background: #ffffff;
|
||||
}
|
||||
.box-content {
|
||||
margin: 20rpx 0;
|
||||
|
||||
@@ -86,80 +86,69 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import storage from "@/utils/storage.js";
|
||||
import { commentsMemberOrder } from "@/api/members.js";
|
||||
import { handleUploadAfterRead } from "@/utils/uploadHelper.js";
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { commentsMemberOrder } from '@/api/members.js'
|
||||
import { handleUploadAfterRead } from '@/utils/uploadHelper.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
storage,
|
||||
type: "textarea", //输入框状态为 textarea
|
||||
border: false, //没有border
|
||||
maxlength: 500, //评价最大字数为500字
|
||||
placeholder:
|
||||
"宝贝满足您的期待吗?说说它的优点和美中不足的地方吧。您的评价会帮助更多的人",
|
||||
sku: {}, //订单信息
|
||||
form: {
|
||||
content: "", //评价详情
|
||||
goodsId: "", //商品id
|
||||
grade: "GOOD", //默认为好评
|
||||
orderItemSn: "", //商品的sn
|
||||
skuId: "", //商品skuId
|
||||
descriptionScore: 5, //默认描述得分为5分
|
||||
serviceScore: 5, //默认服务得分为5分
|
||||
deliveryScore: 5, //默认物流得分为5分
|
||||
},
|
||||
uploadFileList: [],
|
||||
};
|
||||
},
|
||||
onLoad(options) {
|
||||
// 获取上一级传过来的数据进行解析
|
||||
this.form.orderItemSn = options.sn;
|
||||
this.sku = JSON.parse(decodeURIComponent(options.sku));
|
||||
this.form.goodsId = this.sku.goodsId;
|
||||
this.form.skuId = this.sku.skuId;
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 点击评价
|
||||
*/
|
||||
onGrade(grade) {
|
||||
this.form.grade = grade;
|
||||
},
|
||||
const store = useStore()
|
||||
|
||||
/**
|
||||
* 提交评价
|
||||
*/
|
||||
onSubmit() {
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
commentsMemberOrder(this.form).then((res) => {
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
if (res.data.success) {
|
||||
uni.showToast({
|
||||
title: "发布评价成功",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
success: () => {
|
||||
setTimeout(() => {
|
||||
uni.navigateBack();
|
||||
}, 500);
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
const type = 'textarea'
|
||||
const border = false
|
||||
const maxlength = 500
|
||||
const placeholder =
|
||||
'宝贝满足您的期待吗?说说它的优点和美中不足的地方吧。您的评价会帮助更多的人'
|
||||
|
||||
onUploadAfterRead(event) {
|
||||
handleUploadAfterRead(event, this.uploadFileList, (urls) => {
|
||||
this.form.images = urls;
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
const sku = ref<Record<string, any>>({})
|
||||
const form = reactive<Record<string, any>>({
|
||||
content: '',
|
||||
goodsId: '',
|
||||
grade: 'GOOD',
|
||||
orderItemSn: '',
|
||||
skuId: '',
|
||||
descriptionScore: 5,
|
||||
serviceScore: 5,
|
||||
deliveryScore: 5,
|
||||
})
|
||||
const uploadFileList = ref<any[]>([])
|
||||
|
||||
onLoad((options) => {
|
||||
form.orderItemSn = options.sn
|
||||
sku.value = JSON.parse(decodeURIComponent(options.sku))
|
||||
form.goodsId = sku.value.goodsId
|
||||
form.skuId = sku.value.skuId
|
||||
})
|
||||
|
||||
function onGrade(grade: string) {
|
||||
form.grade = grade
|
||||
}
|
||||
|
||||
function onSubmit() {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
commentsMemberOrder(form).then((res) => {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
if (res.data.success) {
|
||||
uni.showToast({
|
||||
title: '发布评价成功',
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
success: () => {
|
||||
setTimeout(() => {
|
||||
uni.navigateBack()
|
||||
}, 500)
|
||||
},
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function onUploadAfterRead(event: any) {
|
||||
handleUploadAfterRead(event, uploadFileList.value, (urls) => {
|
||||
form.images = urls
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -384,471 +384,426 @@
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import * as API_Address from "@/api/address";
|
||||
import * as API_Order from "@/api/order";
|
||||
import * as API_Trade from "@/api/trade";
|
||||
import configs from "@/config/config";
|
||||
import LiLiWXPay from "@/js_sdk/lili-pay/wx-pay.js";
|
||||
import invoices from "@/pages/order/invoice/setInvoice";
|
||||
import { mapState } from "vuex";
|
||||
export default {
|
||||
onLoad: function (val) {
|
||||
this.routerVal = val;
|
||||
},
|
||||
components: {
|
||||
invoices,
|
||||
},
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, watch, getCurrentInstance } from 'vue'
|
||||
import { onLoad, onShow, onBackPress } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import * as API_Address from '@/api/address'
|
||||
import * as API_Order from '@/api/order'
|
||||
import * as API_Trade from '@/api/trade'
|
||||
import configs from '@/config/config'
|
||||
import LiLiWXPay from '@/js_sdk/lili-pay/wx-pay.js'
|
||||
import invoices from '@/pages/order/invoice/setInvoice'
|
||||
import {
|
||||
unitPrice,
|
||||
goodsFormatPrice,
|
||||
secrecyMobile,
|
||||
isLogin,
|
||||
} from '@/utils/filters.js'
|
||||
|
||||
data() {
|
||||
return {
|
||||
configs,
|
||||
userImage: configs.defaultUserPhoto,
|
||||
invoiceFlag: false, //开票开关
|
||||
shippingText: "LOGISTICS",
|
||||
shippingFlag: false,
|
||||
shippingMethod: [],
|
||||
shippingWay: [
|
||||
{
|
||||
value: "LOGISTICS",
|
||||
label: "物流",
|
||||
},
|
||||
{
|
||||
value: "SELF_PICK_UP",
|
||||
label: "自提",
|
||||
},
|
||||
],
|
||||
isAssemble: false, //是否拼团
|
||||
// 判断是否填写过备注
|
||||
remarkFlag: false,
|
||||
selectAddressId: "",
|
||||
routerVal: "",
|
||||
params: {},
|
||||
// 优惠劵
|
||||
couponList: "",
|
||||
// 已选地址
|
||||
address: "",
|
||||
shopAddress: "",
|
||||
// 发票信息
|
||||
receiptList: "",
|
||||
// 店铺信息
|
||||
orderMessage: "",
|
||||
data: "",
|
||||
// 存储备注
|
||||
remarkVal: [],
|
||||
remarkVal1: "",
|
||||
detail: "", //返回的所有数据
|
||||
endWay: "", //最后一个参团人
|
||||
masterWay: "", //团长信息
|
||||
pintuanFlage: true, //是开团还是拼团
|
||||
notSupportFreight: [], //不支持运费
|
||||
notSupportFreightNoticeText: "",
|
||||
storeAddress: "",
|
||||
const store = useStore()
|
||||
const { proxy } = getCurrentInstance()!
|
||||
const lightColor = computed(() => store.getters.lightColor)
|
||||
const mainColor = computed(() => store.getters.mainColor)
|
||||
const aiderLightColor = computed(() => store.getters.aiderLightColor)
|
||||
const remark = computed(() => store.state.remark)
|
||||
|
||||
originOrderData:"", // 原始订单数据
|
||||
};
|
||||
interface ShippingOption {
|
||||
value: string
|
||||
label: string
|
||||
}
|
||||
|
||||
const shippingWay: ShippingOption[] = [
|
||||
{ value: 'LOGISTICS', label: '物流' },
|
||||
{ value: 'SELF_PICK_UP', label: '自提' },
|
||||
]
|
||||
|
||||
const userImage = configs.defaultUserPhoto
|
||||
const invoiceFlag = ref(false)
|
||||
const shippingText = ref('LOGISTICS')
|
||||
const shippingFlag = ref(false)
|
||||
const shippingMethod = ref<ShippingOption[]>([])
|
||||
const isAssemble = ref(false)
|
||||
const remarkFlag = ref(false)
|
||||
const selectAddressId = ref('')
|
||||
const routerVal = ref<Record<string, any>>({})
|
||||
const params = ref<Record<string, any>>({})
|
||||
const couponList = ref('')
|
||||
const address = ref<any>('')
|
||||
const shopAddress = ref('')
|
||||
const receiptList = ref<any>('')
|
||||
const orderMessage = ref<any>('')
|
||||
const data = ref('')
|
||||
const remarkVal = ref<any[]>([])
|
||||
const remarkVal1 = ref('')
|
||||
const detail = ref('')
|
||||
const endWay = ref<any>('')
|
||||
const masterWay = ref<any>('')
|
||||
const pintuanFlage = ref(true)
|
||||
const notSupportFreight = ref<any[]>([])
|
||||
const notSupportFreightNoticeText = ref('')
|
||||
const storeAddress = ref<any>('')
|
||||
const originOrderData = ref<any>('')
|
||||
|
||||
watch(
|
||||
remarkVal,
|
||||
(val) => {
|
||||
store.commit('setRemark', val)
|
||||
},
|
||||
watch: {
|
||||
// 监听备注 并在 vuex 中存储
|
||||
remarkVal: {
|
||||
handler(val) {
|
||||
this.$store.commit("setRemark", val);
|
||||
},
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
...mapState(["remark"]),
|
||||
},
|
||||
/**
|
||||
* 监听返回
|
||||
*/
|
||||
onBackPress(e) {
|
||||
if (e.from == "backbutton") {
|
||||
const curRoute = getCurrentPages().slice(-1)[0]?.options || {};
|
||||
if (curRoute.addId) {
|
||||
uni.reLaunch({
|
||||
url: "/pages/tabbar/cart/cartList",
|
||||
});
|
||||
} else if (this.routerVal?.way === "CART") {
|
||||
uni.switchTab({
|
||||
url: "/pages/tabbar/cart/cartList",
|
||||
});
|
||||
} else {
|
||||
uni.navigateBack();
|
||||
}
|
||||
return true;
|
||||
{ immediate: true, deep: true }
|
||||
)
|
||||
|
||||
onLoad((val) => {
|
||||
routerVal.value = val || {}
|
||||
})
|
||||
|
||||
onBackPress((e) => {
|
||||
if (e.from == 'backbutton') {
|
||||
const curRoute = getCurrentPages().slice(-1)[0]?.options || {}
|
||||
if (curRoute.addId) {
|
||||
uni.reLaunch({
|
||||
url: '/pages/tabbar/cart/cartList',
|
||||
})
|
||||
} else if (routerVal.value?.way === 'CART') {
|
||||
uni.switchTab({
|
||||
url: '/pages/tabbar/cart/cartList',
|
||||
})
|
||||
} else {
|
||||
uni.navigateBack()
|
||||
}
|
||||
},
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
async onShow() {
|
||||
// 判断是否存在写过备注信息的商品
|
||||
if (this.remark && this.remark.length > 0) {
|
||||
this.remarkFlag = true;
|
||||
onShow(async () => {
|
||||
if (remark.value && remark.value.length > 0) {
|
||||
remarkFlag.value = true
|
||||
}
|
||||
uni.showLoading({
|
||||
mask: true,
|
||||
})
|
||||
try {
|
||||
await getOrderList()
|
||||
await getDistribution()
|
||||
if (routerVal.value.way == 'PINTUAN') {
|
||||
isAssemble.value = true
|
||||
routerVal.value.parentOrder = JSON.parse(
|
||||
decodeURIComponent(routerVal.value.parentOrder)
|
||||
)
|
||||
pintuanWay()
|
||||
}
|
||||
uni.showLoading({
|
||||
mask: true,
|
||||
});
|
||||
try {
|
||||
await this.getOrderList();
|
||||
await this.getDistribution();
|
||||
if (this.routerVal.way == "PINTUAN") {
|
||||
this.isAssemble = true;
|
||||
this.routerVal.parentOrder = JSON.parse(
|
||||
decodeURIComponent(this.routerVal.parentOrder)
|
||||
);
|
||||
this.pintuanWay();
|
||||
}
|
||||
} finally {
|
||||
uni.hideLoading();
|
||||
} finally {
|
||||
uni.hideLoading()
|
||||
}
|
||||
})
|
||||
|
||||
function getShippingLabel() {
|
||||
const item =
|
||||
shippingMethod.value.find((e) => e.value === shippingText.value) ||
|
||||
shippingWay.find((e) => e.value === shippingText.value)
|
||||
return item ? item.label : ''
|
||||
}
|
||||
|
||||
async function callbackInvoice(val: any) {
|
||||
invoiceFlag.value = false
|
||||
receiptList.value = val
|
||||
if (val) {
|
||||
const submit = {
|
||||
way: routerVal.value.way,
|
||||
...receiptList.value,
|
||||
}
|
||||
},
|
||||
mounted() {},
|
||||
const receipt = await API_Order.getReceipt(submit)
|
||||
if (receipt.data.success) {
|
||||
shippingFlag.value = false
|
||||
getOrderList()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
methods: {
|
||||
getShippingLabel() {
|
||||
const item =
|
||||
this.shippingMethod.find((e) => e.value === this.shippingText) ||
|
||||
this.shippingWay.find((e) => e.value === this.shippingText);
|
||||
return item ? item.label : "";
|
||||
},
|
||||
function navigateToStore(val: any) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/product/shopPage?id=' + val.storeId,
|
||||
})
|
||||
}
|
||||
|
||||
//发票回调 选择发票之后刷新购物车
|
||||
async callbackInvoice(val) {
|
||||
this.invoiceFlag = false;
|
||||
this.receiptList = val;
|
||||
if (val) {
|
||||
let submit = {
|
||||
way: this.routerVal.way,
|
||||
...this.receiptList,
|
||||
};
|
||||
let receipt = await API_Order.getReceipt(submit);
|
||||
if (receipt.data.success) {
|
||||
this.shippingFlag = false;
|
||||
this.getOrderList();
|
||||
}
|
||||
function clickToAddress() {
|
||||
navigateTo(
|
||||
`/pages/mine/address/address?from=cart&way=${
|
||||
routerVal.value.way
|
||||
}&parentOrder=${encodeURIComponent(
|
||||
JSON.stringify(routerVal.value.parentOrder)
|
||||
)}`
|
||||
)
|
||||
}
|
||||
|
||||
function clickToStoreAddress() {
|
||||
navigateTo(
|
||||
`/pages/mine/address/storeAddress?from=cart&way=${routerVal.value.way}&storeId=${remarkVal.value[0].storeId}`
|
||||
)
|
||||
}
|
||||
|
||||
function pintuanWay() {
|
||||
const { memberId } = routerVal.value.parentOrder
|
||||
const userInfo = isLogin()
|
||||
if (memberId) {
|
||||
endWay.value = userInfo
|
||||
masterWay.value = routerVal.value.parentOrder
|
||||
pintuanFlage.value = false
|
||||
} else {
|
||||
pintuanFlage.value = true
|
||||
masterWay.value = userInfo
|
||||
}
|
||||
}
|
||||
|
||||
function invoice() {
|
||||
invoiceFlag.value = true
|
||||
}
|
||||
|
||||
function GET_Discount() {
|
||||
let storeIds: any[] = []
|
||||
let skus: any[] = []
|
||||
const selectedCoupon: any[] = []
|
||||
if (orderMessage.value.platformCoupon) {
|
||||
selectedCoupon.push(orderMessage.value.platformCoupon.memberCoupon.id)
|
||||
}
|
||||
if (
|
||||
orderMessage.value.storeCoupons &&
|
||||
Object.keys(orderMessage.value.storeCoupons)[0]
|
||||
) {
|
||||
const storeMemberCouponsId = Object.keys(
|
||||
orderMessage.value.storeCoupons
|
||||
)[0]
|
||||
const storeCouponId =
|
||||
orderMessage.value.storeCoupons[storeMemberCouponsId].memberCoupon.id
|
||||
selectedCoupon.push(storeCouponId)
|
||||
}
|
||||
orderMessage.value.cartList.forEach((item: any) => {
|
||||
item.skuList.forEach((sku: any) => {
|
||||
storeIds.push(sku.storeId)
|
||||
skus.push(sku.goodsSku.id)
|
||||
})
|
||||
})
|
||||
storeIds = Array.from(new Set(storeIds))
|
||||
skus = Array.from(new Set(skus))
|
||||
uni.setStorage({
|
||||
key: 'totalPrice',
|
||||
data: orderMessage.value.priceDetailDTO.goodsPrice,
|
||||
})
|
||||
navigateTo(
|
||||
`/pages/cart/coupon/index?way=${routerVal.value.way}&storeId=${storeIds}&skuId=${skus}&selectedCoupon=${selectedCoupon}`
|
||||
)
|
||||
}
|
||||
|
||||
function navigateTo(url: string) {
|
||||
uni.navigateTo({
|
||||
url,
|
||||
})
|
||||
}
|
||||
|
||||
function createTradeFun() {
|
||||
proxy!.$u.throttle(() => {
|
||||
if (shippingText.value === 'SELF_PICK_UP') {
|
||||
if (!storeAddress.value.id) {
|
||||
uni.showToast({
|
||||
title: '请选择提货点',
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
return false
|
||||
}
|
||||
},
|
||||
|
||||
// 跳转到店铺
|
||||
navigateToStore(val) {
|
||||
uni.navigateTo({
|
||||
url: "/pages/product/shopPage?id=" + val.storeId,
|
||||
});
|
||||
},
|
||||
// 点击跳转地址
|
||||
clickToAddress() {
|
||||
this.navigateTo(
|
||||
`/pages/mine/address/address?from=cart&way=${
|
||||
this.routerVal.way
|
||||
}&parentOrder=${encodeURIComponent(
|
||||
JSON.stringify(this.routerVal.parentOrder)
|
||||
)}`
|
||||
);
|
||||
},
|
||||
clickToStoreAddress() {
|
||||
this.navigateTo(
|
||||
`/pages/mine/address/storeAddress?from=cart&way=${this.routerVal.way}&storeId=${this.remarkVal[0].storeId}`
|
||||
);
|
||||
},
|
||||
|
||||
// 判断团长以及团员信息
|
||||
pintuanWay() {
|
||||
const { memberId } = this.routerVal.parentOrder;
|
||||
|
||||
const userInfo = this.isLogin();
|
||||
if (memberId) {
|
||||
this.endWay = userInfo;
|
||||
this.masterWay = this.routerVal.parentOrder;
|
||||
this.pintuanFlage = false;
|
||||
} else {
|
||||
this.pintuanFlage = true;
|
||||
this.masterWay = userInfo;
|
||||
} else if (
|
||||
shippingText.value === 'LOGISTICS' &&
|
||||
orderMessage.value.cartTypeEnum !== 'VIRTUAL'
|
||||
) {
|
||||
if (!address.value.id) {
|
||||
uni.showToast({
|
||||
title: '请选择地址',
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
return false
|
||||
}
|
||||
},
|
||||
// 判断发票
|
||||
invoice() {
|
||||
this.invoiceFlag = true;
|
||||
},
|
||||
}
|
||||
|
||||
// 领取优惠券
|
||||
GET_Discount() {
|
||||
// 循环店铺id,商品id获取优惠券
|
||||
let store = [];
|
||||
let skus = [];
|
||||
let selectedCoupon = [];
|
||||
if (this.orderMessage.platformCoupon)
|
||||
selectedCoupon.push(this.orderMessage.platformCoupon.memberCoupon.id);
|
||||
if (
|
||||
this.orderMessage.storeCoupons &&
|
||||
Object.keys(this.orderMessage.storeCoupons)[0]
|
||||
) {
|
||||
let storeMemberCouponsId = Object.keys(
|
||||
this.orderMessage.storeCoupons
|
||||
)[0];
|
||||
let storeCouponId =
|
||||
this.orderMessage.storeCoupons[storeMemberCouponsId].memberCoupon.id;
|
||||
selectedCoupon.push(storeCouponId);
|
||||
}
|
||||
this.orderMessage.cartList.forEach((item) => {
|
||||
item.skuList.forEach((sku) => {
|
||||
store.push(sku.storeId);
|
||||
skus.push(sku.goodsSku.id);
|
||||
});
|
||||
});
|
||||
store = Array.from(new Set(store));
|
||||
skus = Array.from(new Set(skus));
|
||||
uni.setStorage({
|
||||
key: "totalPrice",
|
||||
data: this.orderMessage.priceDetailDTO.goodsPrice,
|
||||
});
|
||||
this.navigateTo(
|
||||
`/pages/cart/coupon/index?way=${this.routerVal.way}&storeId=${store}&skuId=${skus}&selectedCoupon=${selectedCoupon}`
|
||||
);
|
||||
},
|
||||
let client
|
||||
// #ifdef H5
|
||||
client = 'H5'
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN
|
||||
client = 'WECHAT_MP'
|
||||
// #endif
|
||||
// #ifdef APP-PLUS
|
||||
client = 'APP'
|
||||
// #endif
|
||||
|
||||
/**
|
||||
* 跳转
|
||||
*/
|
||||
navigateTo(url) {
|
||||
uni.navigateTo({
|
||||
url,
|
||||
});
|
||||
},
|
||||
const submit: Record<string, any> = {
|
||||
client,
|
||||
way: routerVal.value.way,
|
||||
remark: remarkVal.value,
|
||||
parentOrderSn: '',
|
||||
}
|
||||
if (routerVal.value.parentOrder && routerVal.value.parentOrder.orderSn) {
|
||||
submit.parentOrderSn = routerVal.value.parentOrder.orderSn
|
||||
} else {
|
||||
delete submit.parentOrderSn
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交订单准备支付
|
||||
*/
|
||||
|
||||
// 创建订单
|
||||
createTradeFun() {
|
||||
// 防抖
|
||||
this.$u.throttle(() => {
|
||||
if (this.shippingText === "SELF_PICK_UP") {
|
||||
if (!this.storeAddress.id) {
|
||||
uni.showToast({
|
||||
title: "请选择提货点",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
return false;
|
||||
}
|
||||
} else if (this.shippingText === "LOGISTICS" && this.orderMessage.cartTypeEnum !== 'VIRTUAL') {
|
||||
if (!this.address.id) {
|
||||
uni.showToast({
|
||||
title: "请选择地址",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 创建订单
|
||||
let client;
|
||||
// #ifdef H5
|
||||
client = "H5";
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN
|
||||
client = "WECHAT_MP";
|
||||
// #endif
|
||||
// #ifdef APP-PLUS
|
||||
client = "APP";
|
||||
// #endif
|
||||
|
||||
let submit = {
|
||||
client,
|
||||
way: this.routerVal.way,
|
||||
remark: this.remarkVal,
|
||||
parentOrderSn: "",
|
||||
};
|
||||
// 如果是拼团并且当前用户不是团长
|
||||
this.routerVal.parentOrder && this.routerVal.parentOrder.orderSn
|
||||
? (submit.parentOrderSn = this.routerVal.parentOrder.orderSn)
|
||||
: delete submit.parentOrderSn;
|
||||
|
||||
/**
|
||||
* 创建订单
|
||||
*/
|
||||
API_Trade.createTrade(submit).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({
|
||||
title: "创建订单成功!",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
// 如果当前价格为0跳转到订单列表
|
||||
if (this.orderMessage.priceDetailDTO.billPrice == 0) {
|
||||
uni.navigateTo({
|
||||
url: "/pages/order/myOrder?status=0",
|
||||
});
|
||||
} else {
|
||||
// #ifdef MP-WEIXIN
|
||||
// 微信小程序中点击创建订单直接开始支付
|
||||
this.pay(res.data.result.sn);
|
||||
// #endif
|
||||
|
||||
// #ifndef MP-WEIXIN
|
||||
this.navigateTo(
|
||||
`/pages/cart/payment/payOrder?trade_sn=${res.data.result.sn}`
|
||||
);
|
||||
// #endif
|
||||
}
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.data.message,
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
});
|
||||
}, 3000);
|
||||
},
|
||||
|
||||
/**
|
||||
* 微信小程序中直接支付
|
||||
*/
|
||||
async pay(sn) {
|
||||
new LiLiWXPay({
|
||||
sn: sn,
|
||||
price: this.orderMessage.priceDetailDTO.billPrice,
|
||||
}).pay();
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取用户地址
|
||||
*/
|
||||
getUserAddress() {
|
||||
// 如果没有商品选择地址的话 则选择 默认地址
|
||||
API_Address.getAddressDefault().then((res) => {
|
||||
if (res.data.result) {
|
||||
res.data.result.consigneeAddressPath =
|
||||
res.data.result.consigneeAddressPath.split(",");
|
||||
this.address = res.data.result;
|
||||
}
|
||||
});
|
||||
},
|
||||
// 获取配送列表
|
||||
async getDistribution() {
|
||||
let shopRes = await API_Trade.shippingMethodList({
|
||||
way: this.routerVal.way,
|
||||
});
|
||||
let shopList;
|
||||
if (shopRes.data.success) {
|
||||
shopList = shopRes.data.result;
|
||||
let way = [];
|
||||
console.log(shopList);
|
||||
this.shippingWay.forEach((item) => {
|
||||
shopList.forEach((child) => {
|
||||
if (item.value == child) {
|
||||
way.push(item);
|
||||
}
|
||||
});
|
||||
});
|
||||
this.shippingMethod = way;
|
||||
if (way.length && !way.some((item) => item.value === this.shippingText)) {
|
||||
this.shippingText = way[0].value;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 选择配送
|
||||
async confirmDistribution(val) {
|
||||
const selected = val?.value?.[0] || val?.[0];
|
||||
if (!selected?.value) {
|
||||
return;
|
||||
}
|
||||
let res = await API_Trade.setShipMethod({
|
||||
shippingMethod: selected.value,
|
||||
way: this.routerVal.way,
|
||||
});
|
||||
|
||||
this.shippingText = selected.value;
|
||||
API_Trade.createTrade(submit).then((res) => {
|
||||
if (res.data.success) {
|
||||
this.getOrderList();
|
||||
}
|
||||
},
|
||||
|
||||
// 获取结算参数
|
||||
getOrderList() {
|
||||
this.notSupportFreight = [];
|
||||
this.notSupportFreightNoticeText = "";
|
||||
return API_Trade.getCheckoutParams(this.routerVal.way).then((res) => {
|
||||
// 获取结算参数 进行首次判断
|
||||
this.originOrderData = this.orderMessage
|
||||
? JSON.parse(JSON.stringify(this.orderMessage))
|
||||
: null;
|
||||
|
||||
if (
|
||||
!res.data.result.checkedSkuList ||
|
||||
res.data.result.checkedSkuList.length === 0
|
||||
) {
|
||||
if (!this.originOrderData?.checkedSkuList?.length) {
|
||||
uni.switchTab({
|
||||
url: "/pages/tabbar/cart/cartList",
|
||||
});
|
||||
}
|
||||
}
|
||||
if (res.data.result.skuList.length <= 0) {
|
||||
if (!this.originOrderData?.skuList?.length) {
|
||||
uni.navigateTo({
|
||||
url: "/pages/order/myOrder?status=0",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let repeatData;
|
||||
res.data.result.cartList.forEach((item, index) => {
|
||||
// 如果已经写过备注信息的话赋值
|
||||
repeatData = {
|
||||
remark: this.remarkFlag
|
||||
? this.remark[index].storeId == item.storeId
|
||||
? this.remark[index].remark
|
||||
: item.remark
|
||||
: item.remark,
|
||||
storeId: item.storeId,
|
||||
};
|
||||
|
||||
this.remarkVal[index] = repeatData;
|
||||
});
|
||||
|
||||
this.orderMessage = res.data.result;
|
||||
/**
|
||||
* 为了避免路径传值在h5中超出限制问题
|
||||
* 这块将可用的优惠券以及不可用的优惠券放入到vuex里面进行存储
|
||||
*/
|
||||
this.$store.state.canUseCoupons = res.data.result.canUseCoupons;
|
||||
this.$store.state.cantUseCoupons = res.data.result.cantUseCoupons;
|
||||
|
||||
if (!res.data.result.memberAddress) {
|
||||
// 获取会员默认地址
|
||||
this.getUserAddress();
|
||||
uni.showToast({
|
||||
title: '创建订单成功!',
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
if (orderMessage.value.priceDetailDTO.billPrice == 0) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/order/myOrder?status=0',
|
||||
})
|
||||
} else {
|
||||
this.address = res.data.result.memberAddress;
|
||||
res.data.result.memberAddress.consigneeAddressPath =
|
||||
res.data.result.memberAddress.consigneeAddressPath.split(",");
|
||||
}
|
||||
if (res.data.result.storeAddress) {
|
||||
this.storeAddress = res.data.result.storeAddress;
|
||||
console.log("storeAddress", this.storeAddress);
|
||||
}
|
||||
if (
|
||||
res.data.result.notSupportFreight &&
|
||||
res.data.result.notSupportFreight.length != 0
|
||||
) {
|
||||
this.notSupportFreight = res.data.result.notSupportFreight;
|
||||
this.notSupportFreightNoticeText = "以下商品超出配送范围:";
|
||||
res.data.result.notSupportFreight.forEach((item) => {
|
||||
this.notSupportFreightNoticeText += item.goodsSku.goodsName;
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
// #ifdef MP-WEIXIN
|
||||
pay(res.data.result.sn)
|
||||
// #endif
|
||||
|
||||
//
|
||||
},
|
||||
};
|
||||
// #ifndef MP-WEIXIN
|
||||
navigateTo(
|
||||
`/pages/cart/payment/payOrder?trade_sn=${res.data.result.sn}`
|
||||
)
|
||||
// #endif
|
||||
}
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.data.message,
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
}
|
||||
})
|
||||
}, 3000)
|
||||
}
|
||||
|
||||
async function pay(sn: string) {
|
||||
new LiLiWXPay({
|
||||
sn,
|
||||
price: orderMessage.value.priceDetailDTO.billPrice,
|
||||
}).pay()
|
||||
}
|
||||
|
||||
function getUserAddress() {
|
||||
API_Address.getAddressDefault().then((res) => {
|
||||
if (res.data.result) {
|
||||
res.data.result.consigneeAddressPath =
|
||||
res.data.result.consigneeAddressPath.split(',')
|
||||
address.value = res.data.result
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async function getDistribution() {
|
||||
const shopRes = await API_Trade.shippingMethodList({
|
||||
way: routerVal.value.way,
|
||||
})
|
||||
if (shopRes.data.success) {
|
||||
const shopList = shopRes.data.result
|
||||
const way: ShippingOption[] = []
|
||||
console.log(shopList)
|
||||
shippingWay.forEach((item) => {
|
||||
shopList.forEach((child: string) => {
|
||||
if (item.value == child) {
|
||||
way.push(item)
|
||||
}
|
||||
})
|
||||
})
|
||||
shippingMethod.value = way
|
||||
if (way.length && !way.some((item) => item.value === shippingText.value)) {
|
||||
shippingText.value = way[0].value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function confirmDistribution(val: any) {
|
||||
const selected = val?.value?.[0] || val?.[0]
|
||||
if (!selected?.value) {
|
||||
return
|
||||
}
|
||||
const res = await API_Trade.setShipMethod({
|
||||
shippingMethod: selected.value,
|
||||
way: routerVal.value.way,
|
||||
})
|
||||
|
||||
shippingText.value = selected.value
|
||||
if (res.data.success) {
|
||||
getOrderList()
|
||||
}
|
||||
}
|
||||
|
||||
function getOrderList() {
|
||||
notSupportFreight.value = []
|
||||
notSupportFreightNoticeText.value = ''
|
||||
return API_Trade.getCheckoutParams(routerVal.value.way).then((res) => {
|
||||
originOrderData.value = orderMessage.value
|
||||
? JSON.parse(JSON.stringify(orderMessage.value))
|
||||
: null
|
||||
|
||||
if (
|
||||
!res.data.result.checkedSkuList ||
|
||||
res.data.result.checkedSkuList.length === 0
|
||||
) {
|
||||
if (!originOrderData.value?.checkedSkuList?.length) {
|
||||
uni.switchTab({
|
||||
url: '/pages/tabbar/cart/cartList',
|
||||
})
|
||||
}
|
||||
}
|
||||
if (res.data.result.skuList.length <= 0) {
|
||||
if (!originOrderData.value?.skuList?.length) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/order/myOrder?status=0',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
let repeatData
|
||||
res.data.result.cartList.forEach((item: any, index: number) => {
|
||||
repeatData = {
|
||||
remark: remarkFlag.value
|
||||
? remark.value[index].storeId == item.storeId
|
||||
? remark.value[index].remark
|
||||
: item.remark
|
||||
: item.remark,
|
||||
storeId: item.storeId,
|
||||
}
|
||||
|
||||
remarkVal.value[index] = repeatData
|
||||
})
|
||||
|
||||
orderMessage.value = res.data.result
|
||||
;(store.state as any).canUseCoupons = res.data.result.canUseCoupons
|
||||
;(store.state as any).cantUseCoupons = res.data.result.cantUseCoupons
|
||||
|
||||
if (!res.data.result.memberAddress) {
|
||||
getUserAddress()
|
||||
} else {
|
||||
address.value = res.data.result.memberAddress
|
||||
res.data.result.memberAddress.consigneeAddressPath =
|
||||
res.data.result.memberAddress.consigneeAddressPath.split(',')
|
||||
}
|
||||
if (res.data.result.storeAddress) {
|
||||
storeAddress.value = res.data.result.storeAddress
|
||||
console.log('storeAddress', storeAddress.value)
|
||||
}
|
||||
if (
|
||||
res.data.result.notSupportFreight &&
|
||||
res.data.result.notSupportFreight.length != 0
|
||||
) {
|
||||
notSupportFreight.value = res.data.result.notSupportFreight
|
||||
notSupportFreightNoticeText.value = '以下商品超出配送范围:'
|
||||
res.data.result.notSupportFreight.forEach((item: any) => {
|
||||
notSupportFreightNoticeText.value += item.goodsSku.goodsName
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
page {
|
||||
|
||||
@@ -74,185 +74,128 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getReceiptDetail } from "@/api/order.js";
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { getReceiptDetail } from '@/api/order.js'
|
||||
import { unitPrice } from '@/utils/filters.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
order: {},
|
||||
title_type: "",
|
||||
showInvoicePopup: false,
|
||||
};
|
||||
},
|
||||
onLoad(options) {
|
||||
this.loadData(options.id);
|
||||
},
|
||||
methods: {
|
||||
loadData(id) {
|
||||
getReceiptDetail(id).then((res) => {
|
||||
let order = res.data.result;
|
||||
this.order = order;
|
||||
this.title_type = order.companyName || order.taxpayerId ? "单位" : "个人";
|
||||
});
|
||||
},
|
||||
getTitleNameValue() {
|
||||
return this.title_type === "单位"
|
||||
? this.order.companyName || "-"
|
||||
: this.order.personalName || "-";
|
||||
},
|
||||
viewInvoice() {
|
||||
if (!this.order.invoiceAddress) {
|
||||
const order = ref<Record<string, any>>({})
|
||||
const title_type = ref('')
|
||||
const showInvoicePopup = ref(false)
|
||||
|
||||
onLoad((options) => {
|
||||
loadData(options.id)
|
||||
})
|
||||
|
||||
function loadData(id: string) {
|
||||
getReceiptDetail(id).then((res) => {
|
||||
const result = res.data.result
|
||||
order.value = result
|
||||
title_type.value = result.companyName || result.taxpayerId ? '单位' : '个人'
|
||||
})
|
||||
}
|
||||
|
||||
function getTitleNameValue() {
|
||||
return title_type.value === '单位'
|
||||
? order.value.companyName || '-'
|
||||
: order.value.personalName || '-'
|
||||
}
|
||||
|
||||
function viewInvoice() {
|
||||
if (!order.value.invoiceAddress) {
|
||||
uni.showToast({
|
||||
title: '暂无发票地址',
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
return
|
||||
}
|
||||
if (isImageInvoice()) {
|
||||
showInvoicePopup.value = true
|
||||
return
|
||||
}
|
||||
// #ifdef APP-PLUS
|
||||
plus.runtime.openURL(order.value.invoiceAddress)
|
||||
// #endif
|
||||
// #ifndef APP-PLUS
|
||||
uni.navigateTo({
|
||||
url: '/pages/tabbar/home/web-view?src=' + encodeURIComponent(order.value.invoiceAddress),
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
|
||||
function isImageInvoice() {
|
||||
const url = (order.value.invoiceAddress || '').split('?')[0].toLowerCase()
|
||||
return /\.(png|jpe?g|gif|bmp|webp)$/.test(url)
|
||||
}
|
||||
|
||||
function previewImageInvoice() {
|
||||
if (!order.value.invoiceAddress) return
|
||||
uni.previewImage({
|
||||
current: 0,
|
||||
urls: [order.value.invoiceAddress],
|
||||
})
|
||||
}
|
||||
|
||||
function downloadImageInvoice() {
|
||||
if (!order.value.invoiceAddress) {
|
||||
uni.showToast({
|
||||
title: '暂无发票可下载',
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
return
|
||||
}
|
||||
uni.downloadFile({
|
||||
url: order.value.invoiceAddress,
|
||||
success: (res) => {
|
||||
if (res.statusCode !== 200) {
|
||||
uni.showToast({
|
||||
title: "暂无发票地址",
|
||||
title: '下载失败',
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
return;
|
||||
icon: 'none',
|
||||
})
|
||||
return
|
||||
}
|
||||
if (this.isImageInvoice()) {
|
||||
this.showInvoicePopup = true;
|
||||
return;
|
||||
}
|
||||
// #ifdef APP-PLUS
|
||||
plus.runtime.openURL(this.order.invoiceAddress);
|
||||
const tempFilePath = res.tempFilePath
|
||||
// #ifdef H5
|
||||
const link = document.createElement('a')
|
||||
link.href = tempFilePath || order.value.invoiceAddress
|
||||
link.download = 'invoice'
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
// #endif
|
||||
// #ifndef APP-PLUS
|
||||
uni.navigateTo({
|
||||
url:
|
||||
"/pages/tabbar/home/web-view?src=" +
|
||||
encodeURIComponent(this.order.invoiceAddress),
|
||||
});
|
||||
// #endif
|
||||
},
|
||||
isImageInvoice() {
|
||||
const url = (this.order.invoiceAddress || "").split("?")[0].toLowerCase();
|
||||
return /\.(png|jpe?g|gif|bmp|webp)$/.test(url);
|
||||
},
|
||||
previewImageInvoice() {
|
||||
if (!this.order.invoiceAddress) {
|
||||
return;
|
||||
}
|
||||
uni.previewImage({
|
||||
current: 0,
|
||||
urls: [this.order.invoiceAddress],
|
||||
});
|
||||
},
|
||||
downloadImageInvoice() {
|
||||
if (!this.order.invoiceAddress) {
|
||||
uni.showToast({
|
||||
title: "暂无发票可下载",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
return;
|
||||
}
|
||||
uni.downloadFile({
|
||||
url: this.order.invoiceAddress,
|
||||
success: (res) => {
|
||||
if (res.statusCode !== 200) {
|
||||
uni.showToast({
|
||||
title: "下载失败",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
return;
|
||||
}
|
||||
const tempFilePath = res.tempFilePath;
|
||||
// #ifdef H5
|
||||
const link = document.createElement("a");
|
||||
link.href = tempFilePath || this.order.invoiceAddress;
|
||||
link.download = "invoice";
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
// #endif
|
||||
// #ifndef H5
|
||||
uni.saveImageToPhotosAlbum({
|
||||
filePath: tempFilePath,
|
||||
success: () => {
|
||||
uni.showToast({
|
||||
title: "发票已保存到相册",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
},
|
||||
fail: () => {
|
||||
uni.showToast({
|
||||
title: "保存失败",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
},
|
||||
});
|
||||
// #endif
|
||||
// #ifndef H5
|
||||
uni.saveImageToPhotosAlbum({
|
||||
filePath: tempFilePath,
|
||||
success: () => {
|
||||
uni.showToast({
|
||||
title: '发票已保存到相册',
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
},
|
||||
fail: () => {
|
||||
uni.showToast({
|
||||
title: "下载失败",
|
||||
title: '保存失败',
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
icon: 'none',
|
||||
})
|
||||
},
|
||||
});
|
||||
})
|
||||
// #endif
|
||||
},
|
||||
/**
|
||||
* 点击图片放大或保存
|
||||
*/
|
||||
preview() {
|
||||
//预览发票
|
||||
if (this.order.elec_file_list.length) {
|
||||
uni.previewImage({
|
||||
current: 0,
|
||||
urls: this.order.elec_file_list,
|
||||
longPressActions: {
|
||||
itemList: ["发送给朋友", "保存图片", "收藏"],
|
||||
success: function (data) {},
|
||||
fail: function (err) {},
|
||||
},
|
||||
});
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: "暂无发票可预览",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
fail: () => {
|
||||
uni.showToast({
|
||||
title: '下载失败',
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
},
|
||||
download() {
|
||||
//下载发票
|
||||
let _this = this;
|
||||
if (this.order.elec_file_list.length) {
|
||||
this.order.elec_file_list.forEach((item) => {
|
||||
uni.downloadFile({
|
||||
url: item,
|
||||
success: (res) => {
|
||||
if (res.statusCode === 200) {
|
||||
let tempFilePath = res.tempFilePath;
|
||||
uni.saveFile({
|
||||
tempFilePath: tempFilePath,
|
||||
success: function (res) {
|
||||
uni.showToast({
|
||||
title: "发票已下载到" + res.savedFilePath,
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
});
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: "暂无发票可下载",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -92,340 +92,355 @@
|
||||
</div>
|
||||
</u-popup>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: ["res"],
|
||||
computed: {
|
||||
isSpecialInvoice() {
|
||||
return this.getActiveTitle(this.invoiceType) === "增值税专用发票";
|
||||
},
|
||||
titleName: {
|
||||
get() {
|
||||
return this.isUnitTitle()
|
||||
? this.submitData.companyName
|
||||
: this.submitData.personalName;
|
||||
},
|
||||
set(value) {
|
||||
if (this.isUnitTitle()) {
|
||||
this.submitData.companyName = value;
|
||||
} else {
|
||||
this.submitData.personalName = value;
|
||||
}
|
||||
this.syncReceiptTitle();
|
||||
},
|
||||
},
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed, watch, onMounted, getCurrentInstance } from 'vue'
|
||||
|
||||
interface InvoiceOption {
|
||||
title: string
|
||||
active: boolean
|
||||
disabled?: boolean
|
||||
}
|
||||
|
||||
interface SubmitData {
|
||||
receiptTitle: string
|
||||
receiptType: string
|
||||
personalName: string
|
||||
companyName: string
|
||||
taxpayerId: string
|
||||
receiptContent: string
|
||||
companyAddress: string
|
||||
companyPhone: string
|
||||
bankName: string
|
||||
bankAccount: string
|
||||
receiptPhone: string
|
||||
receiptEmail: string
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
res?: Record<string, any>
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
callbackInvoice: [val: SubmitData | boolean]
|
||||
}>()
|
||||
|
||||
const { proxy } = getCurrentInstance()!
|
||||
|
||||
const shouldClearOnTypeChange = ref(false)
|
||||
const taxpayerFlag = ref(false)
|
||||
const submitData = reactive<SubmitData>({
|
||||
receiptTitle: '',
|
||||
receiptType: '1',
|
||||
personalName: '',
|
||||
companyName: '',
|
||||
taxpayerId: '',
|
||||
receiptContent: '',
|
||||
companyAddress: '',
|
||||
companyPhone: '',
|
||||
bankName: '',
|
||||
bankAccount: '',
|
||||
receiptPhone: '',
|
||||
receiptEmail: '',
|
||||
})
|
||||
const show = ref(true)
|
||||
const title = ref('')
|
||||
const tips =
|
||||
'电子发票即电子增值税发票,是税局认可的有效凭证,其法律效力、基本用途及使用规定同纸质发票。'
|
||||
|
||||
const invoiceType = reactive<InvoiceOption[]>([
|
||||
{ title: '电子普通发票', active: true },
|
||||
{ title: '增值税专用发票', active: false },
|
||||
])
|
||||
|
||||
const invoiceHeader = reactive<InvoiceOption[]>([
|
||||
{ title: '个人', active: false },
|
||||
{ title: '单位', active: false },
|
||||
])
|
||||
|
||||
const goodsType = reactive<InvoiceOption[]>([
|
||||
{ title: '商品明细', active: false },
|
||||
{ title: '商品类别', active: false },
|
||||
])
|
||||
|
||||
const isSpecialInvoice = computed(
|
||||
() => getActiveTitle(invoiceType) === '增值税专用发票'
|
||||
)
|
||||
|
||||
const titleName = computed({
|
||||
get() {
|
||||
return isUnitTitle() ? submitData.companyName : submitData.personalName
|
||||
},
|
||||
watch: {
|
||||
invoiceType: {
|
||||
handler(val) {
|
||||
const currentType = this.getActiveTitle(val);
|
||||
const nextReceiptType =
|
||||
currentType === "增值税专用发票" ? "2" : "1";
|
||||
const previousReceiptType = this.submitData.receiptType;
|
||||
this.submitData.receiptType = nextReceiptType;
|
||||
|
||||
if (
|
||||
this.shouldClearOnTypeChange &&
|
||||
previousReceiptType &&
|
||||
previousReceiptType !== nextReceiptType
|
||||
) {
|
||||
this.clearInvoiceInfo();
|
||||
}
|
||||
|
||||
if (currentType === "增值税专用发票") {
|
||||
this.setActiveByTitle(this.invoiceHeader, "单位");
|
||||
this.setActiveByTitle(this.goodsType, "商品明细");
|
||||
this.title = "单位";
|
||||
this.taxpayerFlag = true;
|
||||
this.submitData.receiptContent = "商品明细";
|
||||
this.syncReceiptTitle();
|
||||
} else {
|
||||
this.setActiveByTitle(this.invoiceHeader, "个人");
|
||||
this.setActiveByTitle(this.goodsType, "商品明细");
|
||||
this.title = "个人";
|
||||
this.taxpayerFlag = false;
|
||||
this.submitData.receiptContent = "商品明细";
|
||||
this.syncReceiptTitle();
|
||||
}
|
||||
this.shouldClearOnTypeChange = false;
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
invoiceHeader: {
|
||||
handler(val) {
|
||||
if (this.isSpecialInvoice) {
|
||||
this.title = "单位";
|
||||
this.taxpayerFlag = true;
|
||||
return;
|
||||
}
|
||||
|
||||
this.title = this.getActiveTitle(val) || "个人";
|
||||
this.taxpayerFlag = this.title == "单位";
|
||||
if (!this.taxpayerFlag) {
|
||||
this.submitData.taxpayerId = "";
|
||||
}
|
||||
this.syncReceiptTitle();
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
goodsType: {
|
||||
handler(val) {
|
||||
this.submitData.receiptContent = val.filter((item) => {
|
||||
return item.active == true;
|
||||
})[0].title;
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
shouldClearOnTypeChange: false,
|
||||
taxpayerFlag: false,
|
||||
submitData: {
|
||||
receiptTitle: "", //发票抬头
|
||||
receiptType: "1", // 发票类型
|
||||
personalName: "",
|
||||
companyName: "",
|
||||
taxpayerId: "", //纳税人
|
||||
receiptContent: "",
|
||||
companyAddress: "", //单位地址
|
||||
companyPhone: "", //单位电话
|
||||
bankName: "", //开户银行
|
||||
bankAccount: "", //银行账号
|
||||
receiptPhone: "", //收票人手机
|
||||
receiptEmail: "", //收票人邮箱
|
||||
},
|
||||
show: true,
|
||||
title: "",
|
||||
tips:
|
||||
"电子发票即电子增值税发票,是税局认可的有效凭证,其法律效力、基本用途及使用规定同纸质发票。",
|
||||
// 发票类型
|
||||
invoiceType: [
|
||||
{
|
||||
title: "电子普通发票",
|
||||
active: true,
|
||||
},
|
||||
{
|
||||
title: "增值税专用发票",
|
||||
active: false,
|
||||
},
|
||||
],
|
||||
// 发票抬头
|
||||
invoiceHeader: [
|
||||
{
|
||||
title: "个人",
|
||||
active: false,
|
||||
},
|
||||
{
|
||||
title: "单位",
|
||||
active: false,
|
||||
},
|
||||
],
|
||||
// 商品类型
|
||||
goodsType: [
|
||||
{
|
||||
title: "商品明细",
|
||||
active: false,
|
||||
},
|
||||
{
|
||||
title: "商品类别",
|
||||
active: false,
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
if (this.res) {
|
||||
this.submitData.receiptType = this.normalizeReceiptType(this.res.receiptType);
|
||||
this.submitData.personalName =
|
||||
this.res.personalName ||
|
||||
(!this.res.companyName && !this.res.taxpayerId ? this.res.receiptTitle || "" : "");
|
||||
this.submitData.companyName =
|
||||
this.res.companyName ||
|
||||
(this.res.taxpayerId ? this.res.receiptTitle || "" : "");
|
||||
this.submitData.taxpayerId = this.res.taxpayerId; //纳税人
|
||||
this.submitData.receiptContent = this.res.receiptContent;
|
||||
this.submitData.companyAddress = this.res.companyAddress || "";
|
||||
this.submitData.companyPhone = this.res.companyPhone || "";
|
||||
this.submitData.bankName = this.res.bankName || "";
|
||||
this.submitData.bankAccount = this.res.bankAccount || "";
|
||||
this.submitData.receiptPhone = this.res.receiptPhone || "";
|
||||
this.submitData.receiptEmail = this.res.receiptEmail || "";
|
||||
if (this.submitData.receiptType === "2") {
|
||||
this.setActiveByTitle(this.invoiceType, "增值税专用发票");
|
||||
this.setActiveByTitle(this.invoiceHeader, "单位");
|
||||
this.setActiveByTitle(this.goodsType, "商品明细");
|
||||
} else {
|
||||
this.setActiveByTitle(this.invoiceType, "电子普通发票");
|
||||
this.res.receiptContent == "商品类别"
|
||||
? this.setActiveByTitle(this.goodsType, "商品类别")
|
||||
: this.setActiveByTitle(this.goodsType, "商品明细");
|
||||
this.res.taxpayerId
|
||||
? this.setActiveByTitle(this.invoiceHeader, "单位")
|
||||
: this.setActiveByTitle(this.invoiceHeader, "个人");
|
||||
}
|
||||
this.syncReceiptTitle();
|
||||
set(value: string) {
|
||||
if (isUnitTitle()) {
|
||||
submitData.companyName = value
|
||||
} else {
|
||||
this.setActiveByTitle(this.invoiceType, "电子普通发票");
|
||||
this.setActiveByTitle(this.invoiceHeader, "个人");
|
||||
this.setActiveByTitle(this.goodsType, "商品明细");
|
||||
this.syncReceiptTitle();
|
||||
submitData.personalName = value
|
||||
}
|
||||
syncReceiptTitle()
|
||||
},
|
||||
})
|
||||
|
||||
watch(
|
||||
invoiceType,
|
||||
(val) => {
|
||||
const currentType = getActiveTitle(val)
|
||||
const nextReceiptType = currentType === '增值税专用发票' ? '2' : '1'
|
||||
const previousReceiptType = submitData.receiptType
|
||||
submitData.receiptType = nextReceiptType
|
||||
|
||||
if (
|
||||
shouldClearOnTypeChange.value &&
|
||||
previousReceiptType &&
|
||||
previousReceiptType !== nextReceiptType
|
||||
) {
|
||||
clearInvoiceInfo()
|
||||
}
|
||||
|
||||
if (currentType === '增值税专用发票') {
|
||||
setActiveByTitle(invoiceHeader, '单位')
|
||||
setActiveByTitle(goodsType, '商品明细')
|
||||
title.value = '单位'
|
||||
taxpayerFlag.value = true
|
||||
submitData.receiptContent = '商品明细'
|
||||
syncReceiptTitle()
|
||||
} else {
|
||||
setActiveByTitle(invoiceHeader, '个人')
|
||||
setActiveByTitle(goodsType, '商品明细')
|
||||
title.value = '个人'
|
||||
taxpayerFlag.value = false
|
||||
submitData.receiptContent = '商品明细'
|
||||
syncReceiptTitle()
|
||||
}
|
||||
shouldClearOnTypeChange.value = false
|
||||
},
|
||||
methods: {
|
||||
normalizeReceiptType(type) {
|
||||
return type === "2" || type === "VATOSPECIAL" ? "2" : "1";
|
||||
},
|
||||
getActiveTitle(list) {
|
||||
const current = list.find((item) => item.active);
|
||||
return current ? current.title : "";
|
||||
},
|
||||
setActiveByTitle(list, title) {
|
||||
list.forEach((item) => {
|
||||
item.active = item.title === title;
|
||||
});
|
||||
},
|
||||
isUnitTitle() {
|
||||
return this.isSpecialInvoice || this.title === "单位";
|
||||
},
|
||||
syncReceiptTitle() {
|
||||
this.submitData.receiptTitle = this.isUnitTitle()
|
||||
? this.submitData.companyName
|
||||
: this.submitData.personalName;
|
||||
},
|
||||
clearInvoiceInfo() {
|
||||
this.submitData.receiptTitle = "";
|
||||
this.submitData.personalName = "";
|
||||
this.submitData.companyName = "";
|
||||
this.submitData.taxpayerId = "";
|
||||
this.submitData.receiptContent = "";
|
||||
this.submitData.companyAddress = "";
|
||||
this.submitData.companyPhone = "";
|
||||
this.submitData.bankName = "";
|
||||
this.submitData.bankAccount = "";
|
||||
this.submitData.receiptPhone = "";
|
||||
this.submitData.receiptEmail = "";
|
||||
},
|
||||
handleClickHeader(val, index, arr) {
|
||||
if (val.disabled) {
|
||||
return;
|
||||
}
|
||||
const previousTitle = this.getActiveTitle(arr);
|
||||
if (arr === this.invoiceType && previousTitle !== val.title) {
|
||||
this.shouldClearOnTypeChange = true;
|
||||
}
|
||||
arr.forEach((item) => {
|
||||
item.active = false;
|
||||
});
|
||||
val.active = true;
|
||||
},
|
||||
/**
|
||||
* 监听关闭
|
||||
*/
|
||||
close(val) {
|
||||
this.$emit("callbackInvoice", val);
|
||||
},
|
||||
submitInvoice() {
|
||||
/**
|
||||
* 验证
|
||||
*/
|
||||
const {
|
||||
receiptTitle,
|
||||
taxpayerId,
|
||||
companyAddress,
|
||||
companyPhone,
|
||||
bankName,
|
||||
bankAccount,
|
||||
receiptPhone,
|
||||
receiptEmail,
|
||||
} = this.submitData;
|
||||
this.syncReceiptTitle();
|
||||
{ deep: true }
|
||||
)
|
||||
|
||||
if (this.$u.test.isEmpty(receiptTitle)) {
|
||||
uni.showToast({
|
||||
title: "请您填写发票抬头!",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
!this.$u.test.isEmpty(receiptTitle) &&
|
||||
this.$u.test.isEmpty(taxpayerId) &&
|
||||
this.invoiceHeader[1].active == true
|
||||
) {
|
||||
uni.showToast({
|
||||
title: "请您填写纳税人识别号!",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
watch(
|
||||
invoiceHeader,
|
||||
(val) => {
|
||||
if (isSpecialInvoice.value) {
|
||||
title.value = '单位'
|
||||
taxpayerFlag.value = true
|
||||
return
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
if (this.isSpecialInvoice && this.$u.test.isEmpty(companyAddress)) {
|
||||
uni.showToast({
|
||||
title: "请您填写单位地址!",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (this.isSpecialInvoice && this.$u.test.isEmpty(companyPhone)) {
|
||||
uni.showToast({
|
||||
title: "请您填写单位电话!",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (this.isSpecialInvoice && this.$u.test.isEmpty(bankName)) {
|
||||
uni.showToast({
|
||||
title: "请您填写开户银行!",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (this.isSpecialInvoice && this.$u.test.isEmpty(bankAccount)) {
|
||||
uni.showToast({
|
||||
title: "请您填写银行账号!",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (this.$u.test.isEmpty(receiptPhone)) {
|
||||
uni.showToast({
|
||||
title: "请您填写收票人手机!",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!this.$u.test.mobile(receiptPhone)) {
|
||||
uni.showToast({
|
||||
title: "请输入正确的收票人手机号!",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!this.$u.test.isEmpty(receiptEmail) && !this.$u.test.email(receiptEmail)) {
|
||||
uni.showToast({
|
||||
title: "请输入正确的收票人邮箱!",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
this.show = false;
|
||||
this.close(this.submitData);
|
||||
},
|
||||
title.value = getActiveTitle(val) || '个人'
|
||||
taxpayerFlag.value = title.value == '单位'
|
||||
if (!taxpayerFlag.value) {
|
||||
submitData.taxpayerId = ''
|
||||
}
|
||||
syncReceiptTitle()
|
||||
},
|
||||
};
|
||||
{ deep: true }
|
||||
)
|
||||
|
||||
watch(
|
||||
goodsType,
|
||||
(val) => {
|
||||
submitData.receiptContent = val.filter((item) => item.active == true)[0].title
|
||||
},
|
||||
{ deep: true }
|
||||
)
|
||||
|
||||
onMounted(() => {
|
||||
if (props.res) {
|
||||
submitData.receiptType = normalizeReceiptType(props.res.receiptType)
|
||||
submitData.personalName =
|
||||
props.res.personalName ||
|
||||
(!props.res.companyName && !props.res.taxpayerId
|
||||
? props.res.receiptTitle || ''
|
||||
: '')
|
||||
submitData.companyName =
|
||||
props.res.companyName ||
|
||||
(props.res.taxpayerId ? props.res.receiptTitle || '' : '')
|
||||
submitData.taxpayerId = props.res.taxpayerId
|
||||
submitData.receiptContent = props.res.receiptContent
|
||||
submitData.companyAddress = props.res.companyAddress || ''
|
||||
submitData.companyPhone = props.res.companyPhone || ''
|
||||
submitData.bankName = props.res.bankName || ''
|
||||
submitData.bankAccount = props.res.bankAccount || ''
|
||||
submitData.receiptPhone = props.res.receiptPhone || ''
|
||||
submitData.receiptEmail = props.res.receiptEmail || ''
|
||||
if (submitData.receiptType === '2') {
|
||||
setActiveByTitle(invoiceType, '增值税专用发票')
|
||||
setActiveByTitle(invoiceHeader, '单位')
|
||||
setActiveByTitle(goodsType, '商品明细')
|
||||
} else {
|
||||
setActiveByTitle(invoiceType, '电子普通发票')
|
||||
props.res.receiptContent == '商品类别'
|
||||
? setActiveByTitle(goodsType, '商品类别')
|
||||
: setActiveByTitle(goodsType, '商品明细')
|
||||
props.res.taxpayerId
|
||||
? setActiveByTitle(invoiceHeader, '单位')
|
||||
: setActiveByTitle(invoiceHeader, '个人')
|
||||
}
|
||||
syncReceiptTitle()
|
||||
} else {
|
||||
setActiveByTitle(invoiceType, '电子普通发票')
|
||||
setActiveByTitle(invoiceHeader, '个人')
|
||||
setActiveByTitle(goodsType, '商品明细')
|
||||
syncReceiptTitle()
|
||||
}
|
||||
})
|
||||
|
||||
function normalizeReceiptType(type: string) {
|
||||
return type === '2' || type === 'VATOSPECIAL' ? '2' : '1'
|
||||
}
|
||||
|
||||
function getActiveTitle(list: InvoiceOption[]) {
|
||||
const current = list.find((item) => item.active)
|
||||
return current ? current.title : ''
|
||||
}
|
||||
|
||||
function setActiveByTitle(list: InvoiceOption[], activeTitle: string) {
|
||||
list.forEach((item) => {
|
||||
item.active = item.title === activeTitle
|
||||
})
|
||||
}
|
||||
|
||||
function isUnitTitle() {
|
||||
return isSpecialInvoice.value || title.value === '单位'
|
||||
}
|
||||
|
||||
function syncReceiptTitle() {
|
||||
submitData.receiptTitle = isUnitTitle()
|
||||
? submitData.companyName
|
||||
: submitData.personalName
|
||||
}
|
||||
|
||||
function clearInvoiceInfo() {
|
||||
submitData.receiptTitle = ''
|
||||
submitData.personalName = ''
|
||||
submitData.companyName = ''
|
||||
submitData.taxpayerId = ''
|
||||
submitData.receiptContent = ''
|
||||
submitData.companyAddress = ''
|
||||
submitData.companyPhone = ''
|
||||
submitData.bankName = ''
|
||||
submitData.bankAccount = ''
|
||||
submitData.receiptPhone = ''
|
||||
submitData.receiptEmail = ''
|
||||
}
|
||||
|
||||
function handleClickHeader(
|
||||
val: InvoiceOption,
|
||||
_index: number,
|
||||
arr: InvoiceOption[]
|
||||
) {
|
||||
if (val.disabled) {
|
||||
return
|
||||
}
|
||||
const previousTitle = getActiveTitle(arr)
|
||||
if (arr === invoiceType && previousTitle !== val.title) {
|
||||
shouldClearOnTypeChange.value = true
|
||||
}
|
||||
arr.forEach((item) => {
|
||||
item.active = false
|
||||
})
|
||||
val.active = true
|
||||
}
|
||||
|
||||
function close(val: SubmitData | boolean) {
|
||||
emit('callbackInvoice', val)
|
||||
}
|
||||
|
||||
function submitInvoice() {
|
||||
const {
|
||||
receiptTitle,
|
||||
taxpayerId,
|
||||
companyAddress,
|
||||
companyPhone,
|
||||
bankName,
|
||||
bankAccount,
|
||||
receiptPhone,
|
||||
receiptEmail,
|
||||
} = submitData
|
||||
syncReceiptTitle()
|
||||
|
||||
if (proxy.$u.test.isEmpty(receiptTitle)) {
|
||||
uni.showToast({
|
||||
title: '请您填写发票抬头!',
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
return false
|
||||
}
|
||||
if (
|
||||
!proxy.$u.test.isEmpty(receiptTitle) &&
|
||||
proxy.$u.test.isEmpty(taxpayerId) &&
|
||||
invoiceHeader[1].active == true
|
||||
) {
|
||||
uni.showToast({
|
||||
title: '请您填写纳税人识别号!',
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
return false
|
||||
}
|
||||
if (isSpecialInvoice.value && proxy.$u.test.isEmpty(companyAddress)) {
|
||||
uni.showToast({
|
||||
title: '请您填写单位地址!',
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
return false
|
||||
}
|
||||
if (isSpecialInvoice.value && proxy.$u.test.isEmpty(companyPhone)) {
|
||||
uni.showToast({
|
||||
title: '请您填写单位电话!',
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
return false
|
||||
}
|
||||
if (isSpecialInvoice.value && proxy.$u.test.isEmpty(bankName)) {
|
||||
uni.showToast({
|
||||
title: '请您填写开户银行!',
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
return false
|
||||
}
|
||||
if (isSpecialInvoice.value && proxy.$u.test.isEmpty(bankAccount)) {
|
||||
uni.showToast({
|
||||
title: '请您填写银行账号!',
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
return false
|
||||
}
|
||||
if (proxy.$u.test.isEmpty(receiptPhone)) {
|
||||
uni.showToast({
|
||||
title: '请您填写收票人手机!',
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
return false
|
||||
}
|
||||
if (!proxy.$u.test.mobile(receiptPhone)) {
|
||||
uni.showToast({
|
||||
title: '请输入正确的收票人手机号!',
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
return false
|
||||
}
|
||||
if (
|
||||
!proxy.$u.test.isEmpty(receiptEmail) &&
|
||||
!proxy.$u.test.email(receiptEmail)
|
||||
) {
|
||||
uni.showToast({
|
||||
title: '请输入正确的收票人邮箱!',
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
return false
|
||||
}
|
||||
|
||||
show.value = false
|
||||
close(submitData)
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.form-item {
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<u-empty text="暂无订单" mode="list"
|
||||
v-if="tabItem.loaded === true && tabItem.orderList.length === 0"></u-empty>
|
||||
<!-- 订单列表 -->
|
||||
<view class="seller-view" :key="oderIndex" v-for="(order, oderIndex) in tabItem.orderList">
|
||||
<view class="seller-view" :key="orderIndex" v-for="(order, orderIndex) in tabItem.orderList">
|
||||
<!-- 店铺名称 -->
|
||||
<view class="seller-info u-flex u-row-between">
|
||||
<view class="seller-name wes" @click="navigateToStore(order)">
|
||||
@@ -108,458 +108,339 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import uniLoadMore from "@/components/uni-load-more/uni-load-more.vue";
|
||||
import {
|
||||
getOrderList,
|
||||
cancelOrder,
|
||||
confirmReceipt
|
||||
} from "@/api/order.js";
|
||||
import {
|
||||
getClearReason
|
||||
} from "@/api/after-sale.js";
|
||||
import LiLiWXPay from "@/js_sdk/lili-pay/wx-pay.js";
|
||||
export default {
|
||||
components: {
|
||||
uniLoadMore,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
lightColor: this.$lightColor,
|
||||
tabCurrentIndex: 0, //导航栏索引
|
||||
navList: [
|
||||
//导航栏list
|
||||
{
|
||||
state: 0,
|
||||
text: "全部",
|
||||
loadStatus: "more",
|
||||
orderList: [],
|
||||
pageNumber: 1,
|
||||
},
|
||||
{
|
||||
state: 1,
|
||||
text: "待付款",
|
||||
loadStatus: "more",
|
||||
orderList: [],
|
||||
pageNumber: 1,
|
||||
},
|
||||
{
|
||||
state: 2,
|
||||
text: "待发货",
|
||||
loadStatus: "more",
|
||||
orderList: [],
|
||||
pageNumber: 1,
|
||||
},
|
||||
{
|
||||
state: 3,
|
||||
text: "待收货",
|
||||
loadStatus: "more",
|
||||
orderList: [],
|
||||
pageNumber: 1,
|
||||
},
|
||||
{
|
||||
state: 4,
|
||||
text: "已完成",
|
||||
loadStatus: "more",
|
||||
orderList: [],
|
||||
pageNumber: 1,
|
||||
},
|
||||
{
|
||||
state: 5,
|
||||
text: "已取消",
|
||||
loadStatus: "more",
|
||||
orderList: [],
|
||||
pageNumber: 1,
|
||||
},
|
||||
],
|
||||
status: "", //接收导航栏状态
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
tag: "ALL",
|
||||
},
|
||||
orderStatus: [
|
||||
//订单状态
|
||||
{
|
||||
orderStatus: "ALL", //全部
|
||||
},
|
||||
{
|
||||
orderStatus: "WAIT_PAY", //代付款
|
||||
},
|
||||
{
|
||||
orderStatus: "WAIT_SHIP",
|
||||
},
|
||||
{
|
||||
orderStatus: "WAIT_ROG", //待收货
|
||||
},
|
||||
{
|
||||
orderStatus: "COMPLETE", //已完成
|
||||
},
|
||||
{
|
||||
orderStatus: "CANCELLED", //已取消
|
||||
},
|
||||
{
|
||||
orderStatus: "STAY_PICKED_UP", //待自提
|
||||
},
|
||||
],
|
||||
cancelShow: false, //是否显示取消
|
||||
orderSn: "", //ordersn
|
||||
reason: "", //取消原因
|
||||
cancelList: [], //取消列表
|
||||
rogShow: false, //显示是否收货
|
||||
};
|
||||
},
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed, watch, getCurrentInstance } from 'vue'
|
||||
import { onLoad, onShow, onPullDownRefresh, onBackPress } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import uniLoadMore from '@/components/uni-load-more/uni-load-more.vue'
|
||||
import { getOrderList, cancelOrder, confirmReceipt } from '@/api/order.js'
|
||||
import { getClearReason } from '@/api/after-sale.js'
|
||||
import LiLiWXPay from '@/js_sdk/lili-pay/wx-pay.js'
|
||||
import {
|
||||
unitPrice,
|
||||
parseGoodsImageUrl,
|
||||
tipsToLogin,
|
||||
orderStatusList,
|
||||
} from '@/utils/filters.js'
|
||||
|
||||
/**
|
||||
* 跳转到个人中心
|
||||
*/
|
||||
onBackPress(e) {
|
||||
if (e.from == "backbutton") {
|
||||
uni.switchTab({
|
||||
url: "/pages/tabbar/user/my",
|
||||
});
|
||||
return true; //阻止默认返回行为
|
||||
}
|
||||
},
|
||||
onPullDownRefresh() {
|
||||
if (this.tabCurrentIndex) {
|
||||
this.initData(this.tabCurrentIndex);
|
||||
} else {
|
||||
this.initData(0);
|
||||
}
|
||||
// this.loadData(this.status);
|
||||
},
|
||||
onShow() {
|
||||
if (this.tipsToLogin()) {
|
||||
if (!this.tabCurrentIndex) {
|
||||
this.initData(0);
|
||||
}
|
||||
}
|
||||
// this.loadData(this.status);
|
||||
},
|
||||
const store = useStore()
|
||||
const { proxy } = getCurrentInstance()!
|
||||
const lightColor = computed(() => store.getters.lightColor)
|
||||
const mainColor = computed(() => store.getters.mainColor)
|
||||
|
||||
onLoad(options) {
|
||||
/**
|
||||
* 修复app端点击除全部订单外的按钮进入时不加载数据的问题
|
||||
* 替换onLoad下代码即可
|
||||
*/
|
||||
let status = Number(options.status);
|
||||
this.status = status;
|
||||
interface NavTabItem {
|
||||
state: number
|
||||
text: string
|
||||
loadStatus: string
|
||||
orderList: any[]
|
||||
pageNumber: number
|
||||
loaded?: boolean
|
||||
}
|
||||
|
||||
this.tabCurrentIndex = status;
|
||||
// if (status == 0) {
|
||||
// this.loadData(status);
|
||||
// }
|
||||
},
|
||||
const tabCurrentIndex = ref(0)
|
||||
const navList = reactive<NavTabItem[]>([
|
||||
{ state: 0, text: '全部', loadStatus: 'more', orderList: [], pageNumber: 1 },
|
||||
{ state: 1, text: '待付款', loadStatus: 'more', orderList: [], pageNumber: 1 },
|
||||
{ state: 2, text: '待发货', loadStatus: 'more', orderList: [], pageNumber: 1 },
|
||||
{ state: 3, text: '待收货', loadStatus: 'more', orderList: [], pageNumber: 1 },
|
||||
{ state: 4, text: '已完成', loadStatus: 'more', orderList: [], pageNumber: 1 },
|
||||
{ state: 5, text: '已取消', loadStatus: 'more', orderList: [], pageNumber: 1 },
|
||||
])
|
||||
|
||||
watch: {
|
||||
/**监听更改请求数据 */
|
||||
tabCurrentIndex(val) {
|
||||
this.params.tag = this.orderStatus[val].orderStatus;
|
||||
//切换标签页将所有的页数都重置为1
|
||||
this.navList.forEach((res) => {
|
||||
res.pageNumber = 1;
|
||||
res.loadStatus = "more";
|
||||
res.orderList = [];
|
||||
});
|
||||
this.loadData(val);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
// 售后
|
||||
applyService(order) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/order/afterSales/afterSales?orderSn=${order.sn}`,
|
||||
});
|
||||
},
|
||||
const status = ref<number>(0)
|
||||
const params = reactive({
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
tag: 'ALL',
|
||||
})
|
||||
|
||||
// 店铺详情
|
||||
navigateToStore(val) {
|
||||
uni.navigateTo({
|
||||
url: "/pages/product/shopPage?id=" + val.storeId,
|
||||
});
|
||||
},
|
||||
renderOrderTag(orderPromotionType) {
|
||||
switch (orderPromotionType) {
|
||||
case "NORMAL":
|
||||
return "";
|
||||
case "PINTUAN":
|
||||
return "拼团订单";
|
||||
break;
|
||||
case "GIFT":
|
||||
return "赠品订单";
|
||||
break;
|
||||
case "POINTS":
|
||||
return "积分订单";
|
||||
break;
|
||||
case "KANJIA":
|
||||
return "砍价订单";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
},
|
||||
renderOrderTagType(orderPromotionType) {
|
||||
switch (orderPromotionType) {
|
||||
case "PINTUAN":
|
||||
return "error";
|
||||
case "GIFT":
|
||||
return "primary";
|
||||
case "POINTS":
|
||||
return "info";
|
||||
case "KANJIA":
|
||||
return "warning";
|
||||
default:
|
||||
return "info";
|
||||
}
|
||||
},
|
||||
getOrderItemImage(goods, order, index) {
|
||||
let image = goods.image;
|
||||
if (!image && order.groupImages) {
|
||||
const images = String(order.groupImages).split(",");
|
||||
image = images[index] || images[0];
|
||||
}
|
||||
return this.parseGoodsImageUrl(image);
|
||||
},
|
||||
/**
|
||||
* 取消订单
|
||||
*/
|
||||
onCancel(sn) {
|
||||
this.orderSn = sn;
|
||||
this.cancelShow = true;
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
getClearReason().then((res) => {
|
||||
if (res.data.result.length >= 1) {
|
||||
this.cancelList = res.data.result;
|
||||
}
|
||||
if (this.$store.state.isShowToast) {
|
||||
uni.hideLoading()
|
||||
};
|
||||
});
|
||||
},
|
||||
const orderStatus = [
|
||||
{ orderStatus: 'ALL' },
|
||||
{ orderStatus: 'WAIT_PAY' },
|
||||
{ orderStatus: 'WAIT_SHIP' },
|
||||
{ orderStatus: 'WAIT_ROG' },
|
||||
{ orderStatus: 'COMPLETE' },
|
||||
{ orderStatus: 'CANCELLED' },
|
||||
{ orderStatus: 'STAY_PICKED_UP' },
|
||||
]
|
||||
|
||||
/**
|
||||
* 初始化数据
|
||||
*/
|
||||
initData(index) {
|
||||
this.navList[index].pageNumber = 1;
|
||||
this.navList[index].loadStatus = "more";
|
||||
this.navList[index].orderList = [];
|
||||
this.loadData(index);
|
||||
},
|
||||
const cancelShow = ref(false)
|
||||
const orderSn = ref('')
|
||||
const reason = ref('')
|
||||
const cancelList = ref<any[]>([])
|
||||
const rogShow = ref(false)
|
||||
|
||||
/**
|
||||
* 等待支付
|
||||
*/
|
||||
waitPay(val) {
|
||||
this.$u.debounce(this.pay(val), 3000);
|
||||
},
|
||||
function hideLoadingIfNeeded() {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付
|
||||
*/
|
||||
pay(val) {
|
||||
if (val.sn) {
|
||||
// #ifdef MP-WEIXIN
|
||||
new LiLiWXPay({
|
||||
sn: val.sn,
|
||||
price: val.flowPrice,
|
||||
orderType: "ORDER",
|
||||
}).pay();
|
||||
// #endif
|
||||
// #ifndef MP-WEIXIN
|
||||
uni.navigateTo({
|
||||
url: "/pages/cart/payment/payOrder?order_sn=" + val.sn,
|
||||
});
|
||||
// #endif
|
||||
}
|
||||
},
|
||||
onBackPress((e) => {
|
||||
if (e.from == 'backbutton') {
|
||||
uni.switchTab({ url: '/pages/tabbar/user/my' })
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
/**
|
||||
* 获取订单列表
|
||||
*/
|
||||
loadData(index) {
|
||||
this.params.pageNumber = this.navList[index].pageNumber;
|
||||
// this.params.tag = this.orderStatus[index].orderStatus;
|
||||
getOrderList(this.params).then((res) => {
|
||||
uni.stopPullDownRefresh();
|
||||
if (!res.data.success) {
|
||||
this.navList[index].loadStatus = "noMore";
|
||||
return false;
|
||||
}
|
||||
let orderList = res.data.result.records;
|
||||
if (orderList.length == 0) {
|
||||
this.navList[index].loadStatus = "noMore";
|
||||
} else if (orderList.length < 10) {
|
||||
this.navList[index].loadStatus = "noMore";
|
||||
}
|
||||
if (orderList.length > 0) {
|
||||
this.navList[index].orderList =
|
||||
this.navList[index].orderList.concat(orderList);
|
||||
this.navList[index].pageNumber += 1;
|
||||
}
|
||||
});
|
||||
},
|
||||
//swiper 切换监听
|
||||
changeTab(e) {
|
||||
this.tabCurrentIndex = e.target.current;
|
||||
},
|
||||
//顶部tab点击
|
||||
tabClick(index) {
|
||||
this.tabCurrentIndex = index;
|
||||
},
|
||||
//删除订单
|
||||
deleteOrder(index) {
|
||||
uni.showLoading({
|
||||
title: "请稍后",
|
||||
});
|
||||
setTimeout(() => {
|
||||
this.navList[this.tabCurrentIndex].orderList.splice(index, 1);
|
||||
if (this.$store.state.isShowToast) {
|
||||
uni.hideLoading()
|
||||
};
|
||||
}, 600);
|
||||
},
|
||||
//取消订单
|
||||
cancelOrder(item) {
|
||||
uni.showLoading({
|
||||
title: "请稍后",
|
||||
});
|
||||
setTimeout(() => {
|
||||
let {
|
||||
stateTip,
|
||||
stateTipColor
|
||||
} = this.orderStateExp(9);
|
||||
item = Object.assign(item, {
|
||||
state: 9,
|
||||
stateTip,
|
||||
stateTipColor,
|
||||
});
|
||||
onPullDownRefresh(() => {
|
||||
if (tabCurrentIndex.value) {
|
||||
initData(tabCurrentIndex.value)
|
||||
} else {
|
||||
initData(0)
|
||||
}
|
||||
})
|
||||
|
||||
//取消订单后删除待付款中该项
|
||||
let list = this.navList[1].orderList;
|
||||
let index = list.findIndex((val) => val.id === item.id);
|
||||
index !== -1 && list.splice(index, 1);
|
||||
if (this.$store.state.isShowToast) {
|
||||
uni.hideLoading()
|
||||
};
|
||||
}, 600);
|
||||
},
|
||||
onShow(() => {
|
||||
if (tipsToLogin()) {
|
||||
if (!tabCurrentIndex.value) {
|
||||
initData(0)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
//订单状态文字和颜色
|
||||
orderStateExp(state) {
|
||||
let stateTip = "",
|
||||
stateTipColor = this.$lightColor;
|
||||
switch (+state) {
|
||||
case 1:
|
||||
stateTip = "待付款";
|
||||
break;
|
||||
case 2:
|
||||
stateTip = "待发货";
|
||||
break;
|
||||
case 9:
|
||||
stateTip = "订单已关闭";
|
||||
stateTipColor = "#909399";
|
||||
break;
|
||||
onLoad((options) => {
|
||||
const statusNum = Number(options?.status)
|
||||
status.value = statusNum
|
||||
tabCurrentIndex.value = statusNum
|
||||
})
|
||||
|
||||
//更多自定义
|
||||
}
|
||||
return {
|
||||
stateTip,
|
||||
stateTipColor,
|
||||
};
|
||||
},
|
||||
watch(tabCurrentIndex, (val) => {
|
||||
params.tag = orderStatus[val].orderStatus
|
||||
navList.forEach((res) => {
|
||||
res.pageNumber = 1
|
||||
res.loadStatus = 'more'
|
||||
res.orderList = []
|
||||
})
|
||||
loadData(val)
|
||||
})
|
||||
|
||||
/**
|
||||
* 跳转到订单详情
|
||||
*/
|
||||
navigateToOrderDetail(sn) {
|
||||
uni.navigateTo({
|
||||
url: "./orderDetail?sn=" + sn,
|
||||
});
|
||||
},
|
||||
function applyService(order: any) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/order/afterSales/afterSales?orderSn=${order.sn}`,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 选择取消原因
|
||||
*/
|
||||
reasonChange(reason) {
|
||||
this.reason = reason;
|
||||
},
|
||||
function navigateToStore(val: any) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/product/shopPage?id=' + val.storeId,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交取消订单(未付款)
|
||||
*/
|
||||
submitCancel() {
|
||||
cancelOrder(this.orderSn, {
|
||||
reason: this.reason
|
||||
}).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({
|
||||
title: "订单已取消",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
this.initData(this.tabCurrentIndex);
|
||||
function renderOrderTag(orderPromotionType: string) {
|
||||
switch (orderPromotionType) {
|
||||
case 'NORMAL':
|
||||
return ''
|
||||
case 'PINTUAN':
|
||||
return '拼团订单'
|
||||
case 'GIFT':
|
||||
return '赠品订单'
|
||||
case 'POINTS':
|
||||
return '积分订单'
|
||||
case 'KANJIA':
|
||||
return '砍价订单'
|
||||
default:
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
this.cancelShow = false;
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.data.message,
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
this.cancelShow = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
function renderOrderTagType(orderPromotionType: string) {
|
||||
switch (orderPromotionType) {
|
||||
case 'PINTUAN':
|
||||
return 'error'
|
||||
case 'GIFT':
|
||||
return 'primary'
|
||||
case 'POINTS':
|
||||
return 'info'
|
||||
case 'KANJIA':
|
||||
return 'warning'
|
||||
default:
|
||||
return 'info'
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认收货显示
|
||||
*/
|
||||
onRog(sn) {
|
||||
this.orderSn = sn;
|
||||
this.rogShow = true;
|
||||
},
|
||||
function getOrderItemImage(goods: any, order: any, index: number) {
|
||||
let image = goods.image
|
||||
if (!image && order.groupImages) {
|
||||
const images = String(order.groupImages).split(',')
|
||||
image = images[index] || images[0]
|
||||
}
|
||||
return parseGoodsImageUrl(image)
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击确认收货
|
||||
*/
|
||||
confirmRog() {
|
||||
confirmReceipt(this.orderSn).then((res) => {
|
||||
if (res.data.code == 200) {
|
||||
uni.showToast({
|
||||
title: "已确认收货",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
this.initData(this.tabCurrentIndex);
|
||||
this.rogShow = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
function onCancel(sn: string) {
|
||||
orderSn.value = sn
|
||||
cancelShow.value = true
|
||||
uni.showLoading({ title: '加载中' })
|
||||
getClearReason().then((res) => {
|
||||
if (res.data.result.length >= 1) {
|
||||
cancelList.value = res.data.result
|
||||
}
|
||||
hideLoadingIfNeeded()
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 评价商品
|
||||
*/
|
||||
onComment(sn) {
|
||||
uni.navigateTo({
|
||||
url: "./evaluate/myEvaluate",
|
||||
});
|
||||
},
|
||||
function initData(index: number) {
|
||||
navList[index].pageNumber = 1
|
||||
navList[index].loadStatus = 'more'
|
||||
navList[index].orderList = []
|
||||
loadData(index)
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新购买
|
||||
*/
|
||||
reBuy(order) {
|
||||
console.log(order);
|
||||
return;
|
||||
uni.navigateTo({
|
||||
url: "/pages/product/goods?id=" + order.id + "&goodsId=" + order.goodsId,
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
function waitPay(val: any) {
|
||||
proxy?.$u?.debounce?.(() => pay(val), 3000, true)?.()
|
||||
}
|
||||
|
||||
function pay(val: any) {
|
||||
if (val.sn) {
|
||||
// #ifdef MP-WEIXIN
|
||||
new LiLiWXPay({
|
||||
sn: val.sn,
|
||||
price: val.flowPrice,
|
||||
orderType: 'ORDER',
|
||||
}).pay()
|
||||
// #endif
|
||||
// #ifndef MP-WEIXIN
|
||||
uni.navigateTo({
|
||||
url: '/pages/cart/payment/payOrder?order_sn=' + val.sn,
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
|
||||
function loadData(index: number) {
|
||||
params.pageNumber = navList[index].pageNumber
|
||||
getOrderList(params).then((res) => {
|
||||
uni.stopPullDownRefresh()
|
||||
if (!res.data.success) {
|
||||
navList[index].loadStatus = 'noMore'
|
||||
return false
|
||||
}
|
||||
const records = res.data.result.records
|
||||
if (records.length == 0) {
|
||||
navList[index].loadStatus = 'noMore'
|
||||
} else if (records.length < 10) {
|
||||
navList[index].loadStatus = 'noMore'
|
||||
}
|
||||
if (records.length > 0) {
|
||||
navList[index].orderList = navList[index].orderList.concat(records)
|
||||
navList[index].pageNumber += 1
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function changeTab(e: any) {
|
||||
tabCurrentIndex.value = e.target.current
|
||||
}
|
||||
|
||||
function tabClick(index: number) {
|
||||
tabCurrentIndex.value = index
|
||||
}
|
||||
|
||||
function deleteOrder(index: number) {
|
||||
uni.showLoading({ title: '请稍后' })
|
||||
setTimeout(() => {
|
||||
navList[tabCurrentIndex.value].orderList.splice(index, 1)
|
||||
hideLoadingIfNeeded()
|
||||
}, 600)
|
||||
}
|
||||
|
||||
function cancelOrderLocal(item: any) {
|
||||
uni.showLoading({ title: '请稍后' })
|
||||
setTimeout(() => {
|
||||
const { stateTip, stateTipColor } = orderStateExp(9)
|
||||
Object.assign(item, {
|
||||
state: 9,
|
||||
stateTip,
|
||||
stateTipColor,
|
||||
})
|
||||
const list = navList[1].orderList
|
||||
const idx = list.findIndex((val) => val.id === item.id)
|
||||
if (idx !== -1) list.splice(idx, 1)
|
||||
hideLoadingIfNeeded()
|
||||
}, 600)
|
||||
}
|
||||
|
||||
function orderStateExp(state: number) {
|
||||
let stateTip = ''
|
||||
let stateTipColor = lightColor.value
|
||||
switch (+state) {
|
||||
case 1:
|
||||
stateTip = '待付款'
|
||||
break
|
||||
case 2:
|
||||
stateTip = '待发货'
|
||||
break
|
||||
case 9:
|
||||
stateTip = '订单已关闭'
|
||||
stateTipColor = '#909399'
|
||||
break
|
||||
}
|
||||
return { stateTip, stateTipColor }
|
||||
}
|
||||
|
||||
function navigateToOrderDetail(sn: string) {
|
||||
uni.navigateTo({
|
||||
url: './orderDetail?sn=' + sn,
|
||||
})
|
||||
}
|
||||
|
||||
function reasonChange(val: string) {
|
||||
reason.value = val
|
||||
}
|
||||
|
||||
function submitCancel() {
|
||||
cancelOrder(orderSn.value, { reason: reason.value }).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({
|
||||
title: '订单已取消',
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
initData(tabCurrentIndex.value)
|
||||
cancelShow.value = false
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.data.message,
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
cancelShow.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function onRog(sn: string) {
|
||||
orderSn.value = sn
|
||||
rogShow.value = true
|
||||
}
|
||||
|
||||
function confirmRog() {
|
||||
confirmReceipt(orderSn.value).then((res) => {
|
||||
if (res.data.code == 200) {
|
||||
uni.showToast({
|
||||
title: '已确认收货',
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
initData(tabCurrentIndex.value)
|
||||
rogShow.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function onComment(_sn: string) {
|
||||
uni.navigateTo({
|
||||
url: './evaluate/myEvaluate',
|
||||
})
|
||||
}
|
||||
|
||||
function reBuy(order: any) {
|
||||
const goods = order.orderItems?.[0]
|
||||
if (!goods) return
|
||||
uni.navigateTo({
|
||||
url: '/pages/product/goods?id=' + goods.id + '&goodsId=' + goods.goodsId,
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
<view class="title">自提点地址:</view>
|
||||
<view class="value address-line-height">{{ order.storeAddressPath }}</view>
|
||||
</view>
|
||||
<view class="order-info-view" @click="callPhone" >
|
||||
<view class="order-info-view" @click="handleCallPhone" >
|
||||
<view class="title">联系方式:</view>
|
||||
<view class="value">{{ order.storeAddressMobile }}<u-icon name='phone-fill' ></u-icon></view>
|
||||
</view>
|
||||
@@ -245,287 +245,258 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getExpress, getPackage } from "@/api/trade.js";
|
||||
import { cancelOrder, confirmReceipt, getOrderDetail } from "@/api/order.js";
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { getExpress, getPackage } from '@/api/trade.js'
|
||||
import { cancelOrder, confirmReceipt, getOrderDetail } from '@/api/order.js'
|
||||
import shares from '@/components/m-share/index'
|
||||
import { getClearReason } from '@/api/after-sale.js'
|
||||
import {
|
||||
unitPrice,
|
||||
secrecyMobile,
|
||||
setClipboard,
|
||||
talkIm,
|
||||
callPhone,
|
||||
} from '@/utils/filters.js'
|
||||
|
||||
import shares from "@/components/m-share/index"; //分享
|
||||
const store = useStore()
|
||||
const lightColor = computed(() => store.getters.lightColor)
|
||||
const mainColor = computed(() => store.getters.mainColor)
|
||||
|
||||
import { getClearReason } from "@/api/after-sale.js";
|
||||
const orderStatusMap: Record<string, { title: string; value?: string }> = {
|
||||
UNPAID: { title: '未付款', value: '商品暂未付款' },
|
||||
PAID: { title: '已付款', value: '买家已付款' },
|
||||
UNDELIVERED: { title: '待发货', value: '商品等待发货中' },
|
||||
PARTS_DELIVERED: { title: '部分发货', value: '商品已部分发货。' },
|
||||
DELIVERED: { title: '已发货', value: '商品已发货,请您耐心等待' },
|
||||
CANCELLED: { title: '已取消', value: '订单已取消' },
|
||||
COMPLETED: { title: '已完成', value: '订单已完成,祝您生活愉快' },
|
||||
STAY_PICKED_UP: { title: '待自提', value: '商品正在等待提取' },
|
||||
TAKE: { title: '待核验' },
|
||||
}
|
||||
|
||||
export default {
|
||||
components: {
|
||||
shares,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
lightColor: this.$lightColor,
|
||||
logisticsList: "", //物流信息
|
||||
shareFlag: false, //拼团分享开关
|
||||
orderStatusMap: {
|
||||
UNPAID: {
|
||||
title: "未付款",
|
||||
value: "商品暂未付款",
|
||||
},
|
||||
PAID: {
|
||||
title: "已付款",
|
||||
value: "买家已付款",
|
||||
},
|
||||
UNDELIVERED: {
|
||||
title: "待发货",
|
||||
value: "商品等待发货中",
|
||||
},
|
||||
PARTS_DELIVERED: {
|
||||
title: "部分发货",
|
||||
value: "商品已部分发货。",
|
||||
},
|
||||
DELIVERED: {
|
||||
title: "已发货",
|
||||
value: "商品已发货,请您耐心等待",
|
||||
},
|
||||
CANCELLED: {
|
||||
title: "已取消",
|
||||
value: "订单已取消",
|
||||
},
|
||||
COMPLETED: {
|
||||
title: "已完成",
|
||||
value: "订单已完成,祝您生活愉快",
|
||||
},
|
||||
STAY_PICKED_UP: {
|
||||
title: "待自提",
|
||||
value: "商品正在等待提取",
|
||||
},
|
||||
TAKE: {
|
||||
title: "待核验",
|
||||
},
|
||||
},
|
||||
order: {},
|
||||
cancelShow: false, //取消订单
|
||||
orderSn: "",
|
||||
orderGoodsList: "", //订单中商品集合
|
||||
orderDetail: "", //订单详情信息
|
||||
sn: "",
|
||||
cancelList: "",
|
||||
rogShow: false,
|
||||
reason: "",
|
||||
orderPackage:"",
|
||||
};
|
||||
},
|
||||
onLoad(options) {
|
||||
this.loadData(options.sn);
|
||||
this.sn = options.sn;
|
||||
},
|
||||
methods: {
|
||||
//获取包裹
|
||||
async getOrderPackage() {
|
||||
getPackage(this.order.sn).then(res => {
|
||||
if (res.data.success) {
|
||||
this.orderPackage = res.data.result
|
||||
}
|
||||
})
|
||||
},
|
||||
handleClickDeliver(){
|
||||
uni.navigateTo({
|
||||
url: `/pages/order/deliverDetail?order_sn=${this.order.sn}`,
|
||||
});
|
||||
},
|
||||
// 退款状态枚举
|
||||
refundPriceList(status) {
|
||||
switch (status) {
|
||||
case 'ALL_REFUND':
|
||||
return "全部退款";
|
||||
case 'PART_REFUND':
|
||||
return "部分退款";
|
||||
case 'NO_REFUND':
|
||||
return "未退款";
|
||||
case 'REFUNDING':
|
||||
return "退款中";
|
||||
default:
|
||||
return "";
|
||||
const logisticsList = ref<any>('')
|
||||
const shareFlag = ref(false)
|
||||
const order = ref<Record<string, any>>({})
|
||||
const cancelShow = ref(false)
|
||||
const orderSn = ref('')
|
||||
const orderGoodsList = ref<any[]>([])
|
||||
const orderDetail = ref<Record<string, any>>({})
|
||||
const sn = ref('')
|
||||
const cancelList = ref<any[]>([])
|
||||
const rogShow = ref(false)
|
||||
const reason = ref('')
|
||||
const orderPackage = ref<any>('')
|
||||
|
||||
function hideLoadingIfNeeded() {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
}
|
||||
|
||||
onLoad((options) => {
|
||||
const orderSnParam = options?.sn || ''
|
||||
sn.value = orderSnParam
|
||||
loadData(orderSnParam)
|
||||
})
|
||||
|
||||
function getOrderPackage() {
|
||||
getPackage(order.value.sn).then((res) => {
|
||||
if (res.data.success) {
|
||||
orderPackage.value = res.data.result
|
||||
}
|
||||
},
|
||||
callPhone(){
|
||||
this.callPhone(this.order.storeAddressMobile )
|
||||
},
|
||||
//联系客服
|
||||
contact(storeId){
|
||||
this.talkIm(storeId)
|
||||
},
|
||||
goToShopPage(val) {
|
||||
uni.navigateTo({
|
||||
url: "/pages/product/shopPage?id=" + val.storeId,
|
||||
});
|
||||
},
|
||||
// 获取物流信息
|
||||
loadLogistics(sn) {
|
||||
getExpress(sn).then((res) => {
|
||||
this.logisticsList = res.data.result;
|
||||
});
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// 分享当前拼团信息
|
||||
inviteGroup() {
|
||||
this.shareFlag = true;
|
||||
},
|
||||
// #TODO 这块需要写一下 目前没有拼团的详细信息
|
||||
ByUserMessage(order) {
|
||||
uni.navigateTo({
|
||||
url:
|
||||
"/pages/cart/payment/shareOrderGoods?sn=" +
|
||||
order.sn +
|
||||
"&sku=" +
|
||||
this.orderGoodsList[0].skuId +
|
||||
"&goodsId=" +
|
||||
this.orderGoodsList[0].goodsId,
|
||||
});
|
||||
},
|
||||
async loadData(sn) {
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
getOrderDetail(sn).then((res) => {
|
||||
const order = res.data.result;
|
||||
this.order = order.order;
|
||||
this.orderGoodsList = order.orderItems;
|
||||
this.orderDetail = res.data.result;
|
||||
if (this.order.deliveryMethod === 'LOGISTICS') {
|
||||
this.loadLogistics(sn);
|
||||
this.getOrderPackage();
|
||||
}
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
});
|
||||
function handleClickDeliver() {
|
||||
uni.navigateTo({
|
||||
url: `/pages/order/deliverDetail?order_sn=${order.value.sn}`,
|
||||
})
|
||||
}
|
||||
|
||||
},
|
||||
onReceipt(val) {
|
||||
uni.navigateTo({
|
||||
url: "/pages/order/invoice/invoiceDetail?id=" + val.id,
|
||||
});
|
||||
},
|
||||
gotoGoodsDetail(sku) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/product/goods?id=${sku.skuId}&goodsId=${sku.goodsId}`,
|
||||
});
|
||||
},
|
||||
onCopy(sn) {
|
||||
setClipboard(sn)
|
||||
},
|
||||
function refundPriceList(status: string) {
|
||||
switch (status) {
|
||||
case 'ALL_REFUND':
|
||||
return '全部退款'
|
||||
case 'PART_REFUND':
|
||||
return '部分退款'
|
||||
case 'NO_REFUND':
|
||||
return '未退款'
|
||||
case 'REFUNDING':
|
||||
return '退款中'
|
||||
default:
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
//售后按钮
|
||||
onAfterSales(sn, sku) {
|
||||
uni.navigateTo({
|
||||
url: `./afterSales/afterSalesSelect?sn=${sn}&sku=${encodeURIComponent(
|
||||
JSON.stringify(sku)
|
||||
)}`,
|
||||
});
|
||||
},
|
||||
// 去支付
|
||||
toPay(val) {
|
||||
val.sn
|
||||
? uni.navigateTo({
|
||||
url: "/pages/cart/payment/payOrder?order_sn=" + val.sn,
|
||||
})
|
||||
: false;
|
||||
}, //删除订单
|
||||
deleteOrder(index) {
|
||||
uni.showLoading({
|
||||
title: "请稍后",
|
||||
});
|
||||
setTimeout(() => {
|
||||
this.navList[this.tabCurrentIndex].orderList.splice(index, 1);
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
}, 600);
|
||||
},
|
||||
//取消订单
|
||||
onCancel(sn) {
|
||||
this.orderSn = sn;
|
||||
function handleCallPhone() {
|
||||
if (order.value.storeAddressMobile) {
|
||||
callPhone(order.value.storeAddressMobile)
|
||||
}
|
||||
}
|
||||
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
getClearReason().then((res) => {
|
||||
if (res.data.result.length >= 1) {
|
||||
this.cancelList = res.data.result;
|
||||
}
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
});
|
||||
function contact(storeId: string) {
|
||||
talkIm(storeId)
|
||||
}
|
||||
|
||||
this.cancelShow = true;
|
||||
},
|
||||
function goToShopPage(val: any) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/product/shopPage?id=' + val.storeId,
|
||||
})
|
||||
}
|
||||
|
||||
//提交取消订单(未付款)
|
||||
submitCancel() {
|
||||
cancelOrder(this.orderSn, { reason: this.reason }).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({
|
||||
title: "已取消",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
this.cancelShow = false;
|
||||
setTimeout(() => {
|
||||
uni.reLaunch({
|
||||
url: "/pages/order/myOrder?status=0",
|
||||
});
|
||||
}, 500);
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.data.message,
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
this.cancelShow = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
function loadLogistics(orderSnParam: string) {
|
||||
getExpress(orderSnParam).then((res) => {
|
||||
logisticsList.value = res.data.result
|
||||
})
|
||||
}
|
||||
|
||||
//确认收货
|
||||
onRog(sn) {
|
||||
this.orderSn = sn;
|
||||
this.rogShow = true;
|
||||
},
|
||||
confirmRog() {
|
||||
confirmReceipt(this.orderSn).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({
|
||||
title: "已确认收货",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
this.rogShow = false;
|
||||
this.loadData(this.sn);
|
||||
}
|
||||
});
|
||||
},
|
||||
//评价商品
|
||||
onComment(sn) {
|
||||
uni.navigateTo({
|
||||
url: "./evaluate/myEvaluate",
|
||||
});
|
||||
}, //查看物流
|
||||
onLogistics(order) {
|
||||
uni.navigateTo({
|
||||
url:
|
||||
"/pages/mine/msgTips/packageMsg/logisticsDetail?logi_id=" +
|
||||
order.logi_id +
|
||||
"&ship_no=" +
|
||||
order.ship_no +
|
||||
"&order_sn=" +
|
||||
order.sn,
|
||||
});
|
||||
},
|
||||
function inviteGroup() {
|
||||
shareFlag.value = true
|
||||
}
|
||||
|
||||
//选择取消原因
|
||||
reasonChange(reason) {
|
||||
this.reason = reason;
|
||||
},
|
||||
reBuy(order) {
|
||||
uni.navigateTo({
|
||||
url:
|
||||
"/pages/product/goods?id=" + order.id + "&goodsId=" + order.goodsId,
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
function ByUserMessage(orderItem: any) {
|
||||
uni.navigateTo({
|
||||
url:
|
||||
'/pages/cart/payment/shareOrderGoods?sn=' +
|
||||
orderItem.sn +
|
||||
'&sku=' +
|
||||
orderGoodsList.value[0].skuId +
|
||||
'&goodsId=' +
|
||||
orderGoodsList.value[0].goodsId,
|
||||
})
|
||||
}
|
||||
|
||||
function loadData(orderSnParam: string) {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
getOrderDetail(orderSnParam).then((res) => {
|
||||
const result = res.data.result
|
||||
order.value = result.order
|
||||
orderGoodsList.value = result.orderItems
|
||||
orderDetail.value = result
|
||||
if (order.value.deliveryMethod === 'LOGISTICS') {
|
||||
loadLogistics(orderSnParam)
|
||||
getOrderPackage()
|
||||
}
|
||||
hideLoadingIfNeeded()
|
||||
})
|
||||
}
|
||||
|
||||
function onReceipt(val: any) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/order/invoice/invoiceDetail?id=' + val.id,
|
||||
})
|
||||
}
|
||||
|
||||
function gotoGoodsDetail(sku: any) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/product/goods?id=${sku.skuId}&goodsId=${sku.goodsId}`,
|
||||
})
|
||||
}
|
||||
|
||||
function onCopy(orderSnText: string) {
|
||||
setClipboard(orderSnText)
|
||||
}
|
||||
|
||||
function onAfterSales(orderSnText: string, sku: any) {
|
||||
uni.navigateTo({
|
||||
url: `./afterSales/afterSalesSelect?sn=${orderSnText}&sku=${encodeURIComponent(
|
||||
JSON.stringify(sku)
|
||||
)}`,
|
||||
})
|
||||
}
|
||||
|
||||
function toPay(val: any) {
|
||||
if (val.sn) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/cart/payment/payOrder?order_sn=' + val.sn,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function onCancel(orderSnText: string) {
|
||||
orderSn.value = orderSnText
|
||||
uni.showLoading({ title: '加载中' })
|
||||
getClearReason().then((res) => {
|
||||
if (res.data.result.length >= 1) {
|
||||
cancelList.value = res.data.result
|
||||
}
|
||||
hideLoadingIfNeeded()
|
||||
})
|
||||
cancelShow.value = true
|
||||
}
|
||||
|
||||
function submitCancel() {
|
||||
cancelOrder(orderSn.value, { reason: reason.value }).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({
|
||||
title: '已取消',
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
cancelShow.value = false
|
||||
setTimeout(() => {
|
||||
uni.reLaunch({
|
||||
url: '/pages/order/myOrder?status=0',
|
||||
})
|
||||
}, 500)
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.data.message,
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
cancelShow.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function onRog(orderSnText: string) {
|
||||
orderSn.value = orderSnText
|
||||
rogShow.value = true
|
||||
}
|
||||
|
||||
function confirmRog() {
|
||||
confirmReceipt(orderSn.value).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({
|
||||
title: '已确认收货',
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
rogShow.value = false
|
||||
loadData(sn.value)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function onComment(_orderSnText: string) {
|
||||
uni.navigateTo({
|
||||
url: './evaluate/myEvaluate',
|
||||
})
|
||||
}
|
||||
|
||||
function onLogistics(orderItem: any) {
|
||||
uni.navigateTo({
|
||||
url:
|
||||
'/pages/mine/msgTips/packageMsg/logisticsDetail?logi_id=' +
|
||||
orderItem.logi_id +
|
||||
'&ship_no=' +
|
||||
orderItem.ship_no +
|
||||
'&order_sn=' +
|
||||
orderItem.sn,
|
||||
})
|
||||
}
|
||||
|
||||
function reasonChange(val: string) {
|
||||
reason.value = val
|
||||
}
|
||||
|
||||
function reBuy(orderItem: any) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/product/goods?id=' + orderItem.id + '&goodsId=' + orderItem.goodsId,
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
@@ -10,31 +10,23 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getArticleDetail } from "@/api/article.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 用于接收上一级通过路径传输的数据
|
||||
routers: "",
|
||||
// 请求文章接口后存储文章信息
|
||||
articleData: "",
|
||||
};
|
||||
},
|
||||
onLoad(val) {
|
||||
this.routers = val;
|
||||
getArticleDetail(val.id).then((res) => {
|
||||
if (res.data.result) {
|
||||
// 将请求的文章数据赋值
|
||||
this.articleData = res.data.result.content;
|
||||
}
|
||||
// 修改当前NavigationBar(标题头)为文章头部
|
||||
uni.setNavigationBarTitle({
|
||||
title: val.title,
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { getArticleDetail } from '@/api/article.js'
|
||||
|
||||
const articleData = ref('')
|
||||
|
||||
onLoad((val) => {
|
||||
getArticleDetail(val.id).then((res) => {
|
||||
if (res.data.result) {
|
||||
articleData.value = res.data.result.content
|
||||
}
|
||||
uni.setNavigationBarTitle({
|
||||
title: val.title,
|
||||
})
|
||||
})
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
page {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="seller-control" :style="themeStyle">
|
||||
<u-navbar
|
||||
:border="false"
|
||||
:fixed="true"
|
||||
@@ -18,56 +18,71 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getCompanyDetail } from "@/api/entry";
|
||||
import step1 from "./step1";
|
||||
import step2 from "./step2";
|
||||
import step3 from "./step3";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
companyData: "",
|
||||
current: 1,
|
||||
};
|
||||
},
|
||||
components: {
|
||||
step1,
|
||||
step2,
|
||||
step3,
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
methods: {
|
||||
back() {
|
||||
if (this.current > 1) {
|
||||
this.current--;
|
||||
return;
|
||||
}
|
||||
uni.navigateBack({
|
||||
delta: 1,
|
||||
fail: () => {
|
||||
uni.switchTab({ url: "/pages/tabbar/home/index" });
|
||||
},
|
||||
});
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { useStore } from '@/store'
|
||||
import { getCompanyDetail } from '@/api/entry'
|
||||
import step1 from './step1.vue'
|
||||
import step2 from './step2.vue'
|
||||
import step3 from './step3.vue'
|
||||
import { getThemeStyle } from '@/utils/theme'
|
||||
|
||||
const store = useStore()
|
||||
|
||||
const themeStyle = computed(() => getThemeStyle(store.state.theme))
|
||||
|
||||
const companyData = ref<any>('')
|
||||
const current = ref(1)
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
|
||||
function back() {
|
||||
if (current.value > 1) {
|
||||
current.value--
|
||||
return
|
||||
}
|
||||
uni.navigateBack({
|
||||
delta: 1,
|
||||
fail: () => {
|
||||
uni.switchTab({ url: '/pages/tabbar/home/index' })
|
||||
},
|
||||
async init(next) {
|
||||
const res = await getCompanyDetail();
|
||||
if (res.data.success) {
|
||||
this.companyData = res.data.result;
|
||||
next ? this.current++ : "";
|
||||
}
|
||||
},
|
||||
next() {
|
||||
this.init("next");
|
||||
},
|
||||
finished() {
|
||||
uni.navigateTo({
|
||||
url: "/pages/passport/entry/seller/index",
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
async function init(next?: string) {
|
||||
const res = await getCompanyDetail()
|
||||
if (res.data.success) {
|
||||
companyData.value = res.data.result
|
||||
if (next) {
|
||||
current.value++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function next() {
|
||||
init('next')
|
||||
}
|
||||
|
||||
function finished() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/passport/entry/seller/index',
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
<style lang="scss">
|
||||
page {
|
||||
background: #f7f7f7;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "./entry.scss";
|
||||
|
||||
.seller-control {
|
||||
min-height: 100vh;
|
||||
background: #f7f7f7;
|
||||
}
|
||||
</style>
|
||||
|
||||
92
pages/passport/entry/seller/entry-form.scss
Normal file
92
pages/passport/entry/seller/entry-form.scss
Normal file
@@ -0,0 +1,92 @@
|
||||
@mixin seller-entry-form {
|
||||
:deep(.u-form-item) {
|
||||
padding: 0;
|
||||
margin-top: 24rpx;
|
||||
}
|
||||
|
||||
:deep(.u-form-item__body) {
|
||||
flex-direction: column !important;
|
||||
align-items: stretch !important;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:deep(.u-form-item__body__left) {
|
||||
width: 100% !important;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
:deep(.u-form-item__body__left__content__label) {
|
||||
display: block;
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
line-height: 1.4;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
:deep(.u-form-item__body__right),
|
||||
:deep(.u-form-item__body__right__content),
|
||||
:deep(.u-form-item__body__right__content__slot) {
|
||||
width: 100%;
|
||||
flex: none;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
:deep(.u-form-item__body__right__content__slot) {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.field-input {
|
||||
width: 100%;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.field-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16rpx;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.field-row .field-input {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.field-textarea {
|
||||
width: 100%;
|
||||
|
||||
:deep(.u-textarea) {
|
||||
background: #fafafa !important;
|
||||
border-radius: 12rpx;
|
||||
padding: 20rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
:deep(.u-textarea__field) {
|
||||
width: 100%;
|
||||
font-size: 28rpx;
|
||||
line-height: 1.6;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin seller-entry-submit {
|
||||
text-align: center;
|
||||
background: var(--theme-light, #ff6b35);
|
||||
height: 88rpx;
|
||||
line-height: 88rpx;
|
||||
color: #fff;
|
||||
width: 92%;
|
||||
margin: 40rpx auto 60rpx;
|
||||
border-radius: 100px;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
|
||||
.picker-action {
|
||||
flex-shrink: 0;
|
||||
color: var(--theme-light, #ff6b35);
|
||||
font-size: 28rpx;
|
||||
white-space: nowrap;
|
||||
}
|
||||
@@ -1,18 +1,28 @@
|
||||
.flag-title {
|
||||
font-size: 42rpx;
|
||||
font-weight: bold;
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
line-height: 1.4;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
.submit,
|
||||
.notice {
|
||||
font-weight: bold;
|
||||
font-size: 28rpx;
|
||||
|
||||
height: 92rpx;
|
||||
text-align: center;
|
||||
letter-spacing: 4rpx;
|
||||
line-height: 92rpx;
|
||||
.wrapper {
|
||||
box-sizing: border-box;
|
||||
min-height: 100vh;
|
||||
padding: 20rpx 24rpx 40rpx;
|
||||
background: #f8f8f8;
|
||||
}
|
||||
|
||||
.column {
|
||||
padding: 32rpx;
|
||||
margin-bottom: 20rpx;
|
||||
background: #fff;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
.wrapper {
|
||||
padding:16rpx;
|
||||
}
|
||||
|
||||
.tips {
|
||||
color: #999;
|
||||
font-size: 24rpx;
|
||||
line-height: 1.4;
|
||||
margin-top: 12rpx;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<u-navbar
|
||||
:border="false"
|
||||
:fixed="true"
|
||||
:placeholder="true"
|
||||
:auto-back="true"
|
||||
></u-navbar>
|
||||
<div>
|
||||
<div class="wrapper" :style="themeStyle">
|
||||
<u-navbar
|
||||
:border="false"
|
||||
:fixed="true"
|
||||
:placeholder="true"
|
||||
:auto-back="true"
|
||||
></u-navbar>
|
||||
<div class="entry-content">
|
||||
<div class="title">店铺入驻</div>
|
||||
<div class="step-list">
|
||||
<div
|
||||
@@ -24,144 +24,164 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getCompanyDetail } from "@/api/entry";
|
||||
export default {
|
||||
components: {},
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { onLoad, onShow } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { tipsToLogin } from '@/utils/filters.js'
|
||||
import { getCompanyDetail } from '@/api/entry'
|
||||
import { getThemeStyle } from '@/utils/theme'
|
||||
|
||||
data() {
|
||||
return {
|
||||
current: 999,
|
||||
entrySteps: [
|
||||
{
|
||||
title: "填写资质信息",
|
||||
value: "APPLY",
|
||||
},
|
||||
{
|
||||
title: "提交审核",
|
||||
value: "APPLYING",
|
||||
},
|
||||
],
|
||||
const store = useStore()
|
||||
|
||||
storeStatusWay: [
|
||||
{
|
||||
title: "申请已通过,请联系管理员",
|
||||
value: "OPEN",
|
||||
},
|
||||
{
|
||||
title: "店铺已关闭,重申请联系管理员",
|
||||
value: "CLOSED",
|
||||
},
|
||||
{
|
||||
title: "审核未通过,请修改资质信息",
|
||||
value: "REFUSED",
|
||||
},
|
||||
],
|
||||
const themeStyle = computed(() => getThemeStyle(store.state.theme))
|
||||
|
||||
companyData: "", // 公司信息
|
||||
};
|
||||
const current = ref(999)
|
||||
const companyData = ref<any>('')
|
||||
|
||||
const entrySteps = ref([
|
||||
{
|
||||
title: '填写资质信息',
|
||||
value: 'APPLY',
|
||||
},
|
||||
onShow() {
|
||||
if(this.tipsToLogin()){
|
||||
this.init();
|
||||
}
|
||||
{
|
||||
title: '提交审核',
|
||||
value: 'APPLYING',
|
||||
},
|
||||
])
|
||||
|
||||
mounted() {},
|
||||
const storeStatusWay = [
|
||||
{
|
||||
title: '申请已通过,请联系管理员',
|
||||
value: 'OPEN',
|
||||
},
|
||||
{
|
||||
title: '店铺已关闭,重申请联系管理员',
|
||||
value: 'CLOSED',
|
||||
},
|
||||
{
|
||||
title: '审核未通过,请修改资质信息',
|
||||
value: 'REFUSED',
|
||||
},
|
||||
]
|
||||
|
||||
onLoad(options) {},
|
||||
methods: {
|
||||
getEntryNotice() {
|
||||
uni.navigateTo({
|
||||
url: "/pages/mine/help/tips?type=STORE_REGISTER",
|
||||
});
|
||||
onShow(() => {
|
||||
if (tipsToLogin()) {
|
||||
init()
|
||||
}
|
||||
})
|
||||
|
||||
onLoad(() => {})
|
||||
|
||||
function getEntryNotice() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/mine/help/tips?type=STORE_REGISTER',
|
||||
})
|
||||
}
|
||||
|
||||
function keepOn() {
|
||||
if (companyData.value && companyData.value.storeDisable == 'OPEN') {
|
||||
uni.showToast({
|
||||
title: '审核已通过',
|
||||
icon: 'none',
|
||||
})
|
||||
} else {
|
||||
uni.navigateTo({
|
||||
url: '/pages/passport/entry/seller/control',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async function init() {
|
||||
entrySteps.value = [
|
||||
{
|
||||
title: '填写资质信息',
|
||||
value: 'APPLY',
|
||||
},
|
||||
keepOn() {
|
||||
if (this.companyData && this.companyData.storeDisable == "OPEN") {
|
||||
uni.showToast({
|
||||
title:"审核已通过",
|
||||
icon:"none"
|
||||
})
|
||||
} else {
|
||||
uni.navigateTo({
|
||||
url: "/pages/passport/entry/seller/control",
|
||||
});
|
||||
}
|
||||
{
|
||||
title: '提交审核',
|
||||
value: 'APPLYING',
|
||||
},
|
||||
async init() {
|
||||
this.entrySteps = [
|
||||
{
|
||||
title: "填写资质信息",
|
||||
value: "APPLY",
|
||||
},
|
||||
{
|
||||
title: "提交审核",
|
||||
value: "APPLYING",
|
||||
},
|
||||
];
|
||||
const res = await getCompanyDetail();
|
||||
if (res.data.success) {
|
||||
this.companyData = res.data.result;
|
||||
]
|
||||
const res = await getCompanyDetail()
|
||||
if (res.data.success) {
|
||||
companyData.value = res.data.result
|
||||
|
||||
if (this.companyData) {
|
||||
this.storeStatusWay.forEach((item) => {
|
||||
if (item.value == this.companyData.storeDisable) {
|
||||
this.entrySteps.push(item);
|
||||
}
|
||||
});
|
||||
|
||||
this.current =
|
||||
this.entrySteps.findIndex(
|
||||
(item) => item.value == this.companyData.storeDisable
|
||||
) || 0;
|
||||
} else {
|
||||
this.current = 0;
|
||||
if (companyData.value) {
|
||||
storeStatusWay.forEach((item) => {
|
||||
if (item.value == companyData.value.storeDisable) {
|
||||
entrySteps.value.push(item)
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
})
|
||||
|
||||
current.value =
|
||||
entrySteps.value.findIndex(
|
||||
(item) => item.value == companyData.value.storeDisable
|
||||
) || 0
|
||||
} else {
|
||||
current.value = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
<style lang="scss">
|
||||
page {
|
||||
background: #fff;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
@import url("./entry.scss");
|
||||
.wrapper {
|
||||
padding: 0 80rpx;
|
||||
min-height: 100vh;
|
||||
background: #fff;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.entry-content {
|
||||
padding: 32rpx 80rpx calc(40rpx + env(safe-area-inset-bottom));
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.title {
|
||||
padding-top: calc(104rpx);
|
||||
font-style: normal;
|
||||
line-height: 1;
|
||||
line-height: 1.2;
|
||||
font-weight: 500;
|
||||
font-size: 56rpx;
|
||||
color: #333;
|
||||
padding-left: 20rpx;
|
||||
}
|
||||
|
||||
.step-list {
|
||||
margin: 80rpx 0;
|
||||
}
|
||||
|
||||
.step-item {
|
||||
padding: 30rpx 20rpx;
|
||||
font-size: 40rpx;
|
||||
font-weight: bold;
|
||||
color: #666;
|
||||
}
|
||||
.step-list {
|
||||
margin: 80rpx 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
.active {
|
||||
color: $light-color;
|
||||
background: rgba($color: $light-color, $alpha: 0.1);
|
||||
|
||||
.step-item.active {
|
||||
color: var(--theme-light, #ff6b35);
|
||||
background: var(--theme-light-10, rgba(255, 107, 53, 0.1));
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
|
||||
.submit,
|
||||
.notice {
|
||||
font-weight: bold;
|
||||
font-size: 28rpx;
|
||||
height: 92rpx;
|
||||
text-align: center;
|
||||
letter-spacing: 4rpx;
|
||||
line-height: 92rpx;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
|
||||
.submit {
|
||||
color: #fff;
|
||||
margin-top: 120rpx;
|
||||
background: rgba($light-color, 0.8);
|
||||
background: var(--theme-light, #ff6b35);
|
||||
}
|
||||
|
||||
.notice {
|
||||
margin-top: 40rpx;
|
||||
color: #333;
|
||||
|
||||
@@ -1,113 +1,118 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<u-form label-width="200" :model="form" ref="uForm">
|
||||
<div class="wrapper" :style="themeStyle">
|
||||
<up-form label-position="top" :model="form" ref="uForm">
|
||||
<div class="column">
|
||||
<div class="flag-title light-color">基础信息</div>
|
||||
<u-form-item
|
||||
<up-form-item
|
||||
required
|
||||
:border-bottom="false"
|
||||
prop="companyName"
|
||||
label="公司名称"
|
||||
><u-input
|
||||
><u-input border="none" class="field-input"
|
||||
v-model="form.companyName"
|
||||
:custom-style="defaultInputStyle"
|
||||
/></u-form-item>
|
||||
<u-form-item
|
||||
:custom-style="fieldInputStyle"
|
||||
/></up-form-item>
|
||||
<up-form-item
|
||||
required
|
||||
:border-bottom="false"
|
||||
prop="companyAddressPath"
|
||||
label="公司所在地"
|
||||
>
|
||||
<div @click="showPicker()" style="margin-right: 30rpx;">选择</div>
|
||||
<u-input
|
||||
disabled
|
||||
:custom-style="defaultInputStyle"
|
||||
v-model="form.companyAddressPath"
|
||||
/></u-form-item>
|
||||
<u-form-item
|
||||
<view class="field-row">
|
||||
<u-input
|
||||
disabled
|
||||
border="none"
|
||||
class="field-input"
|
||||
:custom-style="fieldInputStyle"
|
||||
v-model="form.companyAddressPath"
|
||||
/>
|
||||
<view class="picker-action" @click="showPicker()">选择</view>
|
||||
</view>
|
||||
</up-form-item>
|
||||
<up-form-item
|
||||
required
|
||||
:border-bottom="false"
|
||||
prop="companyAddress"
|
||||
label="公司详细地址"
|
||||
><u-input
|
||||
:custom-style="defaultInputStyle"
|
||||
><u-input border="none" class="field-input"
|
||||
:custom-style="fieldInputStyle"
|
||||
v-model="form.companyAddress"
|
||||
/></u-form-item>
|
||||
<u-form-item
|
||||
/></up-form-item>
|
||||
<up-form-item
|
||||
required
|
||||
:border-bottom="false"
|
||||
prop="employeeNum"
|
||||
label="员工人数"
|
||||
><u-input
|
||||
><u-input border="none" class="field-input"
|
||||
type="number"
|
||||
:custom-style="defaultInputStyle"
|
||||
:custom-style="fieldInputStyle"
|
||||
v-model="form.employeeNum"
|
||||
/></u-form-item>
|
||||
/></up-form-item>
|
||||
|
||||
<u-form-item
|
||||
<up-form-item
|
||||
required
|
||||
:border-bottom="false"
|
||||
prop="companyPhone"
|
||||
label="公司电话"
|
||||
><u-input
|
||||
><u-input border="none" class="field-input"
|
||||
type="number"
|
||||
:custom-style="defaultInputStyle"
|
||||
:custom-style="fieldInputStyle"
|
||||
v-model="form.companyPhone"
|
||||
/></u-form-item>
|
||||
<u-form-item
|
||||
/></up-form-item>
|
||||
<up-form-item
|
||||
:border-bottom="false"
|
||||
prop="registeredCapital"
|
||||
label="注册资金"
|
||||
required
|
||||
><u-input
|
||||
><u-input border="none" class="field-input"
|
||||
type="number"
|
||||
:custom-style="defaultInputStyle"
|
||||
:custom-style="fieldInputStyle"
|
||||
v-model="form.registeredCapital"
|
||||
/></u-form-item>
|
||||
<u-form-item
|
||||
/></up-form-item>
|
||||
<up-form-item
|
||||
required
|
||||
:border-bottom="false"
|
||||
prop="linkName"
|
||||
label="联系人姓名"
|
||||
><u-input :custom-style="defaultInputStyle" v-model="form.linkName"
|
||||
/></u-form-item>
|
||||
<u-form-item
|
||||
><u-input border="none" class="field-input" :custom-style="fieldInputStyle" v-model="form.linkName"
|
||||
/></up-form-item>
|
||||
<up-form-item
|
||||
required
|
||||
:border-bottom="false"
|
||||
prop="linkPhone"
|
||||
label="联系人电话"
|
||||
><u-input
|
||||
><u-input border="none" class="field-input"
|
||||
type="number"
|
||||
:custom-style="defaultInputStyle"
|
||||
:custom-style="fieldInputStyle"
|
||||
v-model="form.linkPhone"
|
||||
/></u-form-item>
|
||||
<u-form-item
|
||||
/></up-form-item>
|
||||
<up-form-item
|
||||
required
|
||||
:border-bottom="false"
|
||||
prop="companyEmail"
|
||||
label="电子邮箱"
|
||||
><u-input
|
||||
:custom-style="defaultInputStyle"
|
||||
><u-input border="none" class="field-input"
|
||||
:custom-style="fieldInputStyle"
|
||||
v-model="form.companyEmail"
|
||||
/></u-form-item>
|
||||
/></up-form-item>
|
||||
</div>
|
||||
<div class="column">
|
||||
<div class="flag-title light-color">营业执照信息</div>
|
||||
<u-form-item
|
||||
<up-form-item
|
||||
required
|
||||
:border-bottom="false"
|
||||
prop="licenseNum"
|
||||
label="营业执照号"
|
||||
><u-input :custom-style="defaultInputStyle" v-model="form.licenseNum"
|
||||
/></u-form-item>
|
||||
<u-form-item
|
||||
><u-input border="none" class="field-input" :custom-style="fieldInputStyle" v-model="form.licenseNum"
|
||||
/></up-form-item>
|
||||
<up-form-item
|
||||
required
|
||||
:border-bottom="false"
|
||||
prop="scope"
|
||||
label="法定经营范围"
|
||||
><u-input :custom-style="defaultInputStyle" v-model="form.scope"
|
||||
/></u-form-item>
|
||||
<u-form-item
|
||||
><u-input border="none" class="field-input" :custom-style="fieldInputStyle" v-model="form.scope"
|
||||
/></up-form-item>
|
||||
<up-form-item
|
||||
:border-bottom="false"
|
||||
prop="licencePhoto"
|
||||
label="营业执照电子版"
|
||||
@@ -126,25 +131,25 @@
|
||||
请压缩图片在2M以内,确保文字清晰以免上传或审核失败
|
||||
</div>
|
||||
</div>
|
||||
</u-form-item>
|
||||
</up-form-item>
|
||||
</div>
|
||||
<div class="column">
|
||||
<div class="flag-title light-color">法人信息</div>
|
||||
<u-form-item
|
||||
<up-form-item
|
||||
required
|
||||
:border-bottom="false"
|
||||
prop="legalName"
|
||||
label="法人姓名"
|
||||
><u-input :custom-style="defaultInputStyle" v-model="form.legalName"
|
||||
/></u-form-item>
|
||||
<u-form-item
|
||||
><u-input border="none" class="field-input" :custom-style="fieldInputStyle" v-model="form.legalName"
|
||||
/></up-form-item>
|
||||
<up-form-item
|
||||
required
|
||||
:border-bottom="false"
|
||||
prop="legalId"
|
||||
label="法人证件号"
|
||||
><u-input :custom-style="defaultInputStyle" v-model="form.legalId"
|
||||
/></u-form-item>
|
||||
<u-form-item
|
||||
><u-input border="none" class="field-input" :custom-style="fieldInputStyle" v-model="form.legalId"
|
||||
/></up-form-item>
|
||||
<up-form-item
|
||||
required
|
||||
:border-bottom="false"
|
||||
prop="legalPhoto"
|
||||
@@ -166,11 +171,10 @@
|
||||
:max-count="1"
|
||||
></u-upload>
|
||||
</div>
|
||||
</u-form-item>
|
||||
{{form}}
|
||||
</up-form-item>
|
||||
</div>
|
||||
</u-form>
|
||||
<div class="submit" @click="validatorStep1Form">提交/下一步</div>
|
||||
</up-form>
|
||||
<view class="submit" @click="validatorStep1Form">提交/下一步</view>
|
||||
<m-city
|
||||
:provinceData="list"
|
||||
headTitle="区域选择"
|
||||
@@ -182,234 +186,222 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { applyFirst } from "@/api/entry";
|
||||
import city from "@/components/m-city/m-city.vue";
|
||||
import storage from "@/utils/storage.js";
|
||||
import { handleUploadAfterRead, getUploadedUrls } from "@/utils/uploadHelper.js";
|
||||
import * as RegExp from "@/utils/RegExp.js";
|
||||
export default {
|
||||
components: { "m-city": city },
|
||||
data() {
|
||||
return {
|
||||
storage,
|
||||
defaultInputStyle: {
|
||||
background: "#f7f7f7",
|
||||
padding: "0 20rpx",
|
||||
"border-radius": "10rpx",
|
||||
},
|
||||
legalPhotoFileList: [],
|
||||
legalPhotoBackFileList: [],
|
||||
licencePhotoFileList: [],
|
||||
form: {
|
||||
companyName: "",
|
||||
companyAddressIdPath: [],
|
||||
companyAddressPath: "",
|
||||
companyAddress: "",
|
||||
employeeNum: "",
|
||||
registeredCapital: "",
|
||||
linkName: "",
|
||||
linkPhone: "",
|
||||
companyPhone: "",
|
||||
companyEmail: "",
|
||||
licenseNum: "",
|
||||
scope: "",
|
||||
legalPhoto: "",
|
||||
licencePhoto: "",
|
||||
legalName: "",
|
||||
legalId: "",
|
||||
},
|
||||
list: [
|
||||
{
|
||||
id: "",
|
||||
localName: "请选择",
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
rules: {
|
||||
// 验证规则
|
||||
companyName: [{ required: true, message: "请填写公司信息" }],
|
||||
companyAddressPath: [{ required: true, message: "请选择公司所在地" }],
|
||||
companyAddress: [{ required: true, message: "请填写公司详细地址" }],
|
||||
employeeNum: [{ required: true, message: "请填写公司员工总数" }],
|
||||
registeredCapital: [{ required: true, message: "请填写公司注册资金" }],
|
||||
linkName: [{ required: true, message: "请填写联系人姓名" }],
|
||||
linkPhone: [
|
||||
{ required: true, message: "请填写联系人电话" },
|
||||
{
|
||||
// 自定义验证函数,见上说明
|
||||
validator: (rule, value, callback) => {
|
||||
// 上面有说,返回true表示校验通过,返回false表示不通过
|
||||
// this.$u.test.mobile()就是返回true或者false的
|
||||
return this.$u.test.mobile(value);
|
||||
},
|
||||
message: "手机号码不正确",
|
||||
// 触发器可以同时用blur和change
|
||||
trigger: ["change", "blur"],
|
||||
},
|
||||
],
|
||||
companyPhone: [
|
||||
{ required: true, message: "请填写公司电话" },
|
||||
{
|
||||
// 自定义验证函数,见上说明
|
||||
validator: (rule, value, callback) => {
|
||||
// 上面有说,返回true表示校验通过,返回false表示不通过
|
||||
// this.$u.test.mobile()就是返回true或者false的
|
||||
return this.$u.test.mobile(value);
|
||||
},
|
||||
message: "请填写正确的号码",
|
||||
// 触发器可以同时用blur和change
|
||||
trigger: ["change", "blur"],
|
||||
},
|
||||
],
|
||||
companyEmail: [
|
||||
{ required: true, message: "请填写电子邮箱" },
|
||||
{
|
||||
// 自定义验证函数,见上说明
|
||||
validator: (rule, value, callback) => {
|
||||
// 上面有说,返回true表示校验通过,返回false表示不通过
|
||||
// this.$u.test.mobile()就是返回true或者false的
|
||||
return this.$u.test.email(value);
|
||||
},
|
||||
message: "请填写正确的电子邮箱",
|
||||
// 触发器可以同时用blur和change
|
||||
trigger: ["change", "blur"],
|
||||
},
|
||||
],
|
||||
licenseNum: [
|
||||
{ required: true, message: "请填写营业执照号" },
|
||||
{ pattern: RegExp.licenseNum, message: "请输入正确的营业执照号" },
|
||||
],
|
||||
scope: [{ required: true, message: "请填写营业执照所示经营范围" }],
|
||||
legalPhoto: [{ required: true, message: "请上传法人身份证照片" },
|
||||
{
|
||||
// 自定义验证函数,见上说明
|
||||
validator: (rule, value, callback) => {
|
||||
// 上面有说,返回true表示校验通过,返回false表示不通过
|
||||
// this.$u.test.mobile()就是返回true或者false的
|
||||
return value.length === 2;
|
||||
},
|
||||
message: "请上传法人身份证正反照片",
|
||||
// 触发器可以同时用blur和change
|
||||
trigger: ["change", "blur"],
|
||||
}],
|
||||
licencePhoto: [{ required: true, message: "请上传营业执照" }],
|
||||
legalName: [{ required: true, message: "请输入法人姓名" }],
|
||||
legalId: [
|
||||
{ required: true, message: "请输入法人证件号" },
|
||||
{ pattern: RegExp.IDCard, message: "请输入正确的证件号" },
|
||||
],
|
||||
},
|
||||
};
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed, watch, getCurrentInstance } from 'vue'
|
||||
import { onReady } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { applyFirst } from '@/api/entry'
|
||||
import MCity from '@/components/m-city/m-city.vue'
|
||||
import { handleUploadAfterRead, getUploadedUrls } from '@/utils/uploadHelper.js'
|
||||
import * as RegExp from '@/utils/RegExp.js'
|
||||
import { getThemeStyle } from '@/utils/theme'
|
||||
import { fieldInputStyle } from '@/utils/form-style.js'
|
||||
|
||||
const props = defineProps<{ companyData?: any }>()
|
||||
const emit = defineEmits<{ callback: [] }>()
|
||||
|
||||
const store = useStore()
|
||||
const { proxy } = getCurrentInstance()!
|
||||
|
||||
const themeStyle = computed(() => getThemeStyle(store.state.theme))
|
||||
|
||||
const uForm = ref<any>(null)
|
||||
const cityPicker = ref<any>(null)
|
||||
|
||||
const legalPhotoFileList = ref<any[]>([])
|
||||
const legalPhotoBackFileList = ref<any[]>([])
|
||||
const licencePhotoFileList = ref<any[]>([])
|
||||
|
||||
const form = reactive<Record<string, any>>({
|
||||
companyName: '',
|
||||
companyAddressIdPath: [],
|
||||
companyAddressPath: '',
|
||||
companyAddress: '',
|
||||
employeeNum: '',
|
||||
registeredCapital: '',
|
||||
linkName: '',
|
||||
linkPhone: '',
|
||||
companyPhone: '',
|
||||
companyEmail: '',
|
||||
licenseNum: '',
|
||||
scope: '',
|
||||
legalPhoto: '',
|
||||
licencePhoto: '',
|
||||
legalName: '',
|
||||
legalId: '',
|
||||
})
|
||||
|
||||
const list = ref([
|
||||
{
|
||||
id: '',
|
||||
localName: '请选择',
|
||||
children: [],
|
||||
},
|
||||
mounted() {
|
||||
this.$refs.uForm.setRules(this.rules);
|
||||
},
|
||||
props: ["companyData"],
|
||||
watch: {
|
||||
companyData: {
|
||||
handler(val) {
|
||||
if (val) {
|
||||
this["form"] = val;
|
||||
// 给图片赋值
|
||||
const judgeDeepPhoto = ["legalPhoto", "licencePhoto"];
|
||||
judgeDeepPhoto.forEach((key) => {
|
||||
if (this.form[key]) {
|
||||
this.form[key].split(",").forEach((item) => {
|
||||
this[`${key}FileList`].push({ url: item });
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
deep: true,
|
||||
])
|
||||
|
||||
const rules = {
|
||||
companyName: [{ required: true, message: '请填写公司信息' }],
|
||||
companyAddressPath: [{ required: true, message: '请选择公司所在地' }],
|
||||
companyAddress: [{ required: true, message: '请填写公司详细地址' }],
|
||||
employeeNum: [{ required: true, message: '请填写公司员工总数' }],
|
||||
registeredCapital: [{ required: true, message: '请填写公司注册资金' }],
|
||||
linkName: [{ required: true, message: '请填写联系人姓名' }],
|
||||
linkPhone: [
|
||||
{ required: true, message: '请填写联系人电话' },
|
||||
{
|
||||
validator: (_rule: unknown, value: string) => proxy.$u.test.mobile(value),
|
||||
message: '手机号码不正确',
|
||||
trigger: ['change', 'blur'],
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onUploadAfterRead(event, key, fileListKey) {
|
||||
if (!Array.isArray(this.form[key])) {
|
||||
this.form[key] = [];
|
||||
],
|
||||
companyPhone: [
|
||||
{ required: true, message: '请填写公司电话' },
|
||||
{
|
||||
validator: (_rule: unknown, value: string) => proxy.$u.test.mobile(value),
|
||||
message: '请填写正确的号码',
|
||||
trigger: ['change', 'blur'],
|
||||
},
|
||||
],
|
||||
companyEmail: [
|
||||
{ required: true, message: '请填写电子邮箱' },
|
||||
{
|
||||
validator: (_rule: unknown, value: string) => proxy.$u.test.email(value),
|
||||
message: '请填写正确的电子邮箱',
|
||||
trigger: ['change', 'blur'],
|
||||
},
|
||||
],
|
||||
licenseNum: [
|
||||
{ required: true, message: '请填写营业执照号' },
|
||||
{ pattern: RegExp.licenseNum, message: '请输入正确的营业执照号' },
|
||||
],
|
||||
scope: [{ required: true, message: '请填写营业执照所示经营范围' }],
|
||||
legalPhoto: [
|
||||
{ required: true, message: '请上传法人身份证照片' },
|
||||
{
|
||||
validator: (_rule: unknown, value: string | string[]) =>
|
||||
Array.isArray(value) ? value.length === 2 : false,
|
||||
message: '请上传法人身份证正反照片',
|
||||
trigger: ['change', 'blur'],
|
||||
},
|
||||
],
|
||||
licencePhoto: [{ required: true, message: '请上传营业执照' }],
|
||||
legalName: [{ required: true, message: '请输入法人姓名' }],
|
||||
legalId: [
|
||||
{ required: true, message: '请输入法人证件号' },
|
||||
{ pattern: RegExp.IDCard, message: '请输入正确的证件号' },
|
||||
],
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.companyData,
|
||||
(val) => {
|
||||
if (val) {
|
||||
Object.assign(form, val)
|
||||
const judgeDeepPhoto = ['legalPhoto', 'licencePhoto'] as const
|
||||
const fileListMap = {
|
||||
legalPhoto: legalPhotoFileList,
|
||||
licencePhoto: licencePhotoFileList,
|
||||
}
|
||||
handleUploadAfterRead(event, this[fileListKey], () => {
|
||||
if (key === "legalPhoto") {
|
||||
this.form[key] = [
|
||||
...getUploadedUrls(this.legalPhotoFileList),
|
||||
...getUploadedUrls(this.legalPhotoBackFileList),
|
||||
];
|
||||
} else {
|
||||
this.form[key] = getUploadedUrls(this[fileListKey]);
|
||||
judgeDeepPhoto.forEach((key) => {
|
||||
if (form[key]) {
|
||||
form[key].split(',').forEach((item: string) => {
|
||||
fileListMap[key].value.push({ url: item })
|
||||
})
|
||||
}
|
||||
});
|
||||
},
|
||||
getPickerParentValue(e) {
|
||||
this.form.companyAddressIdPath = [];
|
||||
|
||||
let name = "";
|
||||
e.forEach((item, index) => {
|
||||
if (item.id) {
|
||||
// 遍历数据
|
||||
this.form.companyAddressIdPath.push(item.id);
|
||||
if (index == e.length - 1) {
|
||||
name += item.localName;
|
||||
} else {
|
||||
name += item.localName + ",";
|
||||
}
|
||||
this.form.companyAddressPath = name;
|
||||
}
|
||||
});
|
||||
},
|
||||
// 显示三级地址联动
|
||||
showPicker() {
|
||||
console.log(this.$refs)
|
||||
this.$refs.cityPicker.show();
|
||||
},
|
||||
validatorStep1Form() {
|
||||
this.$refs.uForm.validate(async (valid) => {
|
||||
console.log(valid);
|
||||
if (valid) {
|
||||
const params = { ...this.form };
|
||||
|
||||
params.legalPhoto = params.legalPhoto.toString();
|
||||
params.licencePhoto = params.licencePhoto.toString();
|
||||
params.companyAddressIdPath = params.companyAddressIdPath.toString();
|
||||
delete params.complexAddress;
|
||||
|
||||
const res = await applyFirst(params);
|
||||
if (res.data.success) {
|
||||
uni.showToast({
|
||||
title: "提交成功!",
|
||||
icon: "none",
|
||||
});
|
||||
this.$emit("callback");
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
})
|
||||
}
|
||||
},
|
||||
};
|
||||
{ deep: true }
|
||||
)
|
||||
|
||||
onReady(() => {
|
||||
uForm.value?.setRules(rules)
|
||||
})
|
||||
|
||||
function onUploadAfterRead(
|
||||
event: any,
|
||||
key: string,
|
||||
fileListKey: 'licencePhotoFileList' | 'legalPhotoFileList' | 'legalPhotoBackFileList'
|
||||
) {
|
||||
const fileListMap = {
|
||||
licencePhotoFileList,
|
||||
legalPhotoFileList,
|
||||
legalPhotoBackFileList,
|
||||
}
|
||||
|
||||
if (!Array.isArray(form[key])) {
|
||||
form[key] = []
|
||||
}
|
||||
|
||||
handleUploadAfterRead(event, fileListMap[fileListKey].value, () => {
|
||||
if (key === 'legalPhoto') {
|
||||
form[key] = [
|
||||
...getUploadedUrls(legalPhotoFileList.value),
|
||||
...getUploadedUrls(legalPhotoBackFileList.value),
|
||||
]
|
||||
} else {
|
||||
form[key] = getUploadedUrls(fileListMap[fileListKey].value)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function getPickerParentValue(e: any[]) {
|
||||
form.companyAddressIdPath = []
|
||||
|
||||
let name = ''
|
||||
e.forEach((item, index) => {
|
||||
if (item.id) {
|
||||
form.companyAddressIdPath.push(item.id)
|
||||
if (index == e.length - 1) {
|
||||
name += item.localName
|
||||
} else {
|
||||
name += item.localName + ','
|
||||
}
|
||||
form.companyAddressPath = name
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function showPicker() {
|
||||
cityPicker.value?.show()
|
||||
}
|
||||
|
||||
function validatorStep1Form() {
|
||||
uForm.value?.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
const params = { ...form }
|
||||
|
||||
params.legalPhoto = params.legalPhoto.toString()
|
||||
params.licencePhoto = params.licencePhoto.toString()
|
||||
params.companyAddressIdPath = params.companyAddressIdPath.toString()
|
||||
delete params.complexAddress
|
||||
|
||||
const res = await applyFirst(params)
|
||||
if (res.data.success) {
|
||||
uni.showToast({
|
||||
title: '提交成功!',
|
||||
icon: 'none',
|
||||
})
|
||||
emit('callback')
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
/* page {
|
||||
background: #fff;
|
||||
} */
|
||||
<style lang="scss">
|
||||
page {
|
||||
background: #f8f8f8;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
@import url("./entry.scss");
|
||||
@import "./entry.scss";
|
||||
@import "./entry-form.scss";
|
||||
|
||||
.column {
|
||||
padding: 32rpx;
|
||||
margin-bottom: 20rpx;
|
||||
background: #fff;
|
||||
.wrapper {
|
||||
@include seller-entry-form;
|
||||
}
|
||||
|
||||
.submit {
|
||||
color: #fff;
|
||||
margin-top: 120rpx;
|
||||
background: rgba($light-color, 0.8);
|
||||
}
|
||||
.tips {
|
||||
color: #999;
|
||||
font-size: 24rpx;
|
||||
line-height: 1.2;
|
||||
margin-top: 10rpx;
|
||||
@include seller-entry-submit;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,144 +1,135 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<u-form label-width="250" :model="form" ref="uForm">
|
||||
<div class="wrapper" :style="themeStyle">
|
||||
<up-form label-position="top" :model="form" ref="uForm">
|
||||
<div class="column">
|
||||
<div class="flag-title light-color">基础信息</div>
|
||||
<u-form-item
|
||||
<up-form-item
|
||||
required
|
||||
:border-bottom="false"
|
||||
prop="settlementBankAccountName"
|
||||
label="银行开户名"
|
||||
><u-input
|
||||
><u-input border="none" class="field-input"
|
||||
v-model="form.settlementBankAccountName"
|
||||
:custom-style="defaultInputStyle"
|
||||
/></u-form-item>
|
||||
:custom-style="fieldInputStyle"
|
||||
/></up-form-item>
|
||||
|
||||
<u-form-item
|
||||
<up-form-item
|
||||
required
|
||||
:border-bottom="false"
|
||||
prop="settlementBankAccountNum"
|
||||
label="银行账号"
|
||||
><u-input
|
||||
:custom-style="defaultInputStyle"
|
||||
><u-input border="none" class="field-input"
|
||||
:custom-style="fieldInputStyle"
|
||||
v-model="form.settlementBankAccountNum"
|
||||
/></u-form-item>
|
||||
<u-form-item
|
||||
/></up-form-item>
|
||||
<up-form-item
|
||||
required
|
||||
:border-bottom="false"
|
||||
prop="settlementBankBranchName"
|
||||
label="开户银行支行名称"
|
||||
><u-input
|
||||
:custom-style="defaultInputStyle"
|
||||
><u-input border="none" class="field-input"
|
||||
:custom-style="fieldInputStyle"
|
||||
v-model="form.settlementBankBranchName"
|
||||
/></u-form-item>
|
||||
/></up-form-item>
|
||||
|
||||
<u-form-item
|
||||
<up-form-item
|
||||
required
|
||||
:border-bottom="false"
|
||||
prop="settlementBankJointName"
|
||||
label="支行联行号"
|
||||
><u-input
|
||||
:custom-style="defaultInputStyle"
|
||||
><u-input border="none" class="field-input"
|
||||
:custom-style="fieldInputStyle"
|
||||
v-model="form.settlementBankJointName"
|
||||
/></u-form-item>
|
||||
/></up-form-item>
|
||||
</div>
|
||||
</u-form>
|
||||
<div class="submit" @click="validatorStep2Form">提交/下一步</div>
|
||||
</up-form>
|
||||
<view class="submit" @click="validatorStep2Form">提交/下一步</view>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { applySecond } from "@/api/entry";
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed, watch } from 'vue'
|
||||
import { onReady } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { applySecond } from '@/api/entry'
|
||||
import { getThemeStyle } from '@/utils/theme'
|
||||
import { fieldInputStyle } from '@/utils/form-style.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
defaultInputStyle: {
|
||||
background: "#f7f7f7",
|
||||
padding: "0 20rpx",
|
||||
"border-radius": "10rpx",
|
||||
},
|
||||
form: {
|
||||
settlementBankAccountName: "",
|
||||
settlementBankAccountNum: "",
|
||||
settlementBankBranchName: "",
|
||||
settlementBankJointName: "",
|
||||
},
|
||||
const props = defineProps<{ companyData?: any }>()
|
||||
const emit = defineEmits<{ callback: [] }>()
|
||||
|
||||
rules: {
|
||||
// 验证规则
|
||||
settlementBankAccountName: [
|
||||
{ required: true, message: "请填写银行开户名称" },
|
||||
],
|
||||
settlementBankAccountNum: [
|
||||
{ required: true, message: "请填写银行账号" },
|
||||
],
|
||||
settlementBankBranchName: [
|
||||
{ required: true, message: "请填写开户银行支行名称" },
|
||||
],
|
||||
settlementBankJointName: [
|
||||
{ required: true, message: "请填写支行联行号" },
|
||||
],
|
||||
},
|
||||
};
|
||||
const store = useStore()
|
||||
|
||||
const themeStyle = computed(() => getThemeStyle(store.state.theme))
|
||||
|
||||
const uForm = ref<any>(null)
|
||||
|
||||
const form = reactive({
|
||||
settlementBankAccountName: '',
|
||||
settlementBankAccountNum: '',
|
||||
settlementBankBranchName: '',
|
||||
settlementBankJointName: '',
|
||||
})
|
||||
|
||||
const rules = {
|
||||
settlementBankAccountName: [
|
||||
{ required: true, message: '请填写银行开户名称' },
|
||||
],
|
||||
settlementBankAccountNum: [
|
||||
{ required: true, message: '请填写银行账号' },
|
||||
],
|
||||
settlementBankBranchName: [
|
||||
{ required: true, message: '请填写开户银行支行名称' },
|
||||
],
|
||||
settlementBankJointName: [
|
||||
{ required: true, message: '请填写支行联行号' },
|
||||
],
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.companyData,
|
||||
(val) => {
|
||||
if (val) {
|
||||
Object.assign(form, val)
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$refs.uForm.setRules(this.rules);
|
||||
},
|
||||
props: ["companyData"],
|
||||
watch: {
|
||||
companyData: {
|
||||
handler(val) {
|
||||
this["form"] = val;
|
||||
console.log(this.form)
|
||||
},
|
||||
deep: true,
|
||||
immediate:true
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
validatorStep2Form() {
|
||||
this.$refs.uForm.validate(async (valid) => {
|
||||
if (valid) {
|
||||
const params = { ...this.form };
|
||||
const res = await applySecond(params);
|
||||
if (res.data.success) {
|
||||
uni.showToast({
|
||||
title: "提交成功!",
|
||||
icon: "none",
|
||||
});
|
||||
this.$emit("callback");
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
{ deep: true, immediate: true }
|
||||
)
|
||||
|
||||
onReady(() => {
|
||||
uForm.value?.setRules(rules)
|
||||
})
|
||||
|
||||
function validatorStep2Form() {
|
||||
uForm.value?.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
const params = { ...form }
|
||||
const res = await applySecond(params)
|
||||
if (res.data.success) {
|
||||
uni.showToast({
|
||||
title: '提交成功!',
|
||||
icon: 'none',
|
||||
})
|
||||
emit('callback')
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
/* page {
|
||||
background: #fff;
|
||||
} */
|
||||
<style lang="scss">
|
||||
page {
|
||||
background: #f8f8f8;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
@import url("./entry.scss");
|
||||
@import "./entry.scss";
|
||||
@import "./entry-form.scss";
|
||||
|
||||
.wrapper {
|
||||
// padding: 50rpx 32rpx 16rpx 32rpx;
|
||||
}
|
||||
.column {
|
||||
padding: 32rpx;
|
||||
margin-bottom: 20rpx;
|
||||
background: #fff;
|
||||
@include seller-entry-form;
|
||||
}
|
||||
|
||||
.submit {
|
||||
color: #fff;
|
||||
margin-top: 120rpx;
|
||||
background: rgba($light-color, 0.8);
|
||||
}
|
||||
.tips {
|
||||
color: #999;
|
||||
font-size: 24rpx;
|
||||
line-height: 1.2;
|
||||
margin-top: 10rpx;
|
||||
@include seller-entry-submit;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<u-form label-width="200" :model="form" ref="uForm">
|
||||
<div class="wrapper" :style="themeStyle">
|
||||
<up-form label-position="top" :model="form" ref="uForm">
|
||||
<div class="column">
|
||||
<div class="flag-title light-color">基础信息</div>
|
||||
<u-form-item
|
||||
<up-form-item
|
||||
required
|
||||
:border-bottom="false"
|
||||
prop="storeName"
|
||||
label="店铺名称"
|
||||
><u-input v-model="form.storeName" :custom-style="defaultInputStyle"
|
||||
/></u-form-item>
|
||||
<u-form-item
|
||||
><u-input border="none" class="field-input" v-model="form.storeName" :custom-style="fieldInputStyle"
|
||||
/></up-form-item>
|
||||
<up-form-item
|
||||
required
|
||||
:border-bottom="false"
|
||||
prop="storeLogo"
|
||||
@@ -25,39 +25,45 @@
|
||||
:max-count="1"
|
||||
></u-upload>
|
||||
</div>
|
||||
</u-form-item>
|
||||
<u-form-item
|
||||
</up-form-item>
|
||||
<up-form-item
|
||||
required
|
||||
:border-bottom="false"
|
||||
prop="goodsManagementCategory"
|
||||
label="店铺经营类目"
|
||||
>
|
||||
<div @click="showCategory()" style="margin-right: 30rpx;">选择</div>
|
||||
|
||||
<u-input
|
||||
:custom-style="defaultInputStyle"
|
||||
v-model="goodsManagementCategory"
|
||||
disabled
|
||||
@click="showCategory()"
|
||||
/></u-form-item>
|
||||
>
|
||||
<view class="field-row">
|
||||
<u-input
|
||||
border="none"
|
||||
class="field-input"
|
||||
:custom-style="fieldInputStyle"
|
||||
v-model="goodsManagementCategory"
|
||||
disabled
|
||||
@click="showCategory()"
|
||||
/>
|
||||
<view class="picker-action" @click="showCategory()">选择</view>
|
||||
</view>
|
||||
</up-form-item>
|
||||
|
||||
<u-form-item
|
||||
<up-form-item
|
||||
required
|
||||
:border-bottom="false"
|
||||
prop="storeAddressPath"
|
||||
label="店铺所在地"
|
||||
>
|
||||
<div @click="showPicker()" style="margin-right: 30rpx;">选择</div>
|
||||
<u-input
|
||||
:custom-style="defaultInputStyle"
|
||||
v-model="form.storeAddressPath"
|
||||
|
||||
disabled
|
||||
|
||||
/>
|
||||
</u-form-item>
|
||||
<view class="field-row">
|
||||
<u-input
|
||||
border="none"
|
||||
class="field-input"
|
||||
:custom-style="fieldInputStyle"
|
||||
v-model="form.storeAddressPath"
|
||||
disabled
|
||||
/>
|
||||
<view class="picker-action" @click="showPicker()">选择</view>
|
||||
</view>
|
||||
</up-form-item>
|
||||
|
||||
<!-- <u-form-item
|
||||
<!-- <up-form-item
|
||||
required
|
||||
:border-bottom="false"
|
||||
prop="storeAddressPath"
|
||||
@@ -65,30 +71,35 @@
|
||||
>
|
||||
<div class="get-center" @click="clickUniMap()">开始定位</div>
|
||||
<div class="tips-success" v-if="form.storeCenter">已成功定位</div>
|
||||
</u-form-item> -->
|
||||
</up-form-item> -->
|
||||
|
||||
<u-form-item
|
||||
<up-form-item
|
||||
required
|
||||
:border-bottom="false"
|
||||
prop="storeAddressDetail"
|
||||
label="店铺详细地址"
|
||||
><u-input
|
||||
:custom-style="defaultInputStyle"
|
||||
><u-input border="none" class="field-input"
|
||||
:custom-style="fieldInputStyle"
|
||||
v-model="form.storeAddressDetail"
|
||||
/></u-form-item>
|
||||
<u-form-item
|
||||
/></up-form-item>
|
||||
<up-form-item
|
||||
required
|
||||
:border-bottom="false"
|
||||
prop="storeDesc"
|
||||
label="店铺简介"
|
||||
><u-input
|
||||
type="textarea"
|
||||
:custom-style="defaultInputStyle"
|
||||
>
|
||||
<u-textarea
|
||||
class="field-textarea"
|
||||
border="none"
|
||||
height="240"
|
||||
maxlength="500"
|
||||
v-model="form.storeDesc"
|
||||
/></u-form-item>
|
||||
placeholder="请输入店铺简介"
|
||||
/>
|
||||
</up-form-item>
|
||||
</div>
|
||||
</u-form>
|
||||
<div class="submit" @click="validatorStep1Form">提交平台审核</div>
|
||||
</up-form>
|
||||
<view class="submit" @click="validatorStep3Form">提交平台审核</view>
|
||||
<m-city
|
||||
:provinceData="list"
|
||||
headTitle="区域选择"
|
||||
@@ -108,261 +119,256 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { applyThird } from "@/api/entry";
|
||||
import { getCategoryList } from "@/api/goods";
|
||||
import city from "@/components/m-city/m-city.vue";
|
||||
import storage from "@/utils/storage.js";
|
||||
import { handleUploadAfterRead } from "@/utils/uploadHelper.js";
|
||||
import uniMap from "@/components/uniMap";
|
||||
import permision from "@/js_sdk/wa-permission/permission.js";
|
||||
export default {
|
||||
components: { "m-city": city, uniMap },
|
||||
data() {
|
||||
return {
|
||||
storage,
|
||||
mapFlag: false,
|
||||
defaultInputStyle: {
|
||||
background: "#f7f7f7",
|
||||
padding: "0 20rpx",
|
||||
"border-radius": "10rpx",
|
||||
},
|
||||
goodsManagementCategory: "",
|
||||
storeLogoFileList: [],
|
||||
categoryList: [],
|
||||
form: {
|
||||
storeName: "",
|
||||
storeLogo: "",
|
||||
goodsManagementCategory: "",
|
||||
storeAddressPath: "",
|
||||
storeAddressDetail: "",
|
||||
storeDesc: "",
|
||||
},
|
||||
list: [
|
||||
{
|
||||
id: "",
|
||||
localName: "请选择",
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
rules: {
|
||||
// 验证规则
|
||||
goodsManagementCategory: [
|
||||
{ required: true, message: "请选择店铺经营类目" },
|
||||
],
|
||||
storeName: [{ required: true, message: "请填写店铺名称" }],
|
||||
storeLogo: [{ required: true, message: "请上传店铺logo" }],
|
||||
storeDesc: [{ required: true, message: "请填写店铺简介" }],
|
||||
storeCenter: [{ required: true, message: "请选择店铺位置" }],
|
||||
storeAddressIdPath: [{ required: true, message: "请选择店铺位置" }],
|
||||
storeAddressDetail: [{ required: true, message: "请输入店铺详细地址" }],
|
||||
},
|
||||
enableCategory: false,
|
||||
};
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed, watch, onMounted } from 'vue'
|
||||
import { onReady } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { applyThird } from '@/api/entry'
|
||||
import { getCategoryList } from '@/api/goods'
|
||||
import MCity from '@/components/m-city/m-city.vue'
|
||||
import uniMap from '@/components/uniMap'
|
||||
import permision from '@/js_sdk/wa-permission/permission.js'
|
||||
import { handleUploadAfterRead } from '@/utils/uploadHelper.js'
|
||||
import { getThemeStyle } from '@/utils/theme'
|
||||
import { fieldInputStyle } from '@/utils/form-style.js'
|
||||
|
||||
const props = defineProps<{ companyData?: any }>()
|
||||
const emit = defineEmits<{ callback: [] }>()
|
||||
|
||||
const store = useStore()
|
||||
|
||||
const themeStyle = computed(() => getThemeStyle(store.state.theme))
|
||||
|
||||
const uForm = ref<any>(null)
|
||||
const cityPicker = ref<any>(null)
|
||||
|
||||
const mapFlag = ref(false)
|
||||
const enableCategory = ref(false)
|
||||
const goodsManagementCategory = ref('')
|
||||
const storeLogoFileList = ref<any[]>([])
|
||||
const categoryList = ref<any[]>([])
|
||||
|
||||
const form = reactive<Record<string, any>>({
|
||||
storeName: '',
|
||||
storeLogo: '',
|
||||
goodsManagementCategory: '',
|
||||
storeAddressPath: '',
|
||||
storeAddressDetail: '',
|
||||
storeDesc: '',
|
||||
})
|
||||
|
||||
const list = ref([
|
||||
{
|
||||
id: '',
|
||||
localName: '请选择',
|
||||
children: [],
|
||||
},
|
||||
mounted() {
|
||||
this.$refs.uForm.setRules(this.rules);
|
||||
this.fetchCategoryList();
|
||||
])
|
||||
|
||||
const rules = {
|
||||
goodsManagementCategory: [
|
||||
{ required: true, message: '请选择店铺经营类目' },
|
||||
],
|
||||
storeName: [{ required: true, message: '请填写店铺名称' }],
|
||||
storeLogo: [{ required: true, message: '请上传店铺logo' }],
|
||||
storeDesc: [{ required: true, message: '请填写店铺简介' }],
|
||||
storeCenter: [{ required: true, message: '请选择店铺位置' }],
|
||||
storeAddressIdPath: [{ required: true, message: '请选择店铺位置' }],
|
||||
storeAddressDetail: [{ required: true, message: '请输入店铺详细地址' }],
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.companyData,
|
||||
(val) => {
|
||||
if (val) {
|
||||
Object.assign(form, val)
|
||||
const judgeDeepPhoto = ['storeLogo']
|
||||
|
||||
judgeDeepPhoto.forEach((key) => {
|
||||
if (form[key]) {
|
||||
storeLogoFileList.value = []
|
||||
form[key].split(',').forEach((item: string) => {
|
||||
storeLogoFileList.value.push({ url: item })
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
props: ["companyData"],
|
||||
watch: {
|
||||
companyData: {
|
||||
handler(val) {
|
||||
this["form"] = val;
|
||||
// 给图片赋值
|
||||
const judgeDeepPhoto = ["storeLogo"];
|
||||
{ deep: true, immediate: true }
|
||||
)
|
||||
|
||||
judgeDeepPhoto.forEach((key) => {
|
||||
if (this.form[key]) {
|
||||
this.form[key].split(",").forEach((item) => {
|
||||
this[`${key}FileList`].push({ url: item });
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
deep: true,
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
onReady(() => {
|
||||
uForm.value?.setRules(rules)
|
||||
})
|
||||
|
||||
methods: {
|
||||
callBackAddress(val) {
|
||||
console.log(val);
|
||||
this.form.storeAddressDetail = val.address;
|
||||
this.form.storeCenter = `${val.longitude},${val.latitude}`;
|
||||
},
|
||||
// 关闭地图
|
||||
closeMap() {
|
||||
this.mapFlag = false;
|
||||
},
|
||||
// 打开地图并访问权限
|
||||
clickUniMap() {
|
||||
console.log("click");
|
||||
// #ifdef APP-PLUS
|
||||
if (plus.os.name == "iOS") {
|
||||
// ios系统
|
||||
permision.judgeIosPermission("location")
|
||||
? (this.mapFlag = true)
|
||||
: this.refuseMap();
|
||||
} else {
|
||||
// 安卓
|
||||
this.requestAndroidPermission(
|
||||
"android.permission.ACCESS_FINE_LOCATION"
|
||||
);
|
||||
}
|
||||
// #endif
|
||||
onMounted(() => {
|
||||
fetchCategoryList()
|
||||
})
|
||||
|
||||
// #ifndef APP-PLUS
|
||||
this.mapFlag = true;
|
||||
// #endif
|
||||
},
|
||||
function callBackAddress(val: any) {
|
||||
form.storeAddressDetail = val.address
|
||||
form.storeCenter = `${val.longitude},${val.latitude}`
|
||||
}
|
||||
|
||||
// 如果拒绝权限 提示区设置
|
||||
refuseMap() {
|
||||
uni.showModal({
|
||||
title: "温馨提示",
|
||||
content: "您已拒绝定位,请开启",
|
||||
confirmText: "去设置",
|
||||
success(res) {
|
||||
if (res.confirm) {
|
||||
//打开授权设置
|
||||
// #ifndef MP-WEIXIN
|
||||
uni.getSystemInfo({
|
||||
success(res) {
|
||||
if (res.platform == "ios") {
|
||||
//IOS
|
||||
plus.runtime.openURL("app-settings://");
|
||||
} else if (res.platform == "android") {
|
||||
//安卓
|
||||
let main = plus.android.runtimeMainActivity();
|
||||
let Intent = plus.android.importClass(
|
||||
"android.content.Intent"
|
||||
);
|
||||
let mIntent = new Intent("android.settings.ACTION_SETTINGS");
|
||||
main.startActivity(mIntent);
|
||||
}
|
||||
},
|
||||
});
|
||||
// #endif
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
// 获取安卓是否拥有地址权限
|
||||
async requestAndroidPermission(permisionID) {
|
||||
var result = await permision.requestAndroidPermission(permisionID);
|
||||
function closeMap() {
|
||||
mapFlag.value = false
|
||||
}
|
||||
|
||||
if (result == 1) {
|
||||
this.mapFlag = true;
|
||||
} else {
|
||||
this.refuseMap();
|
||||
function clickUniMap() {
|
||||
// #ifdef APP-PLUS
|
||||
if (plus.os.name == 'iOS') {
|
||||
permision.judgeIosPermission('location')
|
||||
? (mapFlag.value = true)
|
||||
: refuseMap()
|
||||
} else {
|
||||
requestAndroidPermission('android.permission.ACCESS_FINE_LOCATION')
|
||||
}
|
||||
// #endif
|
||||
|
||||
// #ifndef APP-PLUS
|
||||
mapFlag.value = true
|
||||
// #endif
|
||||
}
|
||||
|
||||
function refuseMap() {
|
||||
uni.showModal({
|
||||
title: '温馨提示',
|
||||
content: '您已拒绝定位,请开启',
|
||||
confirmText: '去设置',
|
||||
success(res) {
|
||||
if (res.confirm) {
|
||||
// #ifndef MP-WEIXIN
|
||||
uni.getSystemInfo({
|
||||
success(sysRes) {
|
||||
if (sysRes.platform == 'ios') {
|
||||
plus.runtime.openURL('app-settings://')
|
||||
} else if (sysRes.platform == 'android') {
|
||||
const main = plus.android.runtimeMainActivity()
|
||||
const Intent = plus.android.importClass('android.content.Intent')
|
||||
const mIntent = new Intent('android.settings.ACTION_SETTINGS')
|
||||
main.startActivity(mIntent)
|
||||
}
|
||||
},
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
confirmCategory(val) {
|
||||
this.form.goodsManagementCategory = val[0].value;
|
||||
this.goodsManagementCategory = val[0].label;
|
||||
},
|
||||
async fetchCategoryList() {
|
||||
const res = await getCategoryList(0);
|
||||
async function requestAndroidPermission(permisionID: string) {
|
||||
const result = await permision.requestAndroidPermission(permisionID)
|
||||
|
||||
if (result == 1) {
|
||||
mapFlag.value = true
|
||||
} else {
|
||||
refuseMap()
|
||||
}
|
||||
}
|
||||
|
||||
function confirmCategory(val: any[]) {
|
||||
form.goodsManagementCategory = val[0].value
|
||||
goodsManagementCategory.value = val[0].label
|
||||
}
|
||||
|
||||
async function fetchCategoryList() {
|
||||
const res = await getCategoryList(0)
|
||||
if (res.data.success) {
|
||||
if (res.data.result.length) {
|
||||
categoryList.value = res.data.result.map((item: any) => {
|
||||
return { label: item.name, value: item.id }
|
||||
})
|
||||
|
||||
if (form.goodsManagementCategory) {
|
||||
goodsManagementCategory.value = categoryList.value.find(
|
||||
(item) => form.goodsManagementCategory == item.value
|
||||
)?.label || ''
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onUploadAfterRead(
|
||||
event: any,
|
||||
key: string,
|
||||
fileListKey: 'storeLogoFileList'
|
||||
) {
|
||||
handleUploadAfterRead(event, storeLogoFileList.value, (urls) => {
|
||||
form[key] = urls
|
||||
})
|
||||
}
|
||||
|
||||
function getPickerParentValue(e: any[]) {
|
||||
form.storeAddressIdPath = []
|
||||
let name = ''
|
||||
e.forEach((item, index) => {
|
||||
if (item.id) {
|
||||
form.storeAddressIdPath.push(item.id)
|
||||
if (index == e.length - 1) {
|
||||
name += item.localName
|
||||
} else {
|
||||
name += item.localName + ','
|
||||
}
|
||||
form.storeAddressPath = name
|
||||
}
|
||||
})
|
||||
|
||||
form.storeCenter = e[e.length - 1].center
|
||||
}
|
||||
|
||||
function showPicker() {
|
||||
cityPicker.value?.show()
|
||||
}
|
||||
|
||||
function showCategory() {
|
||||
enableCategory.value = true
|
||||
}
|
||||
|
||||
function validatorStep3Form() {
|
||||
uForm.value?.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
const params = { ...form }
|
||||
params.storeLogo = params.storeLogo.toString()
|
||||
params.storeAddressIdPath = params.storeAddressIdPath.toString()
|
||||
const res = await applyThird(params)
|
||||
if (res.data.success) {
|
||||
if (res.data.result.length) {
|
||||
this.categoryList = res.data.result.map((item) => {
|
||||
return { label: item.name, value: item.id };
|
||||
});
|
||||
|
||||
if (this.form.goodsManagementCategory) {
|
||||
this.goodsManagementCategory = this.categoryList.find(
|
||||
(item) => this.form.goodsManagementCategory == item.value
|
||||
).label;
|
||||
}
|
||||
}
|
||||
uni.showToast({
|
||||
title: '提交成功!',
|
||||
icon: 'none',
|
||||
})
|
||||
emit('callback')
|
||||
}
|
||||
},
|
||||
onUploadAfterRead(event, key, fileListKey) {
|
||||
handleUploadAfterRead(event, this[fileListKey], (urls) => {
|
||||
this.form[key] = urls;
|
||||
});
|
||||
},
|
||||
getPickerParentValue(e) {
|
||||
this.form.storeAddressIdPath = [];
|
||||
console.log(e)
|
||||
let name = "";
|
||||
e.forEach((item, index) => {
|
||||
if (item.id) {
|
||||
// 遍历数据
|
||||
this.form.storeAddressIdPath.push(item.id);
|
||||
if (index == e.length - 1) {
|
||||
name += item.localName;
|
||||
} else {
|
||||
name += item.localName + ",";
|
||||
}
|
||||
this.form['storeAddressPath'] = name
|
||||
}
|
||||
});
|
||||
|
||||
this.form.storeCenter = e[e.length-1].center
|
||||
},
|
||||
// 显示三级地址联动
|
||||
showPicker() {
|
||||
this.$refs.cityPicker.show();
|
||||
},
|
||||
showCategory() {
|
||||
this.enableCategory = true;
|
||||
},
|
||||
validatorStep1Form() {
|
||||
this.$refs.uForm.validate(async (valid) => {
|
||||
console.log(valid);
|
||||
if (valid) {
|
||||
const params = { ...this.form };
|
||||
params.storeLogo = params.storeLogo.toString();
|
||||
params.storeAddressIdPath = params.storeAddressIdPath.toString();
|
||||
const res = await applyThird(params);
|
||||
if (res.data.success) {
|
||||
uni.showToast({
|
||||
title: "提交成功!",
|
||||
icon: "none",
|
||||
});
|
||||
this.$emit("callback");
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
/* page {
|
||||
background: #fff;
|
||||
} */
|
||||
<style lang="scss">
|
||||
page {
|
||||
background: #f8f8f8;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
@import url("./entry.scss");
|
||||
@import "./entry.scss";
|
||||
@import "./entry-form.scss";
|
||||
|
||||
.wrapper {
|
||||
@include seller-entry-form;
|
||||
}
|
||||
|
||||
.get-center {
|
||||
padding: 12rpx 30rpx;
|
||||
background: $light-color;
|
||||
background: var(--theme-light, #ff6b35);
|
||||
border-radius: 10rpx;
|
||||
font-size: 24rpx;
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
display: inline;
|
||||
}
|
||||
.column {
|
||||
padding: 32rpx;
|
||||
margin-bottom: 20rpx;
|
||||
background: #fff;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.submit {
|
||||
color: #fff;
|
||||
margin-top: 120rpx;
|
||||
background: rgba($light-color, 0.8);
|
||||
}
|
||||
.tips {
|
||||
color: #999;
|
||||
font-size: 24rpx;
|
||||
line-height: 1.2;
|
||||
margin-top: 10rpx;
|
||||
@include seller-entry-submit;
|
||||
}
|
||||
|
||||
.tips-success {
|
||||
color: $weChat-color;
|
||||
font-size: 24rpx;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -31,79 +31,78 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { scannerCodeLogin, scannerCodeLoginConfirm } from "@/api/login";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
errorMsg: "",
|
||||
token: "",
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
errorMsg(val) {
|
||||
if (val) {
|
||||
uni.showToast({
|
||||
title: val,
|
||||
icon: "none",
|
||||
});
|
||||
// uni.navigateBack()
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue'
|
||||
import { onLoad, onShow } from '@dcloudio/uni-app'
|
||||
import { forceLogin } from '@/utils/filters.js'
|
||||
import { scannerCodeLogin, scannerCodeLoginConfirm } from '@/api/login'
|
||||
|
||||
const errorMsg = ref('')
|
||||
const token = ref('')
|
||||
|
||||
watch(errorMsg, (val) => {
|
||||
if (val) {
|
||||
uni.showToast({
|
||||
title: val,
|
||||
icon: 'none',
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
onLoad((params) => {
|
||||
token.value = params.token || ''
|
||||
if (!token.value) {
|
||||
errorMsg.value = '信息异常'
|
||||
}
|
||||
})
|
||||
|
||||
onShow(() => {
|
||||
forceLogin()
|
||||
scannerCodeLogin({ token: token.value }).then((res) => {
|
||||
if (res.data.code == 200) {
|
||||
const code = res.data.result
|
||||
switch (code) {
|
||||
case 0:
|
||||
case 1:
|
||||
errorMsg.value = ''
|
||||
break
|
||||
case 2:
|
||||
case 3:
|
||||
errorMsg.value = '请勿重复扫码'
|
||||
break
|
||||
case 4:
|
||||
errorMsg.value = '二维码已过期,重新扫码'
|
||||
break
|
||||
default:
|
||||
errorMsg.value = '状态异常'
|
||||
}
|
||||
},
|
||||
},
|
||||
onShow() {
|
||||
this.forceLogin();
|
||||
scannerCodeLogin({ token: this.token }).then((res) => {
|
||||
if (res.data.code == 200) {
|
||||
let code = res.data.result;
|
||||
switch (code) {
|
||||
case 0:
|
||||
case 1:
|
||||
this.errorMsg = "";
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
this.errorMsg = "请勿重复扫码";
|
||||
break;
|
||||
case 4:
|
||||
this.errorMsg = "二维码已过期,重新扫码";
|
||||
break;
|
||||
default:
|
||||
this.errorMsg = "状态异常";
|
||||
}
|
||||
} else {
|
||||
this.errorMsg = res.data.message;
|
||||
}
|
||||
});
|
||||
},
|
||||
onLoad(params) {
|
||||
this.token = params.token;
|
||||
if (this.token == undefined || this.token == "") {
|
||||
this.errorMsg = "信息异常";
|
||||
} else {
|
||||
errorMsg.value = res.data.message
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
confirmLogin() {
|
||||
this.config(1);
|
||||
},
|
||||
cancelLogin() {
|
||||
this.config(0);
|
||||
},
|
||||
config(code) {
|
||||
scannerCodeLoginConfirm({ token: this.token, code: code }).then((res) => {
|
||||
let title = res.data.success ? "操作成功" : "操作失败";
|
||||
uni.showToast({
|
||||
title: title,
|
||||
duration: 1500,
|
||||
icon: "none",
|
||||
});
|
||||
setTimeout(function () {
|
||||
uni.navigateBack();
|
||||
}, 1000);
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
})
|
||||
})
|
||||
|
||||
function confirmLogin() {
|
||||
submitLoginConfirm(1)
|
||||
}
|
||||
|
||||
function cancelLogin() {
|
||||
submitLoginConfirm(0)
|
||||
}
|
||||
|
||||
function submitLoginConfirm(code: number) {
|
||||
scannerCodeLoginConfirm({ token: token.value, code }).then((res) => {
|
||||
const title = res.data.success ? '操作成功' : '操作失败'
|
||||
uni.showToast({
|
||||
title,
|
||||
duration: 1500,
|
||||
icon: 'none',
|
||||
})
|
||||
setTimeout(() => {
|
||||
uni.navigateBack()
|
||||
}, 1000)
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
page {
|
||||
|
||||
@@ -19,39 +19,33 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { whetherNavigate } from "@/utils/Foundation"; //登录跳转
|
||||
import config from "@/config/config";
|
||||
import api from "@/config/api.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 授权信息展示,商城名称
|
||||
projectName: config.name,
|
||||
};
|
||||
},
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { whetherNavigate } from '@/utils/Foundation'
|
||||
import config from '@/config/config'
|
||||
import api from '@/config/api.js'
|
||||
|
||||
//微信小程序进入页面,先获取code,否则几率出现code和后续交互数据不对应情况
|
||||
mounted() {
|
||||
// 小程序默认分享
|
||||
uni.showShareMenu({ withShareTicket: true });
|
||||
},
|
||||
methods: {
|
||||
back() {
|
||||
whetherNavigate();
|
||||
},
|
||||
getUserProfile() {
|
||||
let code = "WECHAT";
|
||||
let buyer = api.buyer;
|
||||
window.open(buyer + `/passport/connect/connect/login/web/` + code, "_self");
|
||||
},
|
||||
backToHome() {
|
||||
uni.switchTab({
|
||||
url: `/pages/tabbar/home/index`,
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
const projectName = ref(config.name)
|
||||
|
||||
onMounted(() => {
|
||||
uni.showShareMenu({ withShareTicket: true })
|
||||
})
|
||||
|
||||
function back() {
|
||||
whetherNavigate()
|
||||
}
|
||||
|
||||
function getUserProfile() {
|
||||
const code = 'WECHAT'
|
||||
const buyer = api.buyer
|
||||
window.open(buyer + `/passport/connect/connect/login/web/` + code, '_self')
|
||||
}
|
||||
|
||||
function backToHome() {
|
||||
uni.switchTab({
|
||||
url: '/pages/tabbar/home/index',
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -46,197 +46,127 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mpAutoLogin
|
||||
} from "@/api/connect.js";
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { useStore } from '@/store'
|
||||
import { mpAutoLogin } from '@/api/connect.js'
|
||||
import { whetherNavigate } from '@/utils/Foundation'
|
||||
import { getUserInfo } from '@/api/members'
|
||||
import storage from '@/utils/storage.js'
|
||||
import config from '@/config/config'
|
||||
|
||||
import {
|
||||
whetherNavigate
|
||||
} from "@/utils/Foundation"; //登录跳转
|
||||
import {
|
||||
getUserInfo
|
||||
} from "@/api/members";
|
||||
import storage from "@/utils/storage.js";
|
||||
import config from '@/config/config'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
lightColor:this.$lightColor,
|
||||
checked:false,
|
||||
configs:config,
|
||||
// 是否展示手机号码授权弹窗,默认第一步不展示,要先获取用户基础信息
|
||||
phoneAuthPopup: false,
|
||||
// 授权信息展示,商城名称
|
||||
projectName: config.name,
|
||||
//微信返回信息,用于揭秘信息,获取sessionkey
|
||||
code: "",
|
||||
//微信昵称
|
||||
nickName: "",
|
||||
logingFlag: false,
|
||||
//微信头像
|
||||
image: "",
|
||||
};
|
||||
},
|
||||
const store = useStore()
|
||||
const lightColor = computed(() => store.getters.lightColor)
|
||||
|
||||
//微信小程序进入页面,先获取code,否则几率出现code和后续交互数据不对应情况
|
||||
mounted() {
|
||||
// 小程序默认分享
|
||||
uni.showShareMenu({
|
||||
withShareTicket: true
|
||||
});
|
||||
const checked = ref(false)
|
||||
const configs = config
|
||||
const phoneAuthPopup = ref(false)
|
||||
const projectName = ref(config.name)
|
||||
const code = ref('')
|
||||
const nickName = ref('')
|
||||
const logingFlag = ref(false)
|
||||
const image = ref('')
|
||||
|
||||
onMounted(() => {
|
||||
uni.showShareMenu({ withShareTicket: true })
|
||||
uni.login({
|
||||
success: (res) => {
|
||||
if (res.errMsg === 'login:ok') {
|
||||
code.value = res.code
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '系统异常,请联系管理员!',
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
//获取code
|
||||
uni.login({
|
||||
success: (res) => {
|
||||
if(res.errMsg === "login:ok") {
|
||||
this.code = res.code
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: "系统异常,请联系管理员!"
|
||||
})
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* TODO 此方法不一定是最优解,如果有更好的办法请在 https://gitee.com/beijing_hongye_huicheng/lilishop/issues 中提出
|
||||
* 小程序返回bug
|
||||
* 1.介于微信登录是在login.vue的基础上作为判断跳转来
|
||||
* 所以在页面栈中会自动记录回退路径,所以导致每次微信小程序点击回退就会自动返回login页面
|
||||
* 当然login页面的判断就是 没有登录就会跳转到微信小程序页面 导致了无法回退到之前页面
|
||||
* 2.解决方法: 尝试在回退的时候判断地址,让回退多一级这样就避免了
|
||||
*/
|
||||
function back() {
|
||||
whetherNavigate('wx')
|
||||
}
|
||||
|
||||
back() {
|
||||
whetherNavigate("wx");
|
||||
},
|
||||
backToHome() {
|
||||
uni.switchTab({
|
||||
url: `/pages/tabbar/home/index`,
|
||||
});
|
||||
},
|
||||
function backToHome() {
|
||||
uni.switchTab({
|
||||
url: '/pages/tabbar/home/index',
|
||||
})
|
||||
}
|
||||
|
||||
function completeLogin(accessToken: string, refreshToken: string) {
|
||||
storage.setAccessToken(accessToken)
|
||||
storage.setRefreshToken(refreshToken)
|
||||
uni.showToast({
|
||||
title: '登录成功!',
|
||||
icon: 'none',
|
||||
})
|
||||
getUserInfo().then((user) => {
|
||||
storage.setUserInfo(user.data.result)
|
||||
storage.setHasLogin(true)
|
||||
uni.navigateBack({ delta: 1 })
|
||||
})
|
||||
}
|
||||
|
||||
function getUserProfile() {
|
||||
if (!checked.value) {
|
||||
uni.showToast({
|
||||
title: '请勾选协议',
|
||||
icon: 'none',
|
||||
})
|
||||
return
|
||||
}
|
||||
logingFlag.value = true
|
||||
|
||||
if (!code.value) return
|
||||
|
||||
//获取用户信息
|
||||
getUserProfile(e) {
|
||||
if(!this.checked){
|
||||
uni.showToast({
|
||||
title:"请勾选协议",
|
||||
icon:'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
this.logingFlag = true;
|
||||
uni.getUserProfile({
|
||||
desc: '用于完善会员资料',
|
||||
success: (res) => {
|
||||
nickName.value = res.userInfo.nickName
|
||||
image.value = res.userInfo.avatarUrl
|
||||
|
||||
if (this.code) {
|
||||
// 推荐使用wx.getUserProfile获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认
|
||||
uni.getUserProfile({
|
||||
desc: "用于完善会员资料", // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
|
||||
success: (res) => {
|
||||
console.log("success", res)
|
||||
this.nickName = res.userInfo.nickName;
|
||||
this.image = res.userInfo.avatarUrl;
|
||||
if (configs.enableFetchMobileLogin) {
|
||||
phoneAuthPopup.value = true
|
||||
return
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据公有的配置设置登录方式
|
||||
*/
|
||||
if(this.configs.enableFetchMobileLogin){
|
||||
this.phoneAuthPopup = true;
|
||||
return false
|
||||
}
|
||||
let iv = res.iv;
|
||||
let encryptedData = res.encryptedData;
|
||||
mpAutoLogin({
|
||||
encryptedData: res.encryptedData,
|
||||
iv: res.iv,
|
||||
code: code.value,
|
||||
image: image.value,
|
||||
nickName: nickName.value,
|
||||
}).then((apiRes) => {
|
||||
completeLogin(apiRes.data.result.accessToken, apiRes.data.result.refreshToken)
|
||||
})
|
||||
},
|
||||
fail: (res) => {
|
||||
console.log('fail', res)
|
||||
},
|
||||
})
|
||||
|
||||
let code = this.code;
|
||||
let image = this.image;
|
||||
let nickName = this.nickName;
|
||||
mpAutoLogin({
|
||||
encryptedData,
|
||||
iv,
|
||||
code,
|
||||
image,
|
||||
nickName,
|
||||
}).then((apiRes) => {
|
||||
storage.setAccessToken(apiRes.data.result.accessToken);
|
||||
storage.setRefreshToken(apiRes.data.result.refreshToken);
|
||||
// 登录成功
|
||||
uni.showToast({
|
||||
title: "登录成功!",
|
||||
icon: "none",
|
||||
});
|
||||
//获取用户信息
|
||||
getUserInfo().then((user) => {
|
||||
storage.setUserInfo(user.data.result);
|
||||
storage.setHasLogin(true);
|
||||
logingFlag.value = false
|
||||
}
|
||||
|
||||
uni.navigateBack({
|
||||
delta: 1,
|
||||
});
|
||||
});
|
||||
});
|
||||
function getPhoneNumber(e: any) {
|
||||
const { iv, encryptedData } = e.detail
|
||||
if (!encryptedData) {
|
||||
uni.showToast({
|
||||
title: '请授予手机号码权限,手机号码会和会员系统用户绑定!',
|
||||
icon: 'none',
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
},
|
||||
fail: (res) => {
|
||||
console.log("fail", res)
|
||||
},
|
||||
});
|
||||
|
||||
this.logingFlag = false;
|
||||
}
|
||||
},
|
||||
|
||||
//获取手机号授权
|
||||
getPhoneNumber(e) {
|
||||
let iv = e.detail.iv;
|
||||
let encryptedData = e.detail.encryptedData;
|
||||
if (!e.detail.encryptedData) {
|
||||
uni.showToast({
|
||||
title: "请授予手机号码权限,手机号码会和会员系统用户绑定!",
|
||||
icon: "none",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
let code = this.code;
|
||||
let image = this.image;
|
||||
let nickName = this.nickName;
|
||||
mpAutoLogin({
|
||||
encryptedData,
|
||||
iv,
|
||||
code,
|
||||
image,
|
||||
nickName,
|
||||
}).then((res) => {
|
||||
storage.setAccessToken(res.data.result.accessToken);
|
||||
storage.setRefreshToken(res.data.result.refreshToken);
|
||||
// 登录成功
|
||||
uni.showToast({
|
||||
title: "登录成功!",
|
||||
icon: "none",
|
||||
});
|
||||
//获取用户信息
|
||||
getUserInfo().then((user) => {
|
||||
storage.setUserInfo(user.data.result);
|
||||
storage.setHasLogin(true);
|
||||
|
||||
uni.navigateBack({
|
||||
delta: 1,
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
|
||||
|
||||
},
|
||||
};
|
||||
mpAutoLogin({
|
||||
encryptedData,
|
||||
iv,
|
||||
code: code.value,
|
||||
image: image.value,
|
||||
nickName: nickName.value,
|
||||
}).then((res) => {
|
||||
completeLogin(res.data.result.accessToken, res.data.result.refreshToken)
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
/*微信授权*/
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<u-col span="12">
|
||||
<u-row :gutter="12">
|
||||
<u-col :offset="1" span="4">
|
||||
<u-button class="btns" @click="askValue=''">清空</u-button>
|
||||
<u-button class="btns" @click="params.askValue=''">清空</u-button>
|
||||
</u-col>
|
||||
<u-col :offset="2" span="4">
|
||||
<u-button class="btns" @click="getAskMessage()" type="success">提交</u-button>
|
||||
@@ -36,75 +36,83 @@
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import * as API_GOODS from "../../api/goods";
|
||||
import * as API_MEM from "../../api/members";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
askGoods: "",
|
||||
queryGoodsDetail: "",
|
||||
border: true,
|
||||
params: {
|
||||
askValue: "",
|
||||
anonymous: "YES",
|
||||
},
|
||||
};
|
||||
},
|
||||
onLoad(options) {
|
||||
this.askGoods = options;
|
||||
this.getGoodsData();
|
||||
},
|
||||
methods: {
|
||||
getGoodsData() {
|
||||
if (this.askGoods.goods_id) {
|
||||
API_GOODS.getGoods(this.askGoods.goods_id).then((result) => {
|
||||
this.queryGoodsDetail = result.data;
|
||||
});
|
||||
}
|
||||
},
|
||||
getAskMessage() {
|
||||
uni.showLoading();
|
||||
if (this.params.askValue == "") {
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import * as API_GOODS from '../../api/goods'
|
||||
import * as API_MEM from '../../api/members'
|
||||
import { useStore } from '@/store'
|
||||
|
||||
const store = useStore()
|
||||
|
||||
const askGoods = ref<any>('')
|
||||
const queryGoodsDetail = ref<any>('')
|
||||
const border = ref(true)
|
||||
const params = reactive({
|
||||
askValue: '',
|
||||
anonymous: 'YES',
|
||||
})
|
||||
|
||||
function getGoodsData() {
|
||||
if (askGoods.value.goods_id) {
|
||||
API_GOODS.getGoods(askGoods.value.goods_id).then((result) => {
|
||||
queryGoodsDetail.value = result.data
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function getAskMessage() {
|
||||
uni.showLoading()
|
||||
if (params.askValue == '') {
|
||||
uni.showToast({
|
||||
title: '请填写内容!',
|
||||
icon: 'none',
|
||||
})
|
||||
if (store.state.isShowToast) {
|
||||
uni.hideLoading()
|
||||
}
|
||||
return false
|
||||
}
|
||||
API_MEM.consultating(
|
||||
askGoods.value.goods_id,
|
||||
params.askValue,
|
||||
params.anonymous
|
||||
)
|
||||
.then((res) => {
|
||||
if (res.statusCode == 200) {
|
||||
uni.showToast({
|
||||
title: "请填写内容!",
|
||||
icon: "none",
|
||||
});
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
return false;
|
||||
}
|
||||
API_MEM.consultating(
|
||||
this.askGoods.goods_id,
|
||||
this.params.askValue,
|
||||
this.params.anonymous
|
||||
)
|
||||
.then((res) => {
|
||||
if (res.statusCode == 200) {
|
||||
uni.showToast({
|
||||
title: "提交成功!",
|
||||
icon: "none",
|
||||
});
|
||||
this.askValue = "";
|
||||
}
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
title: '提交成功!',
|
||||
icon: 'none',
|
||||
})
|
||||
.catch((err) => {
|
||||
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
});
|
||||
},
|
||||
radioGroupChange(e) {
|
||||
|
||||
},
|
||||
radioChange(e) {
|
||||
if (this.anonymous == "YES") {
|
||||
this.anonymous = "NO";
|
||||
} else {
|
||||
this.anonymous = "YES";
|
||||
params.askValue = ''
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
if (store.state.isShowToast) {
|
||||
uni.hideLoading()
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
if (store.state.isShowToast) {
|
||||
uni.hideLoading()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function radioGroupChange(_e: any) {}
|
||||
|
||||
function radioChange(_e: any) {
|
||||
if (params.anonymous == 'YES') {
|
||||
params.anonymous = 'NO'
|
||||
} else {
|
||||
params.anonymous = 'YES'
|
||||
}
|
||||
}
|
||||
|
||||
function goodsDetail() {}
|
||||
|
||||
onLoad((options: any) => {
|
||||
askGoods.value = options
|
||||
getGoodsData()
|
||||
})
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.img {
|
||||
|
||||
@@ -82,130 +82,129 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as membersApi from "@/api/members.js";
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref } from 'vue'
|
||||
import { onLoad, onReachBottom } from '@dcloudio/uni-app'
|
||||
import * as membersApi from '@/api/members.js'
|
||||
import configs from '@/config/config'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
configs,
|
||||
status: "loadmore",
|
||||
userImage: configs.defaultUserPhoto,
|
||||
commentDetail: "",
|
||||
selectIndex: "0",
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
grade: "",
|
||||
import { noPassByName } from '@/utils/filters.js'
|
||||
|
||||
const status = ref('loadmore')
|
||||
const userImage = configs.defaultUserPhoto
|
||||
const commentDetail = ref<any>('')
|
||||
const selectIndex = ref(0)
|
||||
const params = reactive<any>({
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
grade: '',
|
||||
})
|
||||
const gradeList: Record<string, string> = {
|
||||
GOOD: '好评',
|
||||
MODERATE: '中评',
|
||||
WORSE: '差评',
|
||||
HAVEIMAGE: '有图',
|
||||
}
|
||||
const commDetail = ref<any[]>([])
|
||||
const opid = ref('')
|
||||
|
||||
function commentScore(item: any) {
|
||||
return item.descriptionScore || item.deliveryScore || 0
|
||||
}
|
||||
|
||||
function splitImg(val: any) {
|
||||
if (val && val.split(',')) {
|
||||
return val.split(',')
|
||||
} else if (val) {
|
||||
return val
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
function getGoodsCommentsFun(id: string) {
|
||||
status.value = 'loading'
|
||||
membersApi.getGoodsComments(id, params).then((res) => {
|
||||
if (
|
||||
res.data.result.records == [] ||
|
||||
res.data.result.records == '' ||
|
||||
res.data.result.records == null
|
||||
) {
|
||||
status.value = 'noMore'
|
||||
return false
|
||||
}
|
||||
commDetail.value = commDetail.value.concat(res.data.result.records)
|
||||
status.value = 'loadmore'
|
||||
})
|
||||
}
|
||||
|
||||
function getGoodsCommentsNum(id: string) {
|
||||
membersApi.getGoodsCommentsCount(id).then((res) => {
|
||||
if (res.statusCode === 200) {
|
||||
commentDetail.value = res.data.result
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function select(index: number) {
|
||||
Object.assign(params, {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
})
|
||||
selectIndex.value = index
|
||||
params.grade = ['', 'GOOD', 'MODERATE', 'WORSE', ''][selectIndex.value]
|
||||
if (selectIndex.value === 4) {
|
||||
params.haveImage = 1
|
||||
}
|
||||
commDetail.value = []
|
||||
if (selectIndex.value === 0) {
|
||||
Object.assign(params, {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
grade: '',
|
||||
})
|
||||
}
|
||||
getGoodsCommentsFun(opid.value)
|
||||
}
|
||||
|
||||
function preview(urls: string[], index: number) {
|
||||
uni.previewImage({
|
||||
current: index,
|
||||
urls: urls,
|
||||
longPressActions: {
|
||||
itemList: ['保存图片'],
|
||||
success: function () {
|
||||
uni.showToast({
|
||||
title: '保存成功',
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
},
|
||||
gradeList: {
|
||||
GOOD: "好评",
|
||||
MODERATE: "中评",
|
||||
WORSE: "差评",
|
||||
HAVEIMAGE: "有图",
|
||||
fail: function () {
|
||||
uni.showToast({
|
||||
title: '保存失败',
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
},
|
||||
commDetail: [],
|
||||
dataTotal: 0,
|
||||
opid: "",
|
||||
};
|
||||
},
|
||||
async onLoad(options) {
|
||||
this.getGoodsCommentsFun(options.id);
|
||||
this.getGoodsCommentsNum(options.id);
|
||||
this.opid = options.id;
|
||||
},
|
||||
|
||||
onReachBottom() {
|
||||
this.params.pageNumber++;
|
||||
this.getGoodsCommentsFun(this.opid);
|
||||
},
|
||||
|
||||
methods: {
|
||||
commentScore(item) {
|
||||
return item.descriptionScore || item.deliveryScore || 0;
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
splitImg(val) {
|
||||
if (val && val.split(",")) {
|
||||
return val.split(",");
|
||||
} else if (val) {
|
||||
return val;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
function loadmore() {
|
||||
params.pageNumber++
|
||||
getGoodsCommentsFun(opid.value)
|
||||
}
|
||||
|
||||
getGoodsCommentsFun(id) {
|
||||
this.status = "loading";
|
||||
membersApi.getGoodsComments(id, this.params).then((res) => {
|
||||
if (
|
||||
res.data.result.records == [] ||
|
||||
res.data.result.records == "" ||
|
||||
res.data.result.records == null
|
||||
) {
|
||||
this.status = "noMore";
|
||||
return false;
|
||||
}
|
||||
this.commDetail = this.commDetail.concat(res.data.result.records);
|
||||
this.dataTotal = res.data.result.total;
|
||||
this.status = "loadmore";
|
||||
});
|
||||
},
|
||||
onLoad((options: any) => {
|
||||
getGoodsCommentsFun(options.id)
|
||||
getGoodsCommentsNum(options.id)
|
||||
opid.value = options.id
|
||||
})
|
||||
|
||||
getGoodsCommentsNum(id) {
|
||||
membersApi.getGoodsCommentsCount(id).then((res) => {
|
||||
if (res.statusCode === 200) {
|
||||
this.commentDetail = res.data.result;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
select(index) {
|
||||
this.params = {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
};
|
||||
this.selectIndex = index;
|
||||
this.params.grade = ["", "GOOD", "MODERATE", "WORSE", ""][
|
||||
this.selectIndex
|
||||
];
|
||||
this.selectIndex === 4 ? (this.params.haveImage = 1) : true;
|
||||
this.commDetail = [];
|
||||
if (this.selectIndex === 0) {
|
||||
this.params = {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
grade: "",
|
||||
};
|
||||
}
|
||||
this.getGoodsCommentsFun(this.opid);
|
||||
},
|
||||
|
||||
preview(urls, index) {
|
||||
uni.previewImage({
|
||||
current: index,
|
||||
urls: urls,
|
||||
longPressActions: {
|
||||
itemList: ["保存图片"],
|
||||
success: function () {
|
||||
uni.showToast({
|
||||
title: "保存成功",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
},
|
||||
fail: function () {
|
||||
uni.showToast({
|
||||
title: "保存失败",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
onReachBottom(() => {
|
||||
params.pageNumber++
|
||||
getGoodsCommentsFun(opid.value)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -3,89 +3,81 @@
|
||||
<chat></chat>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
},
|
||||
onLoad (e) {
|
||||
// 腾讯云智服客服插件需在 manifest.json 的 mp-weixin.plugins 中注册后方可使用,
|
||||
// 未注册时 requirePlugin 会抛出 "has not registered any plugins",此处做容错处理。
|
||||
let chat
|
||||
try {
|
||||
chat = requirePlugin('myPlugin')
|
||||
} catch (err) {
|
||||
uni.showToast({
|
||||
title: '客服功能暂未配置',
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
})
|
||||
return
|
||||
}
|
||||
const params = JSON.parse((decodeURIComponent(e.params)))
|
||||
chat.init({
|
||||
sign: params.mpSign, //必传,公司渠道唯一标识,腾讯云智服后台系统创建「小程序插件」渠道后,在「渠道管理」获取
|
||||
token: params.token, //非必填
|
||||
uid: params.uuid, //用户唯一标识,如果没有则不填写,默认为空
|
||||
title: params.storageName, //非必填,如果未填写,默认获取配置标题
|
||||
isRMB: '', //商品是否显示人民币¥,默认显示,false不显示
|
||||
data: { //参数c1,c2,c3,c4,c5用于传递用户信息,参数d1,d2,d3,d4,d5,d6用于传递商品信息,默认为空
|
||||
c1: '',
|
||||
c2: '',
|
||||
c3: '',
|
||||
c4: '',
|
||||
c5: '',
|
||||
d1: params.goodsName, //商品描述
|
||||
d2: params.price, //价格
|
||||
d3: '', //原价格
|
||||
d4: params.goodsImg, //展示商品图片链接
|
||||
d5: '', //商品跳转链接
|
||||
d6: params.goodsId, //商品id
|
||||
data: ''//加密串,非必填
|
||||
},
|
||||
viewUrl(res){ //需要跳转外部链接,则需要配置一个web-view
|
||||
if (res) {
|
||||
wx.navigateTo({
|
||||
url: '/pages/webview/index?href=' + res
|
||||
})
|
||||
}
|
||||
},
|
||||
setTitle(res){ //设置标题
|
||||
if (res) {
|
||||
wx.setNavigationBarTitle({
|
||||
title: res
|
||||
})
|
||||
}
|
||||
},
|
||||
setBarColor(res) { //设置导航栏背景色
|
||||
if (res) {
|
||||
wx.setNavigationBarColor({
|
||||
frontColor: '#ffffff',
|
||||
backgroundColor: res
|
||||
})
|
||||
}
|
||||
},
|
||||
success(res){ //初始化成功时调用
|
||||
if (res.data == 'success') {
|
||||
console.log('success');
|
||||
}
|
||||
},
|
||||
fail(res){ //初始化失败时调用
|
||||
if (res.data == 'initError') {
|
||||
console.log(res.message);
|
||||
}
|
||||
},
|
||||
leave(res){ //离开会话页面
|
||||
if (res) {
|
||||
console.log(res);
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
<script setup lang="ts">
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
|
||||
onLoad((e: any) => {
|
||||
// 腾讯云智服客服插件需在 manifest.json 的 mp-weixin.plugins 中注册后方可使用,
|
||||
// 未注册时 requirePlugin 会抛出 "has not registered any plugins",此处做容错处理。
|
||||
let chat
|
||||
try {
|
||||
chat = requirePlugin('myPlugin')
|
||||
} catch (err) {
|
||||
uni.showToast({
|
||||
title: '客服功能暂未配置',
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
})
|
||||
return
|
||||
}
|
||||
</script>
|
||||
const params = JSON.parse(decodeURIComponent(e.params))
|
||||
chat.init({
|
||||
sign: params.mpSign,
|
||||
token: params.token,
|
||||
uid: params.uuid,
|
||||
title: params.storageName,
|
||||
isRMB: '',
|
||||
data: {
|
||||
c1: '',
|
||||
c2: '',
|
||||
c3: '',
|
||||
c4: '',
|
||||
c5: '',
|
||||
d1: params.goodsName,
|
||||
d2: params.price,
|
||||
d3: '',
|
||||
d4: params.goodsImg,
|
||||
d5: '',
|
||||
d6: params.goodsId,
|
||||
data: ''
|
||||
},
|
||||
viewUrl(res: string){
|
||||
if (res) {
|
||||
wx.navigateTo({
|
||||
url: '/pages/webview/index?href=' + res
|
||||
})
|
||||
}
|
||||
},
|
||||
setTitle(res: string){
|
||||
if (res) {
|
||||
wx.setNavigationBarTitle({
|
||||
title: res
|
||||
})
|
||||
}
|
||||
},
|
||||
setBarColor(res: string) {
|
||||
if (res) {
|
||||
wx.setNavigationBarColor({
|
||||
frontColor: '#ffffff',
|
||||
backgroundColor: res
|
||||
})
|
||||
}
|
||||
},
|
||||
success(res: any){
|
||||
if (res.data == 'success') {
|
||||
console.log('success');
|
||||
}
|
||||
},
|
||||
fail(res: any){
|
||||
if (res.data == 'initError') {
|
||||
console.log(res.message);
|
||||
}
|
||||
},
|
||||
leave(res: any){
|
||||
if (res) {
|
||||
console.log(res);
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -9,41 +9,35 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getLicencePhoto } from "@/api/store.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
storeData: {},
|
||||
};
|
||||
},
|
||||
onLoad(options) {
|
||||
this.getStoreLicencePhoto(options.id);
|
||||
},
|
||||
methods: {
|
||||
async getStoreLicencePhoto(id) {
|
||||
let res = await getLicencePhoto(id);
|
||||
if (res.data.success) {
|
||||
this.storeData = res.data.result;
|
||||
}
|
||||
},
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { getLicencePhoto } from '@/api/store.js'
|
||||
|
||||
/**
|
||||
* 点击图片放大或保存
|
||||
*/
|
||||
preview() {
|
||||
uni.previewImage({
|
||||
current: 0,
|
||||
urls: [this.storeData.licencePhoto],
|
||||
longPressActions: {
|
||||
itemList: ["保存图片"],
|
||||
success: function (data) {},
|
||||
fail: function (err) {},
|
||||
},
|
||||
});
|
||||
const storeData = ref<any>({})
|
||||
|
||||
async function getStoreLicencePhoto(id: string) {
|
||||
const res = await getLicencePhoto(id)
|
||||
if (res.data.success) {
|
||||
storeData.value = res.data.result
|
||||
}
|
||||
}
|
||||
|
||||
function preview() {
|
||||
uni.previewImage({
|
||||
current: 0,
|
||||
urls: [storeData.value.licencePhoto],
|
||||
longPressActions: {
|
||||
itemList: ['保存图片'],
|
||||
success: function () {},
|
||||
fail: function () {},
|
||||
},
|
||||
},
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
onLoad((options: any) => {
|
||||
getStoreLicencePhoto(options.id)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@@ -53,4 +47,4 @@ export default {
|
||||
margin: 20rpx 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -64,88 +64,82 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as API_Members from "@/api/members.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
lightColor: this.$lightColor,
|
||||
commDetail: {},
|
||||
readMoreInited: {},
|
||||
grade: "",
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
grade: "",
|
||||
},
|
||||
};
|
||||
},
|
||||
props: {
|
||||
goodsDetail: {
|
||||
default: () => ({}),
|
||||
type: Object,
|
||||
},
|
||||
<script setup lang="ts">
|
||||
import { computed, nextTick, ref, watch } from 'vue'
|
||||
import * as API_Members from '@/api/members.js'
|
||||
import { noPassByName } from '@/utils/filters.js'
|
||||
import { useStore } from '@/store'
|
||||
|
||||
const props = defineProps<{
|
||||
goodsDetail?: Record<string, any>
|
||||
}>()
|
||||
|
||||
const store = useStore()
|
||||
const lightColor = computed(() => store.getters.lightColor)
|
||||
const commDetail = ref<any>({})
|
||||
const readMoreInited = ref<Record<number, boolean>>({})
|
||||
const grade = ref('')
|
||||
const params = {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
grade: '',
|
||||
}
|
||||
const uReadMore = ref<any>()
|
||||
|
||||
watch(
|
||||
() => props.goodsDetail,
|
||||
(val) => {
|
||||
if (val && val.goodsId) {
|
||||
grade.value = val.grade
|
||||
getGoodsCommentsMethods()
|
||||
}
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
)
|
||||
|
||||
watch: {
|
||||
goodsDetail: {
|
||||
handler(val) {
|
||||
if (val && val.goodsId) {
|
||||
this.grade = val.grade;
|
||||
this.getGoodsCommentsMethods();
|
||||
}
|
||||
},
|
||||
deep: true,
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
function commentImages(item: any) {
|
||||
const images = item.images || item.image
|
||||
if (!images) return []
|
||||
return typeof images === 'string' ? images.split(',').filter(Boolean) : images
|
||||
}
|
||||
|
||||
methods: {
|
||||
commentImages(item) {
|
||||
const images = item.images || item.image;
|
||||
if (!images) return [];
|
||||
return typeof images === "string" ? images.split(",").filter(Boolean) : images;
|
||||
},
|
||||
function initReadMore(index: number) {
|
||||
if (readMoreInited.value[index]) return
|
||||
readMoreInited.value[index] = true
|
||||
nextTick(() => {
|
||||
const refs = uReadMore.value
|
||||
const target = Array.isArray(refs) ? refs[index] : refs
|
||||
target?.init?.()
|
||||
})
|
||||
}
|
||||
|
||||
initReadMore(index) {
|
||||
if (this.readMoreInited[index]) return;
|
||||
this.readMoreInited[index] = true;
|
||||
this.$nextTick(() => {
|
||||
const refs = this.$refs.uReadMore;
|
||||
const target = Array.isArray(refs) ? refs[index] : refs;
|
||||
target?.init?.();
|
||||
});
|
||||
},
|
||||
function getGoodsCommentsMethods() {
|
||||
if (!props.goodsDetail?.goodsId) return
|
||||
API_Members.getGoodsComments(props.goodsDetail.goodsId, params).then((res) => {
|
||||
readMoreInited.value = {}
|
||||
commDetail.value = res.data.result || {}
|
||||
nextTick(() => {
|
||||
const records = commDetail.value.records || []
|
||||
records.slice(0, 2).forEach((_: any, index: number) => {
|
||||
setTimeout(() => initReadMore(index), 50 * (index + 1))
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
getGoodsCommentsMethods() {
|
||||
if (!this.goodsDetail.goodsId) return;
|
||||
API_Members.getGoodsComments(this.goodsDetail.goodsId, this.params).then((res) => {
|
||||
this.readMoreInited = {};
|
||||
this.commDetail = res.data.result || {};
|
||||
this.$nextTick(() => {
|
||||
const records = this.commDetail.records || [];
|
||||
records.slice(0, 2).forEach((_, index) => {
|
||||
setTimeout(() => this.initReadMore(index), 50 * (index + 1));
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
function toComment(id: string | number, gradeVal: string | number) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/product/comment?id=${id}&grade=${gradeVal}`,
|
||||
})
|
||||
}
|
||||
|
||||
toComment(id, grade) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/product/comment?id=${id}&grade=${grade}`,
|
||||
});
|
||||
},
|
||||
|
||||
previewImg(urls, index) {
|
||||
uni.previewImage({
|
||||
urls,
|
||||
indicator: "number",
|
||||
current: index,
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
function previewImg(urls: string[], index: number) {
|
||||
uni.previewImage({
|
||||
urls,
|
||||
indicator: 'number',
|
||||
current: index,
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -2,12 +2,9 @@
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
|
||||
}
|
||||
<script setup lang="ts">
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -39,30 +39,32 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getGoodsMessage } from "@/api/goods";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
goodsDetail: "",
|
||||
style: {
|
||||
img:"display:block;width:100%"
|
||||
}
|
||||
};
|
||||
},
|
||||
props: ["res", "goodsId", "goodsParams"],
|
||||
computed: {
|
||||
hasDetailContent() {
|
||||
return !!(this.res?.mobileIntro || (this.goodsParams && this.goodsParams.length));
|
||||
},
|
||||
},
|
||||
async mounted() {
|
||||
let res = await getGoodsMessage(this.goodsId);
|
||||
if (res.data.success) {
|
||||
this.goodsDetail = res.data.result;
|
||||
}
|
||||
},
|
||||
};
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { getGoodsMessage } from '@/api/goods'
|
||||
|
||||
const props = defineProps<{
|
||||
res?: any
|
||||
goodsId?: string | number
|
||||
goodsParams?: any[]
|
||||
}>()
|
||||
|
||||
const goodsDetail = ref('')
|
||||
const style = {
|
||||
img: 'display:block;width:100%',
|
||||
}
|
||||
|
||||
const hasDetailContent = computed(() => {
|
||||
return !!(props.res?.mobileIntro || (props.goodsParams && props.goodsParams.length))
|
||||
})
|
||||
|
||||
onMounted(async () => {
|
||||
if (!props.goodsId) return
|
||||
const res = await getGoodsMessage(props.goodsId)
|
||||
if (res.data.success) {
|
||||
goodsDetail.value = res.data.result
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -5,14 +5,12 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup lang="ts">
|
||||
import goodsList from '@/components/m-goods-list/list.vue'
|
||||
export default {
|
||||
props: ["res"],
|
||||
components:{goodsList},
|
||||
methods: {
|
||||
}
|
||||
};
|
||||
|
||||
defineProps<{
|
||||
res?: any[]
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -27,30 +27,33 @@
|
||||
<view class="swiper-dots">{{ current }}/{{ video ? res.length + 1 : res.length }}</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
current: 1,
|
||||
html: ""
|
||||
};
|
||||
},
|
||||
props: ["res", 'video'],
|
||||
watch: {
|
||||
video(val) {
|
||||
this.html = '<video muted="muted" ref="videoPlay" style="width:100%; height:100%;" src=' + val + ' page-gesture show-mute-btn autoplay webkit-playsinline="" playsinline="" ></video>'
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue'
|
||||
|
||||
const props = defineProps<{
|
||||
res?: string[]
|
||||
video?: string
|
||||
}>()
|
||||
|
||||
const current = ref(1)
|
||||
const html = ref('')
|
||||
|
||||
watch(
|
||||
() => props.video,
|
||||
(val) => {
|
||||
if (val) {
|
||||
html.value =
|
||||
'<video muted="muted" ref="videoPlay" style="width:100%; height:100%;" src=' +
|
||||
val +
|
||||
' page-gesture show-mute-btn autoplay webkit-playsinline="" playsinline="" ></video>'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 轮播图对应的dot
|
||||
swiperChange(e) {
|
||||
this.current = e.detail.current + 1;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
console.log(this.video)
|
||||
}
|
||||
};
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
function swiperChange(e: any) {
|
||||
current.value = e.detail.current + 1
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.carousel {
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
|
||||
.showBack {
|
||||
|
||||
margin-top: calc( var(--status-bar-height) + 20px ) !important;
|
||||
|
||||
}
|
||||
margin-top: calc(var(--status-bar-height) + 20px) !important;
|
||||
}
|
||||
|
||||
/* 商品详情底栏改为 flex 布局后,避免全局 mp-iphonex-bottom 把高度撑乱 */
|
||||
.page-bottom.mp-iphonex-bottom {
|
||||
height: auto !important;
|
||||
min-height: 100rpx;
|
||||
box-sizing: border-box;
|
||||
padding-top: 10rpx;
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
}
|
||||
|
||||
@@ -26,83 +26,81 @@
|
||||
<m-city :provinceData="cityList" headTitle="区域选择" ref="cityPicker" pickerSize="4"></m-city>
|
||||
</u-popup>
|
||||
</template>
|
||||
<script>
|
||||
import setup from "@/components/m-buy/popup.js";
|
||||
/************请求存储***************/
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from 'vue'
|
||||
import setup from '@/components/m-buy/popup.js'
|
||||
import * as API_Address from '@/api/address.js'
|
||||
import { clearStrComma, isLogin } from '@/utils/filters.js'
|
||||
|
||||
import * as API_Address from "@/api/address.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
checked: "",
|
||||
setup,
|
||||
addressDetail: "",
|
||||
cityList: [
|
||||
{
|
||||
id: "",
|
||||
localName: "请选择",
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
};
|
||||
const props = defineProps<{
|
||||
goodsId?: string | number
|
||||
addressFlag?: boolean
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
closeAddress: [val: boolean]
|
||||
deliveryData: [val: any]
|
||||
}>()
|
||||
|
||||
const checked = ref<any>('')
|
||||
const addressDetail = ref<any>('')
|
||||
const cityList = ref([
|
||||
{
|
||||
id: '',
|
||||
localName: '请选择',
|
||||
children: [],
|
||||
},
|
||||
props: ["goodsId", "addressFlag"],
|
||||
])
|
||||
|
||||
mounted() {
|
||||
if (this.isLogin("auth")) {
|
||||
this.getShippingAddress();
|
||||
} else {
|
||||
uni.navigateTo({
|
||||
url: "/pages/passport/login",
|
||||
});
|
||||
}
|
||||
},
|
||||
onMounted(() => {
|
||||
if (isLogin('auth')) {
|
||||
getShippingAddress()
|
||||
} else {
|
||||
uni.navigateTo({
|
||||
url: '/pages/passport/login',
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
methods: {
|
||||
/**关闭地址 */
|
||||
closeAddress() {
|
||||
this.$emit("closeAddress", false);
|
||||
this.$emit("deliveryData", this.checked);
|
||||
},
|
||||
function closeAddress() {
|
||||
emit('closeAddress', false)
|
||||
emit('deliveryData', checked.value)
|
||||
}
|
||||
|
||||
getpicker() {
|
||||
uni.navigateTo({
|
||||
url: "/pages/mine/address/add",
|
||||
});
|
||||
this.closeAddress();
|
||||
},
|
||||
function getpicker() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/mine/address/add',
|
||||
})
|
||||
closeAddress()
|
||||
}
|
||||
|
||||
/**获取地址 */
|
||||
getShippingAddress() {
|
||||
if (this.isLogin("auth")) {
|
||||
API_Address.getAddressList(1, 50).then((res) => {
|
||||
if (res.data.success) {
|
||||
this.addressDetail = res.data.result.records;
|
||||
let addr = res.data.result.records.filter((item) => {
|
||||
return item.isDefault == 1;
|
||||
});
|
||||
function getShippingAddress() {
|
||||
if (isLogin('auth')) {
|
||||
API_Address.getAddressList(1, 50).then((res) => {
|
||||
if (res.data.success) {
|
||||
addressDetail.value = res.data.result.records
|
||||
const addr = res.data.result.records.filter((item: any) => {
|
||||
return item.isDefault == 1
|
||||
})
|
||||
|
||||
if (addr[0]) {
|
||||
this.checked = addr[0];
|
||||
this.$emit("deliveryData", this.checked);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (addr[0]) {
|
||||
checked.value = addr[0]
|
||||
emit('deliveryData', checked.value)
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**点击地址返回父级商品状态 */
|
||||
clickAddress(val) {
|
||||
this.checked = val;
|
||||
function clickAddress(val: any) {
|
||||
checked.value = val
|
||||
|
||||
this.addressDetail.forEach((item) => {
|
||||
item.isDefault = false;
|
||||
});
|
||||
val.isDefault = !val.isDefault;
|
||||
this.$emit("deliveryData", this.checked);
|
||||
},
|
||||
},
|
||||
};
|
||||
addressDetail.value.forEach((item: any) => {
|
||||
item.isDefault = false
|
||||
})
|
||||
val.isDefault = !val.isDefault
|
||||
emit('deliveryData', checked.value)
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.light {
|
||||
@@ -165,4 +163,4 @@ export default {
|
||||
line-height: 90rpx;
|
||||
font-size: 34rpx;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -23,66 +23,57 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as API_Promotions from "@/api/promotions";
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import * as API_Promotions from '@/api/promotions'
|
||||
import configs from '@/config/config'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
configs,
|
||||
userImage:configs.defaultUserPhoto,
|
||||
import { noPassByName } from '@/utils/filters.js'
|
||||
import { useStore } from '@/store'
|
||||
|
||||
joinBtnStyle: {
|
||||
background: this.$lightColor,
|
||||
color: "#fff",
|
||||
},
|
||||
/** 待成团订单 */
|
||||
assembleOrder: "",
|
||||
const props = defineProps<{
|
||||
res?: any
|
||||
}>()
|
||||
|
||||
/** 查看更多待成团订单 */
|
||||
assembleOrderAll: "",
|
||||
};
|
||||
},
|
||||
props: ["res"],
|
||||
const emit = defineEmits<{
|
||||
'to-assemble-buy-now': [order: any]
|
||||
}>()
|
||||
|
||||
watch: {
|
||||
res: {
|
||||
handler() {
|
||||
if (this.res && this.res.length != 0) {
|
||||
Object.keys(this.res).forEach((item) => {
|
||||
let key = item.split("-");
|
||||
if (key && key[0] == "PINTUAN") {
|
||||
this.getAssembleInfo(item);
|
||||
}
|
||||
});
|
||||
const store = useStore()
|
||||
const userImage = configs.defaultUserPhoto
|
||||
const assembleOrder = ref<any[]>([])
|
||||
|
||||
const joinBtnStyle = computed(() => ({
|
||||
background: store.getters.lightColor,
|
||||
color: '#fff',
|
||||
}))
|
||||
|
||||
watch(
|
||||
() => props.res,
|
||||
(res) => {
|
||||
if (res && res.length != 0) {
|
||||
Object.keys(res).forEach((item) => {
|
||||
const key = item.split('-')
|
||||
if (key && key[0] == 'PINTUAN') {
|
||||
getAssembleInfo(item)
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
|
||||
// assembleOrder(val) {
|
||||
// this.$emit("assembleOrder", val);
|
||||
// },
|
||||
})
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
mounted() {},
|
||||
methods: {
|
||||
// 获取此商品所有待成团的订单
|
||||
getAssembleInfo(val) {
|
||||
let id = this.res[val].id;
|
||||
API_Promotions.getPromotionGroupMember(id).then((res) => {
|
||||
if (res.data.success) {
|
||||
console.warn(res.data.result);
|
||||
this.assembleOrder = res.data.result;
|
||||
}
|
||||
});
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
buy(order) {
|
||||
this.$emit("to-assemble-buy-now", order);
|
||||
},
|
||||
},
|
||||
};
|
||||
function getAssembleInfo(val: string) {
|
||||
const id = props.res[val].id
|
||||
API_Promotions.getPromotionGroupMember(id).then((res) => {
|
||||
if (res.data.success) {
|
||||
assembleOrder.value = res.data.result
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function buy(order: any) {
|
||||
emit('to-assemble-buy-now', order)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -106,119 +106,118 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
countdownData: {},
|
||||
countdownTimer: null,
|
||||
};
|
||||
<script setup lang="ts">
|
||||
import { computed, onUnmounted, ref, watch } from 'vue'
|
||||
import { goodsFormatPrice } from '@/utils/filters.js'
|
||||
|
||||
const props = defineProps<{
|
||||
res?: any
|
||||
detail?: any
|
||||
}>()
|
||||
|
||||
const countdownData = ref<Record<number, any>>({})
|
||||
let countdownTimer: ReturnType<typeof setInterval> | null = null
|
||||
|
||||
const promotionList = computed(() => {
|
||||
if (!props.res || typeof props.res !== 'object') return []
|
||||
return Object.keys(props.res).map((key) => ({
|
||||
...(props.res[key] || {}),
|
||||
__key: key.split('-')[0],
|
||||
}))
|
||||
})
|
||||
|
||||
watch(
|
||||
promotionList,
|
||||
(list) => {
|
||||
refreshCountdown(list)
|
||||
startCountdownTimer()
|
||||
},
|
||||
props: {
|
||||
res: {
|
||||
type: null,
|
||||
default: {},
|
||||
},
|
||||
detail: {
|
||||
type: null,
|
||||
default: {},
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
promotionList() {
|
||||
if (!this.res || typeof this.res !== "object") return [];
|
||||
return Object.keys(this.res).map((key) => ({
|
||||
...(this.res[key] || {}),
|
||||
__key: key.split("-")[0],
|
||||
}));
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
promotionList: {
|
||||
handler(list) {
|
||||
this.refreshCountdown(list);
|
||||
this.startCountdownTimer();
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
beforeUnmount() {
|
||||
this.clearCountdownTimer();
|
||||
},
|
||||
methods: {
|
||||
clearCountdownTimer() {
|
||||
if (this.countdownTimer) {
|
||||
clearInterval(this.countdownTimer);
|
||||
this.countdownTimer = null;
|
||||
}
|
||||
},
|
||||
startCountdownTimer() {
|
||||
this.clearCountdownTimer();
|
||||
this.countdownTimer = setInterval(() => {
|
||||
this.refreshCountdown(this.promotionList);
|
||||
}, 1000);
|
||||
},
|
||||
refreshCountdown(list = this.promotionList) {
|
||||
const next = {};
|
||||
list.forEach((promotion, index) => {
|
||||
next[index] = this.msToTimeData(this.getCountDownMs(promotion));
|
||||
});
|
||||
this.countdownData = next;
|
||||
},
|
||||
padTime(val) {
|
||||
return String(val ?? 0).padStart(2, "0");
|
||||
},
|
||||
countdownDisplayHours(index) {
|
||||
const data = this.countdownData[index];
|
||||
if (!data) return 0;
|
||||
return data.days * 24 + data.hours;
|
||||
},
|
||||
msToTimeData(ms) {
|
||||
const DAY = 86400000;
|
||||
const HOUR = 3600000;
|
||||
const MINUTE = 60000;
|
||||
const SECOND = 1000;
|
||||
const time = Math.max(Number(ms) || 0, 0);
|
||||
return {
|
||||
days: Math.floor(time / DAY),
|
||||
hours: Math.floor((time % DAY) / HOUR),
|
||||
minutes: Math.floor((time % HOUR) / MINUTE),
|
||||
seconds: Math.floor((time % MINUTE) / SECOND),
|
||||
};
|
||||
},
|
||||
parsePromotionTime(val) {
|
||||
if (val == null || val === "") return 0;
|
||||
if (typeof val === "number" && !Number.isNaN(val)) {
|
||||
return val < 1e12 ? val * 1000 : val;
|
||||
}
|
||||
const text = String(val).trim();
|
||||
if (/^\d+$/.test(text)) {
|
||||
const num = Number(text);
|
||||
return num < 1e12 ? num * 1000 : num;
|
||||
}
|
||||
const parsed = Date.parse(text.replace(/-/g, "/"));
|
||||
return Number.isNaN(parsed) ? 0 : parsed;
|
||||
},
|
||||
getCountDownMs(promotion) {
|
||||
if (!promotion || !promotion.endTime) return 0;
|
||||
const now = Date.now();
|
||||
const startMs = this.parsePromotionTime(promotion.startTime || promotion.start_time);
|
||||
const endMs = this.parsePromotionTime(promotion.endTime);
|
||||
if (!endMs) return 0;
|
||||
const target = startMs && now < startMs ? startMs : endMs;
|
||||
const remain = target - now;
|
||||
return remain > 0 ? remain : 0;
|
||||
},
|
||||
getIsTimer(val) {
|
||||
const now = Date.now();
|
||||
const startMs = this.parsePromotionTime(val.startTime || val.start_time);
|
||||
if (startMs && now < startMs) {
|
||||
return "距离活动开始";
|
||||
}
|
||||
return "距离活动结束";
|
||||
},
|
||||
},
|
||||
};
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
onUnmounted(() => {
|
||||
clearCountdownTimer()
|
||||
})
|
||||
|
||||
function clearCountdownTimer() {
|
||||
if (countdownTimer) {
|
||||
clearInterval(countdownTimer)
|
||||
countdownTimer = null
|
||||
}
|
||||
}
|
||||
|
||||
function startCountdownTimer() {
|
||||
clearCountdownTimer()
|
||||
countdownTimer = setInterval(() => {
|
||||
refreshCountdown(promotionList.value)
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
function refreshCountdown(list = promotionList.value) {
|
||||
const next: Record<number, any> = {}
|
||||
list.forEach((promotion, index) => {
|
||||
next[index] = msToTimeData(getCountDownMs(promotion))
|
||||
})
|
||||
countdownData.value = next
|
||||
}
|
||||
|
||||
function padTime(val: number | undefined) {
|
||||
return String(val ?? 0).padStart(2, '0')
|
||||
}
|
||||
|
||||
function countdownDisplayHours(index: number) {
|
||||
const data = countdownData.value[index]
|
||||
if (!data) return 0
|
||||
return data.days * 24 + data.hours
|
||||
}
|
||||
|
||||
function msToTimeData(ms: number) {
|
||||
const DAY = 86400000
|
||||
const HOUR = 3600000
|
||||
const MINUTE = 60000
|
||||
const SECOND = 1000
|
||||
const time = Math.max(Number(ms) || 0, 0)
|
||||
return {
|
||||
days: Math.floor(time / DAY),
|
||||
hours: Math.floor((time % DAY) / HOUR),
|
||||
minutes: Math.floor((time % HOUR) / MINUTE),
|
||||
seconds: Math.floor((time % MINUTE) / SECOND),
|
||||
}
|
||||
}
|
||||
|
||||
function parsePromotionTime(val: any) {
|
||||
if (val == null || val === '') return 0
|
||||
if (typeof val === 'number' && !Number.isNaN(val)) {
|
||||
return val < 1e12 ? val * 1000 : val
|
||||
}
|
||||
const text = String(val).trim()
|
||||
if (/^\d+$/.test(text)) {
|
||||
const num = Number(text)
|
||||
return num < 1e12 ? num * 1000 : num
|
||||
}
|
||||
const parsed = Date.parse(text.replace(/-/g, '/'))
|
||||
return Number.isNaN(parsed) ? 0 : parsed
|
||||
}
|
||||
|
||||
function getCountDownMs(promotion: any) {
|
||||
if (!promotion || !promotion.endTime) return 0
|
||||
const now = Date.now()
|
||||
const startMs = parsePromotionTime(promotion.startTime || promotion.start_time)
|
||||
const endMs = parsePromotionTime(promotion.endTime)
|
||||
if (!endMs) return 0
|
||||
const target = startMs && now < startMs ? startMs : endMs
|
||||
const remain = target - now
|
||||
return remain > 0 ? remain : 0
|
||||
}
|
||||
|
||||
function getIsTimer(val: any) {
|
||||
const now = Date.now()
|
||||
const startMs = parsePromotionTime(val.startTime || val.start_time)
|
||||
if (startMs && now < startMs) {
|
||||
return '距离活动开始'
|
||||
}
|
||||
return '距离活动结束'
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@@ -1,79 +1,95 @@
|
||||
<template>
|
||||
<view class="wrapper">
|
||||
<div class="coupon-empty" v-if="!res">暂无优惠券</div>
|
||||
<view class="coupon-List" v-for="(item, index) in couponRes" :key="index">
|
||||
<view class="coupon-empty" v-if="!couponRes.length">暂无优惠券</view>
|
||||
<view class="coupon-List" v-for="(item, index) in couponRes" :key="item.id || index">
|
||||
<view class="coupon-item">
|
||||
<view class="top">
|
||||
<div class="price">
|
||||
<span class="price-num" v-if="item.couponType == 'DISCOUNT'">{{ item.couponDiscount }}折</span>
|
||||
<span class="price-num" v-if="item.couponType == 'PRICE'">¥{{unitPrice(item.price) }}</span>
|
||||
</div>
|
||||
<view class="text">
|
||||
<div class="coupon-List-title">
|
||||
<view v-if="item.scopeType">
|
||||
<span v-if="item.scopeType == 'ALL' && item.storeId == '0'">全平台</span>
|
||||
<span v-if="item.scopeType == 'PORTION_GOODS_CATEGORY'">仅限品类</span>
|
||||
<view v-else>{{
|
||||
item.storeName == "platform" ? "全平台" : item.storeName + "店铺"
|
||||
}}使用</view>
|
||||
</view>
|
||||
</div>
|
||||
<div>满{{unitPrice(item.consumeThreshold) }}可用</div>
|
||||
<view class="price">
|
||||
<text class="price-num" v-if="item.couponType == 'DISCOUNT'">{{ item.couponDiscount }}折</text>
|
||||
<text class="price-num" v-else-if="item.couponType == 'PRICE'">¥{{ unitPrice(item.price) }}</text>
|
||||
</view>
|
||||
<view class="lingqu-btn" @click="getCoupon(item, index)">
|
||||
<div class="lingqu-text" :class="yhqFlag[index] ? 'cur' : ''">
|
||||
{{ yhqFlag[index] ? "已领取或领完" : "立即领取" }}
|
||||
</div>
|
||||
<view class="text">
|
||||
<view class="coupon-List-title">
|
||||
<text v-if="item.scopeType == 'ALL' && item.storeId == '0'">全平台</text>
|
||||
<text v-else-if="item.scopeType == 'PORTION_GOODS_CATEGORY'">仅限品类</text>
|
||||
<text v-else-if="item.scopeType == 'PORTION_GOODS'">部分商品</text>
|
||||
<text v-else>{{ item.storeName == 'platform' ? '全平台' : item.storeName + '店铺' }}使用</text>
|
||||
</view>
|
||||
<text>满{{ unitPrice(item.consumeThreshold) }}可用</text>
|
||||
</view>
|
||||
<view class="lingqu-btn" @tap="getCoupon(item, index)">
|
||||
<view class="lingqu-text" :class="{ cur: yhqFlag[index] }">
|
||||
{{ yhqFlag[index] ? '已领取或领完' : '立即领取' }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="line"></view>
|
||||
<view class="time">{{ item.startTime /unixToDate(1000) }} - {{ item.endTime /unixToDate(1000) }}</view>
|
||||
<view class="time">{{ formatCouponTime(item.startTime) }} - {{ formatCouponTime(item.endTime) }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
yhqFlag: [], //获取优惠券判断是否点击
|
||||
couponRes: [],
|
||||
};
|
||||
},
|
||||
props: {
|
||||
res: {
|
||||
type: null,
|
||||
default: "",
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
res: {
|
||||
handler() {
|
||||
if (this.res && this.res.length != 0) {
|
||||
Object.keys(this.res).forEach((item) => {
|
||||
let key = item.split("-")[0];
|
||||
if (key === "COUPON") {
|
||||
this.couponRes.push(this?.res[item]);
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue'
|
||||
import { unitPrice, unixToDate } from '@/utils/filters.js'
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
// 提交优惠券
|
||||
getCoupon(item, index) {
|
||||
this.yhqFlag[index] = true;
|
||||
this.$emit("getCoupon", item);
|
||||
},
|
||||
},
|
||||
};
|
||||
const props = defineProps<{
|
||||
res?: any
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
getCoupon: [item: any]
|
||||
}>()
|
||||
|
||||
const yhqFlag = ref<boolean[]>([])
|
||||
const couponRes = ref<any[]>([])
|
||||
|
||||
function formatCouponTime(val: any) {
|
||||
if (val == null || val === '') return ''
|
||||
const text = String(val).trim()
|
||||
if (!text) return ''
|
||||
if (text.includes('-') || text.includes('/')) {
|
||||
return text.length > 10 ? text.slice(0, 16) : text
|
||||
}
|
||||
const num = Number(text)
|
||||
if (!Number.isFinite(num)) return text
|
||||
const seconds = num < 1e12 ? num : Math.floor(num / 1000)
|
||||
return unixToDate(seconds, 'yyyy-MM-dd')
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.res,
|
||||
(res) => {
|
||||
const list: any[] = []
|
||||
if (res && typeof res === 'object') {
|
||||
Object.keys(res).forEach((item) => {
|
||||
if (item.split('-')[0] === 'COUPON') {
|
||||
list.push(res[item])
|
||||
}
|
||||
})
|
||||
}
|
||||
couponRes.value = list
|
||||
yhqFlag.value = list.map(() => false)
|
||||
},
|
||||
{ immediate: true, deep: true }
|
||||
)
|
||||
|
||||
function getCoupon(item: any, index: number) {
|
||||
if (yhqFlag.value[index]) return
|
||||
yhqFlag.value[index] = true
|
||||
yhqFlag.value = [...yhqFlag.value]
|
||||
emit('getCoupon', item)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.coupon-empty {
|
||||
color: #999;
|
||||
font-size: 26rpx;
|
||||
padding: 20rpx 0;
|
||||
}
|
||||
|
||||
.coupon-item {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
@@ -85,10 +101,12 @@
|
||||
.coupon-List {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 230rpx;
|
||||
min-height: 230rpx;
|
||||
background: #e9ebfb;
|
||||
margin: 30rpx 0;
|
||||
padding: 10rpx 30rpx;
|
||||
border-radius: 12rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
.line {
|
||||
height: 1px;
|
||||
@@ -119,15 +137,17 @@
|
||||
.time {
|
||||
flex: 1;
|
||||
font-size: 24rpx;
|
||||
align-items: center;
|
||||
color: #666;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 12rpx 0 8rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.top {
|
||||
height: 140rpx;
|
||||
min-height: 140rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.price {
|
||||
width: 33%;
|
||||
@@ -135,48 +155,56 @@
|
||||
color: #6772e5;
|
||||
font-size: 40rpx;
|
||||
display: flex;
|
||||
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
|
||||
.price-num {
|
||||
font-size: 50rpx;
|
||||
line-height: 1.2;
|
||||
}
|
||||
}
|
||||
|
||||
.text {
|
||||
width: 33%;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
font-size: 26rpx;
|
||||
color: 333;
|
||||
margin-left: 40rpx;
|
||||
color: #333;
|
||||
margin-left: 20rpx;
|
||||
min-width: 0;
|
||||
|
||||
.coupon-List-title {
|
||||
font-size: 30rpx;
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
margin-bottom: 8rpx;
|
||||
line-height: 1.4;
|
||||
}
|
||||
}
|
||||
|
||||
.lingqu-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-left: 40rpx;
|
||||
flex-shrink: 0;
|
||||
margin-left: 16rpx;
|
||||
|
||||
.lingqu-text {
|
||||
width: 140rpx;
|
||||
height: 40rpx;
|
||||
min-width: 140rpx;
|
||||
height: 56rpx;
|
||||
padding: 0 16rpx;
|
||||
text-align: center;
|
||||
line-height: 40rpx;
|
||||
line-height: 56rpx;
|
||||
color: #fff;
|
||||
background: #6772e5;
|
||||
border-radius: 5px;
|
||||
font-size: 26rpx;
|
||||
border-radius: 28rpx;
|
||||
font-size: 24rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
&.cur {
|
||||
background: none;
|
||||
transform: rotate(45deg) translate(10rpx, -46rpx);
|
||||
background: #ccc;
|
||||
color: #fff;
|
||||
transform: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,140 +1,134 @@
|
||||
<template>
|
||||
<view class="wrapper" v-if="res">
|
||||
<view v-for="(prom, index) in Object.keys(res)" :key="index">
|
||||
<view>
|
||||
<view v-if="prom.split('-')[0] == 'FULL_DISCOUNT'">
|
||||
<div class="res_prom_item" v-if="res[prom].fullMinus">
|
||||
<u-tag text="满减" type="error"></u-tag>
|
||||
<!-- TODO 后续将优化为可点击的商品以及优惠券显示明细 -->
|
||||
<span class="pro-text"
|
||||
>满{{ res[prom].fullMoney }}元 立减现金
|
||||
<span class="price">{{ res[prom].fullMinus }}元</span>
|
||||
<span v-if="res[prom].couponFlag"> 赠送<span>优惠券</span></span>
|
||||
<span v-if="res[prom].pointFlag"> 赠送{{ res[prom].point }}积分</span>
|
||||
<span v-if="res[prom].giftFlag"> 赠送商品</span>
|
||||
<span v-if="res[prom].freeFreightFlag">赠送包邮服务</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="res_prom_item" v-if="res[prom].fullRate && res[prom].fullRateFlag">
|
||||
<u-tag text="打折" type="error"></u-tag>
|
||||
<span class="pro-text"
|
||||
>满{{ res[prom].fullMoney }}元,立享<span class="price"
|
||||
>{{ res[prom].fullRate }}折</span
|
||||
>优惠</span
|
||||
>
|
||||
</div>
|
||||
<view v-for="prom in promotionKeys" :key="prom">
|
||||
<view v-if="getPromType(prom) == 'FULL_DISCOUNT'">
|
||||
<view class="res_prom_item" v-if="res[prom].fullMinus">
|
||||
<view class="deg_tag">满减</view>
|
||||
<text class="pro-text">
|
||||
满{{ res[prom].fullMoney }}元 立减现金
|
||||
<text class="price">{{ res[prom].fullMinus }}元</text>
|
||||
<text v-if="res[prom].couponFlag"> 赠送优惠券</text>
|
||||
<text v-if="res[prom].pointFlag"> 赠送{{ res[prom].point }}积分</text>
|
||||
<text v-if="res[prom].giftFlag"> 赠送商品</text>
|
||||
<text v-if="res[prom].freeFreightFlag"> 赠送包邮服务</text>
|
||||
</text>
|
||||
</view>
|
||||
|
||||
<view v-if="prom.split('-')[0] == 'PINTUAN'">
|
||||
<div class="res_prom_item" v-if="res[prom].requiredNum">
|
||||
<u-tag text="拼团" type="error"></u-tag>
|
||||
<span class="pro-text"
|
||||
>{{ res[prom].requiredNum }}人拼团 限购<span class="price"
|
||||
>{{ res[prom].limitNum }}件</span
|
||||
></span
|
||||
>
|
||||
</div>
|
||||
<view class="res_prom_item" v-if="res[prom].fullRate && res[prom].fullRateFlag">
|
||||
<view class="deg_tag">打折</view>
|
||||
<text class="pro-text">
|
||||
满{{ res[prom].fullMoney }}元,立享
|
||||
<text class="price">{{ res[prom].fullRate }}折</text>
|
||||
优惠
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="prom.split('-')[0] == 'SECKILL'">
|
||||
<div class="res_prom_item">
|
||||
<u-tag text="限时抢购" type="error"></u-tag>
|
||||
<span class="pro-text">限时抢购</span>
|
||||
</div>
|
||||
<view v-if="getPromType(prom) == 'PINTUAN'">
|
||||
<view class="res_prom_item" v-if="res[prom].requiredNum">
|
||||
<view class="deg_tag">拼团</view>
|
||||
<text class="pro-text">
|
||||
{{ res[prom].requiredNum }}人拼团 限购
|
||||
<text class="price">{{ res[prom].limitNum }}件</text>
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="prom.split('-')[0] == 'POINTS_GOODS'">
|
||||
<div class="res_prom_item">
|
||||
<u-tag text="积分活动" type="error"></u-tag>
|
||||
<span class="pro-text">当前商品参与积分活动。<span @click="handClickToJoinPromotion(prom)" class="href">点击此处参与活动</span></span>
|
||||
</div>
|
||||
<view v-if="getPromType(prom) == 'SECKILL'">
|
||||
<view class="res_prom_item">
|
||||
<view class="deg_tag">限时抢购</view>
|
||||
<text class="pro-text">限时抢购</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="prom.split('-')[0] == 'KANJIA'">
|
||||
<div class="res_prom_item">
|
||||
<u-tag text="砍价活动" type="error"></u-tag>
|
||||
<span class="pro-text">当前商品参与砍价活动。<span @click="handClickToJoinPromotion(prom)" class="href">点击此处参与活动</span></span>
|
||||
</div>
|
||||
<view v-if="getPromType(prom) == 'POINTS_GOODS'">
|
||||
<view class="res_prom_item">
|
||||
<view class="deg_tag">积分活动</view>
|
||||
<text class="pro-text">
|
||||
当前商品参与积分活动。
|
||||
<text @tap="handClickToJoinPromotion(prom)" class="href">点击此处参与活动</text>
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="getPromType(prom) == 'KANJIA'">
|
||||
<view class="res_prom_item">
|
||||
<view class="deg_tag">砍价活动</view>
|
||||
<text class="pro-text">
|
||||
当前商品参与砍价活动。
|
||||
<text @tap="handClickToJoinPromotion(prom)" class="href">点击此处参与活动</text>
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="!res">暂无促销活动</view>
|
||||
<view v-if="!promotionKeys.length">暂无促销活动</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
watch: {
|
||||
res: {
|
||||
handler() {
|
||||
if (this.res && this.res.length != 0) {
|
||||
Object.keys(this.res).forEach((item) => {
|
||||
if (item != "COUPON") {
|
||||
let key = item.split("-")[0];
|
||||
this.res[item]._key = key;
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
|
||||
props: {
|
||||
// 父组件传递回来的数据
|
||||
res: {
|
||||
type: null,
|
||||
default: "",
|
||||
},
|
||||
},
|
||||
mounted() {},
|
||||
methods: {
|
||||
// 跳转到参与商品活动的详情列表中
|
||||
handClickToJoinPromotion(val){
|
||||
|
||||
const promotion = {
|
||||
"POINTS_GOODS": `/pages/promotion/point/detail?id=${this.res[val].id}`,
|
||||
"KANJIA": `/pages/promotion/bargain/detail?id=${this.res[val].id}`,
|
||||
}
|
||||
const props = defineProps<{
|
||||
res?: any
|
||||
}>()
|
||||
|
||||
uni.navigateTo({
|
||||
url:promotion[val.split('-')[0]]
|
||||
})
|
||||
const promotionKeys = computed(() => {
|
||||
if (!props.res || typeof props.res !== 'object') return []
|
||||
return Object.keys(props.res).filter((key) => getPromType(key) !== 'COUPON')
|
||||
})
|
||||
|
||||
}
|
||||
},
|
||||
};
|
||||
function getPromType(key: string) {
|
||||
return key.split('-')[0]
|
||||
}
|
||||
|
||||
function handClickToJoinPromotion(val: string) {
|
||||
const type = getPromType(val)
|
||||
const promotionMap: Record<string, string> = {
|
||||
POINTS_GOODS: `/pages/promotion/point/detail?id=${props.res[val].id}`,
|
||||
KANJIA: `/pages/promotion/bargain/detail?id=${props.res[val].id}`,
|
||||
}
|
||||
const url = promotionMap[type]
|
||||
if (url) {
|
||||
uni.navigateTo({ url })
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.deg_tag {
|
||||
flex-shrink: 0;
|
||||
color: $price-color;
|
||||
padding: 4rpx 12rpx;
|
||||
border: 2rpx solid $price-color;
|
||||
border-radius: 6rpx;
|
||||
font-size: 22rpx;
|
||||
line-height: 1.4;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.pro-text {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
font-size: 26rpx;
|
||||
font-family: PingFang SC, PingFang SC-Regular;
|
||||
font-weight: 400;
|
||||
text-align: left;
|
||||
line-height: 1.6;
|
||||
color: #333333;
|
||||
margin-left: 20rpx;
|
||||
word-spacing: 15rpx;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
display: block;
|
||||
}
|
||||
|
||||
::v-deep .u-mode-light-error {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.res_prom_item {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 16rpx;
|
||||
margin: 20rpx 0;
|
||||
}
|
||||
|
||||
.price_image {
|
||||
display: block;
|
||||
.price {
|
||||
color: $price-color;
|
||||
}
|
||||
.href{
|
||||
|
||||
.href {
|
||||
color: $main-color;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -50,51 +50,45 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="this.res != null && Object.keys(res).length == 0">暂无促销信息</view>
|
||||
<view v-if="res != null && Object.keys(res).length == 0">暂无促销信息</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import promotion from './promotion_type';
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
promotion,
|
||||
couponList: ''
|
||||
};
|
||||
},
|
||||
props: {
|
||||
// 父组件传递回来的数据
|
||||
res: {
|
||||
type: null,
|
||||
default: {}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
res: {
|
||||
handler() {
|
||||
if (this.res && this.res.length != 0 && this.res != null) {
|
||||
Object.keys(this.res).forEach(item => {
|
||||
let key = item.split('-')[0];
|
||||
this.res[item].__key = key;
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue'
|
||||
import promotion from './promotion_type'
|
||||
|
||||
if (item.split('-')[0] == 'COUPON') {
|
||||
this.couponList = 'COUPON';
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
mounted() {},
|
||||
methods: {
|
||||
// 此方法条用父级方法
|
||||
shutMask(val) {
|
||||
this.$emit('shutMasks', val);
|
||||
}
|
||||
}
|
||||
};
|
||||
const props = defineProps<{
|
||||
res?: any
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
shutMasks: [val: number]
|
||||
}>()
|
||||
|
||||
const couponList = ref('')
|
||||
|
||||
watch(
|
||||
() => props.res,
|
||||
(res) => {
|
||||
couponList.value = ''
|
||||
if (res && res.length != 0 && res != null) {
|
||||
Object.keys(res).forEach((item) => {
|
||||
const key = item.split('-')[0]
|
||||
res[item].__key = key
|
||||
|
||||
if (item.split('-')[0] == 'COUPON') {
|
||||
couponList.value = 'COUPON'
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
function shutMask(val: number) {
|
||||
emit('shutMasks', val)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user