Initial commit
This commit is contained in:
BIN
miniprogram/pages/usercenter/.DS_Store
vendored
Normal file
BIN
miniprogram/pages/usercenter/.DS_Store
vendored
Normal file
Binary file not shown.
33
miniprogram/pages/usercenter/address/edit/util.js
Normal file
33
miniprogram/pages/usercenter/address/edit/util.js
Normal file
@@ -0,0 +1,33 @@
|
||||
let addressPromise = [];
|
||||
|
||||
/** 地址编辑Promise */
|
||||
export const getAddressPromise = () => {
|
||||
let resolver;
|
||||
let rejecter;
|
||||
const nextPromise = new Promise((resolve, reject) => {
|
||||
resolver = resolve;
|
||||
rejecter = reject;
|
||||
});
|
||||
|
||||
addressPromise.push({ resolver, rejecter });
|
||||
|
||||
return nextPromise;
|
||||
};
|
||||
|
||||
/** 用户保存了一个地址 */
|
||||
export const resolveAddress = (address) => {
|
||||
const allAddress = [...addressPromise];
|
||||
addressPromise = [];
|
||||
|
||||
console.info('用户保存了一个地址', address);
|
||||
|
||||
allAddress.forEach(({ resolver }) => resolver(address));
|
||||
};
|
||||
|
||||
/** 取消编辑 */
|
||||
export const rejectAddress = () => {
|
||||
const allAddress = [...addressPromise];
|
||||
addressPromise = [];
|
||||
|
||||
allAddress.forEach(({ rejecter }) => rejecter(new Error('cancel')));
|
||||
};
|
||||
37
miniprogram/pages/usercenter/components/order-group/index.js
Normal file
37
miniprogram/pages/usercenter/components/order-group/index.js
Normal file
@@ -0,0 +1,37 @@
|
||||
Component({
|
||||
externalClasses: ['title-class', 'icon-class', 'number-class'],
|
||||
options: {
|
||||
multipleSlots: true,
|
||||
},
|
||||
properties: {
|
||||
orderTagInfos: {
|
||||
type: Array,
|
||||
value: [],
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
value: '我的订单',
|
||||
},
|
||||
desc: {
|
||||
type: String,
|
||||
value: '全部订单',
|
||||
},
|
||||
isTop: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
classPrefix: {
|
||||
type: String,
|
||||
value: 'wr',
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onClickItem(e) {
|
||||
this.triggerEvent('onClickItem', e.currentTarget.dataset.item);
|
||||
},
|
||||
|
||||
onClickTop() {
|
||||
this.triggerEvent('onClickTop', {});
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {
|
||||
"t-cell": "tdesign-miniprogram/cell/cell",
|
||||
"t-cell-group": "tdesign-miniprogram/cell-group/cell-group",
|
||||
"t-badge": "tdesign-miniprogram/badge/badge",
|
||||
"t-icon": "tdesign-miniprogram/icon/icon"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<view class="order-group">
|
||||
<t-cell-group wx:if="{{isTop}}">
|
||||
<t-cell
|
||||
t-class="order-group__top"
|
||||
t-class-left="order-group__left"
|
||||
t-class-title="order-group__top__title"
|
||||
t-class-note="order-group__top__note"
|
||||
title="{{title}}"
|
||||
note="{{desc}}"
|
||||
bordered="{{false}}"
|
||||
arrow
|
||||
bind:tap="onClickTop"
|
||||
/>
|
||||
</t-cell-group>
|
||||
<view class="order-group__content">
|
||||
<view
|
||||
class="order-group__item"
|
||||
wx:for="{{orderTagInfos}}"
|
||||
wx:for-item="item"
|
||||
wx:key="index"
|
||||
data-item="{{item}}"
|
||||
bindtap="onClickItem"
|
||||
>
|
||||
<view class="order-group__item__icon icon-class">
|
||||
<t-badge count="{{item.orderNum}}" max-count="{{99}}" color="#FF4646">
|
||||
<t-icon
|
||||
prefix="{{classPrefix}}"
|
||||
name="{{item.iconName}}"
|
||||
size="56rpx"
|
||||
customStyle="background-image: -webkit-linear-gradient(90deg, #6a6a6a 0%,#929292 100%);-webkit-background-clip: text;-webkit-text-fill-color: transparent;"
|
||||
/>
|
||||
</t-badge>
|
||||
</view>
|
||||
<view class="order-group__item__title title-class">{{item.title}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -0,0 +1,56 @@
|
||||
.order-group {
|
||||
margin-bottom: 24rpx;
|
||||
background-color: #ffffff;
|
||||
border-radius: 16rpx 16rpx 0 0;
|
||||
}
|
||||
.order-group .order-group__top {
|
||||
padding: 24rpx 18rpx 24rpx 32rpx;
|
||||
border-radius: 16rpx 16rpx 0 0;
|
||||
}
|
||||
.order-group__top___title {
|
||||
font-size: 32rpx;
|
||||
line-height: 48rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
.order-group__top__note {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
.order-group__content {
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
height: 164rpx;
|
||||
display: flex;
|
||||
background-color: #fff;
|
||||
border-radius: 0 0 16rpx 16rpx;
|
||||
}
|
||||
.order-group__item {
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
}
|
||||
.order-group__item:first-child {
|
||||
border-radius: 0 0 0 16rpx;
|
||||
}
|
||||
.order-group__item:last-child {
|
||||
border-radius: 0 0 16rpx 0;
|
||||
}
|
||||
.order-group__item__title {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
line-height: 32rpx;
|
||||
}
|
||||
.order-group__item__icon {
|
||||
margin-bottom: 20rpx;
|
||||
width: 56rpx;
|
||||
height: 56rpx;
|
||||
position: relative;
|
||||
}
|
||||
.order-group__top__title {
|
||||
font-weight: bold;
|
||||
}
|
||||
.order-group .order-group__left {
|
||||
margin-right: 0;
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
Component({
|
||||
properties: {
|
||||
show: {
|
||||
type: Boolean,
|
||||
observer(show) {
|
||||
if (!show) return;
|
||||
this.updateDivisions();
|
||||
},
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
value: '',
|
||||
observer() {
|
||||
if (!this.data.show) return;
|
||||
this.updateDivisions();
|
||||
},
|
||||
},
|
||||
pickerOptions: {
|
||||
type: Array,
|
||||
value: [],
|
||||
observer() {
|
||||
if (!this.data.show) return;
|
||||
this.updateDivisions();
|
||||
},
|
||||
},
|
||||
headerVisible: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
},
|
||||
data: {
|
||||
pickerValue: [],
|
||||
},
|
||||
methods: {
|
||||
updateDivisions() {
|
||||
const { pickerOptions, value } = this.data;
|
||||
const index = (pickerOptions || []).findIndex(
|
||||
(item) => item.code === value,
|
||||
);
|
||||
|
||||
setTimeout(() => {
|
||||
this.setData({ pickerValue: index >= 0 ? [index] : [0] });
|
||||
}, 0);
|
||||
},
|
||||
|
||||
getAreaByIndex(indexes) {
|
||||
const { pickerOptions } = this.data;
|
||||
return pickerOptions[indexes.toString()];
|
||||
},
|
||||
|
||||
onChange(e) {
|
||||
const currentValue = e.detail.value;
|
||||
const target = this.getAreaByIndex(currentValue);
|
||||
if (target === null) return;
|
||||
|
||||
this.setData({ pickerValue: currentValue });
|
||||
this.triggerEvent('change', { value: target.code, target: target });
|
||||
},
|
||||
|
||||
onConfirm() {
|
||||
const target = this.getAreaByIndex(this.data.pickerValue);
|
||||
this.triggerEvent('confirm', { value: target?.code, target });
|
||||
},
|
||||
|
||||
onClose() {
|
||||
this.triggerEvent('close');
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {
|
||||
"t-popup": "tdesign-miniprogram/popup/popup"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<t-popup visible="{{show}}" placement="bottom">
|
||||
<view class="city-picker-box" slot="content">
|
||||
<view wx:if="{{headerVisible}}" class="city-picker-header city-picker-more">
|
||||
<view class="btn" hover-class="btn__active" catch:tap="onClose">取消</view>
|
||||
<view wx:if="{{title}}" class="title">{{title}}</view>
|
||||
<view class="btn primary" hover-class="btn__active" catch:tap="onConfirm">确定</view>
|
||||
</view>
|
||||
<view wx:else class="city-picker-header">
|
||||
<view wx:if="{{title}}" class="title">{{title}}</view>
|
||||
</view>
|
||||
<picker-view class="picker" indicator-class="picker-center-row" value="{{pickerValue}}" bind:change="onChange">
|
||||
<picker-view-column class="picker-column">
|
||||
<view wx:for="{{ pickerOptions }}" wx:key="code">{{ item.name }}</view>
|
||||
</picker-view-column>
|
||||
</picker-view>
|
||||
<view class="city-picker-footer" wx:if="{{!headerVisible}}">
|
||||
<view class="btn" hover-class="btn__active" catch:tap="onClose">取消</view>
|
||||
<view class="btn primary" hover-class="btn__active" catch:tap="onConfirm">确定</view>
|
||||
</view>
|
||||
</view>
|
||||
</t-popup>
|
||||
@@ -0,0 +1,102 @@
|
||||
.city-picker-container {
|
||||
opacity: 0;
|
||||
position: fixed;
|
||||
top: 100vh;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 100vh;
|
||||
z-index: 100;
|
||||
}
|
||||
.city-picker-container.show {
|
||||
top: 0;
|
||||
opacity: 1;
|
||||
}
|
||||
.city-picker-container.show .city-picker-box {
|
||||
bottom: 0;
|
||||
}
|
||||
.city-picker-shadow {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.65);
|
||||
}
|
||||
.city-picker-header {
|
||||
height: 100rpx;
|
||||
line-height: 100rpx;
|
||||
text-align: center;
|
||||
font-size: 32rpx;
|
||||
color: #333333;
|
||||
}
|
||||
.city-picker-more {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.city-picker-footer {
|
||||
height: 100rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.city-picker-footer .btn {
|
||||
width: 330rpx;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
text-align: center;
|
||||
color: #666666;
|
||||
font-size: 32rpx;
|
||||
position: relative;
|
||||
}
|
||||
.city-picker-footer .btn__active {
|
||||
opacity: 0.5;
|
||||
}
|
||||
.city-picker-footer .btn::after {
|
||||
display: block;
|
||||
content: ' ';
|
||||
position: absolute;
|
||||
left: -50%;
|
||||
right: -50%;
|
||||
top: -50%;
|
||||
bottom: -50%;
|
||||
transform: scale(0.5);
|
||||
border: 1rpx solid #999999;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
.city-picker-footer .btn.primary {
|
||||
color: #fa550f;
|
||||
}
|
||||
.city-picker-footer .btn.primary::after {
|
||||
border-color: #fa550f;
|
||||
}
|
||||
.picker-column:not(:first-child) {
|
||||
margin-left: 40rpx;
|
||||
}
|
||||
.city-picker-box {
|
||||
position: absolute;
|
||||
bottom: -100%;
|
||||
transition: 0.3s bottom ease-in-out;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 100;
|
||||
background-color: #fff;
|
||||
padding: 0 30rpx;
|
||||
color: #333333;
|
||||
font-size: 34rpx;
|
||||
border-radius: 20rpx 20rpx 0 0;
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
}
|
||||
.show .city-picker-shadow {
|
||||
display: block;
|
||||
}
|
||||
.picker {
|
||||
height: 300rpx;
|
||||
margin: 50rpx 0;
|
||||
line-height: 88rpx;
|
||||
text-align: center;
|
||||
}
|
||||
/* 似乎小程序picker-view的bug,indicator-class仅height生效,其他诸如line-height、text-align等放到父class中设置 */
|
||||
.picker-center-row {
|
||||
height: 88rpx;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
const AuthStepType = {
|
||||
ONE: 1,
|
||||
TWO: 2,
|
||||
THREE: 3,
|
||||
};
|
||||
|
||||
Component({
|
||||
options: {
|
||||
multipleSlots: true,
|
||||
},
|
||||
properties: {
|
||||
currAuthStep: {
|
||||
type: Number,
|
||||
value: AuthStepType.ONE,
|
||||
},
|
||||
userInfo: {
|
||||
type: Object,
|
||||
value: {},
|
||||
},
|
||||
isNeedGetUserInfo: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
},
|
||||
data: {
|
||||
defaultAvatarUrl: 'https://tdesign.gtimg.com/miniprogram/template/retail/usercenter/icon-user-center-avatar@2x.png',
|
||||
AuthStepType,
|
||||
},
|
||||
methods: {
|
||||
gotoUserEditPage() {
|
||||
this.triggerEvent('gotoUserEditPage');
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {
|
||||
"t-icon": "tdesign-miniprogram/icon/icon",
|
||||
"t-avatar": "tdesign-miniprogram/avatar/avatar"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<view class="user-center-card">
|
||||
<!-- 未登录的情况 -->
|
||||
<block wx:if="{{currAuthStep === AuthStepType.ONE}}">
|
||||
<view class="user-center-card__header" bind:tap="gotoUserEditPage">
|
||||
<t-avatar image="{{userInfo.avatarUrl || defaultAvatarUrl}}" class="user-center-card__header__avatar" />
|
||||
<view class="user-center-card__header__name">{{'请登录'}}</view>
|
||||
</view>
|
||||
</block>
|
||||
<!-- 已登录但未授权用户信息情况 -->
|
||||
<block wx:if="{{currAuthStep === AuthStepType.TWO}}">
|
||||
<view class="user-center-card__header">
|
||||
<t-avatar image="{{userInfo.avatarUrl || defaultAvatarUrl}}" class="user-center-card__header__avatar" />
|
||||
<view class="user-center-card__header__name">{{userInfo.nickName || '微信用户'}}</view>
|
||||
<!-- 需要授权用户信息,通过slot添加弹窗 -->
|
||||
<view class="user-center-card__header__transparent" wx:if="{{isNeedGetUserInfo}}">
|
||||
<slot name="getUserInfo" />
|
||||
</view>
|
||||
<!-- 不需要授权用户信息,仍然触发gotoUserEditPage事件 -->
|
||||
<view class="user-center-card__header__transparent" bind:tap="gotoUserEditPage" wx:else></view>
|
||||
</view>
|
||||
</block>
|
||||
<!-- 已登录且已经授权用户信息的情况 -->
|
||||
<block wx:if="{{currAuthStep === AuthStepType.THREE}}">
|
||||
<view class="user-center-card__header" bind:tap="gotoUserEditPage">
|
||||
<t-avatar
|
||||
t-class="avatar"
|
||||
mode="aspectFill"
|
||||
class="user-center-card__header__avatar"
|
||||
image="{{userInfo.avatarUrl || defaultAvatarUrl}}"
|
||||
/>
|
||||
<view class="user-center-card__header__name">{{userInfo.nickName || '微信用户'}}</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
@@ -0,0 +1,48 @@
|
||||
.user-center-card {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 480rpx;
|
||||
background-image: url('https://tdesign.gtimg.com/miniprogram/template/retail/template/user-center-bg-v1.png');
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
padding: 0 24rpx;
|
||||
}
|
||||
.user-center-card__header {
|
||||
margin-top: 192rpx;
|
||||
margin-bottom: 48rpx;
|
||||
height: 96rpx;
|
||||
line-height: 48rpx;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
color: #333;
|
||||
position: relative;
|
||||
}
|
||||
.user-center-card__header__avatar {
|
||||
width: 96rpx;
|
||||
height: 96rpx;
|
||||
border-radius: 48rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.user-center-card__header__name {
|
||||
font-size: 36rpx;
|
||||
line-height: 48rpx;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
margin-left: 24rpx;
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
.user-center-card__header__transparent {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
background-color: transparent;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
.user-center-card__icon {
|
||||
line-height: 96rpx;
|
||||
}
|
||||
346
miniprogram/pages/usercenter/index.js
Normal file
346
miniprogram/pages/usercenter/index.js
Normal file
@@ -0,0 +1,346 @@
|
||||
import { fetchUserCenter } from '../../services/usercenter/fetchUsercenter';
|
||||
import Toast from 'tdesign-miniprogram/toast/index';
|
||||
|
||||
// 已登录用户的菜单数据
|
||||
const loggedInMenuData = [
|
||||
[
|
||||
{
|
||||
title: '收货地址',
|
||||
tit: '',
|
||||
url: '',
|
||||
type: 'address',
|
||||
},
|
||||
{
|
||||
title: '优惠券',
|
||||
tit: '',
|
||||
url: '',
|
||||
type: 'coupon',
|
||||
},
|
||||
{
|
||||
title: '我的积分',
|
||||
tit: '',
|
||||
url: '',
|
||||
type: 'points',
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
title: '帮助中心',
|
||||
tit: '',
|
||||
url: '',
|
||||
type: 'help-center',
|
||||
},
|
||||
{
|
||||
title: '客服热线',
|
||||
tit: '',
|
||||
url: '',
|
||||
type: 'service',
|
||||
icon: 'service',
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
title: '退出登录',
|
||||
tit: '',
|
||||
url: '',
|
||||
type: 'logout',
|
||||
icon: 'logout',
|
||||
},
|
||||
],
|
||||
];
|
||||
|
||||
// 未登录用户的菜单数据
|
||||
const guestMenuData = [
|
||||
[
|
||||
{
|
||||
title: '帮助中心',
|
||||
tit: '',
|
||||
url: '',
|
||||
type: 'help-center',
|
||||
},
|
||||
{
|
||||
title: '客服热线',
|
||||
tit: '',
|
||||
url: '',
|
||||
type: 'service',
|
||||
icon: 'service',
|
||||
},
|
||||
],
|
||||
];
|
||||
|
||||
const orderTagInfos = [
|
||||
{
|
||||
title: '待付款',
|
||||
iconName: 'wallet',
|
||||
orderNum: 0,
|
||||
tabType: 1, // 修复:与订单列表页面的状态值匹配
|
||||
status: 1,
|
||||
},
|
||||
{
|
||||
title: '待发货',
|
||||
iconName: 'deliver',
|
||||
orderNum: 0,
|
||||
tabType: 3, // 修复:与订单列表页面的状态值匹配
|
||||
status: 1,
|
||||
},
|
||||
{
|
||||
title: '待收货',
|
||||
iconName: 'package',
|
||||
orderNum: 0,
|
||||
tabType: 5, // 修复:与订单列表页面的状态值匹配
|
||||
status: 1,
|
||||
},
|
||||
{
|
||||
title: '待评价',
|
||||
iconName: 'comment',
|
||||
orderNum: 0,
|
||||
tabType: 6, // 修复:与订单列表页面的状态值匹配
|
||||
status: 1,
|
||||
},
|
||||
{
|
||||
title: '退款/售后',
|
||||
iconName: 'exchang',
|
||||
orderNum: 0,
|
||||
tabType: 'refund', // 修改为refund,跳转到退款记录页面
|
||||
status: 1,
|
||||
},
|
||||
];
|
||||
|
||||
const getDefaultData = () => ({
|
||||
showMakePhone: false,
|
||||
userInfo: {
|
||||
avatarUrl: '',
|
||||
nickName: '正在登录...',
|
||||
phoneNumber: '',
|
||||
},
|
||||
menuData: guestMenuData, // 默认使用未登录菜单
|
||||
orderTagInfos,
|
||||
customerServiceInfo: {},
|
||||
currAuthStep: 1,
|
||||
showKefu: true,
|
||||
versionNo: '',
|
||||
});
|
||||
|
||||
Page({
|
||||
data: getDefaultData(),
|
||||
|
||||
onLoad() {
|
||||
this.getVersionInfo();
|
||||
},
|
||||
|
||||
onShow() {
|
||||
this.getTabBar().init();
|
||||
|
||||
// 检查登录状态
|
||||
const token = wx.getStorageSync('token');
|
||||
if (token) {
|
||||
// 已登录,获取用户信息并设置已登录菜单
|
||||
this.setData({
|
||||
menuData: loggedInMenuData
|
||||
});
|
||||
this.init();
|
||||
} else {
|
||||
// 未登录,显示未登录状态和未登录菜单
|
||||
this.setData({
|
||||
currAuthStep: 1, // 设置为未登录状态
|
||||
userInfo: {
|
||||
avatarUrl: '',
|
||||
nickName: '点击登录',
|
||||
phoneNumber: ''
|
||||
},
|
||||
menuData: guestMenuData
|
||||
});
|
||||
}
|
||||
},
|
||||
onPullDownRefresh() {
|
||||
this.init();
|
||||
},
|
||||
|
||||
init() {
|
||||
this.fetUseriInfoHandle();
|
||||
},
|
||||
|
||||
fetUseriInfoHandle() {
|
||||
fetchUserCenter().then(({ userInfo, countsData, orderTagInfos: orderInfo, customerServiceInfo }) => {
|
||||
// 获取当前菜单数据
|
||||
const currentMenuData = this.data.menuData;
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
if (currentMenuData && currentMenuData.length > 0 && currentMenuData[0]) {
|
||||
currentMenuData[0].forEach((v) => {
|
||||
// 添加数据验证,确保countsData存在且为数组
|
||||
if (Array.isArray(countsData)) {
|
||||
countsData.forEach((counts) => {
|
||||
if (counts.type === v.type) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
v.tit = counts.num;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
const info = orderTagInfos.map((v, index) => ({
|
||||
...v,
|
||||
...(orderInfo && orderInfo[index] ? orderInfo[index] : {}),
|
||||
}));
|
||||
this.setData({
|
||||
userInfo,
|
||||
menuData: currentMenuData,
|
||||
orderTagInfos: info,
|
||||
customerServiceInfo,
|
||||
currAuthStep: 2,
|
||||
});
|
||||
wx.stopPullDownRefresh();
|
||||
});
|
||||
},
|
||||
|
||||
onClickCell({ currentTarget }) {
|
||||
const { type } = currentTarget.dataset;
|
||||
|
||||
switch (type) {
|
||||
case 'address': {
|
||||
wx.navigateTo({ url: '/pages/user/address/list/index' });
|
||||
break;
|
||||
}
|
||||
case 'service': {
|
||||
this.openMakePhone();
|
||||
break;
|
||||
}
|
||||
case 'help-center': {
|
||||
wx.navigateTo({
|
||||
url: '/pages/help-center/index'
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'coupon': {
|
||||
wx.navigateTo({ url: '/pages/coupon/coupon-list/index' });
|
||||
break;
|
||||
}
|
||||
case 'points': {
|
||||
wx.navigateTo({ url: '/pages/points/index' });
|
||||
break;
|
||||
}
|
||||
case 'logout': {
|
||||
this.handleLogout();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
Toast({
|
||||
context: this,
|
||||
selector: '#t-toast',
|
||||
message: '未知跳转',
|
||||
icon: '',
|
||||
duration: 1000,
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
jumpNav(e) {
|
||||
const status = e.detail.tabType;
|
||||
if (status === 'refund') {
|
||||
// 跳转到退款记录页面
|
||||
wx.navigateTo({ url: '/pages/refund/refund-list/index' });
|
||||
} else {
|
||||
wx.navigateTo({ url: `/pages/order/order-list/index?status=${status}` });
|
||||
}
|
||||
},
|
||||
|
||||
jumpAllOrder() {
|
||||
wx.navigateTo({ url: '/pages/order/order-list/index' });
|
||||
},
|
||||
|
||||
openMakePhone() {
|
||||
this.setData({ showMakePhone: true });
|
||||
},
|
||||
|
||||
closeMakePhone() {
|
||||
this.setData({ showMakePhone: false });
|
||||
},
|
||||
|
||||
call() {
|
||||
wx.makePhoneCall({
|
||||
phoneNumber: this.data.customerServiceInfo.servicePhone,
|
||||
});
|
||||
},
|
||||
|
||||
gotoUserEditPage() {
|
||||
const { currAuthStep } = this.data;
|
||||
const token = wx.getStorageSync('token');
|
||||
|
||||
if (!token) {
|
||||
// 未登录,跳转到登录页
|
||||
wx.navigateTo({ url: '/pages/login/index' });
|
||||
} else if (currAuthStep === 2) {
|
||||
// 已登录但未授权,跳转到个人信息页
|
||||
wx.navigateTo({ url: '/pages/user/person-info/index' });
|
||||
} else {
|
||||
// 其他情况,重新获取用户信息
|
||||
this.fetUseriInfoHandle();
|
||||
}
|
||||
},
|
||||
|
||||
getVersionInfo() {
|
||||
const versionInfo = wx.getAccountInfoSync();
|
||||
const { version, envVersion = __wxConfig } = versionInfo.miniProgram;
|
||||
this.setData({
|
||||
versionNo: envVersion === 'release' ? version : envVersion,
|
||||
});
|
||||
},
|
||||
|
||||
handleLogout() {
|
||||
wx.showModal({
|
||||
title: '退出登录',
|
||||
content: '确定要退出登录吗?',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
// 清除本地存储的用户信息
|
||||
wx.removeStorageSync('userInfo');
|
||||
wx.removeStorageSync('token');
|
||||
wx.removeStorageSync('openid');
|
||||
|
||||
// 重置用户信息
|
||||
this.setData({
|
||||
userInfo: {
|
||||
avatarUrl: '',
|
||||
nickName: '正在登录...',
|
||||
phoneNumber: '',
|
||||
},
|
||||
currAuthStep: 1,
|
||||
});
|
||||
|
||||
// 显示退出成功提示
|
||||
Toast({
|
||||
context: this,
|
||||
selector: '#t-toast',
|
||||
message: '退出登录成功',
|
||||
icon: 'check-circle',
|
||||
duration: 1500,
|
||||
});
|
||||
|
||||
// 延迟跳转到登录页
|
||||
setTimeout(() => {
|
||||
wx.reLaunch({
|
||||
url: '/pages/login/index'
|
||||
});
|
||||
}, 1500);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 分享功能
|
||||
onShareAppMessage() {
|
||||
return {
|
||||
title: '个人中心 - 管理我的订单与信息',
|
||||
path: '/pages/usercenter/index'
|
||||
};
|
||||
},
|
||||
|
||||
// 分享到朋友圈
|
||||
onShareTimeline() {
|
||||
return {
|
||||
title: '个人中心 - 管理我的订单与信息'
|
||||
};
|
||||
}
|
||||
});
|
||||
14
miniprogram/pages/usercenter/index.json
Normal file
14
miniprogram/pages/usercenter/index.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"navigationBarTitleText": "个人中心",
|
||||
"navigationStyle": "custom",
|
||||
"usingComponents": {
|
||||
"t-popup": "tdesign-miniprogram/popup/popup",
|
||||
"t-icon": "tdesign-miniprogram/icon/icon",
|
||||
"t-cell-group": "tdesign-miniprogram/cell-group/cell-group",
|
||||
"t-cell": "tdesign-miniprogram/cell/cell",
|
||||
"t-user-center-card": "./components/user-center-card/index",
|
||||
"t-order-group": "./components/order-group/index",
|
||||
"t-toast": "tdesign-miniprogram/toast/toast"
|
||||
},
|
||||
"enablePullDownRefresh": true
|
||||
}
|
||||
47
miniprogram/pages/usercenter/index.wxml
Normal file
47
miniprogram/pages/usercenter/index.wxml
Normal file
@@ -0,0 +1,47 @@
|
||||
<t-user-center-card
|
||||
userInfo="{{userInfo}}"
|
||||
isPhoneHide="{{true}}"
|
||||
name-class="custom-name-class"
|
||||
phone-class="custom-phone-class"
|
||||
avatar-class="customer-avatar-class"
|
||||
currAuthStep="{{currAuthStep}}"
|
||||
bind:gotoUserEditPage="gotoUserEditPage"
|
||||
/>
|
||||
<view class="content-wrapper">
|
||||
<view class="order-group-wrapper">
|
||||
<t-order-group orderTagInfos="{{orderTagInfos}}" bind:onClickTop="jumpAllOrder" bind:onClickItem="jumpNav" />
|
||||
</view>
|
||||
<view wx:for="{{menuData}}" wx:key="item" class="cell-box">
|
||||
<t-cell-group>
|
||||
<t-cell
|
||||
wx:for="{{item}}"
|
||||
wx:for-item="xitem"
|
||||
wx:for-index="xindex"
|
||||
wx:key="xindex"
|
||||
title="{{xitem.title}}"
|
||||
arrow="{{!xitem.icon}}"
|
||||
note="{{xitem.tit}}"
|
||||
data-type="{{xitem.type}}"
|
||||
bordered="{{false}}"
|
||||
bind:click="onClickCell"
|
||||
t-class="t-cell-padding"
|
||||
t-class-note="order-group-note"
|
||||
t-class-left="order-group__left"
|
||||
>
|
||||
<t-icon name="{{xitem.icon}}" size="48rpx" slot="note" />
|
||||
</t-cell>
|
||||
</t-cell-group>
|
||||
</view>
|
||||
</view>
|
||||
<view class="footer__version" wx:if="{{versionNo !== ''}}">当前版本 {{versionNo}}</view>
|
||||
<t-popup visible="{{showMakePhone}}" placement="bottom" bind:visible-change="closeMakePhone" data-index="2">
|
||||
<view class="popup-content">
|
||||
<view class="popup-title border-bottom-1px" wx:if="{{customerServiceInfo.serviceTimeDuration}}">
|
||||
服务时间: {{customerServiceInfo.serviceTimeDuration}}
|
||||
</view>
|
||||
<view class="popup-phone {{showKefu ? 'border-bottom-1px' : ''}}" bind:tap="call">电话客服</view>
|
||||
<button class="popup-phone border-bottom-1px online" open-type="contact" wx:if="{{showKefu}}">在线客服</button>
|
||||
<view class="popup-close" bind:tap="closeMakePhone">取消</view>
|
||||
</view>
|
||||
</t-popup>
|
||||
<t-toast id="t-toast" />
|
||||
146
miniprogram/pages/usercenter/index.wxss
Normal file
146
miniprogram/pages/usercenter/index.wxss
Normal file
@@ -0,0 +1,146 @@
|
||||
page {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.content-wrapper {
|
||||
margin-top: 340rpx;
|
||||
position: relative;
|
||||
padding: 0 30rpx;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
height: 500rpx;
|
||||
}
|
||||
|
||||
.order-group-wrapper {
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.order-group-note {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.cell-box {
|
||||
border-radius: 10rpx;
|
||||
overflow: hidden;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
.icon-color {
|
||||
color: #aaa;
|
||||
}
|
||||
.cell-class {
|
||||
height: 100rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.order-content {
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
background-color: #fff;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
|
||||
.order-item {
|
||||
flex: 1;
|
||||
height: 180rpx;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.order-content-box {
|
||||
margin: auto;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
-webkit-transform: translate(-50%, -50%);
|
||||
-ms-transform: translate(-50%, -50%);
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
.order-content-t {
|
||||
margin-top: 10rpx;
|
||||
font-size: 24rpx;
|
||||
color: #333;
|
||||
letter-spacing: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.popup-content {
|
||||
background: #f5f5f5;
|
||||
margin-bottom: env(safe-area-inset-bottom);
|
||||
border-radius: 16rpx 16rpx 0 0;
|
||||
}
|
||||
.popup-content .popup-title {
|
||||
background: #fff;
|
||||
text-align: center;
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
height: 112rpx;
|
||||
text-align: center;
|
||||
line-height: 112rpx;
|
||||
border-radius: 16rpx 16rpx 0 0;
|
||||
}
|
||||
|
||||
.border-bottom-1px {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.border-bottom-1px::after {
|
||||
position: absolute;
|
||||
display: block;
|
||||
content: '';
|
||||
box-sizing: border-box;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 200%;
|
||||
height: 200%;
|
||||
transform: scale(0.5);
|
||||
transform-origin: left top;
|
||||
border-bottom: 2rpx solid #e5e5e5;
|
||||
}
|
||||
.popup-content .popup-phone,
|
||||
.popup-content .popup-close {
|
||||
background: #fff;
|
||||
height: 100rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
font-size: 30rpx;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
font-weight: 400;
|
||||
color: #333;
|
||||
}
|
||||
.popup-content .popup-phone.online {
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
.popup-content .popup-phone.online::after {
|
||||
content: none;
|
||||
}
|
||||
.popup-content .popup-close {
|
||||
color: #333;
|
||||
border: 0;
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
|
||||
.my-order {
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
.footer__version {
|
||||
text-align: center;
|
||||
margin-top: 50rpx;
|
||||
color: #999;
|
||||
margin-bottom: 4rpx;
|
||||
font-size: 24rpx;
|
||||
line-height: 32rpx;
|
||||
}
|
||||
.cell-box .order-group__left {
|
||||
margin-right: 0;
|
||||
}
|
||||
.cell-box .t-cell-padding {
|
||||
padding: 24rpx 18rpx 24rpx 32rpx;
|
||||
}
|
||||
Reference in New Issue
Block a user