修复bug #77

Merged
ppnwsfegt merged 2 commits from Brunch_LPQ into main 1 month ago

@ -91,12 +91,13 @@
flowList.value = res.data;
}
}
//
// -
const toDetails = (item) => {
console.log(item)
//details.vue
//
const encodedGoods = encodeURIComponent(JSON.stringify(item))
uni.navigateTo({
url: '../detail/detail?goods=' + JSON.stringify(item)
url: '../detail/detail?goods=' + encodedGoods
});
}
onLoad(() => {

@ -1,65 +1,67 @@
import type { CommentListParm } from "../../api/comment/CommentModel";
import { reactive ,ref,onMounted,nextTick} from "vue";
import {getListApi,deleteApi} from '../../api/comment/index'
import { reactive, ref, onMounted, nextTick } from "vue";
import { getListApi, deleteApi } from '../../api/comment/index'
import useInstance from "@/hooks/useInstance";
import { ElMessage } from "element-plus";
export default function useCommentTable(){
const {global} = useInstance()
export default function useCommentTable() {
const { global } = useInstance()
//表格高度
const tableHeight = ref(0)
//接收表格数据
const tableList = ref([])
//列表查询的参数
const listParm = reactive<CommentListParm>({
currentPage:1,
pageSize:10,
total:0
currentPage: 1,
pageSize: 10,
total: 0
})
//列表
const getList = async()=>{
const getList = async () => {
let res = await getListApi(listParm)
if(res && res.code == 200){
if (res && res.code == 200) {
tableList.value = res.data.records;
listParm.total = res.data.total;
}
}
//删除
const deleteBtn = async(commentId:string)=>{
const deleteBtn = async (commentId: string) => {
const confirm = await global.$myconfirm('确定删除吗?')
if(confirm){
if (confirm) {
let res = await deleteApi(commentId)
if(res && res.code == 200){
if (res && res.code == 200) {
ElMessage.success(res.msg)
getList()
}
}
}
//搜索
const searchBtn = ()=>{
const searchBtn = () => {
getList()
}
//重置
const resetBtn = ()=>{
const resetBtn = () => {
listParm.currentPage = 1;
getList()
}
//页容量改变时触发
const sizeChange = (size:number)=>{
const sizeChange = (size: number) => {
listParm.pageSize = size;
getList()
}
//页数改变触发
const currentChange = (page:number)=>{
const currentChange = (page: number) => {
listParm.currentPage = page;
getList()
}
onMounted(()=>{
onMounted(() => {
getList()
nextTick(()=>{
nextTick(() => {
tableHeight.value = window.innerHeight - 180
})
})
return{
return {
listParm,
getList,
searchBtn,
@ -68,6 +70,6 @@ export default function useCommentTable(){
sizeChange,
currentChange,
tableHeight,
deleteBtn
deleteBtn,
}
}

@ -86,6 +86,7 @@ export default function useOrderTable() {
tableHeight.value = window.innerHeight - 220
})
})
return {
tableList,
sendOrder,

@ -1,19 +1,30 @@
<template>
<el-main>
<!-- 预览遮罩层 -->
<div v-if="isPreviewing" class="preview-mask" @click.self="closePreview">
<div class="preview-close" @click="closePreview">×</div>
<div class="preview-image-container">
<img :src="previewImage" class="preview-image" />
</div>
<div class="preview-title">{{ previewTitle }}</div>
<div class="preview-hint">点击任意位置或按ESC键关闭预览</div>
</div>
<!-- 表格 -->
<el-table :height="tableHeight" :data="tableList" border stripe>
<el-table :height="tableHeight" :data="tableList" border stripe :class="{'preview-mode': isPreviewing}">
<el-table-column label="名称" prop="goodsName"></el-table-column>
<el-table-column label="商品图片" prop="goodsImage">
<template #default="scope">
<el-image :src="getGoodsImage(scope.row.goodsImage)"
style="height: 60px; width: 60px; border-radius: 8px"
:preview-src-list="[getGoodsImage(scope.row.goodsImage)]"
fit="cover"
hide-on-click-modal
@error="handleImageError">
<el-image :src="getGoodsImage(scope.row.goodsImage)"
style="height: 60px; width: 60px; border-radius: 8px; cursor: pointer;"
fit="cover"
@error="handleImageError"
@click="openPreview(getGoodsImage(scope.row.goodsImage), scope.row.goodsName)">
<template #error>
<div class="image-error">
<el-icon><Picture /></el-icon>
<el-icon>
<Picture />
</el-icon>
</div>
</template>
</el-image>
@ -21,16 +32,17 @@
</el-table-column>
<el-table-column label="昵称" prop="nickName"></el-table-column>
<el-table-column label="头像" prop="avatarUrl">
<template #default="scope">
<el-image :src="getAvatarUrl(scope.row.avatarUrl)"
style="height: 60px; width: 60px; border-radius: 50%"
:preview-src-list="[getAvatarUrl(scope.row.avatarUrl)]"
fit="cover"
hide-on-click-modal
@error="handleImageError">
<template #default="scoped">
<el-image :src="getAvatarUrl(scoped.row.avatarUrl)"
style="height: 60px; width: 60px; border-radius: 50%; cursor: pointer;"
fit="cover"
@error="handleImageError"
@click="openPreview(getAvatarUrl(scoped.row.avatarUrl), scoped.row.nickName)">
<template #error>
<div class="image-error">
<el-icon><User /></el-icon>
<el-icon>
<User />
</el-icon>
</div>
</template>
</el-image>
@ -46,20 +58,30 @@
<el-table-column label="时间" prop="createTime" width="160"></el-table-column>
<el-table-column label="操作" width="120" align="center">
<template #default="scope">
<el-button :icon="Delete" @click="deleteBtn(scope.row.commentId)" type="danger" size="default">删除</el-button>
<el-button :icon="Delete"
@click="deleteBtn(scope.row.commentId)"
type="danger"
size="default"
:disabled="isPreviewing">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<el-pagination @size-change="sizeChange" @current-change="currentChange" :current-page.sync="listParm.currentPage"
:page-sizes="[10, 20, 40, 80, 100]" :page-size="listParm.pageSize"
layout="total, sizes, prev, pager, next, jumper" :total="listParm.total" background>
<el-pagination @size-change="sizeChange"
@current-change="currentChange"
:current-page.sync="listParm.currentPage"
:page-sizes="[10, 20, 40, 80, 100]"
:page-size="listParm.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="listParm.total"
background
:disabled="isPreviewing">
</el-pagination>
</el-main>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { ref, onMounted, onUnmounted } from 'vue'
import { Delete, Picture, User } from "@element-plus/icons-vue";
import useCommentTable from "../../compositions/comment/useCommentTable";
@ -68,19 +90,100 @@ const imgUrl = ref('http://localhost:8089/')
//
const { listParm, deleteBtn, tableList, sizeChange, currentChange, tableHeight } = useCommentTable();
// URL
const getAvatarUrl = (url: string) => {
if (!url) return '';
// URLURL
if (url.indexOf('http') === 0 || url.indexOf('https') === 0) return url;
//
return imgUrl.value + url;
//
const isPreviewing = ref(false);
const previewImage = ref('');
const previewTitle = ref('');
//
const openPreview = (imageUrl: string, title: string) => {
if (!imageUrl) return;
previewImage.value = imageUrl;
previewTitle.value = title || '图片预览';
isPreviewing.value = true;
//
document.body.style.overflow = 'hidden';
};
//
const closePreview = () => {
isPreviewing.value = false;
previewImage.value = '';
previewTitle.value = '';
//
document.body.style.overflow = '';
};
// ESC
const handleKeydown = (e: KeyboardEvent) => {
if (e.key === 'Escape' && isPreviewing.value) {
closePreview();
}
};
onMounted(() => {
window.addEventListener('keydown', handleKeydown);
});
onUnmounted(() => {
window.removeEventListener('keydown', handleKeydown);
});
//
interface DebugInfo {
message: string;
status: string;
}
// 使
const urlDebugInfo = ref<DebugInfo[]>([]);
//
const addDebugInfo = (message: string, status: string) => {
urlDebugInfo.value.push({
message,
status
});
};
// URL - URL
const getAvatarUrl = (url: string) => {
if (!url) {
//
addDebugInfo('头像URL为空,使用默认占位符', 'error');
return '';
}
// URL
if (url.indexOf('http') === 0 || url.indexOf('https') === 0) {
urlDebugInfo.value.push({
message: `头像URL完整: ${url}`,
status: 'success'
});
return url;
}
//
let cleanUrl = url;
if (cleanUrl.indexOf('/') === 0) {
cleanUrl = cleanUrl.substring(1);
}
//
const fullUrl = imgUrl.value + cleanUrl;
urlDebugInfo.value.push({
message: `头像URL不完整使用完整路径: ${fullUrl}`,
status: 'success'
});
return fullUrl;
};
// URL
const getGoodsImage = (images: string) => {
if (!images) return '';
try {
const imageArray = images.split(',');
if (imageArray.length > 0) {
@ -94,7 +197,7 @@ const getGoodsImage = (images: string) => {
} catch (e) {
console.error('解析商品图片失败:', e);
}
return '';
}
@ -126,4 +229,67 @@ onMounted(() => {
text-overflow: ellipsis;
max-width: 300px;
}
.preview-mask {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.85);
z-index: 9999;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.preview-image-container {
max-width: 80%;
max-height: 80%;
display: flex;
justify-content: center;
align-items: center;
}
.preview-image {
max-width: 100%;
max-height: 100%;
border-radius: 8px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);
}
.preview-close {
position: absolute;
top: 20px;
right: 20px;
color: white;
font-size: 30px;
cursor: pointer;
background: rgba(0, 0, 0, 0.5);
width: 50px;
height: 50px;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
}
.preview-title {
color: white;
margin-top: 20px;
font-size: 18px;
text-align: center;
}
.preview-hint {
color: rgba(255, 255, 255, 0.7);
margin-top: 10px;
font-size: 14px;
}
.preview-mode {
opacity: 0.3;
pointer-events: none;
}
</style>
Loading…
Cancel
Save