mirror of
http://git.coreshop.cn/jianweie/coreshoppro.git
synced 2025-12-06 18:33:27 +08:00
【新增】增加商品列表dto类及查询方法,首页【商品组件】【商品tab组】【仿点餐界面】【栏目列表页】【推荐商品列表】进行替换。
【优化】优化普通商品及营销商品内页不同dom之间间距。微调其他页面样式 【调整】移除.net5升级到.net6保留的startup.cs文件,使用program.cs
This commit is contained in:
@@ -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";
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
150
CoreCms.Net.DTO/ComponentsDTO/GoodListDTO.cs
Normal file
150
CoreCms.Net.DTO/ComponentsDTO/GoodListDTO.cs
Normal 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; }
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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();
|
||||
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();
|
||||
setTimeout(function () {
|
||||
uni.hideLoading();
|
||||
}, 1000);
|
||||
} else {
|
||||
_this.$refs.uToast.show({
|
||||
message: res.msg, type: 'error', complete: function () {
|
||||
|
||||
@@ -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++) {
|
||||
|
||||
@@ -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 |
@@ -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
|
||||
{
|
||||
/// <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");
|
||||
//throw new Exception("测试异常");//for test
|
||||
//其他项目启动时需要做的事情
|
||||
NLogUtil.WriteAll(NLog.LogLevel.Trace, LogType.Web, "网站启动", "网站启动成功");
|
||||
|
||||
host.Run();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//使用nlog写到本地日志文件(万一数据库没创建/连接成功)
|
||||
NLogUtil.WriteFileLog(NLog.LogLevel.Error, LogType.Web, "网站启动", "初始化数据异常", ex);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
/// <summary>
|
||||
/// 创建启动支撑
|
||||
/// </summary>
|
||||
/// <param name="args"></param>
|
||||
/// <returns></returns>
|
||||
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||
Host.CreateDefaultBuilder(args)
|
||||
.UseServiceProviderFactory(new AutofacServiceProviderFactory()) //<--NOTE THIS
|
||||
.ConfigureLogging(logging =>
|
||||
//添加本地路径获取支持
|
||||
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 =>
|
||||
{
|
||||
//实体验证
|
||||
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
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
.UseNLog(); //NLog: Setup NLog for Dependency injection
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
|
||||
#region 解决Ubuntu Nginx 代理不能获取IP问题===================================================================
|
||||
app.UseForwardedHeaders(new ForwardedHeadersOptions
|
||||
{
|
||||
webBuilder
|
||||
.ConfigureKestrel(serverOptions =>
|
||||
{
|
||||
serverOptions.AllowSynchronousIO = true;//启用同步 IO
|
||||
})
|
||||
.UseStartup<Startup>();
|
||||
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 =>
|
||||
{
|
||||
c.SwaggerEndpoint($"/swagger/{version}/swagger.json", $"Doc {version}");
|
||||
});
|
||||
c.RoutePrefix = "doc";
|
||||
});
|
||||
|
||||
|
||||
//使用 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// 启动类
|
||||
/// </summary>
|
||||
public class Program
|
||||
{
|
||||
/// <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, "接口启动", "接口启动成功");
|
||||
|
||||
host.Run();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//使用nlog写到本地日志文件(万一数据库没创建/连接成功)
|
||||
NLogUtil.WriteFileLog(LogLevel.Error, LogType.ApiRequest, "接口启动", "初始化数据异常", ex);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
/// <summary>
|
||||
/// 创建启动支撑
|
||||
/// </summary>
|
||||
/// <param name="args"></param>
|
||||
/// <returns></returns>
|
||||
public static IHostBuilder CreateHostBuilder(string[] 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 =>
|
||||
{
|
||||
return Host.CreateDefaultBuilder(args)
|
||||
.UseServiceProviderFactory(new AutofacServiceProviderFactory()) //<--NOTE THIS
|
||||
.ConfigureLogging(logging =>
|
||||
//实体验证
|
||||
options.Filters.Add<RequiredErrorForClent>();
|
||||
//异常处理
|
||||
options.Filters.Add<GlobalExceptionsFilterForClent>();
|
||||
//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 =>
|
||||
{
|
||||
//获取所有控制器类型并使用属性注入
|
||||
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
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
.UseNLog(); //NLog: Setup NLog for Dependency injection
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
|
||||
#region 解决Ubuntu Nginx 代理不能获取IP问题===================================================================
|
||||
app.UseForwardedHeaders(new ForwardedHeadersOptions
|
||||
{
|
||||
webBuilder
|
||||
.ConfigureKestrel(serverOptions =>
|
||||
{
|
||||
serverOptions.AllowSynchronousIO = true; //启用同步 IO
|
||||
})
|
||||
.UseStartup<Startup>();
|
||||
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
|
||||
{
|
||||
Login = AppSettingsConstVars.HangFireLogin,
|
||||
PasswordClear = AppSettingsConstVars.HangFirePassWord
|
||||
}
|
||||
}
|
||||
});
|
||||
var hangfireOptions = new Hangfire.DashboardOptions
|
||||
{
|
||||
AppPath = "/",//返回时跳转的地址
|
||||
DisplayStorageConnectionString = false,//是否显示数据库连接信息
|
||||
Authorization = new[]
|
||||
{
|
||||
filter
|
||||
},
|
||||
IsReadOnlyFunc = _ => false
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user