mirror of
https://gitee.com/beijing_hongye_huicheng/lilishop-ui.git
synced 2026-11-14 04:49:00 +08:00
style(member): 优化申诉详情、会员等级、优惠券、礼品卡页面样式
This commit is contained in:
@@ -1,185 +1,224 @@
|
||||
<template>
|
||||
<div class="add-eval">
|
||||
<div class="complain-detail">
|
||||
<UserCenterLayout>
|
||||
<div class="title">
|
||||
<p>
|
||||
<span class="fontsize_16 global_color">{{ statusLabel[detail.complainStatus] }}</span>
|
||||
<span class="color999 ml_20">创建时间:</span><span>{{ detail.createTime }}</span>
|
||||
<span class="color999 ml_20">{{ detail.createTime }}</span>
|
||||
</p>
|
||||
<div class="detail-head">
|
||||
<el-tag :type="statusTagType" effect="dark">{{ statusText }}</el-tag>
|
||||
<span class="create-time">创建时间:{{ detail.createTime || "-" }}</span>
|
||||
</div>
|
||||
|
||||
<el-alert class="l_title" show-icon type="warning">我的申诉信息</el-alert>
|
||||
<table cellspacing="0" cellpadding='0' border="1">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>投诉商品</td>
|
||||
<td class="hover-color" @click="linkTo(`/goodsDetail?goodsId=${detail.goodsId}&skuId=${detail.skuId}`)"><img :src="detail.goodsImage" loading="lazy" decoding="async" width="60" alt=""> {{ detail.goodsName }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>投诉主题</td>
|
||||
<td>{{ detail.complainTopic }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>投诉内容</td>
|
||||
<td>{{ detail.content }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>补充内容</td>
|
||||
<td>
|
||||
<div style="display:flex;align-items:center;">
|
||||
<template v-if="detail.images">
|
||||
<div class="demo-upload-list" v-for="(img, index) in detail.images.split(',')" :key="index">
|
||||
<img :src="img" loading="lazy" decoding="async">
|
||||
<section class="panel">
|
||||
<div class="panel-title">我的申诉信息</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">投诉商品</span>
|
||||
<div class="info-value">
|
||||
<button
|
||||
v-if="detail.goodsId"
|
||||
type="button"
|
||||
class="goods-info"
|
||||
@click="goGoodsDetail(detail.skuId, detail.goodsId)"
|
||||
>
|
||||
<img :src="detail.goodsImage" loading="lazy" decoding="async" alt="" />
|
||||
<span class="goods-name">{{ detail.goodsName }}</span>
|
||||
</button>
|
||||
<span v-else class="empty-text">暂无</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">投诉主题</span>
|
||||
<span class="info-value">{{ detail.complainTopic || "暂无" }}</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">投诉内容</span>
|
||||
<span class="info-value">{{ detail.content || "暂无" }}</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">补充内容</span>
|
||||
<div class="info-value">
|
||||
<div v-if="images.length" class="img-list">
|
||||
<div
|
||||
v-for="(img, index) in images"
|
||||
:key="index"
|
||||
class="demo-upload-list"
|
||||
@click="handleView(img)"
|
||||
>
|
||||
<img :src="img" loading="lazy" decoding="async" />
|
||||
<div class="demo-upload-list-cover">
|
||||
<el-icon @click="handleView(img)"><View /></el-icon>
|
||||
<el-icon><View /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div v-else>暂无</div>
|
||||
</div>
|
||||
<span v-else class="empty-text">暂无</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<el-alert class="l_title" show-icon type="warning">商家申诉信息</el-alert>
|
||||
<table cellspacing="0" cellpadding='0' border="1">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>申诉时间</td>
|
||||
<td>{{ detail.appealTime || '暂无' }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>申诉内容</td>
|
||||
<td>{{ detail.appealContent || '暂无' }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>申诉凭证</td>
|
||||
<td>
|
||||
|
||||
<div style="display:flex;align-items:center;">
|
||||
<template v-if="detail.appealImages">
|
||||
<div class="demo-upload-list" v-for="(img, index) in detail.appealImages.split(',')" :key="index">
|
||||
<img :src="img" loading="lazy" decoding="async">
|
||||
<section class="panel">
|
||||
<div class="panel-title">商家申诉信息</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">申诉时间</span>
|
||||
<span class="info-value">{{ detail.appealTime || "暂无" }}</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">申诉内容</span>
|
||||
<span class="info-value">{{ detail.appealContent || "暂无" }}</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">申诉凭证</span>
|
||||
<div class="info-value">
|
||||
<div v-if="appealImages.length" class="img-list">
|
||||
<div
|
||||
v-for="(img, index) in appealImages"
|
||||
:key="index"
|
||||
class="demo-upload-list"
|
||||
@click="handleView(img)"
|
||||
>
|
||||
<img :src="img" loading="lazy" decoding="async" />
|
||||
<div class="demo-upload-list-cover">
|
||||
<el-icon @click="handleView(img)"><View /></el-icon>
|
||||
<el-icon><View /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div v-else>暂无</div>
|
||||
</div>
|
||||
<span v-else class="empty-text">暂无</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<el-alert class="l_title" show-icon type="warning">平台仲裁</el-alert>
|
||||
<table cellspacing="0" cellpadding='0' border="1">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>仲裁意见</td>
|
||||
<td>{{ detail.arbitrationResult || '暂无' }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<section class="panel">
|
||||
<div class="panel-title">平台仲裁</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">仲裁意见</span>
|
||||
<span class="info-value">{{ detail.arbitrationResult || "暂无" }}</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<el-alert class="l_title" show-icon type="warning">对话详情</el-alert>
|
||||
<div class="speak-way" v-if="detail.orderComplaintCommunications && detail.orderComplaintCommunications.length">
|
||||
<div
|
||||
class="speak-msg seller"
|
||||
:class="{'speak-buyer': item.owner == 'BUYER', 'speak-platform': item.owner == 'PLATFORM', 'speak-seller': item.owner == 'STORE',}"
|
||||
:key="i"
|
||||
v-for="(item, i) in detail.orderComplaintCommunications"
|
||||
>
|
||||
{{
|
||||
item.owner == "PLATFORM"
|
||||
? "平台"
|
||||
: item.owner == "BUYER"
|
||||
? "买家"
|
||||
: "卖家"
|
||||
}}[{{ item.createTime }}]:
|
||||
<span>{{ item.content }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>暂无对话</div>
|
||||
<table cellspacing="0" cellpadding='0' border="1" v-if="detail.complainStatus!='COMPLETE'">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>回复:</td>
|
||||
<td><label>
|
||||
<input type="textarea" maxlength="200" :rows="4" clearable
|
||||
style="width:260px" v-model="params.content" />
|
||||
</label></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>
|
||||
<el-button type="primary" :loading="submitLoading" @click="handleSubmit" style="margin-left: 5px">
|
||||
<section class="panel">
|
||||
<div class="panel-title">对话详情</div>
|
||||
<div v-if="communications.length" class="chat-list">
|
||||
<div
|
||||
v-for="(item, i) in communications"
|
||||
:key="i"
|
||||
class="chat-item"
|
||||
:class="{
|
||||
'is-buyer': item.owner === 'BUYER',
|
||||
'is-platform': item.owner === 'PLATFORM',
|
||||
}"
|
||||
>
|
||||
<div class="chat-meta">{{ ownerName(item.owner) }} · {{ item.createTime }}</div>
|
||||
<div class="chat-bubble">{{ item.content }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="empty-text">暂无对话</div>
|
||||
|
||||
<div v-if="detail.complainStatus !== 'COMPLETE'" class="reply-box">
|
||||
<el-input
|
||||
v-model="params.content"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
maxlength="200"
|
||||
show-word-limit
|
||||
placeholder="请输入回复内容"
|
||||
/>
|
||||
<el-button
|
||||
type="primary"
|
||||
:loading="submitLoading"
|
||||
class="reply-btn"
|
||||
@click="handleSubmit"
|
||||
>
|
||||
回复
|
||||
</el-button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<el-dialog title="图片预览" v-model="visible">
|
||||
<img :src="previewImage" loading="lazy" decoding="async" v-if="visible" style="width: 100%">
|
||||
</el-dialog>
|
||||
<el-dialog title="图片预览" v-model="visible">
|
||||
<img :src="previewImage" loading="lazy" decoding="async" v-if="visible" style="width: 100%" />
|
||||
</el-dialog>
|
||||
</UserCenterLayout>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted, reactive, ref } from "vue";
|
||||
import { computed, onMounted, reactive, ref } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { Message } from "@/utils/message";
|
||||
import { View } from '@element-plus/icons-vue';
|
||||
import {getComplainDetail} from '@/api/member.js';
|
||||
import {communication} from '@/api/order';
|
||||
import { View } from "@element-plus/icons-vue";
|
||||
import { getComplainDetail } from "@/api/member.js";
|
||||
import { communication } from "@/api/order";
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
||||
const detail = ref({}); // 评价详情
|
||||
const detail = ref({}); // 投诉详情
|
||||
const visible = ref(false); // 图片预览
|
||||
const previewImage = ref(''); // 预览图片地址
|
||||
const loading = ref(false); // 加载状态
|
||||
const previewImage = ref(""); // 预览图片地址
|
||||
const submitLoading = ref(false); // 回复消息loading
|
||||
// 状态
|
||||
const statusLabel = {
|
||||
NO_APPLY: '未申请',
|
||||
APPLYING: '申请中',
|
||||
COMPLETE: '已完成',
|
||||
EXPIRED: '已失效',
|
||||
CANCEL: '已取消',
|
||||
NEW: '待审核'
|
||||
NO_APPLY: "未申请",
|
||||
APPLYING: "申请中",
|
||||
COMPLETE: "已完成",
|
||||
EXPIRED: "已失效",
|
||||
CANCEL: "已取消",
|
||||
NEW: "待审核",
|
||||
};
|
||||
// 商家回复内容
|
||||
const params = reactive({
|
||||
content: '',
|
||||
complainId: ''
|
||||
content: "",
|
||||
complainId: "",
|
||||
});
|
||||
|
||||
function getDetail () { // 获取投诉详情
|
||||
getComplainDetail(route.query.id).then(res => {
|
||||
if (res.success) detail.value = res.result
|
||||
})
|
||||
const statusText = computed(
|
||||
() => statusLabel[detail.value.complainStatus] || detail.value.complainStatus || ""
|
||||
);
|
||||
const statusTagType = computed(() => {
|
||||
const map = {
|
||||
COMPLETE: "success",
|
||||
APPLYING: "warning",
|
||||
NEW: "warning",
|
||||
CANCEL: "info",
|
||||
EXPIRED: "info",
|
||||
NO_APPLY: "info",
|
||||
};
|
||||
return map[detail.value.complainStatus] || "info";
|
||||
});
|
||||
const images = computed(() =>
|
||||
detail.value.images ? detail.value.images.split(",").filter(Boolean) : []
|
||||
);
|
||||
const appealImages = computed(() =>
|
||||
detail.value.appealImages ? detail.value.appealImages.split(",").filter(Boolean) : []
|
||||
);
|
||||
const communications = computed(() =>
|
||||
Array.isArray(detail.value.orderComplaintCommunications)
|
||||
? detail.value.orderComplaintCommunications
|
||||
: []
|
||||
);
|
||||
|
||||
function ownerName(owner) {
|
||||
return owner === "PLATFORM" ? "平台" : owner === "BUYER" ? "买家" : "卖家";
|
||||
}
|
||||
function goGoodsDetail (skuId, goodsId) { // 跳转商品详情
|
||||
|
||||
function getDetail() {
|
||||
// 获取投诉详情
|
||||
getComplainDetail(route.query.id).then((res) => {
|
||||
if (res.success) detail.value = res.result;
|
||||
});
|
||||
}
|
||||
function goGoodsDetail(skuId, goodsId) {
|
||||
// 跳转商品详情
|
||||
let routerUrl = router.resolve({
|
||||
path: '/goodsDetail',
|
||||
query: {skuId, goodsId}
|
||||
})
|
||||
window.open(routerUrl.href, '_blank')
|
||||
path: "/goodsDetail",
|
||||
query: { skuId, goodsId },
|
||||
});
|
||||
window.open(routerUrl.href, "_blank");
|
||||
}
|
||||
function handleView (name) { // 预览图片
|
||||
function handleView(name) {
|
||||
// 预览图片
|
||||
previewImage.value = name;
|
||||
visible.value = true;
|
||||
}
|
||||
// 回复消息
|
||||
function handleSubmit () {
|
||||
if (params.content === '') {
|
||||
Message.error('请填写对话内容');
|
||||
function handleSubmit() {
|
||||
if (params.content === "") {
|
||||
Message.error("请填写对话内容");
|
||||
return;
|
||||
}
|
||||
submitLoading.value = true;
|
||||
@@ -187,64 +226,129 @@ function handleSubmit () {
|
||||
communication(params).then((res) => {
|
||||
submitLoading.value = false;
|
||||
if (res.success) {
|
||||
Message.success('对话成功');
|
||||
params.content = '';
|
||||
Message.success("对话成功");
|
||||
params.content = "";
|
||||
getDetail();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getDetail()
|
||||
})
|
||||
getDetail();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.speak-way {
|
||||
background-color: #fff;
|
||||
width: 100%;
|
||||
border: 1px solid #999;
|
||||
.detail-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
|
||||
.speak-seller {
|
||||
background-color: #fff2c6;
|
||||
}
|
||||
.create-time {
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.speak-platform {
|
||||
background-color: #ffe2d1;
|
||||
}
|
||||
.panel {
|
||||
margin-top: 16px;
|
||||
border: 1px solid #eee;
|
||||
border-radius: 8px;
|
||||
background: #fff;
|
||||
padding: 16px 20px;
|
||||
}
|
||||
|
||||
.speak-buyer {
|
||||
background-color: #c1d6d5;
|
||||
.panel-title {
|
||||
color: #333;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
line-height: 24px;
|
||||
padding-bottom: 12px;
|
||||
border-bottom: 1px solid #f5f5f5;
|
||||
}
|
||||
|
||||
.info-row {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
padding: 12px 0;
|
||||
border-bottom: 1px solid #f5f5f5;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.speak-msg {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
padding: 0 5px;
|
||||
border-radius: 5px;
|
||||
margin: 5px;
|
||||
background-color: #eee;
|
||||
.info-label {
|
||||
flex: 0 0 80px;
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
color: #333;
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.goods-info {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 0;
|
||||
border: none;
|
||||
background: none;
|
||||
cursor: pointer;
|
||||
|
||||
img {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
border-radius: 6px;
|
||||
background: #f5f5f5;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.goods-name {
|
||||
color: #333;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
&:hover .goods-name {
|
||||
color: $theme_color;
|
||||
}
|
||||
}
|
||||
|
||||
.img-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.demo-upload-list {
|
||||
display: inline-block;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
text-align: center;
|
||||
line-height: 100px;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 4px;
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
background: #f5f5f5;
|
||||
position: relative;
|
||||
box-shadow: 0 1px 1px rgba(0, 0, 0, .2);
|
||||
margin-right: 4px;
|
||||
margin-top: 10px;
|
||||
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.demo-upload-list img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.demo-upload-list-cover {
|
||||
@@ -254,51 +358,70 @@ onMounted(() => {
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: rgba(0, 0, 0, .6);
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #fff;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.demo-upload-list:hover .demo-upload-list-cover {
|
||||
display: block;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.demo-upload-list-cover i {
|
||||
color: #fff;
|
||||
font-size: 30px;
|
||||
cursor: pointer;
|
||||
margin: 0 2px;
|
||||
.chat-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
padding: 16px 0 4px;
|
||||
}
|
||||
|
||||
.icon-upload {
|
||||
width: 58px;
|
||||
height: 58px;
|
||||
line-height: 58px;
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
border: 1px dashed #999;
|
||||
border-radius: 4px;
|
||||
margin-top: 10px;
|
||||
.chat-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
max-width: 80%;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
border-color: $theme_color;
|
||||
}
|
||||
}
|
||||
&.is-buyer {
|
||||
align-self: flex-end;
|
||||
align-items: flex-end;
|
||||
|
||||
.l_title {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-color: #eee;
|
||||
|
||||
td {
|
||||
padding: 10px;
|
||||
|
||||
&:nth-child(1) {
|
||||
width: 120px;
|
||||
color: #999;
|
||||
.chat-bubble {
|
||||
background: $theme_color;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
&.is-platform .chat-bubble {
|
||||
background: #fdf3e4;
|
||||
color: #8a5a00;
|
||||
}
|
||||
}
|
||||
|
||||
.chat-meta {
|
||||
margin-bottom: 4px;
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
.chat-bubble {
|
||||
padding: 8px 12px;
|
||||
border-radius: 8px;
|
||||
background: #f5f5f5;
|
||||
color: #333;
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.reply-box {
|
||||
margin-top: 16px;
|
||||
padding-top: 16px;
|
||||
border-top: 1px solid #f5f5f5;
|
||||
}
|
||||
|
||||
.reply-btn {
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user