fix: 点赞点踩记录

main
wx-jincw 7 days ago
parent 1babd09c72
commit 75e88dc3ca

@ -38,7 +38,6 @@
}, },
"dependencies": { "dependencies": {
"@babel/parser": "^7.9.6", "@babel/parser": "^7.9.6",
"@element-plus/icons-vue": "^2.3.2",
"@riophae/vue-treeselect": "0.4.0", "@riophae/vue-treeselect": "0.4.0",
"async-validator": "^1.11.2", "async-validator": "^1.11.2",
"axios": "^0.24.0", "axios": "^0.24.0",

@ -81,9 +81,9 @@
{{ scope.row.userName || `用户${scope.row.userId}` }} {{ scope.row.userName || `用户${scope.row.userId}` }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="menuDate" header-align="center" align="center" label="点踩日期"> <el-table-column prop="createTime" header-align="center" align="center" label="点踩日期">
<template slot-scope="scope"> <template slot-scope="scope">
{{ formatDateString(scope.row.menuDate) }} {{ formatDateString(scope.row.createTime) }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="remark" header-align="center" align="center" label="意见"></el-table-column> <el-table-column prop="remark" header-align="center" align="center" label="意见"></el-table-column>

@ -74,6 +74,15 @@ export function getDailyMenuRanking(params) {
); );
} }
// 点赞/点踩记录列表
export function listDailyMenuLikeRecords(params) {
return request.get(
'autogencode/pmdailymenudtllike/list',
params,
{ useAdminUrl: true }
);
}
// 报修记录 - 列表 // 报修记录 - 列表
export function listMaintenanceOrder(params) { export function listMaintenanceOrder(params) {
return request.get( return request.get(

@ -0,0 +1,325 @@
<template>
<view class="like-record-popup">
<uni-popup ref="popup" type="bottom" :safe-area="false" :mask-click="true">
<view class="popup-content">
<view class="popup-header">
<text class="popup-title">{{ title }}</text>
<view class="close-btn" @click="close"></view>
</view>
<scroll-view scroll-y class="list-container">
<view v-if="records.length" class="record-list">
<view v-for="item in records" :key="item.id" class="record-item">
<view class="record-header">
<view class="user-info">
<view class="avatar">
<text class="avatar-text">{{ item.userName ? item.userName.charAt(0) : '?' }}</text>
</view>
<view class="user-detail">
<text class="user-name">{{ item.userName || '未知用户' }}</text>
</view>
</view>
<text class="record-time">{{ formatTime(item.createTime) }}</text>
</view>
<view class="record-remark" v-if="item.remark">
<text class="remark-label">意见</text>
<text class="remark-content">{{ item.remark }}</text>
</view>
</view>
</view>
<view v-else class="empty-state">
<image src="/static/images/wg/empty.png" class="empty-icon" />
<text class="empty-text">暂无{{ likeType === '1' ? '点赞' : '点踩' }}记录</text>
</view>
</scroll-view>
<view class="footer" v-if="total > 0">
<text class="page-info"> {{ total }} 条记录</text>
</view>
</view>
</uni-popup>
</view>
</template>
<script>
import { listDailyMenuLikeRecords } from '@/api/property.js';
export default {
name: 'LikeRecordPopup',
props: {
menuDtlId: {
type: [String, Number],
default: ''
},
itemName: {
type: String,
default: ''
},
likeType: {
type: String,
default: '1'
}
},
data() {
return {
records: [],
total: 0,
page: 1,
limit: 20
};
},
computed: {
title() {
return `${this.itemName || '菜品'}${this.likeType === '1' ? '点赞' : '点踩'}记录`;
}
},
methods: {
open() {
this.page = 1;
this.loadRecords();
this.$nextTick(() => {
this.$refs.popup.open();
});
},
close() {
this.$refs.popup.close();
this.$emit('close');
},
async loadRecords() {
this.records = [];
this.total = 0;
if (!this.menuDtlId) return;
try {
uni.showLoading({ title: '加载中...', mask: true });
const res = await listDailyMenuLikeRecords({
page: this.page,
limit: this.limit,
menuDtlId: this.menuDtlId,
likeType: this.likeType
});
const data = res?.data || {};
this.records = data.list || [];
this.total = data.total || 0;
} catch (e) {
console.error('加载记录失败:', e);
this.records = [];
this.total = 0;
} finally {
uni.hideLoading();
}
},
formatTime(time) {
if (!time) return '';
const date = new Date(time.replace(/-/g, '/'));
const y = date.getFullYear();
const m = `${date.getMonth() + 1}`.padStart(2, '0');
const d = `${date.getDate()}`.padStart(2, '0');
const h = `${date.getHours()}`.padStart(2, '0');
const min = `${date.getMinutes()}`.padStart(2, '0');
return `${y}-${m}-${d} ${h}:${min}`;
}
}
};
</script>
<style lang="scss" scoped>
.like-record-popup {
.popup-content {
background: #fff;
border-radius: 32rpx 32rpx 0 0;
max-height: 70vh;
display: flex;
flex-direction: column;
}
.popup-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 32rpx;
border-bottom: 1rpx solid #f2f3f7;
position: relative;
.popup-title {
font-size: 32rpx;
font-weight: 600;
color: #1f2937;
}
.close-btn {
width: 56rpx;
height: 56rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 28rpx;
color: #9ca3af;
cursor: pointer;
&:active {
opacity: 0.7;
}
}
}
.type-tabs {
display: flex;
padding: 20rpx 32rpx;
gap: 20rpx;
background: #f9fafb;
.type-tab {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
gap: 12rpx;
padding: 20rpx;
border-radius: 12rpx;
font-size: 28rpx;
color: #6b7280;
background: #fff;
transition: all 0.3s;
cursor: pointer;
.tab-icon {
width: 32rpx;
height: 32rpx;
}
&.active {
background: #3b82f6;
color: #fff;
}
}
}
.list-container {
flex: 1;
padding: 0 32rpx;
overflow-y: auto;
}
.record-list {
padding: 20rpx 0;
}
.record-item {
padding: 24rpx 0;
border-bottom: 1rpx solid #f2f3f7;
&:last-child {
border-bottom: none;
}
}
.record-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 12rpx;
}
.user-info {
display: flex;
align-items: center;
gap: 16rpx;
}
.avatar {
width: 72rpx;
height: 72rpx;
border-radius: 50%;
background: linear-gradient(135deg, #3b82f6 0%, #60a5fa 100%);
display: flex;
align-items: center;
justify-content: center;
.avatar-text {
font-size: 28rpx;
color: #fff;
font-weight: 600;
}
}
.user-detail {
display: flex;
flex-direction: column;
gap: 8rpx;
}
.user-name {
font-size: 28rpx;
color: #1f2937;
font-weight: 500;
}
.record-type {
font-size: 22rpx;
padding: 4rpx 12rpx;
border-radius: 999rpx;
&.like {
background: #ecfdf3;
color: #16a34a;
}
&.dislike {
background: #fef2f2;
color: #dc2626;
}
}
.record-time {
font-size: 24rpx;
color: #9ca3af;
}
.record-remark {
padding: 16rpx;
background: #f9fafb;
border-radius: 12rpx;
font-size: 26rpx;
line-height: 1.6;
}
.remark-label {
color: #6b7280;
}
.remark-content {
color: #1f2937;
}
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 80rpx 0;
.empty-icon {
width: 120rpx;
height: 120rpx;
opacity: 0.5;
margin-bottom: 20rpx;
}
.empty-text {
font-size: 28rpx;
color: #9ca3af;
}
}
.footer {
padding: 24rpx 32rpx;
border-top: 1rpx solid #f2f3f7;
text-align: center;
.page-info {
font-size: 24rpx;
color: #9ca3af;
}
}
}
</style>

@ -117,7 +117,7 @@
</view> </view>
<view v-if="rankingList.length"> <view v-if="rankingList.length">
<view class="rank-item" v-for="(item, index) in rankingList" :key="item.id"> <view class="rank-item" v-for="(item, index) in rankingList" :key="item.id" @click="viewLikeRecords(item)">
<view class="rank-left"> <view class="rank-left">
<text class="rank-no" :class="index < 3 ? 'top' : ''">{{ index + 1 }}</text> <text class="rank-no" :class="index < 3 ? 'top' : ''">{{ index + 1 }}</text>
<text class="rank-name">{{ item.itemName || '未命名菜品' }}</text> <text class="rank-name">{{ item.itemName || '未命名菜品' }}</text>
@ -131,6 +131,14 @@
</view> </view>
<view v-else class="empty">暂无排行数据</view> <view v-else class="empty">暂无排行数据</view>
</view> </view>
<!-- 点赞点踩记录弹窗 -->
<LikeRecordPopup
ref="likeRecordPopup"
:menu-dtl-id="currentMenuDtlId"
:item-name="currentMenuItemName"
:like-type="currentLikeType"
/>
</view> </view>
</template> </template>
@ -141,11 +149,17 @@ import {
cancelLikeDailyMenuItem, cancelLikeDailyMenuItem,
getDailyMenuRanking getDailyMenuRanking
} from '@/api/property.js'; } from '@/api/property.js';
import { checkPermi } from '@/utils/auth/permission.js';
import LikeRecordPopup from './LikeRecordPopup.vue';
export default { export default {
components: {
LikeRecordPopup
},
dicts: ['canteen_name', 'meal_type'], dicts: ['canteen_name', 'meal_type'],
data() { data() {
return { return {
checkPermi,
selectedDate: '', selectedDate: '',
menuList: [], menuList: [],
rankingType: 'like', rankingType: 'like',
@ -157,7 +171,10 @@ export default {
startDate: '', startDate: '',
endDate: '' endDate: ''
}, },
showRankingDatePicker: false showRankingDatePicker: false,
currentMenuDtlId: '',
currentMenuItemName: '',
currentLikeType: '1'
}; };
}, },
onLoad() { onLoad() {
@ -408,6 +425,18 @@ export default {
this.rankingDateRange.startDate = ''; this.rankingDateRange.startDate = '';
this.rankingDateRange.endDate = ''; this.rankingDateRange.endDate = '';
await this.loadRanking(); await this.loadRanking();
},
// /
viewLikeRecords(item) {
if (!checkPermi('daily_menu_record')) {
return;
}
this.currentMenuDtlId = item.id;
this.currentMenuItemName = item.itemName || '未命名菜品';
this.currentLikeType = this.rankingType === 'like' ? '1' : '2';
this.$nextTick(() => {
this.$refs.likeRecordPopup.open();
});
} }
} }
}; };

Loading…
Cancel
Save