feat: 新增全局布局样式并提升组件响应式表现

- 在 global-layout.scss 中引入全局布局样式,统一页面宽度与对齐方式
- 更新多个组件与页面以优化响应式,包括宽度、间距及 flex 布局等调整
- 在 API 请求中增加 loading 状态管理,改善用户体验
- 优化领券中心与商品详情页,提升功能与 UI 一致性
This commit is contained in:
田香琪
2026-06-23 10:17:35 +08:00
parent c1447b4376
commit 8a60e23214
129 changed files with 5236 additions and 2232 deletions

View File

@@ -13,7 +13,7 @@
style="width: 260px"
/>
</el-form-item>
<el-form-item label="活动时间">
<el-form-item label="活动时间" class="activity-time-form-item">
<el-date-picker
type="datetimerange"
:disabled-date="options.disabledDate"
@@ -22,7 +22,6 @@
start-placeholder="开始时间"
end-placeholder="结束时间"
placeholder="请选择活动时间"
style="width: 260px"
/>
</el-form-item>
@@ -133,14 +132,25 @@
</el-form>
</el-card>
<el-dialog v-model="showCouponSelect" width="80%" title="选择优惠券" destroy-on-close>
<el-dialog
v-model="showCouponSelect"
width="80%"
title="选择优惠券"
destroy-on-close
:close-on-click-modal="false"
>
<couponTemplate
:checked="true"
:selectedList="selectCouponList"
v-if="showCouponSelect"
ref="couponPicker"
manualConfirm
:selectedList="tempCouponList"
getType="ACTIVITY"
promotionStatus="START"
@selected="selectedCoupon"
/>
<template #footer>
<el-button @click="cancelCouponSelect">取消</el-button>
<el-button type="primary" @click="confirmCouponSelect">确定</el-button>
</template>
</el-dialog>
<el-dialog v-model="checkUserList" width="1200px" title="选择会员" destroy-on-close>
@@ -173,6 +183,7 @@ export default {
},
},
showCouponSelect: false,
tempCouponList: [],
rangeTime: "",
checkUserList: false,
selectedMember: [],
@@ -241,9 +252,18 @@ export default {
};
});
},
selectedCoupon(val) {
this.selectCouponList = val;
cancelCouponSelect() {
this.showCouponSelect = false;
},
confirmCouponSelect() {
const list = this.$refs.couponPicker?.getSelection?.() || [];
if (!list.length) {
this.$Message.warning("请至少选择一张优惠券");
return;
}
this.selectCouponList = list;
this.reSelectCoupon();
this.showCouponSelect = false;
},
delCoupon(index) {
this.selectCouponList.splice(index, 1);
@@ -251,8 +271,11 @@ export default {
},
reSelectCoupon() {
this.form.couponActivityItems = this.selectCouponList.map((item) => {
const existing = this.form.couponActivityItems.find(
(entry) => entry.couponId === item.id
);
return {
num: 1,
num: existing ? existing.num : 1,
couponId: item.id,
};
});
@@ -264,6 +287,7 @@ export default {
});
},
showSelector() {
this.tempCouponList = [...this.selectCouponList];
this.showCouponSelect = true;
},
handleSubmit() {
@@ -320,7 +344,7 @@ export default {
};
</script>
<style lang="scss" scpoed>
<style lang="scss" scoped>
h4 {
margin-bottom: 10px;
padding: 0 10px;
@@ -333,6 +357,14 @@ h4 {
text-align: left;
}
.activity-time-form-item {
:deep(.el-date-editor) {
width: 380px !important;
max-width: 380px;
flex-grow: 0;
}
}
.describe {
font-size: 12px;
margin-left: 10px;

View File

@@ -606,5 +606,6 @@ h4 {
.tips {
font-size: 12px;
color: #999;
margin-left: 10px;
}
</style>

View File

@@ -204,6 +204,10 @@ export default {
type: Array,
default: () => [],
},
manualConfirm: {
type: Boolean,
default: false,
},
},
data() {
return {
@@ -222,6 +226,7 @@ export default {
selectDate: [],
showActionColumn: true,
showStatusColumn: true,
isSyncingSelection: false,
};
},
watch: {
@@ -232,6 +237,8 @@ export default {
},
selectedList: {
handler(val) {
if (this.isSyncingSelection) return;
if (this.isSameSelection(val, this.selectList)) return;
this.$nextTick(() => {
this.syncTableSelection(val);
});
@@ -311,20 +318,39 @@ export default {
};
return map[type] || "";
},
isSameSelection(next, current) {
const a = next || [];
const b = current || [];
if (a.length !== b.length) return false;
const nextIds = a.map((item) => item.id).sort().join(",");
const currentIds = b.map((item) => item.id).sort().join(",");
return nextIds === currentIds;
},
syncTableSelection(selected) {
const table = this.$refs.table;
if (!table) return;
const nextList = selected ? [...selected] : [];
this.isSyncingSelection = true;
table.clearSelection();
if (!selected || !selected.length) return;
this.data.forEach((row) => {
if (selected.some((item) => item.id === row.id)) {
table.toggleRowSelection(row, true);
}
if (nextList.length) {
this.data.forEach((row) => {
if (nextList.some((item) => item.id === row.id)) {
table.toggleRowSelection(row, true);
}
});
}
this.selectList = nextList;
this.selectCount = nextList.length;
this.$nextTick(() => {
this.isSyncingSelection = false;
});
},
check() {
this.$emit("selected", this.selectList);
},
getSelection() {
return [...this.selectList];
},
receivePage(id) {
if (id) {
this.$router.push({ name: "coupon-receive", query: { couponId: id } });
@@ -356,9 +382,10 @@ export default {
this.$refs.table?.clearSelection();
},
changeSelect(e) {
if (this.isSyncingSelection) return;
this.selectList = e;
this.selectCount = e.length;
if (this.getType === "ACTIVITY") this.check();
if (this.getType === "ACTIVITY" && !this.manualConfirm) this.check();
},
getDataList() {
this.loading = true;