style(member): 统一会员中心页面风格(卡片面板/状态标签/链接按钮/右对齐分页)

This commit is contained in:
pikachu1995@126.com
2026-10-26 17:01:30 +08:00
parent 1f872254cc
commit b72c792ade
15 changed files with 269 additions and 452 deletions

View File

@@ -27,9 +27,9 @@
</div>
<div class="connect-row">
<span class="connect-name">{{ wechatConnect.label }}</span>
<span class="connect-status" :class="{ 'is-bound': isBound(wechatConnect.type) }">
<el-tag :type="isBound(wechatConnect.type) ? 'success' : 'info'" size="small">
{{ isBound(wechatConnect.type) ? "已绑定" : "未绑定" }}
</span>
</el-tag>
<el-skeleton v-if="connectLoading" animated class="connect-skeleton" />
</div>
</div>
@@ -277,8 +277,9 @@ onMounted(() => {
.safe-card {
padding: 20px;
border: 1px solid #f0f0f0;
border: 1px solid #eee;
border-radius: 8px;
background: #fff;
}
.safe-card-connect {
@@ -295,7 +296,7 @@ onMounted(() => {
width: 48px;
height: 48px;
border-radius: 8px;
background: #fff5f4;
background: color-mix(in srgb, #{$theme_color} 8%, #fff);
color: $theme_color;
display: flex;
align-items: center;
@@ -309,7 +310,7 @@ onMounted(() => {
.safe-title {
margin: 0;
color: #171A26;
color: #333;
font-size: 16px;
font-weight: 600;
line-height: 24px;
@@ -333,26 +334,11 @@ onMounted(() => {
}
.connect-name {
color: #171A26;
color: #333;
font-size: 14px;
line-height: 22px;
}
.connect-status {
height: 22px;
padding: 0 8px;
border-radius: 4px;
background: #f5f5f5;
color: #999;
font-size: 12px;
line-height: 22px;
}
.connect-status.is-bound {
background: #f0faf3;
color: #1f9d55;
}
.connect-skeleton {
width: 120px;
height: 22px;

View File

@@ -34,7 +34,7 @@
<div class="comment-cell">{{ item.grade === 'GOOD' ? '好评' : item.grade === 'WORSE' ? '差评' : '中评' }}</div>
<div class="comment-content">{{ item.content }}</div>
<div class="comment-ops">
<button type="button" class="text-link" @click="evaluateDetail(item.id)">评价详情</button>
<el-button link type="primary" @click="evaluateDetail(item.id)">评价详情</el-button>
</div>
</div>
</div>
@@ -230,19 +230,4 @@ onMounted(() => {
display: flex;
justify-content: center;
}
.text-link {
border: none;
background: none;
padding: 0;
color: #171A26;
font-family: inherit;
font-size: 14px;
line-height: 22px;
cursor: pointer;
&:hover {
color: $theme_color;
}
}
</style>

View File

@@ -32,17 +32,19 @@
{{ item.goodsName }}
</div>
</div>
<div class="complain-cell">{{ statusLabel[item.complainStatus] || item.complainStatus }}</div>
<div class="complain-cell">
<el-tag size="small" :type="statusTagType(item.complainStatus)">{{ statusLabel[item.complainStatus] || item.complainStatus }}</el-tag>
</div>
<div class="complain-topic">{{ item.complainTopic }}</div>
<div class="complain-content">{{ item.content }}</div>
<div class="complain-ops">
<button type="button" class="text-link" @click="goDetail(item.id)">投诉详情</button>
<button
<el-button link type="primary" @click="goDetail(item.id)">投诉详情</el-button>
<el-button
v-if="item.complainStatus === 'APPLYING' || item.complainStatus === 'NEW'"
type="button"
class="text-link"
link
type="danger"
@click="cancel(item.id)"
>取消投诉</button>
>取消投诉</el-button>
</div>
</div>
</div>
@@ -84,6 +86,18 @@ const params = reactive({ // 请求参数
pageSize: 20
});
function statusTagType(status) { // 投诉状态标签类型
const map = {
COMPLETE: 'success',
APPLYING: 'warning',
NEW: 'warning',
CANCEL: 'info',
EXPIRED: 'info',
NO_APPLY: 'info'
};
return map[status] || 'info';
}
function getList() { // 获取投诉列表
complainList(params).then(res => {
if (res.success) {
@@ -268,20 +282,9 @@ onMounted(() => {
flex-direction: column;
align-items: center;
gap: 8px;
}
.text-link {
border: none;
background: none;
padding: 0;
color: #171A26;
font-family: inherit;
font-size: 14px;
line-height: 22px;
cursor: pointer;
&:hover {
color: $theme_color;
.el-button + .el-button {
margin-left: 0;
}
}
</style>

View File

@@ -33,10 +33,10 @@
</div>
<div v-if="params.type === 'GOODS'" class="fav-price">{{ $filters.unitPrice(item.price, '¥') }}</div>
<div class="fav-ops">
<button v-if="params.type === 'GOODS'" type="button" class="op-btn" @click="buynow(item.skuId, item.goodsId)">立即购买</button>
<button v-else type="button" class="op-btn" @click="goShop(item.id)">查看店铺</button>
<button v-if="params.type === 'GOODS'" type="button" class="text-link" @click="cancel(item.skuId)">取消收藏</button>
<button v-else type="button" class="text-link" @click="cancelStore(item.id)">取消收藏</button>
<el-button v-if="params.type === 'GOODS'" type="primary" size="small" @click="buynow(item.skuId, item.goodsId)">立即购买</el-button>
<el-button v-else type="primary" size="small" @click="goShop(item.id)">查看店铺</el-button>
<el-button v-if="params.type === 'GOODS'" link type="danger" @click="cancel(item.skuId)">取消收藏</el-button>
<el-button v-else link type="danger" @click="cancelStore(item.id)">取消收藏</el-button>
</div>
</div>
<el-skeleton size="large" fix v-if="spinShow"></el-skeleton>
@@ -72,10 +72,10 @@
</div>
<div v-if="params.type === 'GOODS'" class="fav-price">{{ $filters.unitPrice(item.price, '¥') }}</div>
<div class="fav-ops">
<button v-if="params.type === 'GOODS'" type="button" class="op-btn" @click="buynow(item.skuId, item.goodsId)">立即购买</button>
<button v-else type="button" class="op-btn" @click="goShop(item.id)">查看店铺</button>
<button v-if="params.type === 'GOODS'" type="button" class="text-link" @click="cancel(item.skuId)">取消收藏</button>
<button v-else type="button" class="text-link" @click="cancelStore(item.id)">取消收藏</button>
<el-button v-if="params.type === 'GOODS'" type="primary" size="small" @click="buynow(item.skuId, item.goodsId)">立即购买</el-button>
<el-button v-else type="primary" size="small" @click="goShop(item.id)">查看店铺</el-button>
<el-button v-if="params.type === 'GOODS'" link type="danger" @click="cancel(item.skuId)">取消收藏</el-button>
<el-button v-else link type="danger" @click="cancelStore(item.id)">取消收藏</el-button>
</div>
</div>
<el-skeleton size="large" fix v-if="spinShow"></el-skeleton>
@@ -316,7 +316,7 @@ onMounted(() => {
margin-top: 6px;
padding: 0 6px;
border-radius: 4px;
background: #fff1f0;
background: color-mix(in srgb, #{$theme_color} 8%, #fff);
color: $theme_color;
font-size: 12px;
line-height: 20px;
@@ -336,37 +336,4 @@ onMounted(() => {
justify-content: center;
gap: 16px;
}
.op-btn {
min-width: 96px;
height: 32px;
padding: 0 12px;
border: 1px solid $theme_color;
border-radius: 4px;
background: $theme_color;
color: #fff;
font-family: inherit;
font-size: 14px;
line-height: 30px;
cursor: pointer;
&:hover {
opacity: 0.9;
}
}
.text-link {
border: none;
background: none;
padding: 0;
color: #171A26;
font-family: inherit;
font-size: 14px;
line-height: 22px;
cursor: pointer;
&:hover {
color: $theme_color;
}
}
</style>

View File

@@ -15,10 +15,10 @@
<template #append><span>输入验证码</span></template>
</el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitRegister">下一步</el-button>
</el-form-item>
</el-form>
<div v-if="(status == 2 || status == 3) && !showPwd" style="text-align: center;width: 50%">
<el-button type="primary" class="ml_10" @click="submitRegister">下一步</el-button>
</div>
<!-- 修改 -->
<el-form ref="formRegisterRef" :model="formRegister" :rules="ruleInline" label-width="80px" v-if="status == 1 && !showPwd">
@@ -43,11 +43,10 @@
<template #prepend><el-icon><Lock /></el-icon></template>
</el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleRegist">修改</el-button>
</el-form-item>
</el-form>
<div v-if="status == 1 && !showPwd" style="width: 50%;text-align: center">
<el-button type="primary" class="ml_10" @click="handleRegist">修改</el-button>
</div>
<!-- 设置&修改的第二种情况 -->
<el-form ref="formDataUpdateRef" :model="formDataUpdate" label-position="left" label-width="100px" :rules="ruleIn"
v-if="showPwd">
@@ -65,10 +64,10 @@
<template #prepend><el-icon><Lock /></el-icon></template>
</el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="setPassword">设置</el-button>
</el-form-item>
</el-form>
<div v-if="showPwd" style="text-align: center;width: 50%">
<el-button type="primary" class="ml_10" @click="setPassword">设置</el-button>
</div>
</UserCenterLayout>
</div>
</template>
@@ -252,9 +251,6 @@ onMounted(() => {
</script>
<style scoped lang="scss">
.wrapper {
text-align: center;
}
.phone {
text-align: left;
}

View File

@@ -87,10 +87,10 @@ onMounted(() => {
<style lang="scss" scoped>
h3 {
margin: 8px 0 12px;
font-size: 15px;
font-size: 16px;
font-weight: 600;
color: #333;
line-height: 1.4;
line-height: 24px;
}
.point-summary {
@@ -102,7 +102,8 @@ h3 {
.point-stat {
flex: 1;
padding: 16px 20px;
background: #fafafa;
background: #fff;
border: 1px solid #eee;
border-radius: 8px;
.label {

View File

@@ -13,7 +13,7 @@
:action="action"
:headers="accessToken"
>
<button type="button" class="ghost-btn">上传头像</button>
<el-button size="small">上传头像</el-button>
</el-upload>
</div>
</el-form-item>
@@ -29,13 +29,13 @@
/>
</el-form-item>
<el-form-item label="性别">
<div class="sex-group">
<button type="button" class="sex-btn" :class="{ active: formItem.sex === 1 }" @click="formItem.sex = 1">男</button>
<button type="button" class="sex-btn" :class="{ active: formItem.sex === 0 }" @click="formItem.sex = 0">女</button>
</div>
<el-radio-group v-model="formItem.sex">
<el-radio-button :value="1">男</el-radio-button>
<el-radio-button :value="0">女</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item>
<button type="button" class="op-btn" @click="save">确认修改</button>
<el-button type="primary" @click="save">确认修改</el-button>
</el-form-item>
</el-form>
</UserCenterLayout>
@@ -167,7 +167,7 @@ function handleSuccess (res, file) { // 上传成功
:deep(.el-form-item__label) {
height: auto;
line-height: 22px;
color: #666;
color: #999;
font-size: 14px;
}
@@ -199,51 +199,5 @@ function handleSuccess (res, file) { // 上传成功
:deep(.profile-field.el-date-editor) {
width: 320px;
}
.sex-group {
display: flex;
gap: 8px;
}
.sex-btn,
.ghost-btn,
.op-btn {
height: 32px;
padding: 0 16px;
border-radius: 4px;
font-family: inherit;
font-size: 14px;
line-height: 30px;
cursor: pointer;
}
.sex-btn,
.ghost-btn {
border: 1px solid #ddd;
background: #fff;
color: #171A26;
&:hover {
border-color: $theme_color;
color: $theme_color;
}
}
.sex-btn.active {
border-color: $theme_color;
background: #fff5f4;
color: $theme_color;
}
.op-btn {
min-width: 96px;
border: 1px solid $theme_color;
background: $theme_color;
color: #fff;
&:hover {
opacity: 0.9;
}
}
</style>

View File

@@ -4,7 +4,7 @@
<div class="order-card status-card" v-if="orderGoods.goodsName || orderGoods.content">
<div class="status-head">
<div class="status-main">
<p class="status-text">{{ gradeText }}</p>
<el-tag :type="gradeTagType" effect="dark">{{ gradeText }}</el-tag>
<p class="status-sn">评价时间:{{ orderGoods.createTime }}</p>
</div>
</div>
@@ -99,6 +99,10 @@ const gradeText = computed(() => {
const map = { GOOD: '好评', MODERATE: '中评', WORSE: '差评' }
return map[orderGoods.value.grade] || '评价详情'
});
const gradeTagType = computed(() => {
const map = { GOOD: 'success', MODERATE: 'warning', WORSE: 'info' }
return map[orderGoods.value.grade] || 'info'
});
function getDetail() {
// 获取评价详情
@@ -130,33 +134,23 @@ onMounted(() => {
}
.order-card {
padding: 4px 0 16px;
margin-bottom: 8px;
border-bottom: 1px solid #f0f0f0;
margin-top: 16px;
padding: 16px 20px;
border: 1px solid #eee;
border-radius: 8px;
background: #fff;
h3 {
margin: 0 0 12px;
font-size: 15px;
font-size: 16px;
font-weight: 600;
color: #333;
line-height: 1.4;
}
&:last-of-type {
border-bottom: none;
line-height: 24px;
}
}
.status-card {
padding-top: 8px;
}
.status-text {
margin: 0;
color: $theme_color;
font-size: 18px;
font-weight: 600;
line-height: 1.4;
margin-top: 0;
}
.status-sn {

View File

@@ -33,7 +33,9 @@
<div class="order-sn">
{{ order.createTime }}<span>售后单号 {{ order.sn }}</span><span class="order-store" @click="shopPage(order.storeId)">{{ order.storeName }}</span>
</div>
<div class="order-status">{{ filterOrderStatus(order.serviceStatus) }}</div>
<div class="order-status">
<el-tag size="small" :type="statusTagType(order.serviceStatus)">{{ filterOrderStatus(order.serviceStatus) }}</el-tag>
</div>
</div>
<div class="order-body">
<div class="col-detail">
@@ -59,19 +61,19 @@
<div class="order-amount">{{ $filters.unitPrice(order.applyRefundPrice, "¥") }}</div>
</div>
<div class="col-ops">
<button
<el-button
v-if="order.serviceStatus == 'PASS' && order.serviceType != 'RETURN_MONEY'"
type="button"
class="op-btn"
type="primary"
size="small"
@click="openModal(order)"
>提交物流</button>
<button type="button" class="text-link" @click="goDetail(order.sn)">售后详情</button>
<button
>提交物流</el-button>
<el-button link type="primary" @click="goDetail(order.sn)">售后详情</el-button>
<el-button
v-if="order.afterSaleAllowOperationVO && order.afterSaleAllowOperationVO.cancel"
type="button"
class="text-link"
link
type="danger"
@click="cancel(order.sn)"
>取消售后</button>
>取消售后</el-button>
</div>
</div>
</div>
@@ -253,6 +255,14 @@ function filterOrderStatus(status) { // 获取订单状态中文
});
return ob && ob[0] ? ob[0].name : status
}
function statusTagType(status) { // 售后状态对应标签类型
const map = {
APPLY: 'warning', APPLYING: 'warning',
COMPLETE: 'success',
CANCEL: 'info', EXPIRED: 'info'
}
return map[status] || 'info'
}
// 获取物流公司列表
function getCompany() {
getLogisticsCompany().then(res => {
@@ -372,7 +382,7 @@ onMounted(() => {
align-items: center;
min-width: 0;
font-size: 14px;
color: #171A26;
color: #333;
line-height: 1.5;
span {
@@ -476,38 +486,9 @@ onMounted(() => {
flex-direction: column;
align-items: center;
gap: 8px;
}
.op-btn {
min-width: 96px;
height: 32px;
padding: 0 12px;
border: 1px solid $theme_color;
border-radius: 4px;
background: $theme_color;
color: #fff;
font-family: inherit;
font-size: 14px;
line-height: 30px;
cursor: pointer;
&:hover {
opacity: 0.9;
}
}
.text-link {
border: none;
background: none;
padding: 0;
color: #171A26;
font-family: inherit;
font-size: 14px;
line-height: 22px;
cursor: pointer;
&:hover {
color: $theme_color;
:deep(.el-button + .el-button) {
margin-left: 0;
}
}
}

View File

@@ -1,10 +1,10 @@
<template>
<div class="order-detail">
<UserCenterLayout>
<div class="order-card status-card" v-if="afterSale.sn">
<div class="panel" v-if="afterSale.sn">
<div class="status-head">
<div class="status-main">
<p class="status-text">{{ afterSale.serviceName }}</p>
<el-tag :type="statusTagType" effect="dark">{{ afterSale.serviceName }}</el-tag>
<p class="status-sn">
售后单号:{{ afterSale.sn }}
<span>订单号:{{ afterSale.orderSn }}</span>
@@ -13,8 +13,8 @@
<div class="status-side">
<div class="operation-time">创建时间:{{ afterSale.createTime }}</div>
<div class="status-actions" v-if="canSubmitLogistics || canCancel">
<button v-if="canSubmitLogistics" type="button" class="op-btn" @click="openModal">提交物流</button>
<button v-if="canCancel" type="button" class="text-link" @click="cancel(afterSale.sn)">取消售后</button>
<el-button v-if="canSubmitLogistics" type="primary" size="small" @click="openModal">提交物流</el-button>
<el-button v-if="canCancel" link type="primary" @click="cancel(afterSale.sn)">取消售后</el-button>
</div>
</div>
</div>
@@ -28,7 +28,7 @@
</div>
</div>
</div>
<div class="order-card" v-if="logList.length">
<div class="panel" v-if="logList.length">
<h3>售后进程</h3>
<el-steps
class="progress"
@@ -43,50 +43,48 @@
></el-step>
</el-steps>
</div>
<div class="order-card">
<div class="panel">
<h3>服务单信息</h3>
<div class="info-list">
<div class="info-row">
<span class="info-label">退款方式</span>
<span class="info-value">{{ afterSale.refundWay == 'ORIGINAL' ? '原路退回' : '账号退款' }}</span>
</div>
<div class="info-row">
<span class="info-label">申请退款金额</span>
<span class="info-value">{{ $filters.unitPrice(afterSale.applyRefundPrice, '¥') }}</span>
</div>
<div class="info-row" v-if="afterSale.actualRefundPrice">
<span class="info-label">实际退款金额</span>
<span class="info-value">{{ $filters.unitPrice(afterSale.actualRefundPrice, '¥') }}</span>
</div>
<template v-if="afterSale.refundWay === 'OFFLINE'">
<div class="info-row">
<span class="label">退款方式</span>
<span>{{ afterSale.refundWay == 'ORIGINAL' ? '原路退回' : '账号退款' }}</span>
<span class="info-label">退款开户行</span>
<span class="info-value">{{ afterSale.bankDepositName }}</span>
</div>
<div class="info-row">
<span class="label">申请退款金额</span>
<span>{{ $filters.unitPrice(afterSale.applyRefundPrice, '¥') }}</span>
</div>
<div class="info-row" v-if="afterSale.actualRefundPrice">
<span class="label">实际退款金额</span>
<span>{{ $filters.unitPrice(afterSale.actualRefundPrice, '¥') }}</span>
</div>
<template v-if="afterSale.refundWay === 'OFFLINE'">
<div class="info-row">
<span class="label">退款开户行</span>
<span>{{ afterSale.bankDepositName }}</span>
</div>
<div class="info-row">
<span class="label">退款开户名</span>
<span>{{ afterSale.bankAccountName }}</span>
</div>
<div class="info-row">
<span class="label">退款卡号</span>
<span>{{ afterSale.bankAccountNumber }}</span>
</div>
</template>
<div class="info-row">
<span class="label">商品处理方式</span>
<span>{{ afterSale.serviceType == 'RETURN_MONEY' ? '退款' : '退货' }}</span>
<span class="info-label">退款开户名</span>
<span class="info-value">{{ afterSale.bankAccountName }}</span>
</div>
<div class="info-row">
<span class="label">退款原因</span>
<span>{{ afterSale.reasonName }}</span>
</div>
<div class="info-row">
<span class="label">问题描述</span>
<span>{{ afterSale.problemDesc }}</span>
<span class="info-label">退款卡号</span>
<span class="info-value">{{ afterSale.bankAccountNumber }}</span>
</div>
</template>
<div class="info-row">
<span class="info-label">商品处理方式</span>
<span class="info-value">{{ afterSale.serviceType == 'RETURN_MONEY' ? '退款' : '退货' }}</span>
</div>
<div class="info-row">
<span class="info-label">退款原因</span>
<span class="info-value">{{ afterSale.reasonName }}</span>
</div>
<div class="info-row">
<span class="info-label">问题描述</span>
<span class="info-value">{{ afterSale.problemDesc }}</span>
</div>
</div>
<div class="order-card" v-if="afterSale.afterSaleImage">
<div class="panel" v-if="afterSale.afterSaleImage">
<h3>图片信息</h3>
<div class="image-list">
<img
@@ -175,6 +173,22 @@ const canCancel = computed(() => {
return afterSale.value.afterSaleAllowOperationVO && afterSale.value.afterSaleAllowOperationVO.cancel
});
const statusTagType = computed(() => {
const map = {
APPLY: 'warning',
PASS: 'success',
REFUSE: 'info',
BUYER_RETURN: 'warning',
SELLER_CONFIRM: 'warning',
SELLER_TERMINATION: 'info',
BUYER_CONFIRM: 'warning',
BUYER_CANCEL: 'info',
COMPLETE: 'success',
WAIT_REFUND: 'warning'
};
return map[afterSale.value.serviceStatus] || 'info';
});
function getDetail () { // 售后详情
afterSaleDetail(route.query.sn).then(res => {
if (res.success) {
@@ -286,26 +300,22 @@ onMounted(() => {
color: #333;
}
.order-card {
padding: 4px 0 16px;
margin-bottom: 8px;
border-bottom: 1px solid #f0f0f0;
.panel {
margin-top: 16px;
padding: 16px 20px;
border: 1px solid #eee;
border-radius: 8px;
background: #fff;
h3 {
margin: 0 0 12px;
font-size: 15px;
padding-bottom: 12px;
border-bottom: 1px solid #f5f5f5;
font-size: 16px;
font-weight: 600;
color: #333;
line-height: 1.4;
line-height: 24px;
}
&:last-child {
border-bottom: none;
}
}
.status-card {
padding-top: 8px;
}
.status-head {
@@ -315,17 +325,16 @@ onMounted(() => {
gap: 16px;
}
.status-text {
margin: 0;
color: $theme_color;
font-size: 18px;
font-weight: 600;
line-height: 1.4;
.status-main {
display: flex;
align-items: center;
gap: 12px;
flex-wrap: wrap;
}
.status-sn {
margin: 6px 0 0;
color: #171A26;
margin: 0;
color: #999;
font-size: 14px;
line-height: 22px;
@@ -340,7 +349,7 @@ onMounted(() => {
}
.operation-time {
color: #171A26;
color: #999;
font-size: 14px;
line-height: 22px;
}
@@ -392,7 +401,7 @@ onMounted(() => {
span {
margin: 0 4px;
color: #438cde;
color: #333;
cursor: pointer;
&:hover {
@@ -435,35 +444,30 @@ onMounted(() => {
}
}
.info-list {
border: 1px solid #f0f0f0;
border-radius: 8px;
overflow: hidden;
}
.info-row {
display: grid;
grid-template-columns: 140px minmax(0, 1fr);
min-height: 44px;
border-top: 1px solid #f0f0f0;
display: flex;
gap: 16px;
padding: 12px 0;
border-bottom: 1px solid #f5f5f5;
font-size: 14px;
line-height: 22px;
&:first-child {
border-top: none;
&:last-child {
border-bottom: none;
padding-bottom: 4px;
}
}
span {
display: flex;
align-items: center;
padding: 10px 16px;
color: #171A26;
}
.info-label {
flex: 0 0 96px;
color: #999;
}
.label {
background: #fafafa;
color: #666;
}
.info-value {
flex: 1;
min-width: 0;
color: #333;
word-break: break-all;
}
.image-list {
@@ -480,37 +484,4 @@ onMounted(() => {
cursor: pointer;
}
}
.op-btn {
min-width: 96px;
height: 32px;
padding: 0 12px;
border: 1px solid $theme_color;
border-radius: 4px;
background: $theme_color;
color: #fff;
font-family: inherit;
font-size: 14px;
line-height: 30px;
cursor: pointer;
&:hover {
opacity: 0.9;
}
}
.text-link {
border: none;
background: none;
padding: 0;
color: #171A26;
font-family: inherit;
font-size: 14px;
line-height: 22px;
cursor: pointer;
&:hover {
color: $theme_color;
}
}
</style>

View File

@@ -1,26 +1,20 @@
<template>
<div class="apply-after-sale">
<UserCenterLayout>
<el-table :data="goodsData" border>
<el-table-column label="商品名称">
<template #default="{ row }">
<div style="padding:5px;display:flex;">
<img :src="row.image" loading="lazy" decoding="async" style="vertical-align: top;" width="60" height="60" alt="">
<span class="ml_10">{{ row.goodsName }}</span>
</div>
</template>
</el-table-column>
<el-table-column label="价格">
<template #default="{ row }">
<div>{{ $filters.unitPrice(row.applyRefundPrice, '¥') }}</div>
</template>
</el-table-column>
<el-table-column prop="num" label="购买数量" />
</el-table>
<div class="goods-row" v-for="(goods, index) in goodsData" :key="index">
<img class="goods-img" :src="goods.image" loading="lazy" decoding="async" alt="">
<div class="goods-info">
<div class="goods-name">{{ goods.goodsName }}</div>
<div class="goods-meta">
<span class="goods-price">{{ $filters.unitPrice(goods.applyRefundPrice, '¥') }}</span>
<span class="goods-num">×{{ goods.num }}</span>
</div>
</div>
</div>
<div>
<el-form :model="form" ref="formRef" class="mt_10" :rules="rules" label-width="80px">
<el-form-item label="售后类别">
<el-radio-group v-model="form.serviceType" @change="changeReason" type="button" button-style="solid">
<el-radio-group v-model="form.serviceType" @change="changeReason">
<el-radio v-if="info.returnGoods" label="RETURN_GOODS">退货</el-radio>
<el-radio v-if="info.returnMoney" label="RETURN_MONEY">退款</el-radio>
</el-radio-group>
@@ -224,6 +218,50 @@ onMounted(() => {
<style lang="scss" scoped>
/** 商品信息 */
.goods-row {
display: flex;
align-items: center;
padding: 12px 0;
}
.goods-img {
width: 56px;
height: 56px;
flex-shrink: 0;
border: 1px solid #f0f0f0;
border-radius: 4px;
object-fit: cover;
}
.goods-info {
min-width: 0;
margin-left: 12px;
}
.goods-name {
color: #333;
font-size: 14px;
line-height: 22px;
}
.goods-meta {
display: flex;
align-items: center;
gap: 12px;
margin-top: 4px;
}
.goods-price {
color: $theme_color;
font-size: 14px;
font-weight: 600;
}
.goods-num {
color: #999;
font-size: 14px;
}
.order-price {
text-align: right;
margin-top: 30px;

View File

@@ -164,17 +164,6 @@ onMounted(() => {
})
</script>
<style lang="scss" scoped>
.delivery-rate {
display: flex;
align-items: center;
margin-top: 20px;
height: 50px;
border-bottom: 1px solid #eee;
>div:nth-child(1) {
width: 30%;
font-weight: bold;
}
}
.goods-eval{
display: flex;
.goods-con {

View File

@@ -30,7 +30,7 @@
</div>
</div>
</div>
<el-empty v-else description="暂无收货地址" />
<empty v-else _Title="暂无收货地址" />
</UserCenterLayout>
</div>
</template>
@@ -130,7 +130,7 @@ onMounted(() => {
.address-name {
font-size: 16px;
font-weight: 600;
color: $light_title_color;
color: #333;
}
.address-mobile {
@@ -183,13 +183,13 @@ onMounted(() => {
}
.del-btn:hover {
color: #f56c6c;
color: $theme_color;
}
}
.default-address-tag {
margin-left: 10px;
background-color: #fff3f2 !important;
background-color: color-mix(in srgb, #{$theme_color} 8%, #fff) !important;
border: 1px solid $theme_color !important;
color: $theme_color !important;
}

View File

@@ -1,6 +1,10 @@
<template>
<div class="wrapper">
<UserCenterLayout>
<UserCenterLayout
:tabs="walletTabs"
:active-tab="activeWalletTabIndex"
@tab-change="handleTabChange"
>
<div class="wallet-summary">
<div class="wallet-stat">
@@ -13,8 +17,8 @@
</div>
</div>
<div class="account-btns">
<button type="button" class="op-btn" @click="recharge">在线充值</button>
<button type="button" class="ghost-btn" @click="withdrawalApply">申请提现</button>
<el-button type="primary" @click="recharge">在线充值</el-button>
<el-button @click="withdrawalApply">申请提现</el-button>
</div>
<el-dialog v-model="modal" width="530">
<template #header><p>
@@ -36,7 +40,7 @@
</el-form>
</div>
<template #footer><div style="text-align: center">
<el-button size="large" type="success" @click="rechargePrice">充值</el-button>
<el-button size="large" type="primary" @click="rechargePrice">充值</el-button>
</div></template>
</el-dialog>
<!-- 提现申请 -->
@@ -65,7 +69,7 @@
number
size="large"
><template #append><span>元</span></template></el-input>
<span style="color: red">最低提现金额 {{ withdrawApplyFormData.minPrice }}元</span>
<span class="form-tip">最低提现金额 {{ withdrawApplyFormData.minPrice }}元</span>
</el-form-item>
<el-form-item v-if="withdrawApplyFormData.type === 'ALI'" label="真实姓名" prop="realName">
<el-input
@@ -86,14 +90,9 @@
</el-form>
</div>
<template #footer><div style="text-align: center">
<el-button size="large" type="success" @click="withdrawal">提现</el-button>
<el-button size="large" type="primary" @click="withdrawal">提现</el-button>
</div></template>
</el-dialog>
<div class="wallet-tabs">
<div class="wallet-tab" :class="{ active: activeWalletTab === 'log' }" @click="tabPaneChange('log')">余额日志</div>
<div class="wallet-tab" :class="{ active: activeWalletTab === 'recharge' }" @click="tabPaneChange('recharge')">充值记录</div>
<div class="wallet-tab" :class="{ active: activeWalletTab === 'withdrawApply' }" @click="tabPaneChange('withdrawApply')">提现记录</div>
</div>
<div v-show="activeWalletTab === 'log'">
<empty v-if="!(logColumnsData.records || []).length" />
@@ -181,7 +180,7 @@
</template>
<script setup>
import { onMounted, reactive, ref } from "vue";
import { computed, onMounted, reactive, ref } from "vue";
import { useRouter } from "vue-router";
import { Message } from "@/utils/message";
import {getDepositLog, getMembersWallet, getRecharge, getWithdrawApply, recharge as apiRecharge, withdrawalApply as apiWithdrawalApply} from '@/api/member';
@@ -196,6 +195,12 @@ const formDataRef = ref(null);
const withdrawApplyFormDataRef = ref(null);
const activeWalletTab = ref("log");
const walletTabs = ["余额日志", "充值记录", "提现记录"]; // 钱包页签
const walletTabKeys = ["log", "recharge", "withdrawApply"]; // 页签对应标识
const activeWalletTabIndex = computed(() => {
const index = walletTabKeys.indexOf(activeWalletTab.value);
return index > -1 ? index : 0;
});
const frozenDeposit = ref(0); // 冻结余额
const memberDeposit = ref(0); // 余额
@@ -290,6 +295,10 @@ function tabPaneChange(v) {
getWithdrawApplyData();
}
}
// 页签切换
function handleTabChange(index) {
tabPaneChange(walletTabKeys[index]);
}
// 充值记录
function getRechargeData() {
getRecharge(rechargeForm).then((res) => {
@@ -416,7 +425,8 @@ function withdrawal() {
.wallet-stat {
flex: 1;
padding: 16px 20px;
background: #fafafa;
background: #fff;
border: 1px solid #eee;
border-radius: 8px;
.label {
@@ -445,67 +455,9 @@ function withdrawal() {
margin-bottom: 8px;
}
.op-btn,
.ghost-btn {
height: 32px;
padding: 0 16px;
border-radius: 4px;
font-family: inherit;
.form-tip {
color: #999;
font-size: 14px;
line-height: 30px;
cursor: pointer;
}
.op-btn {
border: 1px solid $theme_color;
background: $theme_color;
color: #fff;
&:hover {
opacity: 0.9;
}
}
.ghost-btn {
border: 1px solid #ddd;
background: #fff;
color: #171A26;
&:hover {
border-color: $theme_color;
color: $theme_color;
}
}
.wallet-tabs {
display: flex;
gap: 24px;
margin: 16px 0;
border-bottom: 1px solid #f0f0f0;
}
.wallet-tab {
position: relative;
padding: 10px 0;
color: #666;
font-size: 14px;
line-height: 22px;
cursor: pointer;
&.active {
color: $theme_color;
font-weight: 600;
&::after {
content: '';
position: absolute;
left: 0;
right: 0;
bottom: 0;
height: 2px;
background: $theme_color;
}
}
}
.wallet-list {