mirror of
http://git.coreshop.cn/jianweie/coreshoppro.git
synced 2025-12-06 20:03:26 +08:00
# 2022-01-24
### 开源社区版(会员专业版同步修改): 【完善】实现营销结果【GOODS_HALF_PRICE】指定商品每第几件减指定金额。 ### 0.1.2 会员专业版: 【新增】微信直播带货组件添加支持base64上传到微信侧功能。 【优化】定时任务调整工作线程数及日志数量。 【优化】定时任务执行时间基准调整为本地loacl时间。
This commit is contained in:
@@ -16,6 +16,8 @@ using CoreCms.Net.Configuration;
|
|||||||
using CoreCms.Net.Utility.Extensions;
|
using CoreCms.Net.Utility.Extensions;
|
||||||
using Hangfire;
|
using Hangfire;
|
||||||
using Hangfire.MySql;
|
using Hangfire.MySql;
|
||||||
|
using Hangfire.Redis;
|
||||||
|
using Hangfire.SqlServer;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
|
|
||||||
@@ -34,7 +36,13 @@ namespace CoreCms.Net.Core.Config
|
|||||||
var isEnabledRedis = AppSettingsConstVars.RedisUseTimedTask;
|
var isEnabledRedis = AppSettingsConstVars.RedisUseTimedTask;
|
||||||
if (isEnabledRedis)
|
if (isEnabledRedis)
|
||||||
{
|
{
|
||||||
services.AddHangfire(x => x.UseRedisStorage(AppSettingsConstVars.RedisConfigConnectionString));
|
services.AddHangfire(x => x.UseRedisStorage(AppSettingsConstVars.RedisConfigConnectionString, new RedisStorageOptions()
|
||||||
|
{
|
||||||
|
Db = 10,
|
||||||
|
SucceededListSize = 500,//后续列表中的最大可见后台作业,以防止它无限增长。
|
||||||
|
DeletedListSize = 500,//删除列表中的最大可见后台作业,以防止其无限增长。
|
||||||
|
InvisibilityTimeout = TimeSpan.FromMinutes(30),
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -48,14 +56,22 @@ namespace CoreCms.Net.Core.Config
|
|||||||
JobExpirationCheckInterval = TimeSpan.FromHours(1), //- 作业到期检查间隔(管理过期记录)。默认值为1小时。
|
JobExpirationCheckInterval = TimeSpan.FromHours(1), //- 作业到期检查间隔(管理过期记录)。默认值为1小时。
|
||||||
CountersAggregateInterval = TimeSpan.FromMinutes(5), //- 聚合计数器的间隔。默认为5分钟。
|
CountersAggregateInterval = TimeSpan.FromMinutes(5), //- 聚合计数器的间隔。默认为5分钟。
|
||||||
PrepareSchemaIfNecessary = true, //- 如果设置为true,则创建数据库表。默认是true。
|
PrepareSchemaIfNecessary = true, //- 如果设置为true,则创建数据库表。默认是true。
|
||||||
DashboardJobListLimit = 50000, //- 仪表板作业列表限制。默认值为50000。
|
DashboardJobListLimit = 500, //- 仪表板作业列表限制。默认值为50000。
|
||||||
TransactionTimeout = TimeSpan.FromMinutes(1), //- 交易超时。默认为1分钟。
|
TransactionTimeout = TimeSpan.FromMinutes(1), //- 交易超时。默认为1分钟。
|
||||||
TablesPrefix = "Hangfire" //- 数据库中表的前缀。默认为none
|
TablesPrefix = "Hangfire" //- 数据库中表的前缀。默认为none
|
||||||
})));
|
})));
|
||||||
}
|
}
|
||||||
else if (dbTypeString == DbType.SqlServer.ToString())
|
else if (dbTypeString == DbType.SqlServer.ToString())
|
||||||
{
|
{
|
||||||
services.AddHangfire(x => x.UseSqlServerStorage(AppSettingsConstVars.DbSqlConnection));
|
services.AddHangfire(x => x.UseSqlServerStorage(AppSettingsConstVars.DbSqlConnection, new SqlServerStorageOptions()
|
||||||
|
{
|
||||||
|
QueuePollInterval = TimeSpan.FromSeconds(15), //- 作业队列轮询间隔。默认值为15秒。
|
||||||
|
JobExpirationCheckInterval = TimeSpan.FromHours(1), //- 作业到期检查间隔(管理过期记录)。默认值为1小时。
|
||||||
|
CountersAggregateInterval = TimeSpan.FromMinutes(5), //- 聚合计数器的间隔。默认为5分钟。
|
||||||
|
PrepareSchemaIfNecessary = true, //- 如果设置为true,则创建数据库表。默认是true。
|
||||||
|
DashboardJobListLimit = 500, //- 仪表板作业列表限制。默认值为50000。
|
||||||
|
TransactionTimeout = TimeSpan.FromMinutes(1), //- 交易超时。默认为1分钟。
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,8 +80,9 @@ namespace CoreCms.Net.Core.Config
|
|||||||
options.Queues = new[] { GlobalEnumVars.HangFireQueuesConfig.@default.ToString(), GlobalEnumVars.HangFireQueuesConfig.apis.ToString(), GlobalEnumVars.HangFireQueuesConfig.web.ToString(), GlobalEnumVars.HangFireQueuesConfig.recurring.ToString() };
|
options.Queues = new[] { GlobalEnumVars.HangFireQueuesConfig.@default.ToString(), GlobalEnumVars.HangFireQueuesConfig.apis.ToString(), GlobalEnumVars.HangFireQueuesConfig.web.ToString(), GlobalEnumVars.HangFireQueuesConfig.recurring.ToString() };
|
||||||
options.ServerTimeout = TimeSpan.FromMinutes(4);
|
options.ServerTimeout = TimeSpan.FromMinutes(4);
|
||||||
options.SchedulePollingInterval = TimeSpan.FromSeconds(15);//秒级任务需要配置短点,一般任务可以配置默认时间,默认15秒
|
options.SchedulePollingInterval = TimeSpan.FromSeconds(15);//秒级任务需要配置短点,一般任务可以配置默认时间,默认15秒
|
||||||
options.ShutdownTimeout = TimeSpan.FromMinutes(30); //超时时间
|
options.ShutdownTimeout = TimeSpan.FromMinutes(5); //超时时间
|
||||||
options.WorkerCount = Math.Max(Environment.ProcessorCount, 20); //工作线程数,当前允许的最大线程,默认20
|
//options.WorkerCount = Math.Max(Environment.ProcessorCount, 2); //工作线程数,当前允许的最大线程,默认20
|
||||||
|
options.WorkerCount = 2; //工作线程数,当前允许的最大线程,默认20
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,6 +80,9 @@ namespace CoreCms.Net.Services
|
|||||||
case "GOODS_ONE_PRICE":
|
case "GOODS_ONE_PRICE":
|
||||||
promotionModel = result_GOODS_ONE_PRICE(parameters, item, promotionInfo);
|
promotionModel = result_GOODS_ONE_PRICE(parameters, item, promotionInfo);
|
||||||
break;
|
break;
|
||||||
|
case "GOODS_HALF_PRICE": //todo 指定商品每第几件减指定金额
|
||||||
|
promotionModel = result_GOODS_HALF_PRICE(parameters, item, promotionInfo);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
promotionModel = 0;
|
promotionModel = 0;
|
||||||
break;
|
break;
|
||||||
@@ -316,5 +319,35 @@ namespace CoreCms.Net.Services
|
|||||||
return promotionMoney;
|
return promotionMoney;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//商品第N个半价
|
||||||
|
public decimal result_GOODS_HALF_PRICE(JObject parameters, CartProducts cartProducts, CoreCmsPromotion promotionInfo)
|
||||||
|
{
|
||||||
|
if (!parameters.ContainsKey("money")) return 0;
|
||||||
|
var objMoney = parameters["money"].ObjectToDecimal(0);
|
||||||
|
|
||||||
|
//如果一口价比商品价格高,那么就不执行了
|
||||||
|
decimal promotionMoney = 0;
|
||||||
|
if (cartProducts.products.price <= objMoney)
|
||||||
|
{
|
||||||
|
return promotionMoney;
|
||||||
|
}
|
||||||
|
//第几个优惠
|
||||||
|
var num = parameters["num"].ObjectToInt(0);
|
||||||
|
//购买的数量
|
||||||
|
var buyNum = cartProducts.nums;
|
||||||
|
//取整数,保证满足了,才优惠 ,比如设置 原价 10 第2个 减少5,购买5个产品的时候,实际只优惠2个产品的价格
|
||||||
|
var promotionNum = buyNum / num;
|
||||||
|
var pmoney = Math.Round((decimal)promotionNum * objMoney / buyNum, 2); //单品优惠的金额
|
||||||
|
var goodsPrice = (decimal)cartProducts.products.price;
|
||||||
|
cartProducts.products.price = goodsPrice - pmoney; //优惠后的平均价格
|
||||||
|
promotionMoney = Math.Round(cartProducts.nums * pmoney, 2);//优惠金额
|
||||||
|
//设置商品优惠总金额
|
||||||
|
cartProducts.products.promotionAmount = Math.Round(cartProducts.products.promotionAmount + promotionMoney, 2);
|
||||||
|
//设置商品的实际销售总金额
|
||||||
|
cartProducts.products.amount = Math.Round(cartProducts.products.amount - promotionMoney, 2);
|
||||||
|
return promotionMoney;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,29 +42,29 @@ namespace CoreCms.Net.Task
|
|||||||
|
|
||||||
|
|
||||||
//自动取消订单任务
|
//自动取消订单任务
|
||||||
RecurringJob.AddOrUpdate<AutoCancelOrderJob>(s => s.Execute(), "0 0/5 * * * ? ", TimeZoneInfo.Utc); // 每5分钟取消一次订单
|
RecurringJob.AddOrUpdate<AutoCancelOrderJob>(s => s.Execute(), "0 0/5 * * * ? ", TimeZoneInfo.Local); // 每5分钟取消一次订单
|
||||||
|
|
||||||
//自动完成订单任务
|
//自动完成订单任务
|
||||||
RecurringJob.AddOrUpdate<CompleteOrderJob>(s => s.Execute(), Cron.Hourly, TimeZoneInfo.Utc); // 每小时自动完成订单
|
RecurringJob.AddOrUpdate<CompleteOrderJob>(s => s.Execute(), Cron.Hourly, TimeZoneInfo.Local); // 每小时自动完成订单
|
||||||
|
|
||||||
//自动评价订单任务
|
//自动评价订单任务
|
||||||
RecurringJob.AddOrUpdate<EvaluateOrderJob>(s => s.Execute(), Cron.Hourly, TimeZoneInfo.Utc); // 每小时自动完成订单
|
RecurringJob.AddOrUpdate<EvaluateOrderJob>(s => s.Execute(), Cron.Hourly, TimeZoneInfo.Local); // 每小时自动完成订单
|
||||||
|
|
||||||
//自动签收订单任务
|
//自动签收订单任务
|
||||||
RecurringJob.AddOrUpdate<AutoSignOrderJob>(s => s.Execute(), Cron.Hourly, TimeZoneInfo.Utc); // 每小时自动完成订单
|
RecurringJob.AddOrUpdate<AutoSignOrderJob>(s => s.Execute(), Cron.Hourly, TimeZoneInfo.Local); // 每小时自动完成订单
|
||||||
|
|
||||||
//催付款订单
|
//催付款订单
|
||||||
RecurringJob.AddOrUpdate<RemindOrderPayJob>(s => s.Execute(), "0 0/5 * * * ? ", TimeZoneInfo.Utc); // 每5分钟催付款订单
|
RecurringJob.AddOrUpdate<RemindOrderPayJob>(s => s.Execute(), "0 0/5 * * * ? ", TimeZoneInfo.Local); // 每5分钟催付款订单
|
||||||
|
|
||||||
//拼团自动取消到期团(每分钟执行一次)
|
//拼团自动取消到期团(每分钟执行一次)
|
||||||
RecurringJob.AddOrUpdate<AutoCanclePinTuanJob>(s => s.Execute(), Cron.Minutely, TimeZoneInfo.Utc); // 每分钟取消一次订单
|
RecurringJob.AddOrUpdate<AutoCanclePinTuanJob>(s => s.Execute(), Cron.Minutely, TimeZoneInfo.Local); // 每分钟取消一次订单
|
||||||
|
|
||||||
//每天凌晨5点定期清理7天前操作日志
|
//每天凌晨5点定期清理7天前操作日志
|
||||||
RecurringJob.AddOrUpdate<RemoveOperationLogJob>(s => s.Execute(), "0 0 5 * * ? ", TimeZoneInfo.Utc); // 每天5点固定时间清理一次
|
RecurringJob.AddOrUpdate<RemoveOperationLogJob>(s => s.Execute(), "0 0 5 * * ? ", TimeZoneInfo.Local); // 每天5点固定时间清理一次
|
||||||
|
|
||||||
|
|
||||||
//定时刷新获取微信AccessToken
|
//定时刷新获取微信AccessToken
|
||||||
RecurringJob.AddOrUpdate<RefreshWeChatAccessTokenJob>(s => s.Execute(), "0 0/2 * * * ? ", TimeZoneInfo.Utc); // 每2分钟刷新获取微信AccessToken
|
RecurringJob.AddOrUpdate<RefreshWeChatAccessTokenJob>(s => s.Execute(), "0 0/2 * * * ? ", TimeZoneInfo.Local); // 每2分钟刷新获取微信AccessToken
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1634,7 +1634,6 @@ namespace CoreCms.Net.Web.Admin.Controllers
|
|||||||
bytes = ms.ToArray();
|
bytes = ms.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
string url = string.Empty;
|
|
||||||
var accessToken = WeChatCacheAccessTokenHelper.GetWxOpenAccessToken();
|
var accessToken = WeChatCacheAccessTokenHelper.GetWxOpenAccessToken();
|
||||||
var client = _weChatApiHttpClientFactory.CreateWxOpenClient();
|
var client = _weChatApiHttpClientFactory.CreateWxOpenClient();
|
||||||
var request = new ShopImageUploadRequest();
|
var request = new ShopImageUploadRequest();
|
||||||
@@ -1665,7 +1664,58 @@ namespace CoreCms.Net.Web.Admin.Controllers
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region 自定义交易组件上传图片(Base64)====================================================
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 自定义交易组件上传图片(Base64)
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<AdminUiCallBack> MiNiShopOpenComponent2_UploadImgByBase64([FromBody] FMBase64Post entity)
|
||||||
|
{
|
||||||
|
var jm = new AdminUiCallBack();
|
||||||
|
|
||||||
|
|
||||||
|
var filesStorageOptions = await _coreCmsSettingServices.GetFilesStorageOptions();
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(entity.base64))
|
||||||
|
{
|
||||||
|
jm.msg = "请上传合法内容";
|
||||||
|
return jm;
|
||||||
|
}
|
||||||
|
|
||||||
|
entity.base64 = entity.base64.Replace("data:image/png;base64,", "").Replace("data:image/jgp;base64,", "").Replace("data:image/jpg;base64,", "").Replace("data:image/jpeg;base64,", "");//将base64头部信息替换
|
||||||
|
byte[] bytes = Convert.FromBase64String(entity.base64);
|
||||||
|
|
||||||
|
var accessToken = WeChatCacheAccessTokenHelper.GetWxOpenAccessToken();
|
||||||
|
var client = _weChatApiHttpClientFactory.CreateWxOpenClient();
|
||||||
|
var request = new ShopImageUploadRequest();
|
||||||
|
request.AccessToken = accessToken;
|
||||||
|
request.ImageFileBytes = bytes;
|
||||||
|
request.ResponseType = 1;
|
||||||
|
|
||||||
|
var response = await client.ExecuteShopImageUploadAsync(request);
|
||||||
|
if (response.IsSuccessful())
|
||||||
|
{
|
||||||
|
jm.code = 0;
|
||||||
|
jm.msg = "上传成功!";
|
||||||
|
jm.data = new
|
||||||
|
{
|
||||||
|
fileUrl = response.Image.TempImageUrl,
|
||||||
|
src = response.Image.TempImageUrl
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
jm.code = 1;
|
||||||
|
jm.msg = response.ErrorMessage;
|
||||||
|
}
|
||||||
|
jm.otherData = response;
|
||||||
|
|
||||||
|
return jm;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -116,7 +116,7 @@
|
|||||||
<div class="imgdiv">
|
<div class="imgdiv">
|
||||||
<img src="{{ item }}" class="layui-upload-img" onclick='layui.coreHelper.viewImage("{{ item }}")' style="width: 100px;height:100px;">
|
<img src="{{ item }}" class="layui-upload-img" onclick='layui.coreHelper.viewImage("{{ item }}")' style="width: 100px;height:100px;">
|
||||||
<div id="operate">
|
<div id="operate">
|
||||||
<div><a class="del" onclick="delImg(this,'{{ item }}')">删除</a>|<a class="setmain" onclick="setDefault(this,'{{ item }}')">设为主图</a></div>
|
<div><a class="del" onclick="delImg(this,'{{ item }}')">删除</a>|<a class="setmain" onclick="setDefault(this,'{{ item }}')">设为主图</a>|<a class="setmain" onclick="upLoadImage(this,'{{ item }}')">图片上传</a></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{# }); }}
|
{{# }); }}
|
||||||
@@ -163,7 +163,8 @@
|
|||||||
<div class="spec_image_item">
|
<div class="spec_image_item">
|
||||||
<img src="{{ item.images && item.images !='null'? item.images : layui.setter.noImagePicUrl }}" id="productImagesSrc" style="width:60px;height:60px">
|
<img src="{{ item.images && item.images !='null'? item.images : layui.setter.noImagePicUrl }}" id="productImagesSrc" style="width:60px;height:60px">
|
||||||
</div>
|
</div>
|
||||||
<input type="hidden" id="productImagesInput" name="product[thumbImg][]" value="{{ item.images && item.images !='null'? item.images : layui.setter.noImagePicUrl }}">
|
<!--<input type="hidden" id="productImagesInput" name="product[thumbImg][]" value="{{ item.images && item.images !='null'? item.images : layui.setter.noImagePicUrl }}">-->
|
||||||
|
<input type="hidden" id="productImagesInput" name="product[thumbImg][]" value="{{layui.setter.noImagePicUrl}}">
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@@ -217,8 +218,6 @@
|
|||||||
, coreHelper = layui.coreHelper;
|
, coreHelper = layui.coreHelper;
|
||||||
|
|
||||||
//加载编辑器
|
//加载编辑器
|
||||||
var Authorization = layui.data(layui.setter.tableName)[layui.setter.request.tokenName];
|
|
||||||
|
|
||||||
var Authorization = layui.data(layui.setter.tableName)[layui.setter.request.tokenName];
|
var Authorization = layui.data(layui.setter.tableName)[layui.setter.request.tokenName];
|
||||||
//重点代码 适配器
|
//重点代码 适配器
|
||||||
class UploadAdapter {
|
class UploadAdapter {
|
||||||
@@ -304,14 +303,14 @@
|
|||||||
window.editor.setData(ids.intro);
|
window.editor.setData(ids.intro);
|
||||||
|
|
||||||
|
|
||||||
if (ids.images) {
|
//if (ids.images) {
|
||||||
imgs = ids.images.split(',');
|
// imgs = ids.images.split(',');
|
||||||
$('#headImg').val(imgs);
|
// $('#headImg').val(imgs);
|
||||||
var getTpl = image_tpl.innerHTML, viewBox = document.getElementById('upload-more-list');
|
// var getTpl = image_tpl.innerHTML, viewBox = document.getElementById('upload-more-list');
|
||||||
laytpl(getTpl).render(imgs, function (html) {
|
// laytpl(getTpl).render(imgs, function (html) {
|
||||||
viewBox.innerHTML = html;
|
// viewBox.innerHTML = html;
|
||||||
});
|
// });
|
||||||
}
|
//}
|
||||||
|
|
||||||
$('#skuCount').val(ids.sku.length);
|
$('#skuCount').val(ids.sku.length);
|
||||||
|
|
||||||
@@ -365,7 +364,7 @@
|
|||||||
aspectRatio: 1 / 1,
|
aspectRatio: 1 / 1,
|
||||||
onCrop: function (data) {
|
onCrop: function (data) {
|
||||||
var loadIndex = layer.load(2);
|
var loadIndex = layer.load(2);
|
||||||
coreHelper.Post("api/Tools/UploadFilesFByBase64", { base64: data }, function (res) {
|
coreHelper.Post("api/Tools/MiNiShopOpenComponent2_UploadImgByBase64", { base64: data }, function (res) {
|
||||||
if (0 === res.code) {
|
if (0 === res.code) {
|
||||||
imgs.push(res.data.fileUrl);
|
imgs.push(res.data.fileUrl);
|
||||||
$('#headImg').val(imgs);
|
$('#headImg').val(imgs);
|
||||||
@@ -385,6 +384,9 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
form.verify({
|
form.verify({
|
||||||
|
|
||||||
verifyoutProductId: [/^.{0,50}$/, '商品序列最大只允许输入50位字符'],
|
verifyoutProductId: [/^.{0,50}$/, '商品序列最大只允许输入50位字符'],
|
||||||
|
|||||||
Reference in New Issue
Block a user