【新增】增加商品列表dto类及查询方法,首页【商品组件】【商品tab组】【仿点餐界面】【栏目列表页】【推荐商品列表】进行替换。

【优化】优化普通商品及营销商品内页不同dom之间间距。微调其他页面样式
【调整】移除.net5升级到.net6保留的startup.cs文件,使用program.cs
This commit is contained in:
大灰灰
2022-11-06 05:38:42 +08:00
parent 84fbcfffbd
commit 45877f0d5c
23 changed files with 1316 additions and 819 deletions

View File

@@ -460,4 +460,18 @@ namespace CoreCms.Net.Configuration
}
/// <summary>
/// 当字段为空图片,替换前端的地址
/// </summary>
public static class EmptyOrNullImagePath
{
/// <summary>
/// 图片地址
/// </summary>
public static string GoodImage = "/static/images/common/empty.png";
}
}

View File

@@ -0,0 +1,150 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace CoreCms.Net.DTO.ComponentsDTO
{
/// <summary>
/// 商品列表中需要的字段
/// </summary>
public class GoodListDTO
{
/// <summary>
/// 商品ID
/// </summary>
public int id { get; set; }
/// <summary>
/// 商品名称
/// </summary>
public string name { get; set; }
/// <summary>
/// 商品简介
/// </summary>
public string brief { get; set; }
/// <summary>
/// 缩略图
/// </summary>
public string image { get; set; }
/// <summary>
/// 视频
/// </summary>
public string video { get; set; }
/// <summary>
/// 商品分类
/// </summary>
public int goodsCategoryId { get; set; }
/// <summary>
/// 商品类别
/// </summary>
public int goodsTypeId { get; set; }
/// <summary>
/// 品牌
/// </summary>
public int brandId { get; set; }
/// <summary>
/// 是否虚拟商品
/// </summary>
public bool isNomalVirtual { get; set; }
/// <summary>
/// 商品单位
/// </summary>
public string unit { get; set; }
/// <summary>
/// 评论次数
/// </summary>
public int commentsCount { get; set; }
/// <summary>
/// 浏览次数
/// </summary>
public int viewCount { get; set; }
/// <summary>
/// 购买次数
/// </summary>
public int buyCount { get; set; }
/// <summary>
/// 商品排序
/// </summary>
public int sort { get; set; }
/// <summary>
/// 标签id逗号分隔
/// </summary>
public string labelIds { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime? createTime { get; set; }
/// <summary>
/// 是否推荐
/// </summary>
public bool isRecommend { get; set; }
/// <summary>
/// 是否热门
/// </summary>
public bool isHot { get; set; }
/// <summary>
/// 初始销量
/// </summary>
public int initialSales { get; set; }
/// <summary>
/// 货品价格
/// </summary>
public System.Decimal price { get; set; }
/// <summary>
/// 货品市场价
/// </summary>
public System.Decimal mktprice { get; set; }
/// <summary>
/// 积分可抵扣金额
/// </summary>
public System.Decimal pointsDeduction { get; set; }
/// <summary>
/// 赠送积分
/// </summary>
public System.Int32 points { get; set; }
/// <summary>
/// 重量(千克)
/// </summary>
public System.Decimal weight { get; set; }
/// <summary>
/// 库存
/// </summary>
public System.Int32 stock { get; set; }
}
}

View File

@@ -12,6 +12,7 @@ using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
using CoreCms.Net.DTO.ComponentsDTO;
using CoreCms.Net.Model.Entities;
using CoreCms.Net.Model.FromBody;
using CoreCms.Net.Model.ViewModels.Basics;
@@ -71,7 +72,7 @@ namespace CoreCms.Net.IRepository
/// <param name="number">数量</param>
/// <param name="isRecommend">是否推荐</param>
/// <returns></returns>
Task<List<CoreCmsGoods>> GetGoodsRecommendList(int number, bool isRecommend = false);
Task<List<GoodListDTO>> GetGoodsRecommendList(int number, bool isRecommend = false);
/// <summary>
/// 获取数据总数
@@ -137,6 +138,19 @@ namespace CoreCms.Net.IRepository
int pageSize = 20, bool blUseNoLock = false);
/// <summary>
/// 重写根据条件及自定义排序查询分页数据返回DTO
/// </summary>
/// <param name="predicate"></param>
/// <param name="orderBy"></param>
/// <param name="pageIndex">当前页面索引</param>
/// <param name="pageSize">分布大小</param>
/// <param name="blUseNoLock">是否使用WITH(NOLOCK)</param>
/// <returns></returns>
Task<IPageList<GoodListDTO>> QueryPageByDTOAsync(Expression<Func<GoodListDTO, bool>> predicate,
string orderBy = "", int pageIndex = 1, int pageSize = 20, bool blUseNoLock = false);
/// <summary>
/// 根据条件查询代理池商品分页数据
/// </summary>
@@ -183,5 +197,35 @@ namespace CoreCms.Net.IRepository
Task<List<CoreCmsGoods>> QueryGoodWithDefaultProductAsync(Expression<Func<CoreCmsGoods, bool>> predicate,
Expression<Func<CoreCmsGoods, object>> orderByPredicate, OrderByType orderByType, bool blUseNoLock = false);
/// <summary>
/// 根据条件查询一定数量数据(用于组件)
/// </summary>
/// <param name="predicate">条件表达式树</param>
/// <param name="take">获取数量</param>
/// <param name="orderByPredicate">排序字段</param>
/// <param name="orderByType">排序顺序</param>
/// <param name="blUseNoLock">是否使用WITH(NOLOCK)</param>
/// <param name="isDataCache">是否缓存</param>
/// <param name="cacheTimes">缓存时间(分钟)</param>
/// <returns></returns>
Task<List<GoodListDTO>> QueryListByComponentsAsync(Expression<Func<GoodListDTO, bool>> predicate, int take,
Expression<Func<GoodListDTO, object>> orderByPredicate, OrderByType orderByType, bool blUseNoLock = false,
bool isDataCache = false, int cacheTimes = int.MaxValue);
/// <summary>
/// 根据条件查询一定数量数据(用于组件)
/// </summary>
/// <param name="predicate">条件表达式树</param>
/// <param name="take">获取数量</param>
/// <param name="orderByType">排序顺序</param>
/// <param name="blUseNoLock">是否使用WITH(NOLOCK)</param>
/// <param name="isDataCache">是否缓存</param>
/// <param name="cacheTimes">缓存时间(分钟)</param>
/// <returns></returns>
Task<List<GoodListDTO>> QueryListByComponentsAsync(Expression<Func<GoodListDTO, bool>> predicate, int take, string orderByType = "", bool blUseNoLock = false,
bool isDataCache = false, int cacheTimes = int.MaxValue);
}
}

View File

@@ -12,6 +12,7 @@ using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
using CoreCms.Net.DTO.ComponentsDTO;
using CoreCms.Net.Model.Entities;
using CoreCms.Net.Model.FromBody;
using CoreCms.Net.Model.ViewModels.Basics;
@@ -135,7 +136,7 @@ namespace CoreCms.Net.IServices
/// <param name="number"></param>
/// <param name="isRecommend">是否推荐</param>
/// <returns></returns>
Task<List<CoreCmsGoods>> GetGoodsRecommendList(int number, bool isRecommend = false);
Task<List<GoodListDTO>> GetGoodsRecommendList(int number, bool isRecommend = false);
/// <summary>
@@ -201,6 +202,17 @@ namespace CoreCms.Net.IServices
string orderBy = "", int pageIndex = 1,
int pageSize = 20, bool blUseNoLock = false);
/// <summary>
/// 重写根据条件及自定义排序查询分页数据返回DTO
/// </summary>
/// <param name="predicate"></param>
/// <param name="orderBy"></param>
/// <param name="pageIndex">当前页面索引</param>
/// <param name="pageSize">分布大小</param>
/// <param name="blUseNoLock">是否使用WITH(NOLOCK)</param>
/// <returns></returns>
Task<IPageList<GoodListDTO>> QueryPageByDTOAsync(Expression<Func<GoodListDTO, bool>> predicate,
string orderBy = "", int pageIndex = 1, int pageSize = 20, bool blUseNoLock = false);
/// <summary>
/// 重写根据条件及自定义排序查询分页数据
@@ -275,5 +287,35 @@ namespace CoreCms.Net.IServices
Task<List<CoreCmsGoods>> QueryGoodWithDefaultProductAsync(Expression<Func<CoreCmsGoods, bool>> predicate,
Expression<Func<CoreCmsGoods, object>> orderByPredicate, OrderByType orderByType, bool blUseNoLock = false);
/// <summary>
/// 根据条件查询一定数量数据(用于组件)
/// </summary>
/// <param name="predicate">条件表达式树</param>
/// <param name="take">获取数量</param>
/// <param name="orderByPredicate">排序字段</param>
/// <param name="orderByType">排序顺序</param>
/// <param name="blUseNoLock">是否使用WITH(NOLOCK)</param>
/// <param name="isDataCache">是否缓存</param>
/// <param name="cacheTimes">缓存时间(分钟)</param>
/// <returns></returns>
Task<List<GoodListDTO>> QueryListByComponentsAsync(Expression<Func<GoodListDTO, bool>> predicate, int take,
Expression<Func<GoodListDTO, object>> orderByPredicate, OrderByType orderByType, bool blUseNoLock = false,
bool isDataCache = false, int cacheTimes = int.MaxValue);
/// <summary>
/// 根据条件查询一定数量数据(用于组件)
/// </summary>
/// <param name="predicate">条件表达式树</param>
/// <param name="take">获取数量</param>
/// <param name="orderByType">排序顺序</param>
/// <param name="blUseNoLock">是否使用WITH(NOLOCK)</param>
/// <param name="isDataCache">是否缓存</param>
/// <param name="cacheTimes">缓存时间(分钟)</param>
/// <returns></returns>
Task<List<GoodListDTO>> QueryListByComponentsAsync(Expression<Func<GoodListDTO, bool>> predicate, int take, string orderByType = "", bool blUseNoLock = false,
bool isDataCache = false, int cacheTimes = int.MaxValue);
}
}

View File

@@ -13,6 +13,7 @@ using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using CoreCms.Net.Configuration;
using CoreCms.Net.DTO.ComponentsDTO;
using CoreCms.Net.IRepository;
using CoreCms.Net.IRepository.UnitOfWork;
using CoreCms.Net.Loging;
@@ -278,6 +279,8 @@ namespace CoreCms.Net.Repository
}
}
}
//删除dto缓存
DbClient.DataCache.RemoveDataCache(nameof(GoodListDTO));
jm.data = entity;
jm.code = bl ? 0 : 1;
@@ -733,6 +736,10 @@ namespace CoreCms.Net.Repository
}
}
//事物处理过程结束
//删除dto缓存
DbClient.DataCache.RemoveDataCache(nameof(GoodListDTO));
jm.code = bl ? 0 : 1;
jm.msg = bl ? GlobalConstVars.EditSuccess : GlobalConstVars.EditFailure;
@@ -756,6 +763,12 @@ namespace CoreCms.Net.Repository
jm.code = bl ? 0 : 1;
jm.msg = bl ? GlobalConstVars.DeleteSuccess : GlobalConstVars.DeleteFailure;
if (bl)
{
//删除dto缓存
DbClient.DataCache.RemoveDataCache(nameof(GoodListDTO));
}
return jm;
}
@@ -882,54 +895,41 @@ namespace CoreCms.Net.Repository
/// <param name="number"></param>
/// <param name="isRecommend"></param>
/// <returns></returns>
public async Task<List<CoreCmsGoods>> GetGoodsRecommendList(int number, bool isRecommend = false)
public async Task<List<GoodListDTO>> GetGoodsRecommendList(int number, bool isRecommend = false)
{
var list = new List<CoreCmsGoods>();
var list = new List<GoodListDTO>();
if (isRecommend)
{
list = await DbClient.Queryable<CoreCmsGoods, CoreCmsProducts>((good, pd) => new JoinQueryInfos(
JoinType.Left, good.id == pd.goodsId))
.Where((good, pd) => pd.isDefalut == true && pd.isDel == false && good.isRecommend == true && good.isDel == false && good.isMarketable == true)
.Select((good, pd) => new CoreCmsGoods
.Select((good, pd) => new GoodListDTO()
{
id = good.id,
bn = good.bn,
name = good.name,
brief = good.brief,
image = good.image,
images = good.images,
image = !SqlFunc.IsNullOrEmpty(good.image) ? good.image : EmptyOrNullImagePath.GoodImage,
video = good.video,
productsDistributionType = good.productsDistributionType,
goodsCategoryId = good.goodsCategoryId,
goodsTypeId = good.goodsTypeId,
brandId = good.brandId,
isNomalVirtual = good.isNomalVirtual,
isMarketable = good.isMarketable,
unit = good.unit,
//intro = good.intro,
spesDesc = good.spesDesc,
parameters = good.parameters,
commentsCount = good.commentsCount,
viewCount = good.viewCount,
buyCount = good.buyCount,
uptime = good.uptime,
downtime = good.downtime,
buyCount = SqlFunc.Subqueryable<CoreCmsOrderItem>()
.LeftJoin<CoreCmsOrder>((sOrderItem, sOrder) => sOrder.orderId == sOrderItem.orderId)
.Where((sOrderItem, sOrder) => sOrderItem.goodsId == good.id && (sOrder.payStatus == (int)GlobalEnumVars.OrderPayStatus.Yes || sOrder.payStatus == (int)GlobalEnumVars.OrderPayStatus.PartialYes))
.Sum(p => p.nums),
sort = good.sort,
labelIds = good.labelIds,
newSpec = good.newSpec,
openSpec = good.openSpec,
createTime = good.createTime,
updateTime = good.updateTime,
isRecommend = good.isRecommend,
isHot = good.isHot,
isDel = good.isDel,
sn = pd.sn,
price = pd.price,
costprice = pd.costprice,
mktprice = pd.mktprice,
stock = pd.stock,
freezeStock = pd.freezeStock,
pointsDeduction = pd.pointsDeduction,
points = pd.points,
weight = pd.weight,
@@ -955,46 +955,33 @@ namespace CoreCms.Net.Repository
{
list = await DbClient.Queryable<CoreCmsGoods, CoreCmsProducts>((good, pd) => new JoinQueryInfos(
JoinType.Left, good.id == pd.goodsId))
.Where((good, pd) => pd.isDefalut == true && pd.isDel == false)
.Select((good, pd) => new CoreCmsGoods
.Where((good, pd) => pd.isDefalut == true && pd.isDel == false && good.isRecommend == true && good.isDel == false && good.isMarketable == true)
.Select((good, pd) => new GoodListDTO
{
id = good.id,
bn = good.bn,
name = good.name,
brief = good.brief,
image = good.image,
images = good.images,
image = !SqlFunc.IsNullOrEmpty(good.image) ? good.image : EmptyOrNullImagePath.GoodImage,
video = good.video,
productsDistributionType = good.productsDistributionType,
goodsCategoryId = good.goodsCategoryId,
goodsTypeId = good.goodsTypeId,
brandId = good.brandId,
isNomalVirtual = good.isNomalVirtual,
isMarketable = good.isMarketable,
unit = good.unit,
//intro = good.intro,
spesDesc = good.spesDesc,
parameters = good.parameters,
commentsCount = good.commentsCount,
viewCount = good.viewCount,
buyCount = good.buyCount,
uptime = good.uptime,
downtime = good.downtime,
buyCount = SqlFunc.Subqueryable<CoreCmsOrderItem>()
.LeftJoin<CoreCmsOrder>((sOrderItem, sOrder) => sOrder.orderId == sOrderItem.orderId)
.Where((sOrderItem, sOrder) => sOrderItem.goodsId == good.id && (sOrder.payStatus == (int)GlobalEnumVars.OrderPayStatus.Yes || sOrder.payStatus == (int)GlobalEnumVars.OrderPayStatus.PartialYes))
.Sum(p => p.nums),
sort = good.sort,
labelIds = good.labelIds,
newSpec = good.newSpec,
openSpec = good.openSpec,
createTime = good.createTime,
updateTime = good.updateTime,
isRecommend = good.isRecommend,
isHot = good.isHot,
isDel = good.isDel,
sn = pd.sn,
price = pd.price,
costprice = pd.costprice,
mktprice = pd.mktprice,
stock = pd.stock,
freezeStock = pd.freezeStock,
pointsDeduction = pd.pointsDeduction,
points = pd.points,
weight = pd.weight,
@@ -1655,6 +1642,113 @@ namespace CoreCms.Net.Repository
}
#endregion
#region DTO
/// <summary>
/// 重写根据条件及自定义排序查询分页数据返回DTO
/// </summary>
/// <param name="predicate"></param>
/// <param name="orderBy"></param>
/// <param name="pageIndex">当前页面索引</param>
/// <param name="pageSize">分布大小</param>
/// <param name="blUseNoLock">是否使用WITH(NOLOCK)</param>
/// <returns></returns>
public async Task<IPageList<GoodListDTO>> QueryPageByDTOAsync(Expression<Func<GoodListDTO, bool>> predicate, string orderBy = "",
int pageIndex = 1, int pageSize = 20, bool blUseNoLock = false)
{
RefAsync<int> totalCount = 0;
List<GoodListDTO> page;
if (blUseNoLock)
{
page = await DbClient.Queryable<CoreCmsGoods, CoreCmsProducts>((good, pd) => new JoinQueryInfos(
JoinType.Left, good.id == pd.goodsId))
.Where((good, pd) => pd.isDefalut == true && pd.isDel == false && good.isMarketable == true && good.isDel == false)
.Select((good, pd) => new GoodListDTO
{
id = good.id,
name = good.name,
brief = good.brief,
image = !SqlFunc.IsNullOrEmpty(good.image) ? good.image : EmptyOrNullImagePath.GoodImage,
video = good.video,
goodsCategoryId = good.goodsCategoryId,
goodsTypeId = good.goodsTypeId,
brandId = good.brandId,
isNomalVirtual = good.isNomalVirtual,
unit = good.unit,
commentsCount = good.commentsCount,
viewCount = good.viewCount,
buyCount = SqlFunc.Subqueryable<CoreCmsOrderItem>()
.LeftJoin<CoreCmsOrder>((sOrderItem, sOrder) => sOrder.orderId == sOrderItem.orderId)
.Where((sOrderItem, sOrder) => sOrderItem.goodsId == good.id && (sOrder.payStatus == (int)GlobalEnumVars.OrderPayStatus.Yes || sOrder.payStatus == (int)GlobalEnumVars.OrderPayStatus.PartialYes))
.Sum(p => p.nums),
sort = good.sort,
labelIds = good.labelIds,
createTime = good.createTime,
isRecommend = good.isRecommend,
isHot = good.isHot,
price = pd.price,
mktprice = pd.mktprice,
stock = pd.stock,
pointsDeduction = pd.pointsDeduction,
points = pd.points,
weight = pd.weight,
initialSales = good.initialSales,
})
.With(SqlWith.NoLock)
.MergeTable()
.Where(predicate)
.OrderBy(orderBy)
.ToPageListAsync(pageIndex, pageSize, totalCount);
}
else
{
page = await DbClient.Queryable<CoreCmsGoods, CoreCmsProducts>((good, pd) => new JoinQueryInfos(
JoinType.Left, good.id == pd.goodsId))
.Where((good, pd) => pd.isDefalut == true && pd.isDel == false && good.isMarketable == true && good.isDel == false)
.Select((good, pd) => new GoodListDTO
{
id = good.id,
name = good.name,
brief = good.brief,
image = !SqlFunc.IsNullOrEmpty(good.image) ? good.image : EmptyOrNullImagePath.GoodImage,
video = good.video,
goodsCategoryId = good.goodsCategoryId,
goodsTypeId = good.goodsTypeId,
brandId = good.brandId,
isNomalVirtual = good.isNomalVirtual,
unit = good.unit,
commentsCount = good.commentsCount,
viewCount = good.viewCount,
buyCount = SqlFunc.Subqueryable<CoreCmsOrderItem>()
.LeftJoin<CoreCmsOrder>((sOrderItem, sOrder) => sOrder.orderId == sOrderItem.orderId)
.Where((sOrderItem, sOrder) => sOrderItem.goodsId == good.id && (sOrder.payStatus == (int)GlobalEnumVars.OrderPayStatus.Yes || sOrder.payStatus == (int)GlobalEnumVars.OrderPayStatus.PartialYes))
.Sum(p => p.nums),
sort = good.sort,
labelIds = good.labelIds,
createTime = good.createTime,
isRecommend = good.isRecommend,
isHot = good.isHot,
price = pd.price,
mktprice = pd.mktprice,
stock = pd.stock,
pointsDeduction = pd.pointsDeduction,
points = pd.points,
weight = pd.weight,
initialSales = good.initialSales,
})
.MergeTable()
.Where(predicate)
.OrderBy(orderBy)
.ToPageListAsync(pageIndex, pageSize, totalCount);
}
var list = new PageList<GoodListDTO>(page, pageIndex, pageSize, totalCount);
return list;
}
#endregion
#region
@@ -2056,5 +2150,219 @@ namespace CoreCms.Net.Repository
#endregion
#region
/// <summary>
/// 根据条件查询一定数量数据(用于组件)
/// </summary>
/// <param name="predicate">条件表达式树</param>
/// <param name="take">获取数量</param>
/// <param name="orderByPredicate">排序字段</param>
/// <param name="orderByType">排序顺序</param>
/// <param name="blUseNoLock">是否使用WITH(NOLOCK)</param>
/// <param name="isDataCache">是否缓存</param>
/// <param name="cacheTimes">缓存时间(分钟)</param>
/// <returns></returns>
public async Task<List<GoodListDTO>> QueryListByComponentsAsync(Expression<Func<GoodListDTO, bool>> predicate, int take,
Expression<Func<GoodListDTO, object>> orderByPredicate, OrderByType orderByType, bool blUseNoLock = false, bool isDataCache = false, int cacheTimes = int.MaxValue)
{
List<GoodListDTO> page;
if (blUseNoLock)
{
page = await DbClient.Queryable<CoreCmsGoods, CoreCmsProducts>((good, pd) => new JoinQueryInfos(
JoinType.Left, good.id == pd.goodsId))
.Where((good, pd) => pd.isDefalut == true && pd.isDel == false && good.isMarketable == true && good.isDel == false)
.Select((good, pd) => new GoodListDTO
{
id = good.id,
name = good.name,
brief = good.brief,
image = !SqlFunc.IsNullOrEmpty(good.image) ? good.image : EmptyOrNullImagePath.GoodImage,
video = good.video,
goodsCategoryId = good.goodsCategoryId,
goodsTypeId = good.goodsTypeId,
brandId = good.brandId,
isNomalVirtual = good.isNomalVirtual,
unit = good.unit,
commentsCount = good.commentsCount,
viewCount = good.viewCount,
buyCount = SqlFunc.Subqueryable<CoreCmsOrderItem>()
.LeftJoin<CoreCmsOrder>((sOrderItem, sOrder) => sOrder.orderId == sOrderItem.orderId)
.Where((sOrderItem, sOrder) => sOrderItem.goodsId == good.id && (sOrder.payStatus == (int)GlobalEnumVars.OrderPayStatus.Yes || sOrder.payStatus == (int)GlobalEnumVars.OrderPayStatus.PartialYes))
.Sum(p => p.nums),
sort = good.sort,
labelIds = good.labelIds,
createTime = good.createTime,
isRecommend = good.isRecommend,
isHot = good.isHot,
price = pd.price,
mktprice = pd.mktprice,
stock = pd.stock,
pointsDeduction = pd.pointsDeduction,
points = pd.points,
weight = pd.weight,
initialSales = good.initialSales,
})
.With(SqlWith.NoLock)
.MergeTable()
.WhereIF(predicate != null, predicate)
.OrderByIF(orderByPredicate != null, orderByPredicate, orderByType)
.Take(take)
.WithCacheIF(isDataCache, cacheTimes)
.ToListAsync();
}
else
{
page = await DbClient.Queryable<CoreCmsGoods, CoreCmsProducts>((good, pd) => new JoinQueryInfos(
JoinType.Left, good.id == pd.goodsId))
.Where((good, pd) => pd.isDefalut == true && pd.isDel == false && good.isMarketable == true && good.isDel == false)
.Select((good, pd) => new GoodListDTO
{
id = good.id,
name = good.name,
brief = good.brief,
image = !SqlFunc.IsNullOrEmpty(good.image) ? good.image : EmptyOrNullImagePath.GoodImage,
video = good.video,
goodsCategoryId = good.goodsCategoryId,
goodsTypeId = good.goodsTypeId,
brandId = good.brandId,
isNomalVirtual = good.isNomalVirtual,
unit = good.unit,
commentsCount = good.commentsCount,
viewCount = good.viewCount,
buyCount = SqlFunc.Subqueryable<CoreCmsOrderItem>()
.LeftJoin<CoreCmsOrder>((sOrderItem, sOrder) => sOrder.orderId == sOrderItem.orderId)
.Where((sOrderItem, sOrder) => sOrderItem.goodsId == good.id && (sOrder.payStatus == (int)GlobalEnumVars.OrderPayStatus.Yes || sOrder.payStatus == (int)GlobalEnumVars.OrderPayStatus.PartialYes))
.Sum(p => p.nums),
sort = good.sort,
labelIds = good.labelIds,
createTime = good.createTime,
isRecommend = good.isRecommend,
isHot = good.isHot,
price = pd.price,
mktprice = pd.mktprice,
stock = pd.stock,
pointsDeduction = pd.pointsDeduction,
points = pd.points,
weight = pd.weight,
initialSales = good.initialSales,
})
.MergeTable()
.WhereIF(predicate != null, predicate)
.OrderByIF(orderByPredicate != null, orderByPredicate, orderByType)
.WithCacheIF(isDataCache, cacheTimes)
.Take(take).ToListAsync();
}
return page;
}
#endregion
#region
/// <summary>
/// 根据条件查询一定数量数据(用于组件)
/// </summary>
/// <param name="predicate">条件表达式树</param>
/// <param name="take">获取数量</param>
/// <param name="orderByType">排序顺序</param>
/// <param name="blUseNoLock">是否使用WITH(NOLOCK)</param>
/// <param name="isDataCache">是否缓存</param>
/// <param name="cacheTimes">缓存时间(分钟)</param>
/// <returns></returns>
public async Task<List<GoodListDTO>> QueryListByComponentsAsync(Expression<Func<GoodListDTO, bool>> predicate, int take, string orderByType = "", bool blUseNoLock = false, bool isDataCache = false, int cacheTimes = int.MaxValue)
{
List<GoodListDTO> page;
if (blUseNoLock)
{
page = await DbClient.Queryable<CoreCmsGoods, CoreCmsProducts>((good, pd) => new JoinQueryInfos(
JoinType.Left, good.id == pd.goodsId))
.Where((good, pd) => pd.isDefalut == true && pd.isDel == false && good.isMarketable == true && good.isDel == false)
.Select((good, pd) => new GoodListDTO
{
id = good.id,
name = good.name,
brief = good.brief,
image = !SqlFunc.IsNullOrEmpty(good.image) ? good.image : EmptyOrNullImagePath.GoodImage,
video = good.video,
goodsCategoryId = good.goodsCategoryId,
goodsTypeId = good.goodsTypeId,
brandId = good.brandId,
isNomalVirtual = good.isNomalVirtual,
unit = good.unit,
commentsCount = good.commentsCount,
viewCount = good.viewCount,
buyCount = SqlFunc.Subqueryable<CoreCmsOrderItem>()
.LeftJoin<CoreCmsOrder>((sOrderItem, sOrder) => sOrder.orderId == sOrderItem.orderId)
.Where((sOrderItem, sOrder) => sOrderItem.goodsId == good.id && (sOrder.payStatus == (int)GlobalEnumVars.OrderPayStatus.Yes || sOrder.payStatus == (int)GlobalEnumVars.OrderPayStatus.PartialYes))
.Sum(p => p.nums),
sort = good.sort,
labelIds = good.labelIds,
createTime = good.createTime,
isRecommend = good.isRecommend,
isHot = good.isHot,
price = pd.price,
mktprice = pd.mktprice,
stock = pd.stock,
pointsDeduction = pd.pointsDeduction,
points = pd.points,
weight = pd.weight,
initialSales = good.initialSales,
})
.With(SqlWith.NoLock)
.MergeTable()
.WhereIF(predicate != null, predicate)
.OrderByIF(!string.IsNullOrEmpty(orderByType), orderByType)
.Take(take)
.WithCacheIF(isDataCache, cacheTimes)
.ToListAsync();
}
else
{
page = await DbClient.Queryable<CoreCmsGoods, CoreCmsProducts>((good, pd) => new JoinQueryInfos(
JoinType.Left, good.id == pd.goodsId))
.Where((good, pd) => pd.isDefalut == true && pd.isDel == false && good.isMarketable == true && good.isDel == false)
.Select((good, pd) => new GoodListDTO
{
id = good.id,
name = good.name,
brief = good.brief,
image = !SqlFunc.IsNullOrEmpty(good.image) ? good.image : EmptyOrNullImagePath.GoodImage,
video = good.video,
goodsCategoryId = good.goodsCategoryId,
goodsTypeId = good.goodsTypeId,
brandId = good.brandId,
isNomalVirtual = good.isNomalVirtual,
unit = good.unit,
commentsCount = good.commentsCount,
viewCount = good.viewCount,
buyCount = SqlFunc.Subqueryable<CoreCmsOrderItem>()
.LeftJoin<CoreCmsOrder>((sOrderItem, sOrder) => sOrder.orderId == sOrderItem.orderId)
.Where((sOrderItem, sOrder) => sOrderItem.goodsId == good.id && (sOrder.payStatus == (int)GlobalEnumVars.OrderPayStatus.Yes || sOrder.payStatus == (int)GlobalEnumVars.OrderPayStatus.PartialYes))
.Sum(p => p.nums),
sort = good.sort,
labelIds = good.labelIds,
createTime = good.createTime,
isRecommend = good.isRecommend,
isHot = good.isHot,
price = pd.price,
mktprice = pd.mktprice,
stock = pd.stock,
pointsDeduction = pd.pointsDeduction,
points = pd.points,
weight = pd.weight,
initialSales = good.initialSales,
})
.MergeTable()
.WhereIF(predicate != null, predicate)
.OrderByIF(!string.IsNullOrEmpty(orderByType), orderByType)
.WithCacheIF(isDataCache, cacheTimes)
.Take(take).ToListAsync();
}
return page;
}
#endregion
}
}

View File

@@ -15,6 +15,7 @@ using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using CoreCms.Net.Configuration;
using CoreCms.Net.DTO.ComponentsDTO;
using CoreCms.Net.IRepository;
using CoreCms.Net.IRepository.UnitOfWork;
using CoreCms.Net.IServices;
@@ -910,7 +911,7 @@ namespace CoreCms.Net.Services
/// <param name="number"></param>
/// <param name="isRecommend"></param>
/// <returns></returns>
public async Task<List<CoreCmsGoods>> GetGoodsRecommendList(int number, bool isRecommend = false)
public async Task<List<GoodListDTO>> GetGoodsRecommendList(int number, bool isRecommend = false)
{
return await _dal.GetGoodsRecommendList(number, isRecommend);
}
@@ -998,6 +999,24 @@ namespace CoreCms.Net.Services
}
#endregion
#region DTO
/// <summary>
/// 重写根据条件及自定义排序查询分页数据返回DTO
/// </summary>
/// <param name="predicate"></param>
/// <param name="orderBy"></param>
/// <param name="pageIndex">当前页面索引</param>
/// <param name="pageSize">分布大小</param>
/// <param name="blUseNoLock">是否使用WITH(NOLOCK)</param>
/// <returns></returns>
public async Task<IPageList<GoodListDTO>> QueryPageByDTOAsync(Expression<Func<GoodListDTO, bool>> predicate,
string orderBy = "", int pageIndex = 1, int pageSize = 20, bool blUseNoLock = false)
{
return await _dal.QueryPageByDTOAsync(predicate, orderBy, pageIndex, pageSize, blUseNoLock);
}
#endregion
/// <summary>
/// 根据条件查询代理池商品分页数据
/// </summary>
@@ -1058,5 +1077,46 @@ namespace CoreCms.Net.Services
return await _dal.QueryGoodWithDefaultProductAsync(predicate, orderByPredicate, orderByType, blUseNoLock);
}
/// <summary>
/// 根据条件查询一定数量数据(用于组件)
/// </summary>
/// <param name="predicate">条件表达式树</param>
/// <param name="take">获取数量</param>
/// <param name="orderByPredicate">排序字段</param>
/// <param name="orderByType">排序顺序</param>
/// <param name="blUseNoLock">是否使用WITH(NOLOCK)</param>
/// <param name="isDataCache">是否缓存</param>
/// <param name="cacheTimes">缓存时间(分钟)</param>
/// <returns></returns>
public async Task<List<GoodListDTO>> QueryListByComponentsAsync(Expression<Func<GoodListDTO, bool>> predicate,
int take,
Expression<Func<GoodListDTO, object>> orderByPredicate, OrderByType orderByType, bool blUseNoLock = false,
bool isDataCache = false, int cacheTimes = int.MaxValue)
{
return await _dal.QueryListByComponentsAsync(predicate, take, orderByPredicate, orderByType, blUseNoLock,
isDataCache, cacheTimes);
}
/// <summary>
/// 根据条件查询一定数量数据(用于组件)
/// </summary>
/// <param name="predicate">条件表达式树</param>
/// <param name="take">获取数量</param>
/// <param name="orderByPredicate">排序字段</param>
/// <param name="orderByType">排序顺序</param>
/// <param name="blUseNoLock">是否使用WITH(NOLOCK)</param>
/// <param name="isDataCache">是否缓存</param>
/// <param name="cacheTimes">缓存时间(分钟)</param>
/// <returns></returns>
public async Task<List<GoodListDTO>> QueryListByComponentsAsync(Expression<Func<GoodListDTO, bool>> predicate,
int take, string orderByType = "", bool blUseNoLock = false,
bool isDataCache = false, int cacheTimes = int.MaxValue)
{
return await _dal.QueryListByComponentsAsync(predicate, take, orderByType, blUseNoLock,
isDataCache, cacheTimes);
}
}
}

View File

@@ -13,6 +13,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using CoreCms.Net.Configuration;
using CoreCms.Net.DTO.ComponentsDTO;
using CoreCms.Net.IRepository;
using CoreCms.Net.IRepository.UnitOfWork;
using CoreCms.Net.IServices;
@@ -26,7 +27,9 @@ using CoreCms.Net.Utility.Extensions;
using Essensoft.Paylink.Alipay.Domain;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NPOI.SS.Formula.Functions;
using SqlSugar;
using static NPOI.HSSF.Util.HSSFColor;
namespace CoreCms.Net.Services
@@ -267,10 +270,7 @@ namespace CoreCms.Net.Services
foreach (var jToken in list)
{
var child = (JObject)jToken;
var where = PredicateBuilder.True<CoreCmsGoods>();
where = where.And(p => p.isDel == false);
where = where.And(p => p.isMarketable == true);
var where = PredicateBuilder.True<GoodListDTO>();
if (child != null && child.ContainsKey("type") && child["type"].ToString() == "auto")
{
//商品分类,同时取所有子分类
@@ -301,7 +301,8 @@ namespace CoreCms.Net.Services
}
limit = limit > 0 ? limit : 10;
var goods = await _goodsServices.QueryListByClauseAsync(where, limit, p => p.createTime, OrderByType.Desc, true);
var goods = await _goodsServices.QueryListByComponentsAsync(where, limit, p => p.createTime, OrderByType.Desc, true, true, 60);
if (goods != null && goods.Any())
{
var result = JArray.FromObject(goods);
@@ -318,6 +319,7 @@ namespace CoreCms.Net.Services
{
var orderBy = string.Empty;
string goodidsStr;
var count = 0;
if (child != null && child.ContainsKey("list"))
{
var result = JArray.Parse(child["list"].ToString());
@@ -335,9 +337,11 @@ namespace CoreCms.Net.Services
{
orderBy = " find_in_set(id,'" + goodidsStr + "') ";
}
count = goodids.Count;
}
}
var goods = await _goodsServices.QueryListByClauseAsync(where, orderBy, true);
var goods = await _goodsServices.QueryListByComponentsAsync(where, count, orderBy, true, true, 60);
if (goods != null && goods.Any())
{
var result = JArray.FromObject(goods);
@@ -364,9 +368,7 @@ namespace CoreCms.Net.Services
case "goods":
{
var parameters = (JObject)JsonConvert.DeserializeObject(item.parameters);
var where = PredicateBuilder.True<CoreCmsGoods>();
where = where.And(p => p.isDel == false);
where = where.And(p => p.isMarketable == true);
var where = PredicateBuilder.True<GoodListDTO>();
if (parameters != null && parameters.ContainsKey("type") && parameters["type"].ToString() == "auto")
{
//商品分类,同时取所有子分类
@@ -397,7 +399,7 @@ namespace CoreCms.Net.Services
}
limit = limit > 0 ? limit : 10;
var goods = await _goodsServices.QueryPageAsync(where, " sort desc,id desc ", 1, limit, true);
var goods = await _goodsServices.QueryListByComponentsAsync(where, limit, " sort desc,id desc ", true, true, 60);
if (goods != null && goods.Any())
{
var result = JArray.FromObject(goods);
@@ -414,9 +416,10 @@ namespace CoreCms.Net.Services
{
var orderBy = string.Empty;
string goodidsStr;
var count = 0;
if (parameters != null && parameters.ContainsKey("list"))
{
JArray result = JArray.Parse(parameters["list"].ToString());
var result = JArray.Parse(parameters["list"].ToString());
var goodids = new List<int>();
foreach (var ss in result) //查找某个字段与值
{
@@ -440,11 +443,12 @@ namespace CoreCms.Net.Services
orderBy = " find_in_set(id,'" + goodidsStr + "') ";
}
}
count = goodids.Count;
}
var goods = await _goodsServices.QueryListByClauseAsync(where, orderBy, true);
var goods = await _goodsServices.QueryListByComponentsAsync(where, count, orderBy, true, true, 60);
if (goods != null && goods.Any())
{
JArray result = JArray.FromObject(goods);
var result = JArray.FromObject(goods);
parameters.Remove("list");
parameters.Add("list", result);
}

View File

@@ -20,7 +20,7 @@
<span class="coreshop-font-xs coreshop-text-through coreshop-margin-left-6 coreshop-text-gray" v-if="newData.column==2">{{item.mktprice}}</span>
</view>
<view>
<text class="coreshop-font-10 coreshop-text-gray">{{item.buyCount+'人付款'}}</text>
<text class="coreshop-font-10 coreshop-text-gray">已售{{item.buyCount+item.initialSales}}{{item.unit}}</text>
</view>
</view>
<view class="coreshop-divider" v-if="pointSwitch==1 && pointExchangeModel==2 && pointShowExchangePrice==1 && item.pointsDeduction > 0">
@@ -59,7 +59,7 @@
<span class="coreshop-font-xs coreshop-text-through coreshop-margin-left-6 coreshop-text-gray" v-if="newData.column==2">{{item.mktprice}}</span>
</view>
<view>
<text class="coreshop-font-10 coreshop-text-gray">{{item.buyCount+'人付款'}}</text>
<text class="coreshop-font-10 coreshop-text-gray">已售{{item.buyCount+item.initialSales}}{{item.unit}}</text>
</view>
</view>
<view class="coreshop-divider" v-if="pointSwitch==1 && pointExchangeModel==2 && pointShowExchangePrice==1 && item.pointsDeduction > 0">

View File

@@ -24,7 +24,7 @@
<span class="coreshop-font-xs coreshop-text-through coreshop-margin-left-6 coreshop-text-gray" v-if="coreshopData.parameters.column==2">{{item.mktprice}}</span>
</view>
<view>
<text class="coreshop-font-10 coreshop-text-gray">{{item.buyCount+'人付款'}}</text>
<text class="coreshop-font-10 coreshop-text-gray">已售{{item.buyCount+item.initialSales}}{{item.unit}}</text>
</view>
</view>
<view class="coreshop-divider" v-if="pointSwitch==1 && pointExchangeModel==2 && pointShowExchangePrice==1 && item.pointsDeduction > 0">
@@ -63,7 +63,7 @@
<span class="coreshop-font-xs coreshop-text-through coreshop-margin-left-6 coreshop-text-gray" v-if="coreshopData.parameters.column==2">{{item.mktprice}}</span>
</view>
<view>
<text class="coreshop-font-10 coreshop-text-gray">{{item.buyCount+'人付款'}}</text>
<text class="coreshop-font-10 coreshop-text-gray">已售{{item.buyCount+item.initialSales}}{{item.unit}}</text>
</view>
</view>
<view class="coreshop-divider" v-if="pointSwitch==1 && pointExchangeModel==2 && pointShowExchangePrice==1 && item.pointsDeduction > 0">
@@ -102,7 +102,7 @@
<view class="coreshop-divider">
<view class="complete"></view>
</view>
<view class="coreshop-text-black" v-for="(item, index) in coreshopData.parameters.list" :key="item.id" v-if="count">
<view class="coreshop-text-black" v-for="(item, index) in coreshopData.parameters.list" :key="item.id" v-if="count" @tap="goGoodsDetail(item.id)">
<view class="coreshop-flex coreshop-justify-start coreshop-padding-top-10 coreshop-padding-bottom-10">
<view>
<u--image :src="item.image" mode="widthFix" width="130px" height="130px" radius="8"></u--image>
@@ -111,7 +111,7 @@
<view class="coreshop-font-14 u-line-2 coreshop-text-black">{{ item.name }}</view>
<view class="coreshop-font-11 coreshop-padding-top-5 coreshop-padding-bottom-3 u-line-2 coreshop-text-brown">{{ item.brief }}</view>
<view class="coreshop-flex coreshop-align-center coreshop-padding-top-10 coreshop-padding-bottom-10">
<view class="coreshop-font-11 coreshop-bg-orange coreshop-padding-2 coreshop-border-radius-4 coreshop-margin-right-10">已售{{item.buyCount}}{{item.unit}}</view>
<view class="coreshop-font-11 coreshop-bg-orange coreshop-padding-2 coreshop-border-radius-4 coreshop-margin-right-10">已售{{item.buyCount+item.initialSales}}{{item.unit}}</view>
<view class="coreshop-font-11 coreshop-bg-olive coreshop-padding-2 coreshop-border-radius-4">{{item.viewCount}}人访问</view>
</view>
<view class="coreshop-flex coreshop-justify-between coreshop-flex-direction-row coreshop-align-center">
@@ -119,7 +119,7 @@
<view class="coreshop-font-14 coreshop-text-red">{{ item.price }}</view>
<view class="coreshop-font-12 coreshop-text-gray coreshop-text-through">{{ item.mktprice }}</view>
</view>
<view class="coreshop-buy-btn" @tap="goGoodsDetail(item.id)">马上抢</view>
<view class="coreshop-buy-btn">马上抢</view>
</view>
</view>
<view class="coreshop-flex coreshop-flex-direction-row coreshop-font-11 coreshop-margin-top-5" v-if="pointSwitch==1 && pointExchangeModel==2 && pointShowExchangePrice==1 && item.pointsDeduction > 0">

View File

@@ -16,7 +16,7 @@
<u-swiper height="calc(750rpx * 6 / 6)" radius="0" :list="goodsInfo.album" :autoplay="autoplay" indicator indicatorMode="line" circular @click="clickImg"></u-swiper>
</view>
<view class="coreshop-margin-left-16 coreshop-margin-right-16 coreshop-margin-top-12 coreshop-padding-16 coreshop-border-radius-9 coreshop-bg-white">
<view class="coreshop-margin-left-8 coreshop-margin-right-8 coreshop-margin-top-12 coreshop-padding-8 coreshop-border-radius-9 coreshop-bg-white">
<view class="coreshop-flex coreshop-justify-between coreshop-align-center">
<view class="coreshop-text-red coreshop-font-weight-bold">
<text class="coreshop-font-16">¥</text>
@@ -59,7 +59,7 @@
<u-tag :text="item.name" :bgColor="item.style" :borderColor="item.style"></u-tag>
</view>
</view>
<view class="coreshop-margin-top-16 coreshop-padding-top-16 coreshop-solid-top coreshop-flex coreshop-justify-between coreshop-align-center coreshop-text-gray">
<view class="coreshop-margin-top-8 coreshop-padding-top-16 coreshop-solid-top coreshop-flex coreshop-justify-between coreshop-align-center coreshop-text-gray">
<view class="coreshop-font-12">
<text>已售</text>
<text class="font-color-orange">{{ goodsInfo.buyCount || '0' }}</text>
@@ -74,7 +74,7 @@
</view>
</view>
<view class="coreshop-margin-left-16 coreshop-margin-right-16 coreshop-margin-top-12 coreshop-padding-16 coreshop-border-radius-9 coreshop-bg-white">
<view class="coreshop-margin-left-8 coreshop-margin-right-8 coreshop-margin-top-12 coreshop-padding-8 coreshop-border-radius-9 coreshop-bg-white">
<!--服务-->
<view class="coreshop-flex coreshop-flex-wrap coreshop-font-sm coreshop-flex-direction-row" @tap="serviceTap" v-if="serviceDescription.service.length>0">
<view class="coreshop-basis-2">
@@ -156,7 +156,7 @@
</view>
<!--参数-->
<view class="coreshop-margin-left-16 coreshop-margin-right-16 coreshop-margin-top-12 coreshop-padding-16 coreshop-border-radius-9 coreshop-bg-white" v-if="goodsParams.length>0">
<view class="coreshop-margin-left-8 coreshop-margin-right-8 coreshop-margin-top-12 coreshop-padding-8 coreshop-border-radius-9 coreshop-bg-white" v-if="goodsParams.length>0">
<view>
<text class="coreshop-text-black coreshop-font-weight-bold coreshop-font-15">参数</text>
</view>
@@ -173,7 +173,7 @@
</view>
<!--内容区-->
<view class="coreshop-margin-top-16 coreshop-margin-bottom-12 coreshop-flex coreshop-justify-center coreshop-align-center">
<view class="coreshop-margin-top-8 coreshop-margin-bottom-12 coreshop-flex coreshop-justify-center coreshop-align-center">
<view class="line-70"></view>
<view class="coreshop-margin-left-12 coreshop-margin-right-12 coreshop-text-gray">详情介绍</view>
<view class="line-70"></view>
@@ -200,7 +200,7 @@
</view>
<!--常见问题-->
<view class="coreshop-margin-left-16 coreshop-margin-right-16 coreshop-margin-top-12 coreshop-padding-16 coreshop-border-radius-9 coreshop-bg-white">
<view class="coreshop-margin-left-8 coreshop-margin-right-8 coreshop-margin-top-12 coreshop-padding-8 coreshop-border-radius-9 coreshop-bg-white">
<view class="coreshop-margin-bottom-16">
<text class="coreshop-text-black coreshop-font-weight-bold coreshop-font-15">常见问题</text>
</view>
@@ -218,12 +218,12 @@
<!--为您推荐-->
<view class="coreshop-margin-top-16 coreshop-margin-bottom-12 coreshop-flex coreshop-justify-center coreshop-align-center" v-if="shopRecommendData.length > 0">
<view class="coreshop-margin-top-8 coreshop-margin-bottom-12 coreshop-flex coreshop-justify-center coreshop-align-center" v-if="shopRecommendData.length > 0">
<view class="line-70"></view>
<view class="coreshop-margin-left-12 coreshop-margin-right-12 coreshop-text-gray">为您推荐</view>
<view class="line-70"></view>
</view>
<view class="coreshop-margin-left-16 coreshop-margin-right-16 index-goods coreshop-margin-top-10" v-if="shopRecommendData.length > 0">
<view class="coreshop-margin-left-8 coreshop-margin-right-8 index-goods coreshop-margin-top-10" v-if="shopRecommendData.length > 0">
<custom-waterfalls-flow :value="shopRecommendData" @wapperClick="wapperClick" @imageClick="imageClick">
<!-- #ifdef MP-WEIXIN -->
<view class="goods" v-for="(item,index) in shopRecommendData" :key="index" slot="slot{{index}}">
@@ -239,7 +239,7 @@
<span class="coreshop-font-xs coreshop-text-through coreshop-margin-left-6 coreshop-text-gray">{{item.mktprice}}</span>
</view>
<view>
<text class="coreshop-font-10 coreshop-text-gray">{{item.buyCount+'人付款'}}</text>
<text class="coreshop-font-10 coreshop-text-gray">已售{{item.buyCount+item.initialSales}}{{item.unit}}</text>
</view>
</view>
<view class="coreshop-flex coreshop-flex-direction-row coreshop-font-11 coreshop-margin-top-10 coreshop-padding-top-10 coreshop-solid-top" v-if="pointSwitch==1 && pointExchangeModel==2 && pointShowExchangePrice==1 && item.pointsDeduction > 0">
@@ -276,7 +276,7 @@
<span class="coreshop-font-xs coreshop-text-through coreshop-margin-left-6 coreshop-text-gray">{{item.mktprice}}</span>
</view>
<view>
<text class="coreshop-font-10 coreshop-text-gray">{{item.buyCount+'人付款'}}</text>
<text class="coreshop-font-10 coreshop-text-gray">已售{{item.buyCount+item.initialSales}}{{item.unit}}</text>
</view>
</view>
<view class="coreshop-flex coreshop-flex-direction-row coreshop-font-11 coreshop-margin-top-10 coreshop-padding-top-10 coreshop-solid-top" v-if="pointSwitch==1 && pointExchangeModel==2 && pointShowExchangePrice==1 && item.pointsDeduction > 0">

View File

@@ -16,7 +16,7 @@
<u-swiper height="calc(750rpx * 6 / 6)" radius="0" :list="goodsInfo.album" :autoplay="autoplay" indicator indicatorMode="line" circular @click="clickImg"></u-swiper>
</view>
<view class="coreshop-margin-left-16 coreshop-margin-right-16 coreshop-margin-top-12 coreshop-padding-16 coreshop-border-radius-9 coreshop-bg-white">
<view class="coreshop-margin-left-8 coreshop-margin-right-8 coreshop-margin-top-12 coreshop-padding-8 coreshop-border-radius-9 coreshop-bg-white">
<view class="coreshop-flex coreshop-justify-between coreshop-align-center">
<view class="coreshop-text-red coreshop-font-weight-bold">
<text class="coreshop-font-16">¥</text>
@@ -81,7 +81,7 @@
<u-tag :text="item.name" :bgColor="item.style" :borderColor="item.style"></u-tag>
</view>
</view>
<view class="coreshop-margin-top-16 coreshop-padding-top-16 coreshop-solid-top coreshop-flex coreshop-justify-between coreshop-align-center coreshop-text-gray">
<view class="coreshop-margin-top-8 coreshop-padding-top-16 coreshop-solid-top coreshop-flex coreshop-justify-between coreshop-align-center coreshop-text-gray">
<view class="coreshop-font-12">
<text>已售</text>
<text class="font-color-orange">{{ goodsInfo.buyPinTuanCount || '0' }}</text>
@@ -97,7 +97,7 @@
</view>
<view class="coreshop-margin-left-16 coreshop-margin-right-16 coreshop-margin-top-12 coreshop-padding-16 coreshop-border-radius-9 coreshop-bg-white">
<view class="coreshop-margin-left-8 coreshop-margin-right-8 coreshop-margin-top-12 coreshop-padding-8 coreshop-border-radius-9 coreshop-bg-white">
<!--服务-->
<view class="coreshop-flex coreshop-flex-wrap coreshop-font-sm coreshop-flex-direction-row" @tap="serviceTap" v-if="serviceDescription.service.length>0">
<view class="coreshop-basis-2">
@@ -128,7 +128,7 @@
</view>
<!-- 团购拼单 -->
<view class="coreshop-margin-left-16 coreshop-margin-right-16 coreshop-margin-top-12 coreshop-padding-16 coreshop-border-radius-9 coreshop-bg-white">
<view class="coreshop-margin-left-8 coreshop-margin-right-8 coreshop-margin-top-12 coreshop-padding-8 coreshop-border-radius-9 coreshop-bg-white">
<view class="coreshop-margin-bottom-16">
<text class="coreshop-text-black coreshop-font-weight-bold coreshop-font-15">开团信息</text>
</view>
@@ -201,7 +201,7 @@
</view>
<!--评论-->
<view class="coreshop-margin-left-16 coreshop-margin-right-16 coreshop-margin-top-12 coreshop-padding-16 coreshop-border-radius-9 coreshop-bg-white">
<view class="coreshop-margin-left-8 coreshop-margin-right-8 coreshop-margin-top-12 coreshop-padding-8 coreshop-border-radius-9 coreshop-bg-white">
<view class="coreshop-flex coreshop-flex-wrap coreshop-font-sm coreshop-flex-direction-row">
<view class="coreshop-basis-3">
<text class="coreshop-text-black coreshop-font-weight-bold coreshop-font-15">评价{{goodsComments.length}}</text>
@@ -237,13 +237,13 @@
</view>
</view>
</view>
<view class="coreshop-margin-top-16" v-else>
<view class="coreshop-margin-top-8" v-else>
<text class="coreshop-text-gray coreshop-font-12">该商品暂无评价</text>
</view>
</view>
<!--参数-->
<view class="coreshop-margin-left-16 coreshop-margin-right-16 coreshop-margin-top-12 coreshop-padding-16 coreshop-border-radius-9 coreshop-bg-white" v-if="goodsParams.length>0">
<view class="coreshop-margin-left-8 coreshop-margin-right-8 coreshop-margin-top-12 coreshop-padding-8 coreshop-border-radius-9 coreshop-bg-white" v-if="goodsParams.length>0">
<view>
<text class="coreshop-text-black coreshop-font-weight-bold coreshop-font-15">参数</text>
</view>
@@ -260,7 +260,7 @@
</view>
<!--内容区-->
<view class="coreshop-margin-top-16 coreshop-margin-bottom-12 coreshop-flex coreshop-justify-center coreshop-align-center">
<view class="coreshop-margin-top-8 coreshop-margin-bottom-12 coreshop-flex coreshop-justify-center coreshop-align-center">
<view class="line-70"></view>
<view class="coreshop-margin-left-12 coreshop-margin-right-12 coreshop-text-gray">详情介绍</view>
<view class="line-70"></view>
@@ -314,7 +314,7 @@
</view>
<!--常见问题-->
<view class="coreshop-margin-left-16 coreshop-margin-right-16 coreshop-margin-top-12 coreshop-padding-16 coreshop-border-radius-9 coreshop-bg-white">
<view class="coreshop-margin-left-8 coreshop-margin-right-8 coreshop-margin-top-12 coreshop-padding-8 coreshop-border-radius-9 coreshop-bg-white">
<view class="coreshop-margin-bottom-16">
<text class="coreshop-text-black coreshop-font-weight-bold coreshop-font-15">常见问题</text>
</view>
@@ -332,12 +332,12 @@
<!--为您推荐-->
<view class="coreshop-margin-top-16 coreshop-margin-bottom-12 coreshop-flex coreshop-justify-center coreshop-align-center" v-if="shopRecommendData.length > 0">
<view class="coreshop-margin-top-8 coreshop-margin-bottom-12 coreshop-flex coreshop-justify-center coreshop-align-center" v-if="shopRecommendData.length > 0">
<view class="line-70"></view>
<view class="coreshop-margin-left-12 coreshop-margin-right-12 coreshop-text-gray">为您推荐</view>
<view class="line-70"></view>
</view>
<view class="coreshop-margin-left-16 coreshop-margin-right-16 index-goods coreshop-margin-top-10" v-if="shopRecommendData.length > 0">
<view class="coreshop-margin-left-8 coreshop-margin-right-8 index-goods coreshop-margin-top-10" v-if="shopRecommendData.length > 0">
<custom-waterfalls-flow :value="shopRecommendData" @wapperClick="wapperClick" @imageClick="imageClick">
<!-- #ifdef MP-WEIXIN -->
<view class="goods" v-for="(item,index) in shopRecommendData" :key="index" slot="slot{{index}}">
@@ -353,7 +353,7 @@
<span class="coreshop-font-xs coreshop-text-through coreshop-margin-left-6 coreshop-text-gray">{{item.mktprice}}</span>
</view>
<view>
<text class="coreshop-font-10 coreshop-text-gray">{{item.buyCount+'人付款'}}</text>
<text class="coreshop-font-10 coreshop-text-gray">已售{{item.buyCount+item.initialSales}}{{item.unit}}</text>
</view>
</view>
<view class="coreshop-flex coreshop-flex-direction-row coreshop-font-11 coreshop-margin-top-10 coreshop-padding-top-10 coreshop-solid-top" v-if="pointSwitch==1 && pointExchangeModel==2 && pointShowExchangePrice==1 && item.pointsDeduction > 0">
@@ -390,7 +390,7 @@
<span class="coreshop-font-xs coreshop-text-through coreshop-margin-left-6 coreshop-text-gray">{{item.mktprice}}</span>
</view>
<view>
<text class="coreshop-font-10 coreshop-text-gray">{{item.buyCount+'人付款'}}</text>
<text class="coreshop-font-10 coreshop-text-gray">已售{{item.buyCount+item.initialSales}}{{item.unit}}</text>
</view>
</view>
<view class="coreshop-flex coreshop-flex-direction-row coreshop-font-11 coreshop-margin-top-10 coreshop-padding-top-10 coreshop-solid-top" v-if="pointSwitch==1 && pointExchangeModel==2 && pointShowExchangePrice==1 && item.pointsDeduction > 0">

View File

@@ -16,7 +16,7 @@
<u-swiper height="calc(750rpx * 6 / 6)" radius="0" :list="goodsInfo.album" :autoplay="autoplay" indicator indicatorMode="line" circular @click="clickImg"></u-swiper>
</view>
<view class="coreshop-margin-left-16 coreshop-margin-right-16 coreshop-margin-top-12 coreshop-padding-16 coreshop-border-radius-9 coreshop-bg-white">
<view class="coreshop-margin-left-8 coreshop-margin-right-8 coreshop-margin-top-12 coreshop-padding-8 coreshop-border-radius-9 coreshop-bg-white">
<view class="coreshop-flex coreshop-justify-between coreshop-align-center">
<view class="coreshop-text-red coreshop-font-weight-bold">
<text class="coreshop-font-16">¥</text>
@@ -59,7 +59,7 @@
<u-tag :text="item.name" :bgColor="item.style" :borderColor="item.style"></u-tag>
</view>
</view>
<view class="coreshop-margin-top-16 coreshop-padding-top-16 coreshop-solid-top coreshop-flex coreshop-justify-between coreshop-align-center coreshop-text-gray">
<view class="coreshop-margin-top-8 coreshop-padding-top-16 coreshop-solid-top coreshop-flex coreshop-justify-between coreshop-align-center coreshop-text-gray">
<view class="coreshop-font-12">
<text>销量</text>
<text class="font-color-orange">{{ goodsInfo.buyCount || '0' }}</text>
@@ -74,7 +74,7 @@
</view>
</view>
<view class="coreshop-margin-left-16 coreshop-margin-right-16 coreshop-margin-top-12 coreshop-padding-16 coreshop-border-radius-9 coreshop-bg-white">
<view class="coreshop-margin-left-8 coreshop-margin-right-8 coreshop-margin-top-12 coreshop-padding-8 coreshop-border-radius-9 coreshop-bg-white">
<!--服务-->
<view class="coreshop-flex coreshop-flex-wrap coreshop-font-sm coreshop-flex-direction-row" @tap="serviceTap" v-if="serviceDescription.service.length>0">
<view class="coreshop-basis-2">
@@ -119,7 +119,7 @@
</view>
<!--评论-->
<view class="coreshop-margin-left-16 coreshop-margin-right-16 coreshop-margin-top-12 coreshop-padding-16 coreshop-border-radius-9 coreshop-bg-white">
<view class="coreshop-margin-left-8 coreshop-margin-right-8 coreshop-margin-top-12 coreshop-padding-8 coreshop-border-radius-9 coreshop-bg-white">
<view class="coreshop-flex coreshop-flex-wrap coreshop-font-sm coreshop-flex-direction-row">
<view class="coreshop-basis-3">
<text class="coreshop-text-black coreshop-font-weight-bold coreshop-font-15">评价{{goodsComments.length}}</text>
@@ -155,13 +155,13 @@
</view>
</view>
</view>
<view class="coreshop-margin-top-16" v-else>
<view class="coreshop-margin-top-8" v-else>
<text class="coreshop-text-gray coreshop-font-12">该商品暂无评价</text>
</view>
</view>
<!--参数-->
<view class="coreshop-margin-left-16 coreshop-margin-right-16 coreshop-margin-top-12 coreshop-padding-16 coreshop-border-radius-9 coreshop-bg-white" v-if="goodsParams.length>0">
<view class="coreshop-margin-left-8 coreshop-margin-right-8 coreshop-margin-top-12 coreshop-padding-8 coreshop-border-radius-9 coreshop-bg-white" v-if="goodsParams.length>0">
<view>
<text class="coreshop-text-black coreshop-font-weight-bold coreshop-font-15">参数</text>
</view>
@@ -178,7 +178,7 @@
</view>
<!--内容区-->
<view class="coreshop-margin-top-16 coreshop-margin-bottom-12 coreshop-flex coreshop-justify-center coreshop-align-center">
<view class="coreshop-margin-top-8 coreshop-margin-bottom-12 coreshop-flex coreshop-justify-center coreshop-align-center">
<view class="line-70"></view>
<view class="coreshop-margin-left-12 coreshop-margin-right-12 coreshop-text-gray">详情介绍</view>
<view class="line-70"></view>
@@ -205,7 +205,7 @@
</view>
<!--常见问题-->
<view class="coreshop-margin-left-16 coreshop-margin-right-16 coreshop-margin-top-12 coreshop-padding-16 coreshop-border-radius-9 coreshop-bg-white">
<view class="coreshop-margin-left-8 coreshop-margin-right-8 coreshop-margin-top-12 coreshop-padding-8 coreshop-border-radius-9 coreshop-bg-white">
<view class="coreshop-margin-bottom-16">
<text class="coreshop-text-black coreshop-font-weight-bold coreshop-font-15">常见问题</text>
</view>
@@ -222,12 +222,12 @@
</view>
<!--为您推荐-->
<view class="coreshop-margin-top-16 coreshop-margin-bottom-12 coreshop-flex coreshop-justify-center coreshop-align-center" v-if="shopRecommendData.length > 0">
<view class="coreshop-margin-top-8 coreshop-margin-bottom-12 coreshop-flex coreshop-justify-center coreshop-align-center" v-if="shopRecommendData.length > 0">
<view class="line-70"></view>
<view class="coreshop-margin-left-12 coreshop-margin-right-12 coreshop-text-gray">为您推荐</view>
<view class="line-70"></view>
</view>
<view class="coreshop-margin-left-16 coreshop-margin-right-16 index-goods coreshop-margin-top-10" v-if="shopRecommendData.length > 0">
<view class="coreshop-margin-left-8 coreshop-margin-right-8 index-goods coreshop-margin-top-10" v-if="shopRecommendData.length > 0">
<custom-waterfalls-flow :value="shopRecommendData" @wapperClick="wapperClick" @imageClick="imageClick">
<!-- #ifdef MP-WEIXIN -->
<view class="goods" v-for="(item,index) in shopRecommendData" :key="index" slot="slot{{index}}">
@@ -243,7 +243,7 @@
<span class="coreshop-font-xs coreshop-text-through coreshop-margin-left-6 coreshop-text-gray">{{item.mktprice}}</span>
</view>
<view>
<text class="coreshop-font-10 coreshop-text-gray">{{item.buyCount+'人付款'}}</text>
<text class="coreshop-font-10 coreshop-text-gray">已售{{item.buyCount+item.initialSales}}{{item.unit}}</text>
</view>
</view>
<view class="coreshop-flex coreshop-flex-direction-row coreshop-font-11 coreshop-margin-top-10 coreshop-padding-top-10 coreshop-solid-top" v-if="pointSwitch==1 && pointExchangeModel==2 && pointShowExchangePrice==1 && item.pointsDeduction > 0">
@@ -280,7 +280,7 @@
<span class="coreshop-font-xs coreshop-text-through coreshop-margin-left-6 coreshop-text-gray">{{item.mktprice}}</span>
</view>
<view>
<text class="coreshop-font-10 coreshop-text-gray">{{item.buyCount+'人付款'}}</text>
<text class="coreshop-font-10 coreshop-text-gray">已售{{item.buyCount+item.initialSales}}{{item.unit}}</text>
</view>
</view>
<view class="coreshop-flex coreshop-flex-direction-row coreshop-font-11 coreshop-margin-top-10 coreshop-padding-top-10 coreshop-solid-top" v-if="pointSwitch==1 && pointExchangeModel==2 && pointShowExchangePrice==1 && item.pointsDeduction > 0">

View File

@@ -67,14 +67,14 @@
.icon { width: 38rpx; height: 38rpx; margin-left: 10rpx; }
}
}
.items { display: flex; flex-direction: column; padding-bottom: -30rpx;
.items { display: flex; flex-direction: column;
.good { display: flex; align-items: center; margin-bottom: 30rpx;
.image { width: 160rpx; height: 160rpx; margin-right: 20rpx; border-radius: 8rpx; }
.right { flex: 1; height: 160rpx; overflow: hidden; display: flex; flex-direction: column; align-items: flex-start; justify-content: space-between; padding-right: 14rpx;
.name { font-size: 28rpx; margin-bottom: 10rpx; }
.right { flex: 1; height: 160rpx; overflow: hidden; display: flex; flex-direction: column; align-items: flex-start; justify-content: space-between;
.name { margin-bottom: 10rpx; }
.tips { width: 100%; height: 40rpx; line-height: 40rpx; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 24rpx; color: #919293; margin-bottom: 10rpx; }
.price_and_action { width: 100%; display: flex; justify-content: space-between; align-items: center;
.price { font-size: 28rpx; font-weight: 600; }
.price_and_action { width: 100%; display: flex; justify-content: space-between; align-items: center; padding-top: 5px;
.price { font-size: 28rpx; font-weight: 600; color: #e02e24; }
.btn-group { display: flex; justify-content: space-between; align-items: center; position: relative;
.btn { padding: 0 20rpx; box-sizing: border-box; font-size: 24rpx; height: 44rpx; line-height: 44rpx;
&.property_btn { border-radius: 24rpx; }

View File

@@ -74,17 +74,19 @@
<view class="category" v-for="(good, key) in goodsList" :key="key" :id="`cate-${good.id}`">
<view class="items">
<view class="good">
<image :src="good.images" class="image" @tap="goGoodsDetail(good.id)"></image>
<view class="image">
<u--image :showLoading="true" :src="good.image" width="83px" height="83px" radius="4px" @click="goGoodsDetail(good.id)"></u--image>
</view>
<view class="right">
<text class="name u-line-1" @tap="goGoodsDetail(good.id)">{{ good.name }}</text>
<text class="tips u-line-1" @tap="goGoodsDetail(good.id)">{{ good.brief }}</text>
<text class="u-line-2" @tap="goGoodsDetail(good.id)">{{ good.name }}</text>
<u--text type="info" size="12px" lines="1" :text="good.brief"></u--text>
<!--<text class="tips u-line-1" @tap="goGoodsDetail(good.id)">{{ good.brief }}</text>-->
<view class="price_and_action">
<text class="price">{{ good.price }}</text>
<view class="btn-group">
<button type="primary" class="btn property_btn" hover-class="none" size="mini" @tap="showGoodSkuModal(good)">
选规格
</button>
<!--<view class="dot">111</view>-->
</view>
</view>
</view>
@@ -338,7 +340,9 @@
if (res.status == true) {
_this.goodsSkuInfo = res.data.skuList;
_this.openSkuPopup();
uni.hideLoading();
setTimeout(function () {
uni.hideLoading();
}, 1000);
} else {
_this.$refs.uToast.show({
message: res.msg, type: 'error', complete: function () {
@@ -355,7 +359,9 @@
if (res.status == true) {
_this.goodsSkuInfo = res.data.skuList;
_this.openSkuPopup();
uni.hideLoading();
setTimeout(function () {
uni.hideLoading();
}, 1000);
} else {
_this.$refs.uToast.show({
message: res.msg, type: 'error', complete: function () {

View File

@@ -87,7 +87,7 @@
<view class="coreshop-margin-left-16 coreshop-margin-right-16 index-goods coreshop-margin-top-10" v-if="goodsList.length > 0">
<custom-waterfalls-flow :value="goodsList" @wapperClick="wapperClick" @imageClick="imageClick">
<custom-waterfalls-flow ref="waterfallsFlowRef" :value="goodsList" @wapperClick="wapperClick" @imageClick="imageClick">
<!-- #ifdef MP-WEIXIN -->
<view class="goods" v-for="(item,index) in goodsList" :key="index" slot="slot{{index}}">
<view class="coreshop-padding-top-6 coreshop-padding-bottom-3 coreshop-padding-left-8 coreshop-padding-right-8 coreshop-bg-white coreshop-border-radius-bl-18">
@@ -104,7 +104,7 @@
<span class="coreshop-font-xs coreshop-text-through coreshop-margin-left-6 coreshop-text-gray">{{item.mktprice}}</span>
</view>
<view>
<text class="coreshop-font-10 coreshop-text-gray">{{item.buyCount+'人付款'}}</text>
<text class="coreshop-font-10 coreshop-text-gray">已售{{item.buyCount+item.initialSales}}{{item.unit}}</text>
</view>
</view>
<view class="coreshop-flex coreshop-flex-direction-row coreshop-font-11 coreshop-margin-top-10 coreshop-padding-top-10 coreshop-solid-top" v-if="pointSwitch==1 && pointExchangeModel==2 && pointShowExchangePrice==1 && item.pointsDeduction > 0">
@@ -142,7 +142,7 @@
<span class="coreshop-font-xs coreshop-text-through coreshop-margin-left-6 coreshop-text-gray">{{item.mktprice}}</span>
</view>
<view>
<text class="coreshop-font-10 coreshop-text-gray">{{item.buyCount+'人付款'}}</text>
<text class="coreshop-font-10 coreshop-text-gray">已售{{item.buyCount+item.initialSales}}{{item.unit}}</text>
</view>
</view>
<view class="coreshop-flex coreshop-flex-direction-row coreshop-font-11 coreshop-margin-top-10 coreshop-padding-top-10 coreshop-solid-top" v-if="pointSwitch==1 && pointExchangeModel==2 && pointShowExchangePrice==1 && item.pointsDeduction > 0">
@@ -166,6 +166,7 @@
</template>
<!-- #endif -->
</custom-waterfalls-flow>
<u-loadmore :status="loadStatus" :icon-type="loadIconType" :load-text="loadText" margin-top="20" margin-bottom="20" />
</view>
<!-- 无数据时默认显示 -->
<view class="coreshop-emptybox" v-else>
@@ -334,9 +335,8 @@
// where: where
//});
this.setSearchData(this.searchData, true);
this.getGoods();
// this.$refs.waterfallsFlowRef.refresh();
},
onReachBottom() {
if (this.loadStatus != 'nomore') {
@@ -452,7 +452,12 @@
_this.title = "商品搜索";
}
}
_this.goodsList = _this.goodsList.concat(res.data.list);
//_this.goodsList = _this.goodsList.concat(res.data.list);
let _list = res.data.list;
_this.goodsList = [..._this.goodsList, ..._list]
if (res.data.brands) {
for (let i = 0; i < res.data.brands.length; i++) {

View File

@@ -13,7 +13,7 @@
<!--幻灯片-->
<u-swiper height="calc(750rpx * 6 / 6)" radius="0" :list="goodsInfo.album" :autoplay="autoplay" indicator indicatorMode="line" circular @click="clickImg"></u-swiper>
<view class="coreshop-margin-left-16 coreshop-margin-right-16 coreshop-margin-top-12 coreshop-padding-16 coreshop-border-radius-9 coreshop-bg-white">
<view class="coreshop-margin-left-8 coreshop-margin-right-8 coreshop-margin-top-12 coreshop-padding-8 coreshop-border-radius-9 coreshop-bg-white">
<view class="coreshop-flex coreshop-justify-between coreshop-align-center">
<view class="coreshop-text-red coreshop-font-weight-bold">
<text class="coreshop-font-16">¥</text>
@@ -46,7 +46,7 @@
<u-tag :text="item.name" :bgColor="item.style" :borderColor="item.style"></u-tag>
</view>
</view>
<view class="coreshop-margin-top-16 coreshop-padding-top-16 coreshop-solid-top coreshop-flex coreshop-justify-between coreshop-align-center coreshop-text-gray">
<view class="coreshop-margin-top-8 coreshop-padding-top-16 coreshop-solid-top coreshop-flex coreshop-justify-between coreshop-align-center coreshop-text-gray">
<view class="coreshop-font-12">
<text>销量</text>
<text class="font-color-orange">{{ goodsInfo.buyCount || '0' }}</text>
@@ -62,7 +62,7 @@
</view>
<!--促销-->
<view class="coreshop-margin-left-16 coreshop-margin-right-16 coreshop-margin-top-12 coreshop-padding-16 coreshop-border-radius-9 coreshop-bg-white" v-if="promotion.length > 0" @tap="promotionTap">
<view class="coreshop-margin-left-8 coreshop-margin-right-8 coreshop-margin-top-12 coreshop-padding-8 coreshop-border-radius-9 coreshop-bg-white" v-if="promotion.length > 0" @tap="promotionTap">
<view class="coreshop-flex coreshop-flex-wrap coreshop-font-sm coreshop-flex-direction-row">
<view class="coreshop-basis-2">
<text class="coreshop-text-gray">促销</text>
@@ -80,7 +80,7 @@
</view>
</view>
<view class="coreshop-margin-left-16 coreshop-margin-right-16 coreshop-margin-top-12 coreshop-padding-16 coreshop-border-radius-9 coreshop-bg-white">
<view class="coreshop-margin-left-8 coreshop-margin-right-8 coreshop-margin-top-12 coreshop-padding-8 coreshop-border-radius-9 coreshop-bg-white">
<!--服务-->
<view class="coreshop-flex coreshop-flex-wrap coreshop-font-sm coreshop-flex-direction-row" @tap="serviceTap" v-if="serviceDescription.service.length>0">
<view class="coreshop-basis-2">
@@ -125,7 +125,7 @@
</view>
<!--评论-->
<view class="coreshop-margin-left-16 coreshop-margin-right-16 coreshop-margin-top-12 coreshop-padding-16 coreshop-border-radius-9 coreshop-bg-white">
<view class="coreshop-margin-left-8 coreshop-margin-right-8 coreshop-margin-top-12 coreshop-padding-8 coreshop-border-radius-9 coreshop-bg-white">
<view class="coreshop-flex coreshop-flex-wrap coreshop-font-sm coreshop-flex-direction-row">
<view class="coreshop-basis-3">
<text class="coreshop-text-black coreshop-font-weight-bold coreshop-font-15">评价{{goodsComments.length}}</text>
@@ -161,13 +161,13 @@
</view>
</view>
</view>
<view class="coreshop-margin-top-16" v-else>
<view class="coreshop-margin-top-8" v-else>
<text class="coreshop-text-gray coreshop-font-12">该商品暂无评价</text>
</view>
</view>
<!--参数-->
<view class="coreshop-margin-left-16 coreshop-margin-right-16 coreshop-margin-top-12 coreshop-padding-16 coreshop-border-radius-9 coreshop-bg-white" v-if="goodsParams.length>0">
<view class="coreshop-margin-left-8 coreshop-margin-right-8 coreshop-margin-top-12 coreshop-padding-8 coreshop-border-radius-9 coreshop-bg-white" v-if="goodsParams.length>0">
<view>
<text class="coreshop-text-black coreshop-font-weight-bold coreshop-font-15">参数</text>
</view>
@@ -184,7 +184,7 @@
</view>
<!--内容区-->
<view class="coreshop-margin-top-16 coreshop-margin-bottom-12 coreshop-flex coreshop-justify-center coreshop-align-center">
<view class="coreshop-margin-top-8 coreshop-margin-bottom-12 coreshop-flex coreshop-justify-center coreshop-align-center">
<view class="line-70"></view>
<view class="coreshop-margin-left-12 coreshop-margin-right-12 coreshop-text-gray">详情介绍</view>
<view class="line-70"></view>
@@ -211,7 +211,7 @@
</view>
<!--常见问题-->
<view class="coreshop-margin-left-16 coreshop-margin-right-16 coreshop-margin-top-12 coreshop-padding-16 coreshop-border-radius-9 coreshop-bg-white">
<view class="coreshop-margin-left-8 coreshop-margin-right-8 coreshop-margin-top-12 coreshop-padding-8 coreshop-border-radius-9 coreshop-bg-white">
<view class="coreshop-margin-bottom-16">
<text class="coreshop-text-black coreshop-font-weight-bold coreshop-font-15">常见问题</text>
</view>
@@ -228,12 +228,12 @@
</view>
<!--为您推荐-->
<view class="coreshop-margin-top-16 coreshop-margin-bottom-12 coreshop-flex coreshop-justify-center coreshop-align-center" v-if="shopRecommendData.length > 0">
<view class="coreshop-margin-top-8 coreshop-margin-bottom-12 coreshop-flex coreshop-justify-center coreshop-align-center" v-if="shopRecommendData.length > 0">
<view class="line-70"></view>
<view class="coreshop-margin-left-12 coreshop-margin-right-12 coreshop-text-gray">为您推荐</view>
<view class="line-70"></view>
</view>
<view class="coreshop-margin-left-16 coreshop-margin-right-16 index-goods coreshop-margin-top-10" v-if="shopRecommendData.length > 0">
<view class="coreshop-margin-left-8 coreshop-margin-right-8 index-goods coreshop-margin-top-10" v-if="shopRecommendData.length > 0">
<custom-waterfalls-flow :value="shopRecommendData" @wapperClick="wapperClick" @imageClick="imageClick">
<!-- #ifdef MP-WEIXIN -->
<view class="goods" v-for="(item,index) in shopRecommendData" :key="index" slot="slot{{index}}">
@@ -249,7 +249,7 @@
<span class="coreshop-font-xs coreshop-text-through coreshop-margin-left-6 coreshop-text-gray">{{item.mktprice}}</span>
</view>
<view>
<text class="coreshop-font-10 coreshop-text-gray">{{item.buyCount+'人付款'}}</text>
<text class="coreshop-font-10 coreshop-text-gray">已售{{item.buyCount+item.initialSales}}{{item.unit}}</text>
</view>
</view>
<view class="coreshop-flex coreshop-flex-direction-row coreshop-font-11 coreshop-margin-top-10 coreshop-padding-top-10 coreshop-solid-top" v-if="pointSwitch==1 && pointExchangeModel==2 && pointShowExchangePrice==1 && item.pointsDeduction > 0">
@@ -286,7 +286,7 @@
<span class="coreshop-font-xs coreshop-text-through coreshop-margin-left-6 coreshop-text-gray">{{item.mktprice}}</span>
</view>
<view>
<text class="coreshop-font-10 coreshop-text-gray">{{item.buyCount+'人付款'}}</text>
<text class="coreshop-font-10 coreshop-text-gray">已售{{item.buyCount+item.initialSales}}{{item.unit}}</text>
</view>
</view>
<view class="coreshop-flex coreshop-flex-direction-row coreshop-font-11 coreshop-margin-top-10 coreshop-padding-top-10 coreshop-solid-top" v-if="pointSwitch==1 && pointExchangeModel==2 && pointShowExchangePrice==1 && item.pointsDeduction > 0">

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1001 B

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -1,67 +1,264 @@
using Autofac.Extensions.DependencyInjection;
using Autofac;
using Autofac.Extensions.DependencyInjection;
using CoreCms.Net.Configuration;
using CoreCms.Net.Loging;
using Essensoft.Paylink.Alipay;
using Essensoft.Paylink.WeChatPay;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using NLog.Web;
using StackExchange.Redis;
using System;
using System.Linq;
using System.Reflection;
using CoreCms.Net.Auth;
using CoreCms.Net.Core.AutoFac;
using CoreCms.Net.Core.Config;
using CoreCms.Net.Filter;
using CoreCms.Net.Mapping;
using CoreCms.Net.Middlewares;
using CoreCms.Net.Swagger;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using Yitter.IdGenerator;
using LogLevel = NLog.LogLevel;
namespace CoreCms.Net.Web.Admin
{
/// <summary>
/// 初始化
/// </summary>
public class Program
var builder = WebApplication.CreateBuilder(args);
//添加本地路径获取支持
builder.Services.AddSingleton(new AppSettingsHelper(builder.Environment.ContentRootPath));
builder.Services.AddSingleton(new LogLockHelper(builder.Environment.ContentRootPath));
//Memory缓存
builder.Services.AddMemoryCacheSetup();
//Redis缓存
builder.Services.AddRedisCacheSetup();
//添加数据库连接SqlSugar注入支持
builder.Services.AddSqlSugarSetup();
//配置跨域CORS
builder.Services.AddCorsSetup();
//添加session支持(session依赖于cache进行存储)
builder.Services.AddSession();
// AutoMapper支持
builder.Services.AddAutoMapper(typeof(AutoMapperConfiguration));
//使用 SignalR
builder.Services.AddSignalR();
// 引入Payment 依赖注入(支付宝支付/微信支付)
builder.Services.AddAlipay();
builder.Services.AddWeChatPay();
// 在 appsettings.json 中 配置选项
builder.Services.Configure<WeChatPayOptions>(builder.Configuration.GetSection("WeChatPay"));
builder.Services.Configure<AlipayOptions>(builder.Configuration.GetSection("Alipay"));
//注册自定义微信接口配置文件
builder.Services.Configure<CoreCms.Net.WeChat.Service.Options.WeChatOptions>(builder.Configuration.GetSection(nameof(CoreCms.Net.WeChat.Service.Options.WeChatOptions)));
// 注入工厂 HTTP 客户端
builder.Services.AddHttpClient();
builder.Services.AddSingleton<CoreCms.Net.WeChat.Service.HttpClients.IWeChatApiHttpClientFactory, CoreCms.Net.WeChat.Service.HttpClients.WeChatApiHttpClientFactory>();
//启用客户端IP限制速率
builder.Services.AddIpPolicyRateLimitSetup(builder.Configuration);
//Swagger接口文档注入
builder.Services.AddAdminSwaggerSetup();
//jwt授权支持注入
builder.Services.AddAuthorizationSetupForAdmin();
//上下文注入
builder.Services.AddHttpContextSetup();
//服务配置中加入AutoFac控制器替换规则。
builder.Services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());
//注册mvc注册razor引擎视图
builder.Services.AddMvc(options =>
{
/// <summary>
/// 启动配置
/// </summary>
/// <param name="args"></param>
public static void Main(string[] args)
//实体验证
options.Filters.Add<RequiredErrorForAdmin>();
//异常处理
options.Filters.Add<GlobalExceptionsFilterForAdmin>();
//Swagger剔除不需要加入api展示的列表
options.Conventions.Add(new ApiExplorerIgnores());
options.EnableEndpointRouting = false;
})
.AddNewtonsoftJson(p =>
{
//数据格式首字母小写 不使用驼峰
p.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
//不使用驼峰样式的key
//p.SerializerSettings.ContractResolver = new DefaultContractResolver();
//忽略循环引用
p.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
//设置时间格式
p.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
});
// 雪花漂移算法
// 创建 IdGeneratorOptions 对象,请在构造函数中输入 WorkerId
var options = new IdGeneratorOptions(1);
// WorkerIdBitLength 默认值6支持的 WorkerId 最大值为2^6-1若 WorkerId 超过64可设置更大的 WorkerIdBitLength
// options.WorkerIdBitLength = 10;
// ...... 其它参数设置参考 IdGeneratorOptions 定义,一般来说,只要再设置 WorkerIdBitLength (决定 WorkerId 的最大值)。
// 保存参数(必须的操作,否则以上设置都不能生效):
YitIdHelper.SetIdGenerator(options);
// 初始化以后即可在任何需要生成ID的地方调用以下方法
//var newId = YitIdHelper.NextId();
#region AutoFac注册============================================================================
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
builder.Host.ConfigureContainer<ContainerBuilder>(containerBuilder =>
{
containerBuilder.RegisterModule(new AutofacModuleRegister());
//获取所有控制器类型并使用属性注入
var controllerBaseType = typeof(ControllerBase);
containerBuilder.RegisterAssemblyTypes(typeof(Program).Assembly)
.Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType)
.PropertiesAutowired();
});
#endregion
#region Nlog注册============================================================================
builder.Host.ConfigureLogging(logging =>
{
logging.ClearProviders(); //移除已经注册的其他日志处理程序
logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace); //设置最小的日志级别
})
.UseNLog(); //NLog: Setup NLog for Dependency injection
#endregion
var app = builder.Build();
#region Ubuntu Nginx IP问题===================================================================
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
#endregion
#region ===================================================================
// 开启Ip限流
app.UseIpLimitMiddle();
// 记录请求与返回数据 (注意开启权限,不然本地无法写入)
app.UseRequestResponseLog();
// 用户访问记录(必须放到外层,不然如果遇到异常,会报错,因为不能返回流)(注意开启权限,不然本地无法写入)
app.UseRecordAccessLogsMildd(GlobalEnumVars.CoreShopSystemCategory.Admin.ToString());
// 记录ip请求 (注意开启权限,不然本地无法写入)
app.UseIpLogMildd();
// signalr
app.UseSignalRSendMildd();
#endregion
app.UseSwagger().UseSwaggerUI(c =>
{
//根据版本名称倒序 遍历展示
typeof(CustomApiVersion.ApiVersions).GetEnumNames().OrderByDescending(e => e).ToList().ForEach(
version =>
{
var host = CreateHostBuilder(args).Build();
try
{
//确保NLog.config中连接字符串与appsettings.json中同步
NLogUtil.EnsureNlogConfig("NLog.config");
//throw new Exception("测试异常");//for test
//其他项目启动时需要做的事情
NLogUtil.WriteAll(NLog.LogLevel.Trace, LogType.Web, "网站启动", "网站启动成功");
c.SwaggerEndpoint($"/swagger/{version}/swagger.json", $"Doc {version}");
});
c.RoutePrefix = "doc";
});
host.Run();
}
catch (Exception ex)
{
//使用nlog写到本地日志文件万一数据库没创建/连接成功)
NLogUtil.WriteFileLog(NLog.LogLevel.Error, LogType.Web, "网站启动", "初始化数据异常", ex);
throw;
}
}
/// <summary>
/// 创建启动支撑
/// </summary>
/// <param name="args"></param>
/// <returns></returns>
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseServiceProviderFactory(new AutofacServiceProviderFactory()) //<--NOTE THIS
.ConfigureLogging(logging =>
{
logging.ClearProviders(); //移除已经注册的其他日志处理程序
logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace); //设置最小的日志级别
})
.UseNLog() //NLog: Setup NLog for Dependency injection
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder
.ConfigureKestrel(serverOptions =>
{
serverOptions.AllowSynchronousIO = true;//启用同步 IO
})
.UseStartup<Startup>();
});
}
//使用 Session
app.UseSession();
if (app.Environment.IsDevelopment())
{
// 在开发环境中,使用异常页面,这样可以暴露错误堆栈信息,所以不要放在生产环境。
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
// CORS跨域
app.UseCors(AppSettingsConstVars.CorsPolicyName);
// 跳转https
//app.UseHttpsRedirection();
// 使用cookie
app.UseCookiePolicy();
// 返回错误码
app.UseStatusCodePages();
// Routing
app.UseRouting();
// 先开启认证
app.UseAuthentication();
// 然后是授权中间件
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
"areas",
"{area:exists}/{controller=Default}/{action=Index}/{id?}"
);
endpoints.MapControllerRoute(
"default",
"{controller=Home}/{action=Index}/{id?}");
});
//设置默认起始页如default.html
//此处的路径是相对于wwwroot文件夹的相对路径
var defaultFilesOptions = new DefaultFilesOptions();
defaultFilesOptions.DefaultFileNames.Clear();
defaultFilesOptions.DefaultFileNames.Add("index.html");
app.UseDefaultFiles(defaultFilesOptions);
// 使用静态文件
app.UseStaticFiles();
try
{
//确保NLog.config中连接字符串与appsettings.json中同步
NLogUtil.EnsureNlogConfig("nlog.config");
//其他项目启动时需要做的事情
NLogUtil.WriteAll(LogLevel.Trace, LogType.ApiRequest, "后端启动", "后端启动成功");
app.Run();
}
catch (Exception ex)
{
//使用Nlog写到本地日志文件万一数据库没创建/连接成功)
NLogUtil.WriteFileLog(LogLevel.Error, LogType.ApiRequest, "后端启动", "初始化数据异常", ex);
throw;
}

View File

@@ -1,259 +0,0 @@

using System.Linq;
using Autofac;
using CoreCms.Net.Auth;
using CoreCms.Net.Configuration;
using CoreCms.Net.Core.AutoFac;
using CoreCms.Net.Core.Config;
using CoreCms.Net.Filter;
using CoreCms.Net.Loging;
using CoreCms.Net.Mapping;
using CoreCms.Net.Middlewares;
using CoreCms.Net.Model.ViewModels.Options;
using CoreCms.Net.Swagger;
using Essensoft.Paylink.Alipay;
using Essensoft.Paylink.WeChatPay;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using Yitter.IdGenerator;
namespace CoreCms.Net.Web.Admin
{
/// <summary>
/// 启动配置
/// </summary>
public class Startup
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="configuration"></param>
/// <param name="env"></param>
public Startup(IConfiguration configuration, IWebHostEnvironment env)
{
Configuration = configuration;
Env = env;
}
/// <summary>
/// </summary>
public IConfiguration Configuration { get; }
/// <summary>
/// </summary>
public IWebHostEnvironment Env { get; }
/// <summary>
/// This method gets called by the runtime. Use this method to add services to the container.
/// </summary>
/// <param name="services"></param>
public void ConfigureServices(IServiceCollection services)
{
//添加本地路径获取支持
services.AddSingleton(new AppSettingsHelper(Env.ContentRootPath));
services.AddSingleton(new LogLockHelper(Env.ContentRootPath));
//Memory缓存
services.AddMemoryCacheSetup();
//Redis缓存
services.AddRedisCacheSetup();
//添加数据库连接SqlSugar注入支持
services.AddSqlSugarSetup();
//配置跨域CORS
services.AddCorsSetup();
//添加session支持(session依赖于cache进行存储)
services.AddSession();
// AutoMapper支持
services.AddAutoMapper(typeof(AutoMapperConfiguration));
//使用 SignalR
services.AddSignalR();
// 引入Payment 依赖注入(支付宝支付/微信支付)
services.AddAlipay();
services.AddWeChatPay();
// 在 appsettings.json 中 配置选项
//注册自定义的支付配置文件后面将取消使用Paylink直接走接口请求自定义处理。
services.Configure<WeChatPayOptions>(Configuration.GetSection("WeChatPay"));
services.Configure<AlipayOptions>(Configuration.GetSection("Alipay"));
//注册自定义微信接口配置文件
services.Configure<WeChat.Service.Options.WeChatOptions>(Configuration.GetSection(nameof(WeChat.Service.Options.WeChatOptions)));
// 注入工厂 HTTP 客户端
services.AddHttpClient();
services.AddSingleton<WeChat.Service.HttpClients.IWeChatApiHttpClientFactory, WeChat.Service.HttpClients.WeChatApiHttpClientFactory>();
//启用客户端IP限制速率
services.AddIpPolicyRateLimitSetup(Configuration);
//Swagger接口文档注入
services.AddAdminSwaggerSetup();
//jwt授权支持注入
services.AddAuthorizationSetupForAdmin();
//上下文注入
services.AddHttpContextSetup();
//服务配置中加入AutoFac控制器替换规则。
services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());
//注册mvc注册razor引擎视图
services.AddMvc(options =>
{
//实体验证
options.Filters.Add<RequiredErrorForAdmin>();
//异常处理
options.Filters.Add<GlobalExceptionsFilterForAdmin>();
//Swagger剔除不需要加入api展示的列表
options.Conventions.Add(new ApiExplorerIgnores());
options.EnableEndpointRouting = false;
})
.AddNewtonsoftJson(p =>
{
//数据格式首字母小写 不使用驼峰
p.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
//不使用驼峰样式的key
//p.SerializerSettings.ContractResolver = new DefaultContractResolver();
//忽略循环引用
p.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
//设置时间格式
p.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
});
// 雪花漂移算法
// 创建 IdGeneratorOptions 对象,请在构造函数中输入 WorkerId
var options = new IdGeneratorOptions(1);
// WorkerIdBitLength 默认值6支持的 WorkerId 最大值为2^6-1若 WorkerId 超过64可设置更大的 WorkerIdBitLength
// options.WorkerIdBitLength = 10;
// ...... 其它参数设置参考 IdGeneratorOptions 定义,一般来说,只要再设置 WorkerIdBitLength (决定 WorkerId 的最大值)。
// 保存参数(必须的操作,否则以上设置都不能生效):
YitIdHelper.SetIdGenerator(options);
// 初始化以后即可在任何需要生成ID的地方调用以下方法
//var newId = YitIdHelper.NextId();
}
/// <summary>
/// Autofac规则配置
/// </summary>
/// <param name="builder"></param>
public void ConfigureContainer(ContainerBuilder builder)
{
builder.RegisterModule(new AutofacModuleRegister());
//获取所有控制器类型并使用属性注入
var controllerBaseType = typeof(ControllerBase);
builder.RegisterAssemblyTypes(typeof(Program).Assembly)
.Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType)
.PropertiesAutowired();
}
/// <summary>
/// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
/// </summary>
/// <param name="app"></param>
/// <param name="env"></param>
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
#region Ubuntu Nginx IP问题
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
#endregion
// 开启Ip限流
app.UseIpLimitMiddle();
// 记录请求与返回数据 (注意开启权限,不然本地无法写入)
app.UseRequestResponseLog();
// 用户访问记录(必须放到外层,不然如果遇到异常,会报错,因为不能返回流)(注意开启权限,不然本地无法写入)
app.UseRecordAccessLogsMildd(GlobalEnumVars.CoreShopSystemCategory.Admin.ToString());
// 记录ip请求 (注意开启权限,不然本地无法写入)
app.UseIpLogMildd();
// signalr
app.UseSignalRSendMildd();
app.UseSwagger().UseSwaggerUI(c =>
{
//根据版本名称倒序 遍历展示
typeof(CustomApiVersion.ApiVersions).GetEnumNames().OrderByDescending(e => e).ToList().ForEach(
version =>
{
c.SwaggerEndpoint($"/swagger/{version}/swagger.json", $"Doc {version}");
});
c.RoutePrefix = "doc";
});
//使用 Session
app.UseSession();
if (env.IsDevelopment())
{
// 在开发环境中,使用异常页面,这样可以暴露错误堆栈信息,所以不要放在生产环境。
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
// CORS跨域
app.UseCors(AppSettingsConstVars.CorsPolicyName);
// 跳转https
//app.UseHttpsRedirection();
// 使用静态文件
app.UseStaticFiles();
// 使用cookie
app.UseCookiePolicy();
// 返回错误码
app.UseStatusCodePages();
// Routing
app.UseRouting();
// 先开启认证
app.UseAuthentication();
// 然后是授权中间件
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
"areas",
"{area:exists}/{controller=Default}/{action=Index}/{id?}"
);
endpoints.MapControllerRoute(
"default",
"{controller=Home}/{action=Index}/{id?}");
});
//设置默认起始页如default.html
//此处的路径是相对于wwwroot文件夹的相对路径
var defaultFilesOptions = new DefaultFilesOptions();
defaultFilesOptions.DefaultFileNames.Clear();
defaultFilesOptions.DefaultFileNames.Add("index.html");
app.UseDefaultFiles(defaultFilesOptions);
app.UseStaticFiles();
}
}
}

View File

@@ -18,6 +18,7 @@ using System.Threading.Tasks;
using AutoMapper;
using CoreCms.Net.Auth.HttpContextUser;
using CoreCms.Net.Configuration;
using CoreCms.Net.DTO.ComponentsDTO;
using CoreCms.Net.IServices;
using CoreCms.Net.Model.Entities;
using CoreCms.Net.Model.Entities.Expression;
@@ -150,9 +151,7 @@ namespace CoreCms.Net.Web.WebApi.Controllers
{
var jm = new WebApiCallBack();
var where = PredicateBuilder.True<CoreCmsGoods>();
where = where.And(p => p.isDel == false);
where = where.And(p => p.isMarketable == true);
var where = PredicateBuilder.True<GoodListDTO>();
var className = string.Empty;
if (!string.IsNullOrWhiteSpace(entity.where))
@@ -224,14 +223,8 @@ namespace CoreCms.Net.Web.WebApi.Controllers
orderBy += "," + entity.order;
}
//获取数据
var list = await _goodsServices.QueryPageAsync(where, orderBy, entity.page, entity.limit, false);
if (list.Any())
{
foreach (var goods in list)
{
goods.images = !string.IsNullOrEmpty(goods.images) ? goods.images.Split(",")[0] : "/static/images/common/empty.png";
}
}
var list = await _goodsServices.QueryPageByDTOAsync(where, orderBy, entity.page, entity.limit, true);
//获取品牌
var brands = await _brandServices.QueryListByClauseAsync(p => p.isShow == true, p => p.sort, OrderByType.Desc, true, true);

View File

@@ -1,69 +1,316 @@
using System;
using System.Linq;
using Autofac;
using Autofac.Extensions.DependencyInjection;
using CoreCms.Net.Auth;
using CoreCms.Net.Configuration;
using CoreCms.Net.Core.AutoFac;
using CoreCms.Net.Core.Config;
using CoreCms.Net.Filter;
using CoreCms.Net.Loging;
using CoreCms.Net.Mapping;
using CoreCms.Net.Middlewares;
using CoreCms.Net.Swagger;
using CoreCms.Net.Task;
using CoreCms.Net.WeChat.Service.Mediator;
using Essensoft.Paylink.Alipay;
using Essensoft.Paylink.WeChatPay;
using Hangfire;
using Hangfire.Dashboard.BasicAuthorization;
using MediatR;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json;
using NLog.Web;
using Yitter.IdGenerator;
using LogLevel = NLog.LogLevel;
namespace CoreCms.Net.Web.WebApi
var builder = WebApplication.CreateBuilder(args);
//添加本地路径获取支持
builder.Services.AddSingleton(new AppSettingsHelper(builder.Environment.ContentRootPath));
builder.Services.AddSingleton(new LogLockHelper(builder.Environment.ContentRootPath));
//Memory缓存
builder.Services.AddMemoryCacheSetup();
//Redis缓存
builder.Services.AddRedisCacheSetup();
//添加数据库连接SqlSugar注入支持
builder.Services.AddSqlSugarSetup();
//配置跨域CORS
builder.Services.AddCorsSetup();
//添加session支持(session依赖于cache进行存储)
builder.Services.AddSession();
// AutoMapper支持
builder.Services.AddAutoMapper(typeof(AutoMapperConfiguration));
//MediatR只需要注册一个,同项目或类库下就不需要注册多个)
builder.Services.AddMediatR(typeof(TextMessageEventCommand).Assembly);
//使用 SignalR
builder.Services.AddSignalR();
//Redis消息队列
builder.Services.AddRedisMessageQueueSetup();
// 引入Payment 依赖注入(支付宝支付/微信支付)
builder.Services.AddAlipay();
builder.Services.AddWeChatPay();
// 在 appsettings.json 中 配置选项
builder.Services.Configure<WeChatPayOptions>(builder.Configuration.GetSection("WeChatPay"));
builder.Services.Configure<AlipayOptions>(builder.Configuration.GetSection("Alipay"));
//注册自定义微信接口配置文件
builder.Services.Configure<CoreCms.Net.WeChat.Service.Options.WeChatOptions>(builder.Configuration.GetSection(nameof(CoreCms.Net.WeChat.Service.Options.WeChatOptions)));
// 注入工厂 HTTP 客户端
builder.Services.AddHttpClient();
builder.Services.AddSingleton<CoreCms.Net.WeChat.Service.HttpClients.IWeChatApiHttpClientFactory, CoreCms.Net.WeChat.Service.HttpClients.WeChatApiHttpClientFactory>();
//启用客户端IP限制速率
builder.Services.AddIpPolicyRateLimitSetup(builder.Configuration);
//Swagger接口文档注入
builder.Services.AddAdminSwaggerSetup();
//注册Hangfire定时任务
builder.Services.AddHangFireSetup();
//jwt授权支持注入
builder.Services.AddAuthorizationSetupForAdmin();
//上下文注入
builder.Services.AddHttpContextSetup();
//服务配置中加入AutoFac控制器替换规则。
builder.Services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());
//注册mvc注册razor引擎视图
builder.Services.AddMvc(options =>
{
/// <summary>
/// 启动类
/// </summary>
public class Program
//实体验证
options.Filters.Add<RequiredErrorForClent>();
//异常处理
options.Filters.Add<GlobalExceptionsFilterForClent>();
//Swagger剔除不需要加入api展示的列表
options.Conventions.Add(new ApiExplorerIgnores());
options.EnableEndpointRouting = false;
})
.AddNewtonsoftJson(p =>
{
/// <summary>
/// 启动配置
/// </summary>
/// <param name="args"></param>
public static void Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
try
{
//确保NLog.config中连接字符串与appsettings.json中同步
NLogUtil.EnsureNlogConfig("NLog.config");
//其他项目启动时需要做的事情
NLogUtil.WriteAll(LogLevel.Trace, LogType.ApiRequest, "接口启动", "接口启动成功");
//数据格式首字母小写 不使用驼峰
p.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
//不使用驼峰样式的key
//p.SerializerSettings.ContractResolver = new DefaultContractResolver();
//忽略循环引用
p.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
//设置时间格式
p.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
});
host.Run();
}
catch (Exception ex)
// 雪花漂移算法
// 创建 IdGeneratorOptions 对象,请在构造函数中输入 WorkerId
var options = new IdGeneratorOptions(1);
// WorkerIdBitLength 默认值6支持的 WorkerId 最大值为2^6-1若 WorkerId 超过64可设置更大的 WorkerIdBitLength
// options.WorkerIdBitLength = 10;
// ...... 其它参数设置参考 IdGeneratorOptions 定义,一般来说,只要再设置 WorkerIdBitLength (决定 WorkerId 的最大值)。
// 保存参数(必须的操作,否则以上设置都不能生效):
YitIdHelper.SetIdGenerator(options);
// 初始化以后即可在任何需要生成ID的地方调用以下方法
//var newId = YitIdHelper.NextId();
#region AutoFac注册============================================================================
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
builder.Host.ConfigureContainer<ContainerBuilder>(containerBuilder =>
{
//获取所有控制器类型并使用属性注入
var controllerBaseType = typeof(ControllerBase);
containerBuilder.RegisterAssemblyTypes(typeof(Program).Assembly)
.Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType)
.PropertiesAutowired();
containerBuilder.RegisterModule(new AutofacModuleRegister());
});
#endregion
#region Nlog注册============================================================================
builder.Host.ConfigureLogging(logging =>
{
logging.ClearProviders(); //移除已经注册的其他日志处理程序
logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace); //设置最小的日志级别
})
.UseNLog(); //NLog: Setup NLog for Dependency injection
#endregion
var app = builder.Build();
#region Ubuntu Nginx IP问题===================================================================
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
#endregion
#region ===================================================================
// 开启Ip限流
app.UseIpLimitMiddle();
// 记录请求与返回数据 (注意开启权限,不然本地无法写入)
app.UseRequestResponseLog();
// 用户访问记录(必须放到外层,不然如果遇到异常,会报错,因为不能返回流)(注意开启权限,不然本地无法写入)
app.UseRecordAccessLogsMildd(GlobalEnumVars.CoreShopSystemCategory.Api.ToString());
// 记录ip请求 (注意开启权限,不然本地无法写入)
app.UseIpLogMildd();
// signalr
app.UseSignalRSendMildd();
#endregion
//强制显示中文
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("zh-CN");
app.UseSwagger().UseSwaggerUI(c =>
{
//根据版本名称倒序 遍历展示
typeof(CustomApiVersion.ApiVersions).GetEnumNames().OrderByDescending(e => e).ToList().ForEach(
version =>
{
c.SwaggerEndpoint($"/swagger/{version}/swagger.json", $"Doc {version}");
});
c.RoutePrefix = "doc";
});
#region Hangfire定时任务
//授权
var filter = new BasicAuthAuthorizationFilter(
new BasicAuthAuthorizationFilterOptions
{
SslRedirect = false,
// Require secure connection for dashboard
RequireSsl = false,
// Case sensitive login checking
LoginCaseSensitive = false,
// Users
Users = new[]
{
new BasicAuthAuthorizationUser
{
//使用nlog写到本地日志文件万一数据库没创建/连接成功)
NLogUtil.WriteFileLog(LogLevel.Error, LogType.ApiRequest, "接口启动", "初始化数据异常", ex);
throw;
Login = AppSettingsConstVars.HangFireLogin,
PasswordClear = AppSettingsConstVars.HangFirePassWord
}
}
});
var hangfireOptions = new Hangfire.DashboardOptions
{
AppPath = "/",//返回时跳转的地址
DisplayStorageConnectionString = false,//是否显示数据库连接信息
Authorization = new[]
{
filter
},
IsReadOnlyFunc = _ => false
};
/// <summary>
/// 创建启动支撑
/// </summary>
/// <param name="args"></param>
/// <returns></returns>
public static IHostBuilder CreateHostBuilder(string[] args)
{
return Host.CreateDefaultBuilder(args)
.UseServiceProviderFactory(new AutofacServiceProviderFactory()) //<--NOTE THIS
.ConfigureLogging(logging =>
{
logging.ClearProviders(); //移除已经注册的其他日志处理程序
logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace); //设置最小的日志级别
})
.UseNLog() //NLog: Setup NLog for Dependency injection
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder
.ConfigureKestrel(serverOptions =>
{
serverOptions.AllowSynchronousIO = true; //启用同步 IO
})
.UseStartup<Startup>();
});
}
}
app.UseHangfireDashboard("/job", hangfireOptions); //可以改变Dashboard的url
HangfireDispose.HangfireService();
#endregion
//使用 Session
app.UseSession();
if (app.Environment.IsDevelopment())
{
// 在开发环境中,使用异常页面,这样可以暴露错误堆栈信息,所以不要放在生产环境。
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
// CORS跨域
app.UseCors(AppSettingsConstVars.CorsPolicyName);
// 跳转https
//app.UseHttpsRedirection();
// 使用cookie
app.UseCookiePolicy();
// 返回错误码
app.UseStatusCodePages();
// Routing
app.UseRouting();
// 先开启认证
app.UseAuthentication();
// 然后是授权中间件
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
"areas",
"{area:exists}/{controller=Default}/{action=Index}/{id?}"
);
endpoints.MapControllerRoute(
"default",
"{controller=Home}/{action=Index}/{id?}");
});
//设置默认起始页如default.html
//此处的路径是相对于wwwroot文件夹的相对路径
var defaultFilesOptions = new DefaultFilesOptions();
defaultFilesOptions.DefaultFileNames.Clear();
defaultFilesOptions.DefaultFileNames.Add("index.html");
app.UseDefaultFiles(defaultFilesOptions);
// 使用静态文件
app.UseStaticFiles();
try
{
//确保NLog.config中连接字符串与appsettings.json中同步
NLogUtil.EnsureNlogConfig("nlog.config");
//其他项目启动时需要做的事情
NLogUtil.WriteAll(LogLevel.Trace, LogType.ApiRequest, "接口启动", "接口启动成功");
app.Run();
}
catch (Exception ex)
{
//使用Nlog写到本地日志文件万一数据库没创建/连接成功)
NLogUtil.WriteFileLog(LogLevel.Error, LogType.ApiRequest, "接口启动", "初始化数据异常", ex);
throw;
}

View File

@@ -1,314 +0,0 @@
using Autofac;
using CoreCms.Net.Auth;
using CoreCms.Net.Configuration;
using CoreCms.Net.Core.AutoFac;
using CoreCms.Net.Core.Config;
using CoreCms.Net.Filter;
using CoreCms.Net.Loging;
using CoreCms.Net.Mapping;
using CoreCms.Net.Middlewares;
using CoreCms.Net.Swagger;
using CoreCms.Net.Task;
using Hangfire;
using Hangfire.Dashboard.BasicAuthorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.Linq;
using CoreCms.Net.WeChat.Service.Mediator;
using Essensoft.Paylink.Alipay;
using Essensoft.Paylink.WeChatPay;
using MediatR;
using Microsoft.AspNetCore.HttpOverrides;
using Yitter.IdGenerator;
namespace CoreCms.Net.Web.WebApi
{
/// <summary>
/// 启动配置
/// </summary>
public class Startup
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="configuration"></param>
/// <param name="env"></param>
public Startup(IConfiguration configuration, IWebHostEnvironment env)
{
Configuration = configuration;
Env = env;
}
/// <summary>
/// 配置属性
/// </summary>
public IConfiguration Configuration { get; }
/// <summary>
/// web环境
/// </summary>
public IWebHostEnvironment Env { get; }
/// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
//添加本地路径获取支持
services.AddSingleton(new AppSettingsHelper(Env.ContentRootPath));
services.AddSingleton(new LogLockHelper(Env.ContentRootPath));
//Memory缓存
services.AddMemoryCacheSetup();
//Redis缓存
services.AddRedisCacheSetup();
//添加数据库连接SqlSugar注入支持
services.AddSqlSugarSetup();
//配置跨域CORS
services.AddCorsSetup();
//添加session支持(session依赖于cache进行存储)
services.AddSession();
// AutoMapper支持
services.AddAutoMapper(typeof(AutoMapperConfiguration));
//MediatR只需要注册一个,同项目或类库下就不需要注册多个)
services.AddMediatR(typeof(TextMessageEventCommand).Assembly);
//使用 SignalR
services.AddSignalR();
//Redis消息队列
services.AddRedisMessageQueueSetup();
// 引入Payment 依赖注入(支付宝支付/微信支付)
services.AddAlipay();
services.AddWeChatPay();
// 在 appsettings.json 中 配置选项
services.Configure<WeChatPayOptions>(Configuration.GetSection("WeChatPay"));
services.Configure<AlipayOptions>(Configuration.GetSection("Alipay"));
//注册自定义微信接口配置文件
services.Configure<WeChat.Service.Options.WeChatOptions>(Configuration.GetSection(nameof(WeChat.Service.Options.WeChatOptions)));
// 注入工厂 HTTP 客户端
services.AddHttpClient();
services.AddSingleton<WeChat.Service.HttpClients.IWeChatApiHttpClientFactory, WeChat.Service.HttpClients.WeChatApiHttpClientFactory>();
//启用客户端IP限制速率
services.AddIpPolicyRateLimitSetup(Configuration);
//Swagger接口文档注入
services.AddClientSwaggerSetup();
//注册Hangfire定时任务
services.AddHangFireSetup();
//授权支持注入
services.AddAuthorizationSetupForClient();
//上下文注入
services.AddHttpContextSetup();
//服务配置中加入AutoFac控制器替换规则。
services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());
//注册mvc注册razor引擎视图
services.AddMvc(options =>
{
//实体验证
options.Filters.Add<RequiredErrorForClent>();
//异常处理
options.Filters.Add<GlobalExceptionsFilterForClent>();
//Swagger剔除不需要加入api展示的列表
options.Conventions.Add(new ApiExplorerIgnores());
})
.AddNewtonsoftJson(p =>
{
//数据格式首字母小写 不使用大驼峰
p.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
//不使用驼峰样式的key
//p.SerializerSettings.ContractResolver = new DefaultContractResolver();
//忽略循环引用
p.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
//设置时间格式必须使用yyyy/MM/dd格式因为ios系统不支持2018-03-29格式的时间只识别2018/03/09这种格式。
p.SerializerSettings.DateFormatString = "yyyy/MM/dd HH:mm:ss";
});
// 雪花漂移算法
// 创建 IdGeneratorOptions 对象,请在构造函数中输入 WorkerId
var options = new IdGeneratorOptions(1);
// WorkerIdBitLength 默认值6支持的 WorkerId 最大值为2^6-1若 WorkerId 超过64可设置更大的 WorkerIdBitLength
// options.WorkerIdBitLength = 10;
// ...... 其它参数设置参考 IdGeneratorOptions 定义,一般来说,只要再设置 WorkerIdBitLength (决定 WorkerId 的最大值)。
// 保存参数(必须的操作,否则以上设置都不能生效):
YitIdHelper.SetIdGenerator(options);
// 初始化以后即可在任何需要生成ID的地方调用以下方法
//var newId = YitIdHelper.NextId();
}
/// <summary>
/// Autofac规则配置
/// </summary>
/// <param name="builder"></param>
public void ConfigureContainer(ContainerBuilder builder)
{
//获取所有控制器类型并使用属性注入
var controllerBaseType = typeof(ControllerBase);
builder.RegisterAssemblyTypes(typeof(Program).Assembly)
.Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType)
.PropertiesAutowired();
builder.RegisterModule(new AutofacModuleRegister());
}
// public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IOptions<SenparcSetting> senparcSetting, IOptions<SenparcWeixinSetting> senparcWeixinSetting)
/// <summary>
/// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
/// </summary>
/// <param name="app"></param>
/// <param name="env"></param>
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
#region Ubuntu Nginx IP问题
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
#endregion
// 开启Ip限流
app.UseIpLimitMiddle();
// 记录请求与返回数据 (注意开启权限,不然本地无法写入)
app.UseRequestResponseLog();
// 用户访问记录(必须放到外层,不然如果遇到异常,会报错,因为不能返回流)(注意开启权限,不然本地无法写入)
app.UseRecordAccessLogsMildd(GlobalEnumVars.CoreShopSystemCategory.Api.ToString());
// 记录ip请求 (注意开启权限,不然本地无法写入)
app.UseIpLogMildd();
//强制显示中文
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("zh-CN");
app.UseSwagger().UseSwaggerUI(c =>
{
//根据版本名称倒序 遍历展示
typeof(CustomApiVersion.ApiVersions).GetEnumNames().OrderByDescending(e => e).ToList().ForEach(
version =>
{
c.SwaggerEndpoint($"/swagger/{version}/swagger.json", $"Doc {version}");
});
//设置默认跳转到swagger-ui
c.RoutePrefix = "doc";
//c.RoutePrefix = string.Empty;
});
#region Hangfire定时任务
//授权
var filter = new BasicAuthAuthorizationFilter(
new BasicAuthAuthorizationFilterOptions
{
SslRedirect = false,
// Require secure connection for dashboard
RequireSsl = false,
// Case sensitive login checking
LoginCaseSensitive = false,
// Users
Users = new[]
{
new BasicAuthAuthorizationUser
{
Login = AppSettingsConstVars.HangFireLogin,
PasswordClear = AppSettingsConstVars.HangFirePassWord
}
}
});
var options = new DashboardOptions
{
AppPath = "/",//返回时跳转的地址
DisplayStorageConnectionString = false,//是否显示数据库连接信息
Authorization = new[]
{
filter
},
IsReadOnlyFunc = _ => false
};
app.UseHangfireDashboard("/job", options); //可以改变Dashboard的url
HangfireDispose.HangfireService();
#endregion
//使用 Session
app.UseSession();
if (env.IsDevelopment())
{
// 在开发环境中,使用异常页面,这样可以暴露错误堆栈信息,所以不要放在生产环境。
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
// CORS跨域
app.UseCors(AppSettingsConstVars.CorsPolicyName);
// Routing
app.UseRouting();
// 使用静态文件
app.UseStaticFiles();
// 先开启认证
app.UseAuthentication();
// 然后是授权中间件
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
"areas",
"{area:exists}/{controller=Default}/{action=Index}/{id?}"
);
//endpoints.MapControllers();
endpoints.MapControllerRoute(
"default",
"{controller=Default}/{action=Index}/{id?}");
});
//设置默认起始页如default.html
//此处的路径是相对于wwwroot文件夹的相对路径
var defaultFilesOptions = new DefaultFilesOptions();
defaultFilesOptions.DefaultFileNames.Clear();
defaultFilesOptions.DefaultFileNames.Add("index.html");
app.UseDefaultFiles(defaultFilesOptions);
app.UseStaticFiles();
}
}
}