.NET经销商实战(十四)——购物车功能实现,及自增键做更新时排除字段
作者:互联网
排除某一自增键做更新
.Metadata.SetAfterSaveBehavior(PropertySaveBehavior.Ignore)
1.购物车界面修改
点击查看代码
<template>
<div>
<div class="cart-list">
<ul>
<li>
<p>
<i></i>
<span>处理产品</span>
</p>
<div>
<i></i>
<img src="" alt="" />
<p class="p-name">0.9密度板</p>
<p class="p-price">¥100.00</p>
<p class="p-num">
<span class="sub-num" @click="subNum()">-</span>
<input
type="text"
name=""
id=""
:value="buyNum"
@change="changeNum()"
/>
<span class="add0num" @click="addNum()">+</span>
<b>块</b>
</p>
</div>
<div>
<i class="cart-select">✔</i>
<img src="" alt="" />
<p class="p-name">0.9密度板</p>
<p class="p-price">¥100.00</p>
<p class="p-num">
<span class="sub-num" @click="subNum()">-</span>
<input
type="text"
name=""
id=""
:value="buyNum"
@change="changeNum()"
/>
<span class="add0num" @click="addNum()">+</span>
<b>块</b>
</p>
</div>
</li>
<li>
<p>
<i class="cart-select">✔</i>
<span>处理产品</span>
</p>
<div>
<i class="cart-select">✔</i>
<img src="" alt="" />
<p class="p-name">0.9密度板</p>
<p class="p-price">¥100.00</p>
<p class="p-num">
<span class="sub-num" @click="subNum()">-</span>
<input
type="text"
name=""
id=""
:value="buyNum"
@change="changeNum()"
/>
<span class="add0num" @click="addNum()">+</span>
<b>块</b>
</p>
</div>
</li>
<li>
<p>
<i></i>
<span>处理产品</span>
</p>
<div>
<i></i>
<img src="" alt="" />
<p class="p-name">0.9密度板</p>
<p class="p-price">¥100.00</p>
<p class="p-num">
<span class="sub-num" @click="subNum()">-</span>
<input
type="text"
name=""
id=""
:value="buyNum"
@change="changeNum()"
/>
<span class="add0num" @click="addNum()">+</span>
<b>块</b>
</p>
</div>
<div>
<i></i>
<img src="" alt="" />
<p class="p-name">0.9密度板</p>
<p class="p-price">¥100.00</p>
<p class="p-num">
<span class="sub-num" @click="subNum()">-</span>
<input
type="text"
name=""
id=""
:value="buyNum"
@change="changeNum()"
/>
<span class="add0num" @click="addNum()">+</span>
<b>块</b>
</p>
</div>
</li>
</ul>
</div>
<div class="total-pad">
<i></i>
<span>全选</span>
<span>
合计:¥ <b>{{ totalPrice | price }}</b>
</span>
<button>确定下单</button>
</div>
</div>
</template>
<script>
import { reactive, toRefs } from 'vue'
export default {
// mounted() {
// this.$store.comm
// this.$store.dispatch('setFootMenuIndexAsync', 2)
// },
setup() {
const shoppingCartInfo = reactive({
buyNum: 1,
totalPrice: 6888,
addNum() {
shoppingCartInfo.buyNum++
},
subNum() {
if (shoppingCartInfo.buyNum > 1) {
shoppingCartInfo.buyNum--
}
},
changeNum() {
// var currNum = event.target.value
// if (!isNaN(currNum) && currNum > 0) {
// shoppingCartInfo.buyNum = currNum
// } else {
// event.target.value = shoppingCartInfo.buyNum
// }
},
})
return { ...toRefs(shoppingCartInfo) }
},
}
</script>
<style lang="scss" scoped>
.cart-list {
text-align: left;
ul {
margin-bottom: 108px;
li {
background-color: #fff;
margin-bottom: 12px;
> p {
padding-left: 46px;
position: relative;
height: 46px;
border-bottom: 1px solid #ddd;
i {
border: 1px solid #a9a9a9;
width: 18px;
height: 18px;
line-height: 18px;
border-radius: 18px;
position: absolute;
left: 13px;
top: 13px;
text-align: center;
font-size: 12px;
color: #fff;
font-style: normal;
}
i.cart-select {
background-color: crimson;
border: 1px solid crimson;
}
span {
display: inline-block;
border-left: 3px solid crimson;
height: 28px;
margin: 9px 0;
padding-left: 8px;
line-height: 30px;
}
}
div {
padding-left: 46px;
position: relative;
height: 98px;
padding: 8px 14px 8px 148px;
i {
border: 1px solid #a9a9a9;
width: 18px;
height: 18px;
line-height: 18px;
border-radius: 18px;
position: absolute;
left: 13px;
top: 28px;
text-align: center;
font-size: 12px;
color: #fff;
font-style: normal;
}
i.cart-select {
background-color: crimson;
border: 1px solid crimson;
}
img {
width: 68px;
height: 68px;
background-color: #ccc;
position: absolute;
left: 58px;
top: 20px;
}
p.p-name {
font-size: 13px;
margin-top: 10px;
height: 30px;
}
p.p-price {
font-size: 13px;
height: 20px;
color: crimson;
}
p.p-num {
text-align: right;
padding-right: 20px;
span {
display: inline-block;
width: 18px;
height: 18px;
border: 1px solid crimson;
color: crimson;
border-radius: 9px;
text-align: center;
line-height: 18px;
}
input {
width: 28px;
border: none 0px;
outline: none;
text-align: center;
}
b {
font-weight: normal;
margin-left: 10px;
font-size: 13px;
}
}
}
}
}
}
.total-pad {
height: 58px;
width: 100%;
background-color: #383838;
position: fixed;
left: 0;
bottom: 40px;
i {
display: inline-block;
border: 1px solid #a9a9a9;
width: 18px;
height: 18px;
line-height: 18px;
border-radius: 18px;
background-color: #fff;
margin-left: 13px;
margin-top: 20px;
vertical-align: bottom;
height: 18px;
text-align: center;
font-size: 12px;
color: #fff;
font-style: italic;
}
i.cart-select {
background-color: crimson;
border: 1px solid crimson;
}
span {
color: #fff;
margin-left: 6px;
font-size: 13px;
b {
font-size: 15px;
}
}
button {
float: right;
height: 58px;
width: 120px;
border: 0 none;
background-color: #ddd;
color: #aaa;
font-size: 15px;
font-weight: bold;
}
}
</style>
2.事件总线
(1)DealerPlatform.Common->EventBusHelper->LocalEventBus
LocalEventBus.cs代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace DealerPlatform.Common.EventBusHelper
{
/// <summary>
/// 事件总线泛型类
/// </summary>
/// <typeparam name="T"></typeparam>
public class LocalEventBus<T>
where T : class
{
/// <summary>
/// 定义一个委托
/// </summary>
/// <param name="t"></param>
public delegate void LocalEventHandler(T t);
/// <summary>
/// 定义一个事件
/// </summary>
public event LocalEventHandler localEventHandler;
public async Task Publish(T t)
{
localEventHandler(t);
}
}
}
(2).在program中加入如下代码:
builder.Services.AddScoped(typeof(LocalEventBus<>));
(3).在ShoppingCartService的构造函数中注入:
LocalEventBus<List<ShoppingCartDto>> localEventBusShoppingCartDto
(4).在ShoppingCartService新增如下方法:
点击查看代码
public async Task<List<ShoppingCartDto>> GetShoppingCartDtos()
{
var carts = await CartRepo.GetListAsync();
var dtos = Mapper.Map<List<ShoppingCart>, List<ShoppingCartDto>>(carts);
LocalEventBusShoppingCartDto.Publish(dtos);
return dtos;
}
点击查看代码
public async Task LocalEventHandler(List<ShoppingCartDto> dtos)
{
var productNos = dtos.Select(s => s.ProductNo);
var productDtos = await GetProductByProductNos(productNos.ToArray());
dtos.ForEach(dto =>
{
var productDto = productDtos.FirstOrDefault(s => s.ProductNo == dto.ProductNo);
dto.ProductDto = productDto!;
});
}
完整代码如下:
点击查看代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper;
using DealerPlatform.Common.EventBusHelper;
using DealerPlatform.Core.Repository;
using DealerPlatform.Domain.GlobalDto;
using DealerPlatform.Domain.Models;
using DealerPlatform.Service.ProductApp.Dto;
using DealerPlatform.Service.ProductApp.Vo;
using DealerPlatform.Service.ShoppingCartApp.Dto;
namespace DealerPlatform.Service.ProductApp
{
public partial class ProductService : IProductService
{
public ProductService(
IRepository<Product> productRepo,
IRepository<ProductSale> productSaleRepo,
IRepository<ProductSaleAreaDiff> productSaleAreaDiffRepo,
IRepository<ProductPhoto> productPhotoRepo,
IMapper mapper,
LocalEventBus<List<ShoppingCartDto>> localEventBusShoppingCartDto)
{
ProductRepo = productRepo;
ProductSaleRepo = productSaleRepo;
ProductSaleAreaDiffRepo = productSaleAreaDiffRepo;
ProductPhotoRepo = productPhotoRepo;
Mapper = mapper;
localEventBusShoppingCartDto.localEventHandler += LocalEventHandler;
}
public IRepository<Product> ProductRepo { get; }
public IRepository<ProductSale> ProductSaleRepo { get; }
public IRepository<ProductSaleAreaDiff> ProductSaleAreaDiffRepo { get; }
public IRepository<ProductPhoto> ProductPhotoRepo { get; }
public IMapper Mapper { get; }
public async Task LocalEventHandler(List<ShoppingCartDto> dtos)
{
var productNos = dtos.Select(s => s.ProductNo);
var productDtos = await GetProductByProductNos(productNos.ToArray());
dtos.ForEach(dto =>
{
var productDto = productDtos.FirstOrDefault(s => s.ProductNo == dto.ProductNo);
dto.ProductDto = productDto!;
});
}
/// <summary>
/// 获取商品数据
/// </summary>
/// <returns></returns>
public async Task<IEnumerable<ProductDto>> GetProductDto(string searchText, string? productType, string systemNo, Dictionary<string, string> dicProductProps, PageWithSortDto dto)
{
dto.Sort ??= "ProductName";
int skipNum = (dto.PageIndex - 1) * dto.PageSize;
var bzgg = dicProductProps.ContainsKey("ProductBZGG") ? dicProductProps["ProductBZGG"] : null;
dicProductProps.TryGetValue("ProductCd", out string cd);
dicProductProps.TryGetValue("ProductPp", out string pp);
dicProductProps.TryGetValue("ProductXh", out string xh);
dicProductProps.TryGetValue("ProductCz", out string cz);
dicProductProps.TryGetValue("ProductHb", out string hb);
dicProductProps.TryGetValue("ProductHd", out string hd);
dicProductProps.TryGetValue("ProductGy", out string gy);
dicProductProps.TryGetValue("ProductHs", out string hs);
dicProductProps.TryGetValue("ProductMc", out string mc);
dicProductProps.TryGetValue("ProductDj", out string dj);
dicProductProps.TryGetValue("ProductGg", out string gg);
dicProductProps.TryGetValue("ProductYs", out string ys);
// var products = (from p in (await ProductRepo.GetListAsync())
// orderby p.GetType().GetProperty(sort).GetValue(p)
// select p).Skip(skipNum).Take(pageSize).ToList();
//获取商品主档信息
var products = ProductRepo.GetQueryable().Where(
s => (s.TypeNo == productType || string.IsNullOrWhiteSpace(productType))
&& (s.SysNo == systemNo || string.IsNullOrWhiteSpace(systemNo))
&& (s.ProductName.Contains(searchText) || string.IsNullOrWhiteSpace(searchText))
&& (bzgg == null || s.ProductBzgg == bzgg)
&& (cd == null || s.ProductCd == cd)
&& (pp == null || s.ProductPp == pp)
&& (xh == null || s.ProductXh == xh)
&& (cz == null || s.ProductCz == cz)
&& (hb == null || s.ProductHb == hb)
&& (hd == null || s.ProductHd == hd)
&& (gy == null || s.ProductGy == gy)
&& (hs == null || s.ProductHs == hs)
&& (mc == null || s.ProductMc == mc)
&& (dj == null || s.ProductDj == dj)
&& (gg == null || s.ProductGg == gg)
&& (ys == null || s.ProductYs == ys))
.OrderBy(s => dto.Sort).Skip(skipNum).Take(dto.PageSize);
var dtos = Mapper.Map<List<ProductDto>>(products);
var productPhotos = await GetProductPhotosByProductNo(dtos.Select(s => s.ProductNo).ToArray());
var productSales = await GetProductSalesByProductNo(dtos.Select(s => s.ProductNo).ToArray());
dtos.ForEach(s =>
{
s.ProductPhoto = productPhotos.FirstOrDefault(c => c.ProductNo == s.ProductNo);
s.ProductSale = productSales.FirstOrDefault(c => c.ProductNo == s.ProductNo);
});
//根据productId取到属性
return dtos;
}
public async Task<IEnumerable<ProductTypeVo>> GetProductType(string sysNo)
{
return await Task.Run(() =>
{
var productType = ProductRepo.GetQueryable().Where(s => s.SysNo == sysNo && !string.IsNullOrWhiteSpace(s.TypeName)).Select(s => new ProductTypeVo
{
TypeNo = s.TypeNo,
TypeName = s.TypeName,
}).Distinct().ToList();
return productType;
});
}
/// <summary>
/// 商品类型查询列表
/// </summary>
/// <returns></returns>
public async Task<List<BelongTypeVo>> GetBelongTypesAsync()
{
var data = ProductRepo.GetQueryable().Select(s => new BelongTypeVo
{
SysNo = s.SysNo,
BelongTypeName = s.BelongTypeName,
// BelongTypeNo = s.BelongTypeNo
}).Distinct();
return data.ToList();
}
/// <summary>
/// 获取所有物品属性
/// </summary>
/// <param name="belongTypeNo"></param>
/// <param name="TypeNo"></param>
/// <returns></returns>
public async Task<Dictionary<string, IEnumerable<string>>> GetProductProps(string belongTypeNo, string typeNo)
{
Dictionary<string, IEnumerable<string>> dicProductType = new();
var products = await ProductRepo.GetListAsync(m => m.SysNo == belongTypeNo && (m.TypeNo == typeNo || string.IsNullOrWhiteSpace(typeNo)));
dicProductType.Add("ProductBzgg|包装规格", products.Select(s => s.ProductBzgg).Distinct().Where(m => !string.IsNullOrEmpty(m)).ToList());
dicProductType.Add("ProductCd|产地", products.Select(s => s.ProductCd).Distinct().Where(m => !string.IsNullOrEmpty(m)).ToList());
dicProductType.Add("ProductCz|材质", products.Select(s => s.ProductCz).Distinct().Where(m => !string.IsNullOrEmpty(m)).ToList());
dicProductType.Add("ProductDj|等级", products.Select(s => s.ProductDj).Distinct().Where(m => !string.IsNullOrEmpty(m)).ToList());
dicProductType.Add("ProductGg|规格", products.Select(s => s.ProductGg).Distinct().Where(m => !string.IsNullOrEmpty(m)).ToList());
dicProductType.Add("ProductGy|工艺", products.Select(s => s.ProductGy).Distinct().Where(m => !string.IsNullOrEmpty(m)).ToList());
dicProductType.Add("ProductHb|环保", products.Select(s => s.ProductHb).Distinct().Where(m => !string.IsNullOrEmpty(m)).ToList());
dicProductType.Add("ProductHd|厚度", products.Select(s => s.ProductHd).Distinct().Where(m => !string.IsNullOrEmpty(m)).ToList());
dicProductType.Add("ProductHs|花色", products.Select(s => s.ProductHs).Distinct().Where(m => !string.IsNullOrEmpty(m)).ToList());
dicProductType.Add("ProductMc|面材", products.Select(s => s.ProductMc).Distinct().Where(m => !string.IsNullOrEmpty(m)).ToList());
dicProductType.Add("ProductPp|品牌", products.Select(s => s.ProductPp).Distinct().Where(m => !string.IsNullOrEmpty(m)).ToList());
dicProductType.Add("ProductXh|型号", products.Select(s => s.ProductXh).Distinct().Where(m => !string.IsNullOrEmpty(m)).ToList());
dicProductType.Add("ProductYs|颜色", products.Select(s => s.ProductYs).Distinct().Where(m => !string.IsNullOrEmpty(m)).ToList());
return dicProductType;
}
public async Task<List<ProductDto>> GetProductByProductNos(params string[] postProductNos)
{
var productNos = await ProductRepo.GetListAsync(s => postProductNos.Distinct().Contains(s.ProductNo));
var productDto = Mapper.Map<List<Product>, List<ProductDto>>(productNos);
return productDto;
}
}
}
3.前端改造
点击查看代码
<template>
<div>
<div class="cart-list">
<ul>
<li>
<p>
<i></i>
<span>处理产品</span>
</p>
<div>
<i></i>
<img src="" alt="" />
<p class="p-name">0.9密度板</p>
<p class="p-price">¥100.00</p>
<p class="p-num">
<span class="sub-num" @click="onSubNum()">-</span>
<input
type="text"
name=""
id=""
:value="buyNum"
@change="changeNum()"
/>
<span class="add0num" @click="onAddNum()">+</span>
<b>块</b>
</p>
</div>
<div>
<i class="cart-select">✔</i>
<img src="" alt="" />
<p class="p-name">0.9密度板</p>
<p class="p-price">¥100.00</p>
<p class="p-num">
<span class="sub-num" @click="onSubNum()">-</span>
<input
type="text"
name=""
id=""
:value="buyNum"
@change="changeNum()"
/>
<span class="add0num" @click="onAddNum()">+</span>
<b>块</b>
</p>
</div>
</li>
<li>
<p>
<i class="cart-select">✔</i>
<span>处理产品</span>
</p>
<div>
<i class="cart-select">✔</i>
<img src="" alt="" />
<p class="p-name">0.9密度板</p>
<p class="p-price">¥100.00</p>
<p class="p-num">
<span class="sub-num" @click="onSubNum()">-</span>
<input
type="text"
name=""
id=""
:value="buyNum"
@change="changeNum()"
/>
<span class="add0num" @click="onAddNum()">+</span>
<b>块</b>
</p>
</div>
</li>
<li>
<p>
<i></i>
<span>处理产品</span>
</p>
<div>
<i></i>
<img src="" alt="" />
<p class="p-name">0.9密度板</p>
<p class="p-price">¥100.00</p>
<p class="p-num">
<span class="sub-num" @click="onSubNum()">-</span>
<input
type="text"
name=""
id=""
:value="buyNum"
@change="changeNum()"
/>
<span class="add0num" @click="onAddNum()">+</span>
<b>块</b>
</p>
</div>
<div>
<i></i>
<img src="" alt="" />
<p class="p-name">0.9密度板</p>
<p class="p-price">¥100.00</p>
<p class="p-num">
<span class="sub-num" @click="onSubNum()">-</span>
<input
type="text"
name=""
id=""
:value="buyNum"
@change="changeNum()"
/>
<span class="add0num" @click="onAddNum()">+</span>
<b>块</b>
</p>
</div>
</li>
</ul>
</div>
<div class="total-pad">
<i></i>
<span>全选</span>
<span>
合计:¥ <b>{{ totalPrice | price }}</b>
</span>
<button>确定下单</button>
</div>
</div>
</template>
<script>
import { reactive, toRefs } from 'vue'
import { getCarts } from '@/httpRequests/ShoppingCartRequest'
export default {
// mounted() {
// this.$store.comm
// this.$store.dispatch('setFootMenuIndexAsync', 2)
// },
setup() {
const shoppingCartInfo = reactive({
carts: [],
buyNum: 1,
totalPrice: 6888,
onAddNum() {
shoppingCartInfo.buyNum++
},
onSubNum() {
if (shoppingCartInfo.buyNum > 1) {
shoppingCartInfo.buyNum--
}
},
onChangeNum() {
// var currNum = event.target.value
// if (!isNaN(currNum) && currNum > 0) {
// shoppingCartInfo.buyNum = currNum
// } else {
// event.target.value = shoppingCartInfo.buyNum
// }
},
onGetShoppingCarts: async () => {
var customerNo = localStorage['CustomerNo']
var res = await getCarts(customerNo)
shoppingCartInfo.carts = res
},
})
return { ...toRefs(shoppingCartInfo) }
},
}
</script>
<style lang="scss" scoped>
.cart-list {
text-align: left;
ul {
margin-bottom: 108px;
li {
background-color: #fff;
margin-bottom: 12px;
> p {
padding-left: 46px;
position: relative;
height: 46px;
border-bottom: 1px solid #ddd;
i {
border: 1px solid #a9a9a9;
width: 18px;
height: 18px;
line-height: 18px;
border-radius: 18px;
position: absolute;
left: 13px;
top: 13px;
text-align: center;
font-size: 12px;
color: #fff;
font-style: normal;
}
i.cart-select {
background-color: crimson;
border: 1px solid crimson;
}
span {
display: inline-block;
border-left: 3px solid crimson;
height: 28px;
margin: 9px 0;
padding-left: 8px;
line-height: 30px;
}
}
div {
padding-left: 46px;
position: relative;
height: 98px;
padding: 8px 14px 8px 148px;
i {
border: 1px solid #a9a9a9;
width: 18px;
height: 18px;
line-height: 18px;
border-radius: 18px;
position: absolute;
left: 13px;
top: 28px;
text-align: center;
font-size: 12px;
color: #fff;
font-style: normal;
}
i.cart-select {
background-color: crimson;
border: 1px solid crimson;
}
img {
width: 68px;
height: 68px;
background-color: #ccc;
position: absolute;
left: 58px;
top: 20px;
}
p.p-name {
font-size: 13px;
margin-top: 10px;
height: 30px;
}
p.p-price {
font-size: 13px;
height: 20px;
color: crimson;
}
p.p-num {
text-align: right;
padding-right: 20px;
span {
display: inline-block;
width: 18px;
height: 18px;
border: 1px solid crimson;
color: crimson;
border-radius: 9px;
text-align: center;
line-height: 18px;
}
input {
width: 28px;
border: none 0px;
outline: none;
text-align: center;
}
b {
font-weight: normal;
margin-left: 10px;
font-size: 13px;
}
}
}
}
}
}
.total-pad {
height: 58px;
width: 100%;
background-color: #383838;
position: fixed;
left: 0;
bottom: 40px;
i {
display: inline-block;
border: 1px solid #a9a9a9;
width: 18px;
height: 18px;
line-height: 18px;
border-radius: 18px;
background-color: #fff;
margin-left: 13px;
margin-top: 20px;
vertical-align: bottom;
height: 18px;
text-align: center;
font-size: 12px;
color: #fff;
font-style: italic;
}
i.cart-select {
background-color: crimson;
border: 1px solid crimson;
}
span {
color: #fff;
margin-left: 6px;
font-size: 13px;
b {
font-size: 15px;
}
}
button {
float: right;
height: 58px;
width: 120px;
border: 0 none;
background-color: #ddd;
color: #aaa;
font-size: 15px;
font-weight: bold;
}
}
</style>
标签:font,string,color,height,增键,NET,18px,border,购物车 来源: https://www.cnblogs.com/humblexwang/p/16341088.html