feat: 积分商城样式调整

This commit is contained in:
lzhizhao 2025-08-08 23:44:02 +08:00
parent 562a766257
commit c3e5b629c5
4 changed files with 603 additions and 127 deletions

View File

@ -423,19 +423,19 @@ export default {
open: null, open: null,
list: [] list: []
}, },
{ // {
menuId: getUUID(), // menuId: getUUID(),
parentId: 0, // parentId: 0,
parentName: null, // parentName: null,
name: "积分设置", // name: "积分设置",
url: "marketing/points-setting/index", // url: "marketing/points-setting/index",
perms: "", // perms: "",
type: 1, // type: 1,
elIcon: "el-icon-shopping-cart-full", // elIcon: "el-icon-shopping-cart-full",
orderNum: 0, // orderNum: 0,
open: null, // open: null,
list: [] // list: []
}, // },
{ {
menuId: getUUID(), menuId: getUUID(),
parentId: 0, parentId: 0,

View File

@ -35,19 +35,6 @@
v-model="formInline.productName" v-model="formInline.productName"
></el-input> ></el-input>
</el-form-item> </el-form-item>
<el-form-item label="兑换状态">
<el-select v-model="formInline.redeemEnable" placeholder="请选择">
<el-option
v-for="item in [
{ value: true, label: '启用' },
{ value: false, label: '禁用' },
]"
:key="item.marketId"
:label="item.marketName"
:value="item.marketId"
></el-option>
</el-select>
</el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" @click="$refs.oTable.reload()" <el-button type="primary" @click="$refs.oTable.reload()"
>查询</el-button >查询</el-button
@ -60,24 +47,32 @@
</div> </div>
</template> </template>
</obj-table-plus> </obj-table-plus>
<!-- 添加或编辑 --> <!-- 商品选择弹框 -->
<add-or-update <product-selector
:marketId="formInline.marketId" :storeList="storeList"
:shopId="formInline.shopId" @success="$refs.oTable.reload()"
@queryList="$refs.oTable.reload()" ref="productSelector"
ref="addOrUpdate" ></product-selector>
></add-or-update>
<!-- 积分商品配置弹框 -->
<points-product-config
@success="$refs.oTable.reload()"
ref="pointsProductConfig"
></points-product-config>
<!-- 查看详情 --> <!-- 查看详情 -->
<!-- <viewDetails ref="viewDetails"></viewDetails> --> <!-- <viewDetails ref="viewDetails"></viewDetails> -->
</div> </div>
</template> </template>
<script> <script>
import AddOrUpdate from "./popup/add-or-update.vue"; import ProductSelector from "./popup/product-selector.vue";
// import viewDetails from "./popup/view-details.vue"; import PointsProductConfig from "./popup/points-product-config.vue";
import { mapState } from "vuex"; import { mapState } from "vuex";
export default { export default {
components: { AddOrUpdate }, components: {
ProductSelector,
PointsProductConfig
},
data() { data() {
return { return {
dataList: [], dataList: [],
@ -87,18 +82,18 @@ export default {
unitType: "", unitType: "",
productId: "", productId: "",
productName: "", productName: "",
redeemEnable: "", redeemEnable: ""
}, },
tableProp: { tableProp: {
"auto-resize": true, "auto-resize": true,
border: true, border: true,
height: "auto", height: "auto",
"row-id": "id", "row-id": "id",
"show-overflow": false, "show-overflow": false
}, },
productFilterType: "SALE", productFilterType: "SALE",
selectList: [], selectList: [],
value1: [], value1: []
}; };
}, },
created() { created() {
@ -108,7 +103,7 @@ export default {
? 3 ? 3
: 2, : 2,
marketId: this.marketId, marketId: this.marketId,
shopId: this.shopId, shopId: this.shopId
}; };
this.$nextTick(() => { this.$nextTick(() => {
this.$refs.oTable.reload(); this.$refs.oTable.reload();
@ -120,21 +115,21 @@ export default {
.PointsProductPage({ .PointsProductPage({
pageNumber: pageNo, pageNumber: pageNo,
pageSize: pageSize, pageSize: pageSize,
...this.formInline, ...this.formInline
}) })
.then((res) => { .then(res => {
console.log(res); console.log(res);
this.$refs.oTable.complete( this.$refs.oTable.complete(
res.data.data.data, res.data.data.data,
Number(res.data.data.total) Number(res.data.data.total)
); );
}) })
.catch((err) => { .catch(err => {
this.$refs.oTable.complete(false); this.$refs.oTable.complete(false);
}); });
}, },
add() { add() {
this.$refs.addOrUpdate.toggle().add(); this.$refs.productSelector.show(this.formInline.shopId);
}, },
reset() { reset() {
this.formInline = { this.formInline = {
@ -143,10 +138,10 @@ export default {
? 3 ? 3
: 2, : 2,
marketId: this.marketId, marketId: this.marketId,
shopId: this.shopId, shopId: this.shopId
}; };
this.$refs.oTable.reload(); this.$refs.oTable.reload();
}, }
}, },
computed: { computed: {
tableCols() { tableCols() {
@ -156,12 +151,17 @@ export default {
{ {
title: "商品ID", title: "商品ID",
align: "center", align: "center",
field: "productId", field: "productId"
}, },
{ {
title: "商品名称", title: "商品名称",
align: "center", align: "center",
field: "productName", field: "productName"
},
{
title: "所属店铺",
align: "center",
field: "shopName"
}, },
{ {
title: "兑换积分", title: "兑换积分",
@ -178,78 +178,17 @@ export default {
</span> </span>
); );
} }
}, }
}, },
{ {
title: "剩余兑换库存", title: "剩余兑换库存",
align: "center", align: "center",
field: "totalInventory", field: "totalInventory"
},
{
title: "兑换状态",
align: "center",
field: "redeemEnable",
type: "jsx",
render: ({ row }) => {
let changStatus = () => {
if (row.redeemEnable) {
this.$confirm("是否开启积分商品兑换, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
this.$api.marketing
.reverseEnablePointsProduct({
id: row.id,
})
.then((res) => {
this.$refs.oTable.reload();
})
.catch((err) => {
this.$refs.oTable.reload();
});
})
.catch(() => {
this.$refs.oTable.reload();
});
} else {
this.$confirm("是否关闭积分商品兑换, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
this.$api.marketing
.reverseEnablePointsProduct({
id: row.id,
})
.then((res) => {
this.$refs.oTable.reload();
})
.catch((err) => {
this.$refs.oTable.reload();
});
})
.catch(() => {
this.$refs.oTable.reload();
});
}
};
return (
<el-switch
onChange={changStatus}
v-model={row.redeemEnable}
active-text="启用"
inactive-text="关闭"
></el-switch>
);
},
}, },
{ {
title: "已兑换数", title: "已兑换数",
align: "center", align: "center",
field: "totalRedeemQuantity", field: "totalRedeemQuantity"
}, },
{ {
title: "操作", title: "操作",
@ -261,23 +200,29 @@ export default {
let edit = () => { let edit = () => {
this.$api.marketing this.$api.marketing
.PointsProductDetail({ .PointsProductDetail({
id: row.id, id: row.id
}) })
.then((res) => { .then(res => {
this.$refs.addOrUpdate const productData = {
.toggle({ ...res.data.data, productName: row.productName }) productId: row.productId,
.update(); productName: row.productName,
shopName: row.shopName
};
this.$refs.pointsProductConfig.show(
productData,
res.data.data
);
}) })
.catch((err) => {}); .catch(err => {});
}; };
let deleteProduct = () => { let deleteProduct = () => {
this.$api.marketing this.$api.marketing
.deletePointsProduct({ id: row.id }) .deletePointsProduct({ id: row.id })
.then((res) => { .then(res => {
this.$message.success("删除成功"); this.$message.success("删除成功");
this.$refs.oTable.reload(); this.$refs.oTable.reload();
}) })
.catch((err) => {}); .catch(err => {});
}; };
return ( return (
<div> <div>
@ -303,8 +248,8 @@ export default {
</el-popconfirm> </el-popconfirm>
</div> </div>
); );
}, }
}, }
]; ];
}, },
tableEvent() { tableEvent() {
@ -314,7 +259,7 @@ export default {
}, },
"checkbox-change": ({ records, reserves }) => { "checkbox-change": ({ records, reserves }) => {
this.selectList = [...records, ...reserves]; this.selectList = [...records, ...reserves];
}, }
}; };
}, },
...mapState("userData", [ ...mapState("userData", [
@ -322,9 +267,9 @@ export default {
"marketList", "marketList",
"storeList", "storeList",
"marketId", "marketId",
"shopId", "shopId"
]), ])
}, }
}; };
</script> </script>

View File

@ -0,0 +1,287 @@
<template>
<el-dialog
:title="isEdit ? '编辑积分商品' : '已选择商品'"
:visible.sync="visible"
width="600px"
:append-to-body="true"
:close-on-click-modal="false"
@close="handleClose"
>
<!-- 已选择商品信息 -->
<div class="selected-product" v-if="!isEdit">
<div class="product-info">
<div class="info-item">
<span class="label">商品ID</span>
<span class="value">{{ productData.productId }}</span>
</div>
<div class="info-item">
<span class="label">商品名称</span>
<span class="value">{{ productData.productName }}</span>
</div>
<div class="info-item">
<span class="label">归属摊位</span>
<span class="value">{{ productData.shopName }}</span>
</div>
</div>
</div>
<!-- 配置表单 -->
<el-form
ref="configForm"
:model="configForm"
:rules="configRules"
label-width="140px"
style="margin-top: 20px"
>
<el-form-item label="SKU-ID" prop="skuId">
<el-input
v-model="configForm.skuId"
placeholder="请输入SKU-ID"
:disabled="isEdit"
></el-input>
</el-form-item>
<el-form-item label="兑换所需积分设置" prop="points" required>
<div class="points-input">
<el-button @click="decreasePoints" :disabled="configForm.points <= 1"
>-</el-button
>
<el-input-number
v-model="configForm.points"
:min="1"
:max="99999"
controls-position="right"
style="width: 200px; margin: 0 10px"
></el-input-number>
<el-button @click="increasePoints">+</el-button>
</div>
</el-form-item>
<el-form-item label="兑换库存设置" prop="inventory" required>
<div class="inventory-input">
<el-button
@click="decreaseInventory"
:disabled="configForm.inventory <= 1"
>-</el-button
>
<el-input-number
v-model="configForm.inventory"
:min="1"
:max="99999"
controls-position="right"
style="width: 200px; margin: 0 10px"
></el-input-number>
<el-button @click="increaseInventory">+</el-button>
</div>
</el-form-item>
<el-form-item
label="限制兑换(每人购买不超)"
prop="limitQuantity"
required
>
<div class="limit-input">
<el-button
@click="decreaseLimitQuantity"
:disabled="configForm.limitQuantity <= 0"
>-</el-button
>
<el-input-number
v-model="configForm.limitQuantity"
:min="0"
:max="99999"
controls-position="right"
style="width: 200px; margin: 0 10px"
></el-input-number>
<el-button @click="increaseLimitQuantity">+</el-button>
<el-select
v-model="configForm.limitPeriod"
style="width: 100px; margin-left: 10px"
>
<el-option label="每天" value="DAY"></el-option>
<el-option label="每周" value="WEEK"></el-option>
<el-option label="每月" value="MONTH"></el-option>
</el-select>
</div>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="handleClose">取消</el-button>
<el-button type="primary" @click="handleSubmit" :loading="submitting">
{{ isEdit ? "保存" : "确认" }}
</el-button>
</div>
</el-dialog>
</template>
<script>
export default {
name: "PointsProductConfig",
data() {
return {
visible: false,
isEdit: false,
submitting: false,
productData: {},
configForm: {
skuId: "",
points: 1,
inventory: 10,
limitQuantity: 0,
limitPeriod: "DAY"
},
configRules: {
skuId: [{ required: true, message: "请输入SKU-ID", trigger: "blur" }],
points: [
{ required: true, message: "请设置兑换积分", trigger: "blur" }
],
inventory: [
{ required: true, message: "请设置兑换库存", trigger: "blur" }
],
limitQuantity: [
{ required: true, message: "请设置限制数量", trigger: "blur" }
]
}
};
},
methods: {
show(productData, editData = null) {
this.visible = true;
this.isEdit = !!editData;
this.productData = productData;
if (editData) {
//
this.configForm = {
skuId: editData.skuId || "",
points: editData.minPoints || 1,
inventory: editData.totalInventory || 10,
limitQuantity: editData.limitQuantity || 0,
limitPeriod: editData.limitPeriod || "DAY"
};
} else {
// 使
this.configForm = {
skuId: productData.skuId || "",
points: 1,
inventory: 10,
limitQuantity: 0,
limitPeriod: "DAY"
};
}
},
handleClose() {
this.visible = false;
this.resetForm();
},
resetForm() {
this.productData = {};
this.configForm = {
skuId: "",
points: 1,
inventory: 10,
limitQuantity: 0,
limitPeriod: "DAY"
};
this.isEdit = false;
this.$refs.configForm && this.$refs.configForm.clearValidate();
},
handleSubmit() {
this.$refs.configForm.validate(valid => {
if (valid) {
this.submitting = true;
const submitData = {
...this.productData,
...this.configForm,
minPoints: this.configForm.points,
maxPoints: this.configForm.points,
totalInventory: this.configForm.inventory
};
// API
setTimeout(() => {
this.$message.success(this.isEdit ? "编辑成功" : "添加成功");
this.submitting = false;
this.$emit("success", submitData);
this.handleClose();
}, 1000);
}
});
},
decreasePoints() {
if (this.configForm.points > 1) {
this.configForm.points--;
}
},
increasePoints() {
this.configForm.points++;
},
decreaseInventory() {
if (this.configForm.inventory > 1) {
this.configForm.inventory--;
}
},
increaseInventory() {
this.configForm.inventory++;
},
decreaseLimitQuantity() {
if (this.configForm.limitQuantity > 0) {
this.configForm.limitQuantity--;
}
},
increaseLimitQuantity() {
this.configForm.limitQuantity++;
}
}
};
</script>
<style lang="scss" scoped>
.selected-product {
background: #f5f7fa;
padding: 20px;
border-radius: 4px;
margin-bottom: 20px;
}
.product-info {
.info-item {
display: flex;
margin-bottom: 10px;
&:last-child {
margin-bottom: 0;
}
.label {
color: #606266;
min-width: 80px;
}
.value {
color: #303133;
font-weight: 500;
}
}
}
.points-input,
.inventory-input,
.limit-input {
display: flex;
align-items: center;
.el-button {
width: 40px;
height: 40px;
}
}
.limit-input {
.el-select {
margin-left: 10px;
}
}
</style>

View File

@ -0,0 +1,244 @@
<template>
<el-dialog
title="添加积分商品"
:visible.sync="visible"
width="80%"
:close-on-click-modal="false"
@close="handleClose"
>
<!-- 查询条件 -->
<div class="search-form">
<el-form :inline="true" :model="searchForm" class="demo-form-inline">
<el-form-item label="店铺">
<el-select
v-model="searchForm.shopId"
placeholder="请选择店铺"
disabled
>
<el-option
v-for="item in storeList"
:key="item.shopId"
:label="item.shopName"
:value="item.shopId"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="商品名称">
<el-input
v-model="searchForm.productName"
placeholder="请输入商品名称"
clearable
></el-input>
</el-form-item>
<el-form-item label="商品ID">
<el-input
v-model="searchForm.productId"
placeholder="请输入商品ID"
clearable
></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="searchProducts">查询</el-button>
<el-button @click="resetSearch">重置</el-button>
</el-form-item>
</el-form>
</div>
<!-- 商品列表 -->
<div class="product-list">
<el-table
:data="productList"
border
style="width: 100%"
v-loading="loading"
>
<el-table-column
prop="shopName"
label="商品店铺"
align="center"
width="150"
>
</el-table-column>
<el-table-column prop="productName" label="商品名称" align="center">
</el-table-column>
<el-table-column
prop="productId"
label="商品ID"
align="center"
width="120"
>
</el-table-column>
<el-table-column
prop="price"
label="商品价格"
align="center"
width="100"
>
<template slot-scope="scope"> ¥{{ scope.row.price }} </template>
</el-table-column>
<el-table-column label="操作" align="center" width="150">
<template slot-scope="scope">
<el-button
type="primary"
size="small"
@click="addToPointsMall(scope.row)"
>
添加为积分商品
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="pagination.currentPage"
:page-sizes="[10, 20, 50, 100]"
:page-size="pagination.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="pagination.total"
style="margin-top: 20px; text-align: center"
>
</el-pagination>
</div>
<div slot="footer" class="dialog-footer">
<el-button @click="handleClose">关闭</el-button>
</div>
<!-- 积分商品配置弹框 -->
<points-product-config
ref="pointsProductConfig"
@success="handleConfigSuccess"
></points-product-config>
</el-dialog>
</template>
<script>
import PointsProductConfig from "./points-product-config.vue";
export default {
name: "ProductSelector",
components: {
PointsProductConfig
},
props: {
storeList: {
type: Array,
default: () => []
}
},
data() {
return {
visible: false,
loading: false,
searchForm: {
shopId: "",
productName: "",
productId: ""
},
productList: [],
pagination: {
currentPage: 1,
pageSize: 10,
total: 0
}
};
},
methods: {
show(shopId) {
this.visible = true;
this.searchForm.shopId = shopId;
this.loadProducts();
},
handleClose() {
this.visible = false;
this.resetData();
},
resetData() {
this.searchForm = {
shopId: "",
productName: "",
productId: ""
};
this.productList = [];
this.pagination = {
currentPage: 1,
pageSize: 10,
total: 0
};
},
searchProducts() {
this.pagination.currentPage = 1;
this.loadProducts();
},
resetSearch() {
this.searchForm.productName = "";
this.searchForm.productId = "";
this.searchProducts();
},
loadProducts() {
this.loading = true;
// API - API
setTimeout(() => {
this.productList = [
{
productId: "1212",
productName: "猪肉",
shopName: "猪肉铺",
price: "2.00",
skuId: "194105142774503836"
},
{
productId: "1213",
productName: "牛肉",
shopName: "牛肉铺",
price: "5.00",
skuId: "194105142774503837"
},
{
productId: "1214",
productName: "鸡肉",
shopName: "鸡肉铺",
price: "3.00",
skuId: "194105142774503838"
}
];
this.pagination.total = 3;
this.loading = false;
}, 500);
},
handleSizeChange(val) {
this.pagination.pageSize = val;
this.loadProducts();
},
handleCurrentChange(val) {
this.pagination.currentPage = val;
this.loadProducts();
},
addToPointsMall(product) {
//
this.$refs.pointsProductConfig.show(product);
},
handleConfigSuccess() {
this.$emit("success");
this.handleClose();
}
}
};
</script>
<style lang="scss" scoped>
.search-form {
padding: 20px;
background: #f5f7fa;
border-radius: 4px;
margin-bottom: 20px;
}
.product-list {
min-height: 400px;
}
</style>