Browse Source

feat(评论): 实现评论详情页及店铺二维码功能

- 新增评论详情页面,支持查看主评论及回复列表
- 添加店铺二维码页面,支持生成和保存二维码
- 重构评论相关API到独立模块
- 更新导航栏样式和颜色变量
- 修改项目规则文档,统一使用uni.scss颜色变量
master
主管理员 2 weeks ago
parent
commit
e1ac388643
12 changed files with 964 additions and 106 deletions
  1. +1
    -6
      .trae/rules/project_rules.md
  2. +4
    -93
      api/api.js
  3. +25
    -0
      api/model/comment.js
  4. +1
    -1
      components/base/navbar.vue
  5. +1
    -1
      config.js
  6. +14
    -0
      pages.json
  7. +623
    -0
      pages_order/comment/commentDetail.vue
  8. +9
    -4
      pages_order/components/list/comment/commentItem.vue
  9. +3
    -0
      pages_order/components/list/comment/commentList.vue
  10. +27
    -0
      pages_order/gourmet/gourmetDetail.vue
  11. +255
    -0
      pages_order/gourmet/qrCode.vue
  12. +1
    -1
      uni.scss

+ 1
- 6
.trae/rules/project_rules.md View File

@ -1,6 +1 @@
功能模块
同城群:显示各个地区同城群聊的基本信息,不需要实时聊天、不需要加入群聊、点击进行播放广告看完广告显示群聊二维码
项目中有关颜色的都使用uni.scss的$uni-color变量

+ 4
- 93
api/api.js View File

@ -1,5 +1,6 @@
import http from './http.js'
import utils from '../utils/utils.js'
import commentApi from './model/comment.js'
let limit = {}
@ -158,11 +159,6 @@ const config = {
url: '/city/getScenicDetail',
method: 'GET',
},
//获取评论列表type-0帖子-1租房-2工作-3景点-4美食-5活动-6人找车-7车找人
getCommentPage: {
url: '/city/getCommentPage',
method: 'GET',
},
//获取江华人信息接口
getJiangHuInfo: {
url: '/city/getJiangHuInfo',
@ -212,14 +208,6 @@ const config = {
auth : true,
showLoading : true,
},
//发布评论
addComment: {
url: '/token/addComment',
method: 'POST',
limit : 1000,
auth : true,
showLoading : true,
},
//发布租房信息
publishRent: {
url: '/token/publishRent',
@ -445,86 +433,6 @@ const config = {
auth : true,
showLoading : true,
},
// 获取群组列表
getGroupList : {
url: '/group/getGroupList',
method: 'GET',
auth : false,
limit : 1000,
},
// 获取群组详情
getGroupDetail : {
url: '/group/getGroupDetail',
method: 'GET',
auth : true,
limit : 1000,
},
// 加入群组
joinGroup : {
url: '/group/joinGroup',
method: 'POST',
auth : true,
showLoading : true,
},
// 退出群组
quitGroup : {
url: '/group/quitGroup',
method: 'POST',
auth : true,
showLoading : true,
},
// 创建群组
createGroup : {
url: '/group/createGroup',
method: 'POST',
auth : true,
showLoading : true,
},
// 发送群组消息
sendGroupMessage : {
url: '/group/sendMessage',
method: 'POST',
auth : true,
showLoading : false,
},
// 获取群组消息列表
getGroupMessages : {
url: '/group/getMessages',
method: 'GET',
auth : true,
limit : 1000,
},
// 更新群组公告
updateGroupAnnouncement : {
url: '/group/updateAnnouncement',
method: 'POST',
auth : true,
showLoading : true,
},
// 解散群组
dissolveGroup : {
url: '/group/dissolveGroup',
method: 'POST',
auth : true,
showLoading : true,
},
// 转让群主
transferGroup : {
url: '/group/transferGroup',
method: 'POST',
auth : true,
showLoading : true,
},
}
const models = ['order', 'group', 'article']
@ -610,6 +518,9 @@ function addApiModel(model, key){
}
}
// 添加评论模块API
addApiModel(commentApi, 'comment')
export default api

+ 25
- 0
api/model/comment.js View File

@ -0,0 +1,25 @@
// 评论相关接口
const api = {
// 获取评论详情
getCommentDetail: {
url: '/token/commentDetail',
method: 'GET',
auth: true,
},
//发布评论
addComment: {
url: '/token/addComment',
method: 'POST',
limit : 1000,
auth : true,
showLoading : true,
},
//获取评论列表type-0帖子-1租房-2工作-3景点-4美食-5活动-6人找车-7车找人-8文章
getCommentPage: {
url: '/city/getCommentPage',
method: 'GET',
},
}
export default api

+ 1
- 1
components/base/navbar.vue View File

@ -2,7 +2,7 @@
<!-- <view class="navbar"
:style="{backgroundColor : bgColor}"> -->
<view class="title"
:style="{background : bgColor, color}">
:style="{background : bgColor, color, width: '100vw'}">
<view class="left">
<uv-icon name="home"


+ 1
- 1
config.js View File

@ -7,7 +7,7 @@ import uvUI from '@/uni_modules/uv-ui-tools'
Vue.use(uvUI);
// 当前环境
const type = 'local'
const type = 'prod'
// 环境配置


+ 14
- 0
pages.json View File

@ -245,6 +245,20 @@
"navigationBarTitleText": "文章详情",
"enablePullDownRefresh": false
}
},
{
"path": "gourmet/qrCode",
"style": {
"navigationBarTitleText": "店铺二维码",
"enablePullDownRefresh": false
}
},
{
"path": "comment/commentDetail",
"style": {
"navigationBarTitleText": "评论详情",
"enablePullDownRefresh": true
}
}
]
}],


+ 623
- 0
pages_order/comment/commentDetail.vue View File

@ -0,0 +1,623 @@
<template>
<view class="comment-detail-container">
<navbar :title="pageTitle" leftClick @leftClick="navigateBack"/>
<!-- 加载状态 -->
<view class="loading-container" v-if="loading">
<view class="loading-spinner"></view>
<text class="loading-text">加载中...</text>
</view>
<!-- 错误状态 -->
<view class="error-container" v-if="!loading && hasError">
<text class="error-text">加载失败请重试</text>
<button class="retry-button" @click="loadCommentDetail">重新加载</button>
</view>
<!-- 主评论内容 -->
<view class="main-comment" v-if="!loading && !hasError && mainComment">
<view class="comment-header">
<image class="avatar" :src="mainComment.userHead || '/static/image/center/default-avatar.png'" mode="aspectFill"></image>
<view class="user-info">
<text class="username">{{mainComment.userName}}</text>
<text class="time">{{formatTime(mainComment.createTime)}}</text>
</view>
</view>
<view class="comment-content">
<text>{{mainComment.userValue}}</text>
</view>
<!-- 评论图片 -->
<view class="comment-images" v-if="mainComment.userImage">
<view class="image-grid">
<image
v-for="(img, index) in mainComment.userImage.split(',')"
:key="index"
:src="img"
mode="aspectFill"
@click="previewImage(mainComment.userImage.split(','), index)"
class="comment-image"
></image>
</view>
</view>
<view class="comment-footer">
<text class="reply-count">{{totalReplies}}条回复</text>
<view class="reply-btn" @click="showReplyInput(mainComment.id, mainComment.userName)">
<uv-icon name="chat" color="#666" size="32rpx"></uv-icon>
<text>回复</text>
</view>
</view>
</view>
<!-- 回复列表 -->
<view class="replies-container" v-if="!loading && !hasError && commentList.length > 0">
<view class="reply-item" v-for="(item, index) in commentList" :key="index">
<view class="reply-header">
<image class="avatar" :src="item.userHead || '/static/image/center/default-avatar.png'" mode="aspectFill"></image>
<view class="user-info">
<text class="username">{{item.userName}}</text>
<text class="time">{{formatTime(item.createTime)}}</text>
</view>
</view>
<view class="reply-content">
<view v-if="item.replyToUserName" class="reply-to">
<text>回复 </text>
<text class="reply-username">@{{item.replyToUserName}}</text>
<text></text>
</view>
<text>{{item.userValue}}</text>
</view>
<!-- 回复图片 -->
<view class="reply-images" v-if="item.userImage">
<view class="image-grid">
<image
v-for="(img, imgIndex) in item.userImage.split(',')"
:key="imgIndex"
:src="img"
mode="aspectFill"
@click="previewImage(item.userImage.split(','), imgIndex)"
class="reply-image"
></image>
</view>
</view>
<view class="reply-footer">
<view class="reply-info">
<text v-if="item.replyNum > 0" class="sub-reply-count" @click="navigateToSubComment(item)">
{{item.replyNum}}条回复 >
</text>
</view>
<view class="reply-btn" @click="showReplyInput(item.id, item.userName)">
<uv-icon name="chat" color="#666" size="28rpx"></uv-icon>
<text>回复</text>
</view>
</view>
</view>
</view>
<!-- 加载更多 -->
<view class="load-more" v-if="!loading && !hasError && hasMore">
<text @click="loadMoreReplies">加载更多</text>
</view>
<!-- 回复输入框 -->
<view class="reply-input-container" v-if="showInput">
<view class="input-wrapper">
<input
class="reply-input"
v-model="replyContent"
:placeholder="replyPlaceholder"
focus
confirm-type="send"
@confirm="submitReply"
/>
<button class="send-btn" :disabled="!replyContent.trim()" @click="submitReply">发送</button>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
commentId: '', // ID
parentId: '', // ID
sourceType: '', //
sourceId: '', // ID
pageTitle: '评论详情',
loading: true,
hasError: false,
mainComment: null, //
commentList: [], //
page: 1,
pageSize: 20,
hasMore: false,
totalReplies: 0,
//
showInput: false,
replyContent: '',
replyToId: '', // ID
replyToUserName: '', //
replyPlaceholder: '写回复...'
}
},
onLoad(options) {
//
if (options.id) {
this.commentId = options.id;
}
if (options.parentId) {
this.parentId = options.parentId;
}
if (options.sourceType) {
this.sourceType = options.sourceType;
}
if (options.sourceId) {
this.sourceId = options.sourceId;
}
//
this.loadCommentDetail();
//
this.loadReplies();
},
methods: {
//
loadCommentDetail() {
this.loading = true;
this.hasError = false;
// API
this.$api('getCommentDetail', {
id: this.commentId
}, res => {
this.loading = false;
if (res.code === 200) {
this.mainComment = res.result;
//
this.totalReplies = res.result.replyNum || 0;
} else {
this.hasError = true;
uni.showToast({
title: res.message || '加载失败',
icon: 'none'
});
}
});
},
//
loadReplies() {
// 使pid
this.$api('getCommentPage', {
pid: this.commentId,
page: this.page,
pageSize: this.pageSize
}, res => {
if (res.code === 200) {
if (this.page === 1) {
this.commentList = res.result.records || [];
} else {
this.commentList = [...this.commentList, ...(res.result.records || [])];
}
//
this.hasMore = this.commentList.length < res.result.total;
} else {
uni.showToast({
title: res.message || '加载回复失败',
icon: 'none'
});
}
});
},
//
loadMoreReplies() {
this.page++;
this.loadReplies();
},
//
showReplyInput(commentId, userName = '') {
this.showInput = true;
this.replyToId = commentId;
this.replyToUserName = userName;
this.replyPlaceholder = userName ? `回复 @${userName}` : '写回复...';
this.replyContent = '';
},
//
submitReply() {
if (!this.replyContent.trim()) return;
// API
this.$api('addComment', {
userValue: this.replyContent,
pid: this.commentId,
replyToId: this.replyToId,
replyToUserName: this.replyToUserName,
type: this.sourceType,
orderId: this.sourceId
}, res => {
if (res.code === 200) {
//
this.replyContent = '';
this.showInput = false;
//
this.page = 1;
this.loadReplies();
//
this.totalReplies++;
uni.showToast({
title: '回复成功',
icon: 'success'
});
} else {
uni.showToast({
title: res.message || '回复失败',
icon: 'none'
});
}
});
},
//
navigateToSubComment(comment) {
if (comment.replyNum > 0) {
uni.navigateTo({
url: `/pages_order/comment/commentDetail?id=${comment.id}&parentId=${this.commentId}&sourceType=${this.sourceType}&sourceId=${this.sourceId}`
});
}
},
//
navigateBack() {
uni.navigateBack();
},
//
previewImage(images, index) {
uni.previewImage({
urls: images,
current: index
});
},
//
formatTime(timestamp) {
if (!timestamp) return '';
const now = new Date().getTime();
const diff = now - timestamp;
// 1
if (diff < 60000) {
return '刚刚';
}
// 1
if (diff < 3600000) {
return Math.floor(diff / 60000) + '分钟前';
}
// 24
if (diff < 86400000) {
return Math.floor(diff / 3600000) + '小时前';
}
// 30
if (diff < 2592000000) {
return Math.floor(diff / 86400000) + '天前';
}
// 30
const date = new Date(timestamp);
return `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`;
}
}
}
</script>
<style lang="scss" scoped>
.comment-detail-container {
display: flex;
flex-direction: column;
min-height: 100vh;
background-color: #f5f5f5;
padding-bottom: 100rpx;
}
.loading-container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin-top: 200rpx;
.loading-spinner {
width: 80rpx;
height: 80rpx;
border: 6rpx solid #f3f3f3;
border-top: 6rpx solid $uni-color-primary;
border-radius: 50%;
animation: spin 1s linear infinite;
margin-bottom: 20rpx;
}
.loading-text {
font-size: 28rpx;
color: #666;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
}
.error-container {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 200rpx;
.error-text {
font-size: 28rpx;
color: #999;
margin-bottom: 30rpx;
}
.retry-button {
background-color: $uni-color-primary;
color: #fff;
font-size: 28rpx;
padding: 16rpx 40rpx;
border-radius: 40rpx;
border: none;
}
}
.main-comment {
background-color: #fff;
padding: 30rpx;
margin-bottom: 20rpx;
.comment-header {
display: flex;
align-items: center;
margin-bottom: 20rpx;
.avatar {
width: 80rpx;
height: 80rpx;
border-radius: 50%;
margin-right: 20rpx;
background-color: #f0f0f0;
}
.user-info {
flex: 1;
.username {
font-size: 28rpx;
font-weight: bold;
color: #333;
margin-bottom: 6rpx;
}
.time {
font-size: 24rpx;
color: #999;
}
}
}
.comment-content {
font-size: 30rpx;
color: #333;
line-height: 1.6;
margin-bottom: 20rpx;
}
.comment-images {
margin-bottom: 20rpx;
.image-grid {
display: flex;
flex-wrap: wrap;
.comment-image {
width: 200rpx;
height: 200rpx;
margin-right: 10rpx;
margin-bottom: 10rpx;
border-radius: 8rpx;
background-color: #f0f0f0;
}
}
}
.comment-footer {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 20rpx;
border-top: 1px solid #f0f0f0;
.reply-count {
font-size: 26rpx;
color: #666;
}
.reply-btn {
display: flex;
align-items: center;
text {
font-size: 26rpx;
color: #666;
margin-left: 6rpx;
}
}
}
}
.replies-container {
background-color: #fff;
.reply-item {
padding: 30rpx;
border-bottom: 1px solid #f0f0f0;
&:active {
background-color: #f9f9f9;
}
.reply-header {
display: flex;
align-items: center;
margin-bottom: 16rpx;
.avatar {
width: 70rpx;
height: 70rpx;
border-radius: 50%;
margin-right: 16rpx;
background-color: #f0f0f0;
}
.user-info {
flex: 1;
.username {
font-size: 26rpx;
font-weight: bold;
color: #333;
margin-bottom: 4rpx;
}
.time {
font-size: 22rpx;
color: #999;
}
}
}
.reply-content {
font-size: 28rpx;
color: #333;
line-height: 1.5;
margin-bottom: 16rpx;
padding-left: 86rpx;
.reply-to {
display: inline;
.reply-username {
color: $uni-color-primary;
}
}
}
.reply-images {
padding-left: 86rpx;
margin-bottom: 16rpx;
.image-grid {
display: flex;
flex-wrap: wrap;
.reply-image {
width: 150rpx;
height: 150rpx;
margin-right: 10rpx;
margin-bottom: 10rpx;
border-radius: 8rpx;
background-color: #f0f0f0;
}
}
}
.reply-footer {
display: flex;
justify-content: space-between;
align-items: center;
padding-left: 86rpx;
.reply-info {
.sub-reply-count {
font-size: 24rpx;
color: $uni-color-primary;
}
}
.reply-btn {
display: flex;
align-items: center;
text {
font-size: 24rpx;
color: #666;
margin-left: 4rpx;
}
}
}
}
}
.load-more {
text-align: center;
padding: 30rpx 0;
text {
font-size: 26rpx;
color: #666;
}
}
.reply-input-container {
position: fixed;
bottom: 0;
left: 0;
right: 0;
background-color: #fff;
padding: 20rpx 30rpx;
box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
z-index: 100;
padding-bottom: env(safe-area-inset-bottom);
.input-wrapper {
display: flex;
align-items: center;
.reply-input {
flex: 1;
height: 70rpx;
background-color: #f5f5f5;
border-radius: 35rpx;
padding: 0 30rpx;
font-size: 28rpx;
}
.send-btn {
margin-left: 20rpx;
background-color: $uni-color-primary;
color: #fff;
font-size: 28rpx;
height: 70rpx;
line-height: 70rpx;
padding: 0 30rpx;
border-radius: 35rpx;
&[disabled] {
background-color: #cccccc;
}
}
}
}
</style>

+ 9
- 4
pages_order/components/list/comment/commentItem.vue View File

@ -1,5 +1,5 @@
<template>
<view class="comment">
<view class="comment" @click="navigateToSubComment(item)">
<view class="box">
<view class="headPortraitimg">
<image :src="item.userHead"
@ -36,7 +36,7 @@
<script>
export default {
props : ['item'],
props : ['item', 'parentId', 'sourceType', 'sourceId'],
data() {
return {
@ -48,10 +48,15 @@
return []
}
return this.item.userImage.split(',')
}
},
},
methods: {
//
navigateToSubComment(comment) {
uni.navigateTo({
url: `/pages_order/comment/commentDetail?id=${comment.id}&parentId=${this.parentId}&sourceType=${this.sourceType}&sourceId=${this.sourceId}`
});
},
}
}
</script>


+ 3
- 0
pages_order/components/list/comment/commentList.vue View File

@ -4,6 +4,9 @@
<commentItem
v-for="(item,index) in list"
:key="index"
:parentId="item.id"
:sourceType="params.type"
:sourceId="params.orderId"
:item="item" />
</view>


+ 27
- 0
pages_order/gourmet/gourmetDetail.vue View File

@ -87,6 +87,12 @@
:phoneTitle="detail.title"
:pid="detail.id"
title="联系店家" />
<!-- 二维码入口 -->
<view class="qrcode-btn" @click="goToQrCode">
<uv-icon name="scan" size="30rpx" color="#3B5CF0"></uv-icon>
<text>店铺二维码</text>
</view>
</view>
</view>
@ -184,6 +190,12 @@
// }
},
methods: {
//
goToQrCode() {
uni.navigateTo({
url: `/pages_order/gourmet/qrCode?id=${this.id}`
});
},
tabsClick(item) {
this.tagIndex = item.value
@ -314,6 +326,21 @@
padding: 20rpx;
background-color: #fff;
border-radius: 30rpx;
.qrcode-btn {
display: flex;
align-items: center;
background-color: #f0f5ff;
padding: 10rpx 20rpx;
border-radius: 30rpx;
margin-top: 15rpx;
text {
font-size: 24rpx;
color: #3B5CF0;
margin-left: 10rpx;
}
}
.dynamics {
margin-top: 20rpx;
font-size: 28rpx;


+ 255
- 0
pages_order/gourmet/qrCode.vue View File

@ -0,0 +1,255 @@
<template>
<view class="qrcode-container">
<navbar title="店铺二维码" leftClick @leftClick="$utils.navigateBack"/>
<!-- 加载状态 -->
<view class="loading-container" v-if="loading">
<view class="loading-spinner"></view>
<text class="loading-text">加载中...</text>
</view>
<!-- 二维码图片 -->
<view class="qrcode-wrapper" v-if="qrCodeUrl">
<image
class="qrcode-image"
:src="qrCodeUrl"
mode="aspectFit"
@load="imageLoaded"
@error="imageError"
@longpress="saveImage"
></image>
<text class="qrcode-tip" v-if="!loading && qrCodeUrl">扫描二维码查看店铺详情</text>
<text class="save-tip" v-if="!loading && qrCodeUrl">长按图片可保存到相册</text>
</view>
<!-- 错误状态 -->
<view class="error-container" v-if="!loading && !qrCodeUrl && hasError">
<text class="error-text">二维码加载失败请重试</text>
<button class="retry-button" @click="loadQrCode">重新加载</button>
</view>
</view>
</template>
<script>
export default {
data() {
return {
shopId: '',
qrCodeUrl: '',
loading: true,
hasError: false,
}
},
onLoad(options) {
if (options.id) {
this.shopId = options.id;
this.loadQrCode();
} else {
this.loading = false;
this.hasError = true;
uni.showToast({
title: '缺少店铺ID参数',
icon: 'none'
});
}
},
methods: {
//
loadQrCode() {
if (!this.shopId) return;
this.loading = true;
this.hasError = false;
// 使
this.qrCodeUrl = `${this.$config.baseUrl}/city/shop/shopQrCode?id=${this.shopId}`;
// imageimageLoadedimageError
},
//
imageLoaded() {
this.loading = false;
},
//
imageError() {
this.loading = false;
this.hasError = true;
this.qrCodeUrl = '';
uni.showToast({
title: '二维码加载失败',
icon: 'none'
});
},
//
saveImage() {
if (!this.qrCodeUrl) return;
uni.showLoading({
title: '保存中...'
});
//
uni.downloadFile({
url: this.qrCodeUrl,
success: (res) => {
if (res.statusCode === 200) {
//
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: () => {
uni.hideLoading();
uni.showToast({
title: '保存成功',
icon: 'success'
});
},
fail: (err) => {
uni.hideLoading();
console.error('保存图片失败:', err);
//
if (err.errMsg.indexOf('auth deny') >= 0 || err.errMsg.indexOf('authorize') >= 0) {
this.showAuthModal();
} else {
uni.showToast({
title: '保存失败',
icon: 'none'
});
}
}
});
} else {
uni.hideLoading();
uni.showToast({
title: '图片下载失败',
icon: 'none'
});
}
},
fail: () => {
uni.hideLoading();
uni.showToast({
title: '图片下载失败',
icon: 'none'
});
}
});
},
//
showAuthModal() {
uni.showModal({
title: '提示',
content: '保存图片需要您授权访问相册权限',
confirmText: '去授权',
cancelText: '取消',
success: (res) => {
if (res.confirm) {
//
uni.openSetting({
success: (settingRes) => {
console.log('设置页面成功打开:', settingRes);
}
});
}
}
});
}
}
}
</script>
<style lang="scss" scoped>
.qrcode-container {
display: flex;
flex-direction: column;
align-items: center;
min-height: 100vh;
background-color: #f5f5f5;
padding: 30rpx;
}
.loading-container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin-top: 200rpx;
.loading-spinner {
width: 80rpx;
height: 80rpx;
border: 6rpx solid #f3f3f3;
border-top: 6rpx solid #3B5CF0;
border-radius: 50%;
animation: spin 1s linear infinite;
margin-bottom: 20rpx;
}
.loading-text {
font-size: 28rpx;
color: #666;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
}
.qrcode-wrapper {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 100rpx;
background-color: #fff;
padding: 40rpx;
border-radius: 16rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.1);
.qrcode-image {
width: 500rpx;
height: 500rpx;
margin-bottom: 30rpx;
}
.qrcode-tip {
font-size: 28rpx;
color: #666;
margin-top: 20rpx;
}
.save-tip {
font-size: 24rpx;
color: $uni-color-primary;
margin-top: 10rpx;
}
}
.error-container {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 200rpx;
.error-text {
font-size: 28rpx;
color: #999;
margin-bottom: 30rpx;
}
.retry-button {
background-color: #3B5CF0;
color: #fff;
font-size: 28rpx;
padding: 16rpx 40rpx;
border-radius: 40rpx;
border: none;
}
}
</style>

+ 1
- 1
uni.scss View File

@ -16,7 +16,7 @@ $uni-color: #5baaff;
$uni-price-color: #D03F25;
/* 行为相关颜色 */
$uni-color-primary: #1671ff;
$uni-color-primary: #5baaff;
$uni-color-success: #4cd964;
$uni-color-warning: #f0ad4e;
$uni-color-error: #dd524d;


Loading…
Cancel
Save