fix: 增强错误处理与组件逻辑优化

- 在 App.vue 中添加 JSON 解析错误处理,确保站点信息获取的稳定性。
- 更新多个 API 请求,添加 loading 状态管理,提升用户体验。
- 在 Search.vue 中优化热词列表的解析逻辑,增强容错性。
- 改进购物车、地址管理等 API 请求参数,确保一致性与可用性。
- 新增用户中心布局组件,提升用户界面的一致性与可读性。
This commit is contained in:
田香琪
2026-07-03 18:29:41 +08:00
parent 99de0d4722
commit bd9a5f75b0
79 changed files with 2382 additions and 1207 deletions

View File

@@ -272,11 +272,12 @@ export default {
margin: 0 auto;
background: #fff;
min-height: 1200px;
overflow-x: visible;
}
.model-form-list {
min-height: 500px;
padding-right: 110px;
box-sizing: border-box;
overflow: visible;
}
.top-fixed-advert {
display: flex;

View File

@@ -377,20 +377,34 @@ export default {
.model-item {
position: relative;
margin-bottom: 20px;
width: 100%;
box-sizing: border-box;
overflow: visible;
&:hover {
.del-btn {
display: block;
}
}
}
.model-item :deep(.width_1200_auto) {
width: 100% !important;
max-width: 100% !important;
margin-left: 0 !important;
margin-right: 0 !important;
}
.del-btn {
width: 100px;
height: 100px;
display: none;
position: absolute;
right: -100px;
left: 100%;
right: auto;
top: 0;
z-index: 10;
width: auto;
white-space: nowrap;
display: none;
z-index: 100;
&:hover {
display: block;
}
@@ -420,38 +434,41 @@ export default {
}
/** 热门广告 */
.hot-advert {
width: 1200px;
margin-right: -110px;
width: 100%;
box-sizing: border-box;
overflow: hidden;
.hot-advert-banner {
line-height: 0;
width: 100%;
img {
display: block;
width: 100%;
height: auto;
object-fit: cover;
}
}
}
.advert-list {
width: 100%;
margin: 0;
padding: 5px 0;
padding: 10px;
list-style: none;
box-sizing: border-box;
background: $theme_color;
height: 200px;
height: 210px;
display: flex;
gap: 10px;
align-items: center;
> li {
flex: 0 0 calc((100% - 40px) / 5);
flex: 1 1 0;
min-width: 0;
img {
display: block;
width: 100%;
height: 190px;
object-fit: cover;
cursor: pointer;
border-radius: 10px;
transition: all 150ms ease-in-out;
@@ -473,16 +490,17 @@ export default {
}
/** 折扣广告 */
.discountAdvert-wrap {
width: 1200px;
width: 100%;
position: relative;
overflow: hidden;
}
.discountAdvert {
width: 1300px;
height: 585px;
height: 596px;
margin-left: -100px;
box-sizing: border-box;
background-repeat: no-repeat;
background-size: 1300px 585px;
background-size: 1300px 596px;
position: relative;
> div {
padding-left: 295px;

View File

@@ -101,12 +101,14 @@
v-for="(item, index) in options.right.list"
:key="index"
>
<img :src="item.img" alt="" />
<div class="img-wrap">
<img :src="item.img" alt="" />
<div class="jiaobiao" :class="'jiaobiao' + (index + 1)">
{{ index + 1 }}
</div>
</div>
<p>{{ item.name }}</p>
<p>{{ $filters.unitPrice(item.price, "¥") }}</p>
<div class="jiaobiao" :class="'jiaobiao' + (index + 1)">
{{ index + 1 }}
</div>
<div class="setup-box">
<div>
<el-button size="small" @click.stop="handleSelectGoods(item)"
@@ -499,16 +501,52 @@ export default {
flex-direction: column;
align-items: center;
overflow: hidden;
img {
border-bottom: 1px solid #eee;
border-right: 1px solid #eee;
.img-wrap {
position: relative;
width: 80px;
height: 80px;
flex-shrink: 0;
display: block;
object-fit: cover;
img {
width: 100%;
height: 100%;
display: block;
object-fit: cover;
}
.jiaobiao {
position: absolute;
width: 23px;
height: 23px;
top: 0;
right: 0;
margin: 0;
padding: 0;
max-height: none;
overflow: visible;
display: block;
background: url("../../../assets/festival_icon.png") no-repeat;
color: #fff;
text-align: center;
line-height: 23px;
font-size: 12px;
-webkit-line-clamp: unset;
-webkit-box-orient: unset;
}
.jiaobiao1,
.jiaobiao4 {
background-position: -2px -30px;
}
.jiaobiao2,
.jiaobiao5 {
background-position: -31px -30px;
}
.jiaobiao3,
.jiaobiao6 {
background-position: -60px -30px;
}
}
border-bottom: 1px solid #eee;
border-right: 1px solid #eee;
:nth-child(2) {
> p:nth-child(2) {
width: 100%;
height: auto;
max-height: 32px;
@@ -520,34 +558,12 @@ export default {
-webkit-box-orient: vertical;
text-align: center;
}
:nth-child(3) {
> p:nth-child(3) {
color: $theme_color;
margin-top: 2px;
line-height: 1.2;
flex-shrink: 0;
}
.jiaobiao {
position: absolute;
width: 23px;
height: 23px;
top: 6px;
right: 6px;
background: url("../../../assets/festival_icon.png");
color: #fff;
text-align: center;
}
.jiaobiao1,
.jiaobiao4 {
background-position: -2px -30px;
}
.jiaobiao2,
.jiaobiao5 {
background-position: -31px -30px;
}
.jiaobiao3,
.jiaobiao6 {
background-position: -60px -30px;
}
}
> div:nth-child(3n) {
border-right: none;

View File

@@ -341,18 +341,21 @@ export default {
.recommend {
display: flex;
justify-content: space-between;
width: 100%;
box-sizing: border-box;
.recommend-left {
width: 595px;
.content-left {
display: flex;
align-items: stretch;
padding-top: 10px;
font-size: 12px;
box-sizing: content-box;
> div:nth-child(1) {
width: 189px;
border-right: 1px solid #eee;
height: 360px;
display: flex;
flex-direction: column;
box-sizing: border-box;
img {
margin: 40px 0 0 15px;
}
@@ -370,15 +373,20 @@ export default {
color: #999;
}
.view-btn {
margin-left: 15px;
margin-top: 10px;
align-self: center;
width: 145px;
margin-top: auto;
margin-bottom: 15px;
color: #fff;
}
}
> div:nth-child(2) {
width: 405px;
height: 360px;
display: flex;
flex-wrap: wrap;
align-content: flex-start;
box-sizing: border-box;
> div {
display: flex;
align-items: center;
@@ -410,7 +418,7 @@ export default {
grid-template-rows: repeat(2, 1fr);
height: 360px;
padding-top: 10px;
box-sizing: border-box;
box-sizing: content-box;
> div {
width: 100%;

View File

@@ -211,6 +211,9 @@
.custom-checkbox-card-checked {
border: 2px solid #ff5c58;
}
.oss-card-selectable {
cursor: pointer;
}
.text {
width: 120px;
height: 36px;

View File

@@ -176,9 +176,13 @@
<div v-for="(item, index) in data" :key="index" class="img-item">
<div
class="card"
:class="{ 'custom-checkbox-card-checked': selectedOss.includes(item.id + ',' + item.url) }"
:class="{
'custom-checkbox-card-checked': selectedOss.includes(item.id + ',' + item.url),
'oss-card-selectable': isComponent && selectImage,
}"
@mouseenter="onMouseOver(item, index)"
@mouseleave="onMouseOut(item, index)"
@click="handleCardClick(item, $event)"
>
<el-checkbox
:value="item.id + ',' + item.url"
@@ -1097,6 +1101,23 @@ export default {
this.$emit("selected", e);
}
},
handleCardClick(item, event) {
if (!(this.isComponent && this.selectImage)) return;
if (event?.target?.closest?.(".preview") || event?.target?.closest?.(".card-checkbox")) {
return;
}
const key = `${item.id},${item.url}`;
let next;
if (this.maxSelect === 1) {
next = this.selectedOss.includes(key) ? [] : [key];
} else if (this.selectedOss.includes(key)) {
next = this.selectedOss.filter((k) => k !== key);
} else {
next = [...this.selectedOss, key];
}
this.selectedOss = next;
this.selectOssChange(next);
},
// 页码改变时回调
pageChange(value) {
this.selectedOss = [];