mirror of
http://git.coreshop.cn/jianweie/coreshoppro.git
synced 2026-05-07 01:47:20 +08:00
Merge branch 'feature/jianweie_dev' into 'develop'
Feature/jianweie dev See merge request jianweie/coreshoppro!1
This commit is contained in:
@@ -10,21 +10,110 @@ namespace CoreCms.Net.Caching.AutoMate.RedisCache
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IRedisOperationRepository
|
public interface IRedisOperationRepository
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 延长锁(续约)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
/// <param name="cacheTime"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool LockExtend(string key, string value, TimeSpan cacheTime);
|
||||||
|
|
||||||
//获取 Reids 缓存值
|
/// <summary>
|
||||||
|
/// 延长锁(续约)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
/// <param name="cacheTime"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<bool> LockExtendAsync(string key, string value, TimeSpan cacheTime);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 释放锁
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool LockRelease(string key, string value);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 释放锁
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<bool> LockReleaseAsync(string key, string value);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取锁
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
/// <param name="cacheTime"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool LockTake(string key, string value, TimeSpan cacheTime);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取锁
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
/// <param name="cacheTime"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public Task<bool> LockTakeAsync(string key, string value, TimeSpan cacheTime);
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取值
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <returns></returns>
|
||||||
Task<string> Get(string key);
|
Task<string> Get(string key);
|
||||||
|
|
||||||
|
RedisValue StringGet(string key);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 搜索获取匹配Key
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pattern"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
List<string> SearchKey(string pattern);
|
||||||
|
|
||||||
//获取值,并序列化
|
//获取值,并序列化
|
||||||
Task<TEntity> Get<TEntity>(string key);
|
Task<TEntity> Get<TEntity>(string key);
|
||||||
|
|
||||||
//保存
|
//保存
|
||||||
Task Set(string key, object value, TimeSpan cacheTime);
|
Task<bool> StringSetAsync(string key, string value, TimeSpan cacheTime);
|
||||||
|
|
||||||
|
bool StringSet(string key, string value, TimeSpan cacheTime);
|
||||||
|
|
||||||
|
bool StringSet(string key, string value);
|
||||||
|
|
||||||
|
bool StringSet(string key, RedisValue value);
|
||||||
|
|
||||||
|
bool StringSet(string key, RedisValue value, TimeSpan cacheTime);
|
||||||
|
|
||||||
|
|
||||||
|
Task SetAsync(string key, object value, TimeSpan cacheTime);
|
||||||
|
|
||||||
|
Task<long> StringIncrement(string key, long value=1);
|
||||||
|
|
||||||
|
|
||||||
//判断是否存在
|
//判断是否存在
|
||||||
Task<bool> Exist(string key);
|
Task<bool> KeyExistsAsync(string key);
|
||||||
|
|
||||||
|
bool KeyExists(string key);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取键 过期时间
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<TimeSpan?> KeyTime(string key);
|
||||||
|
|
||||||
//移除某一个缓存值
|
//移除某一个缓存值
|
||||||
Task Remove(string key);
|
Task KeyDeleteAsync(string key);
|
||||||
|
void KeyDelete(string key);
|
||||||
|
|
||||||
//全部清除
|
//全部清除
|
||||||
Task Clear();
|
Task Clear();
|
||||||
@@ -131,26 +220,46 @@ namespace CoreCms.Net.Caching.AutoMate.RedisCache
|
|||||||
Task ListClearAsync(string redisKey);
|
Task ListClearAsync(string redisKey);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 有序集合/定时任务延迟队列用的多(直接传分钟)
|
/// 有序集合/定时任务延迟队列用的多
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="redisKey">key</param>
|
/// <param name="redisKey">key</param>
|
||||||
/// <param name="redisValue">元素</param>
|
/// <param name="redisValue">元素</param>
|
||||||
/// <param name="score">分数</param>
|
/// <param name="score">分数</param>
|
||||||
Task SortedSetAddAsync(string redisKey, string redisValue, double score);
|
Task<bool> SortedSetAddAsync(string redisKey, string redisValue, double score);
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 有序集合/定时任务延迟队列用的多(直接传时间)
|
/// 插入zset
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="redisKey">key</param>
|
/// <param name="key">key</param>
|
||||||
/// <param name="redisValue">元素</param>
|
/// <param name="msg">消息</param>
|
||||||
/// <param name="dt">时间</param>
|
/// <param name="time">延迟执行时间</param>
|
||||||
Task SortedSetAddAsync(string redisKey, string redisValue, DateTime dt);
|
/// <returns></returns>
|
||||||
|
Task<bool> SortedSetAddAsync(string key, string msg, DateTime time);
|
||||||
|
|
||||||
#region 会员陌小北(QQ:1078350533) 添加的 几个有序集合功能
|
/// <summary>
|
||||||
|
/// 返回有序集合中指定成员的索引
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<long?> SortedSetRankAsync(string key, string value);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回有序集合中的分数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<double?> SortedSetScoreAsync(string key, string value);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回有序集合中的分数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
double? SortedSetScore(string key, string value);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 返回有序列表里的数据
|
/// 返回有序列表里的数据
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -170,6 +279,7 @@ namespace CoreCms.Net.Caching.AutoMate.RedisCache
|
|||||||
Task<long> SortedSetRemoveRangeByRankAsync(string redisKey, int start, int stop);
|
Task<long> SortedSetRemoveRangeByRankAsync(string redisKey, int start, int stop);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 返回有序列表里的指定范围数量
|
/// 返回有序列表里的指定范围数量
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -177,9 +287,9 @@ namespace CoreCms.Net.Caching.AutoMate.RedisCache
|
|||||||
/// <param name="start">0 是第一个</param>
|
/// <param name="start">0 是第一个</param>
|
||||||
/// <param name="stop">最大分数值</param>
|
/// <param name="stop">最大分数值</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<long> SortedSetLengthAsync(string redisKey, int start, int stop);
|
Task<long> SortedSetLengthAsync(string redisKey, long min, long max);
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using Microsoft.Extensions.Logging;
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using StackExchange.Redis;
|
using StackExchange.Redis;
|
||||||
|
|
||||||
|
|
||||||
namespace CoreCms.Net.Caching.AutoMate.RedisCache
|
namespace CoreCms.Net.Caching.AutoMate.RedisCache
|
||||||
{
|
{
|
||||||
public class RedisOperationRepository : IRedisOperationRepository
|
public class RedisOperationRepository : IRedisOperationRepository
|
||||||
@@ -39,22 +40,162 @@ namespace CoreCms.Net.Caching.AutoMate.RedisCache
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> Exist(string key)
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取锁
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
/// <param name="cacheTime"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool LockTake(string key, string value, TimeSpan cacheTime)
|
||||||
{
|
{
|
||||||
|
return _database.LockTake(key, value, cacheTime);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 异步获取锁
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
/// <param name="cacheTime"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<bool> LockTakeAsync(string key, string value, TimeSpan cacheTime)
|
||||||
|
{
|
||||||
|
return await _database.LockTakeAsync(key, value, cacheTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 延长锁(续约)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
/// <param name="cacheTime"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
|
||||||
|
public bool LockExtend(string key, string value, TimeSpan cacheTime)
|
||||||
|
{
|
||||||
|
return _database.LockExtend(key, value, cacheTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 延长锁(续约)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
/// <param name="cacheTime"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
|
||||||
|
public async Task<bool> LockExtendAsync(string key, string value, TimeSpan cacheTime)
|
||||||
|
{
|
||||||
|
return await _database.LockExtendAsync(key, value, cacheTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 释放锁
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool LockRelease(string key, string value)
|
||||||
|
{
|
||||||
|
return _database.LockRelease(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 异步释放锁
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<bool> LockReleaseAsync(string key, string value)
|
||||||
|
{
|
||||||
|
return await _database.LockReleaseAsync(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 判断key是否存在
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<bool> KeyExistsAsync(string key)
|
||||||
|
{
|
||||||
|
|
||||||
return await _database.KeyExistsAsync(key);
|
return await _database.KeyExistsAsync(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 判断key是否存在
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool KeyExists(string key)
|
||||||
|
{
|
||||||
|
|
||||||
|
return _database.KeyExists(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取键过期时间
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<TimeSpan?> KeyTime(string key)
|
||||||
|
{
|
||||||
|
|
||||||
|
return await _database.KeyTimeToLiveAsync(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public async Task<string> Get(string key)
|
public async Task<string> Get(string key)
|
||||||
{
|
{
|
||||||
return await _database.StringGetAsync(key);
|
return await _database.StringGetAsync(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Remove(string key)
|
public RedisValue StringGet(string key)
|
||||||
|
{
|
||||||
|
return _database.StringGet(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 搜索匹配Key
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pattern"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public List<string> SearchKey(string pattern)
|
||||||
|
{
|
||||||
|
|
||||||
|
var list = new List<string>();
|
||||||
|
var script = "return redis.call('keys',@pattern)";
|
||||||
|
var prepared = LuaScript.Prepare(script);
|
||||||
|
var redisResult = _database.ScriptEvaluate(prepared, new { pattern });
|
||||||
|
if (!redisResult.IsNull)
|
||||||
|
{
|
||||||
|
foreach (var key in (RedisKey[])redisResult)
|
||||||
|
{
|
||||||
|
|
||||||
|
list.Add(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task KeyDeleteAsync(string key)
|
||||||
{
|
{
|
||||||
await _database.KeyDeleteAsync(key);
|
await _database.KeyDeleteAsync(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Set(string key, object value, TimeSpan cacheTime)
|
public void KeyDelete(string key)
|
||||||
|
{
|
||||||
|
_database.KeyDelete(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async Task SetAsync(string key, object value, TimeSpan cacheTime)
|
||||||
{
|
{
|
||||||
if (value != null)
|
if (value != null)
|
||||||
{
|
{
|
||||||
@@ -63,6 +204,65 @@ namespace CoreCms.Net.Caching.AutoMate.RedisCache
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async Task<bool> StringSetAsync(string key, string value, TimeSpan cacheTime)
|
||||||
|
{
|
||||||
|
|
||||||
|
return await _database.StringSetAsync(key, value, cacheTime);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public bool StringSet(string key, string value, TimeSpan cacheTime)
|
||||||
|
{
|
||||||
|
|
||||||
|
return _database.StringSet(key, value, cacheTime);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public bool StringSet(string key, string value)
|
||||||
|
{
|
||||||
|
|
||||||
|
return _database.StringSet(key, value);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public bool StringSet(string key, RedisValue value, TimeSpan cacheTime)
|
||||||
|
{
|
||||||
|
|
||||||
|
return _database.StringSet(key, value, cacheTime);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public bool StringSet(string key, RedisValue value)
|
||||||
|
{
|
||||||
|
|
||||||
|
return _database.StringSet(key, value);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Increment 递增
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<long> StringIncrement(string key, long value=1)
|
||||||
|
{
|
||||||
|
|
||||||
|
return await _database.StringIncrementAsync(key, value);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public async Task<TEntity> Get<TEntity>(string key)
|
public async Task<TEntity> Get<TEntity>(string key)
|
||||||
{
|
{
|
||||||
var value = await _database.StringGetAsync(key);
|
var value = await _database.StringGetAsync(key);
|
||||||
@@ -77,6 +277,9 @@ namespace CoreCms.Net.Caching.AutoMate.RedisCache
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 根据key获取RedisValue
|
/// 根据key获取RedisValue
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -229,29 +432,70 @@ namespace CoreCms.Net.Caching.AutoMate.RedisCache
|
|||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 有序集合/定时任务延迟队列用的多(直接传分钟)
|
/// 有序集合/定时任务延迟队列用的多
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="redisKey">key</param>
|
/// <param name="redisKey">key</param>
|
||||||
/// <param name="redisValue">元素</param>
|
/// <param name="redisValue">元素</param>
|
||||||
/// <param name="score">分数</param>
|
/// <param name="score">分数</param>
|
||||||
public async Task SortedSetAddAsync(string redisKey, string redisValue, double score)
|
public async Task<bool> SortedSetAddAsync(string redisKey, string redisValue, double score)
|
||||||
{
|
{
|
||||||
await _database.SortedSetAddAsync(redisKey, redisValue, score);
|
return await _database.SortedSetAddAsync(redisKey, redisValue, score);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 有序集合/定时任务延迟队列用的多(直接传时间)
|
/// 添加到有序集合 用时间
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="redisKey">key</param>
|
/// <param name="key"></param>
|
||||||
/// <param name="redisValue">元素</param>
|
/// <param name="msg"></param>
|
||||||
/// <param name="dt">时间</param>
|
/// <param name="time"></param>
|
||||||
public async Task SortedSetAddAsync(string redisKey, string redisValue, DateTime dt)
|
/// <returns></returns>
|
||||||
|
|
||||||
|
public async Task<bool> SortedSetAddAsync(string key, string msg, DateTime time)
|
||||||
{
|
{
|
||||||
var score = (dt.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
|
var score = (time.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
|
||||||
await _database.SortedSetAddAsync(redisKey, redisValue, score);
|
var bl = await _database.SortedSetAddAsync(key, msg, score);
|
||||||
|
//When.NotExists 不更新 直接添加
|
||||||
|
return bl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region 小北 添加的 几个有序集合功能
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取有序集合索引
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<long?> SortedSetRankAsync(string key, string value)
|
||||||
|
{
|
||||||
|
var result= await _database.SortedSetRankAsync(key,value);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回有序集中,成员的分数值。 如果成员元素不是有序集 key 的成员,或 key 不存在,返回 null
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<double?> SortedSetScoreAsync(string key, string value)
|
||||||
|
{
|
||||||
|
var result = await _database.SortedSetScoreAsync(key, value);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public double? SortedSetScore(string key, string value)
|
||||||
|
{
|
||||||
|
var result = _database.SortedSetScore(key, value);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#region 会员陌小北(QQ:1078350533) 添加的 几个有序集合功能
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 返回有序列表里的数据
|
/// 返回有序列表里的数据
|
||||||
@@ -262,12 +506,16 @@ namespace CoreCms.Net.Caching.AutoMate.RedisCache
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task<IEnumerable<string>> SortedSetRangeByRankAsync(string redisKey, int start, int stop)
|
public async Task<IEnumerable<string>> SortedSetRangeByRankAsync(string redisKey, int start, int stop)
|
||||||
{
|
{
|
||||||
var result = await _database.SortedSetRangeByRankAsync(redisKey, start, stop);
|
var result= await _database.SortedSetRangeByRankAsync(redisKey, start, stop);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return result.Select(o => o.ToString());
|
return result.Select(o => o.ToString());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 移出序列表里的指定范围数量
|
/// 移出序列表里的指定范围数量
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -275,7 +523,7 @@ namespace CoreCms.Net.Caching.AutoMate.RedisCache
|
|||||||
/// <param name="start">0 是第一个</param>
|
/// <param name="start">0 是第一个</param>
|
||||||
/// <param name="stop">最大分数值</param>
|
/// <param name="stop">最大分数值</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task<long> SortedSetRemoveRangeByRankAsync(string redisKey, int start, int stop)
|
public async Task<long> SortedSetRemoveRangeByRankAsync(string redisKey, int start, int stop)
|
||||||
{
|
{
|
||||||
return await _database.SortedSetRemoveRangeByRankAsync(redisKey, start, stop);
|
return await _database.SortedSetRemoveRangeByRankAsync(redisKey, start, stop);
|
||||||
}
|
}
|
||||||
@@ -287,13 +535,12 @@ namespace CoreCms.Net.Caching.AutoMate.RedisCache
|
|||||||
/// <param name="start">0 是第一个</param>
|
/// <param name="start">0 是第一个</param>
|
||||||
/// <param name="stop">最大分数值</param>
|
/// <param name="stop">最大分数值</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task<long> SortedSetLengthAsync(string redisKey, int start, int stop)
|
public async Task<long> SortedSetLengthAsync(string redisKey, long min, long max)
|
||||||
{
|
{
|
||||||
return await _database.SortedSetLengthAsync(redisKey, start, stop);
|
return await _database.SortedSetLengthAsync(redisKey, min, max);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion 会员陌小北(QQ:1078350533) 添加的 几个有序集合功能
|
#endregion 小北 添加的 几个有序集合功能
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -413,10 +413,7 @@ namespace CoreCms.Net.Configuration
|
|||||||
/// 微信自定义交易组件-同步创建售后单
|
/// 微信自定义交易组件-同步创建售后单
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const string TransactionComponentAfterSaleCreateSync = "TransactionComponentAfterSaleCreateSyncQueue";
|
public const string TransactionComponentAfterSaleCreateSync = "TransactionComponentAfterSaleCreateSyncQueue";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//用户相关
|
//用户相关
|
||||||
|
|
||||||
@@ -428,6 +425,10 @@ namespace CoreCms.Net.Configuration
|
|||||||
//发送微信模板消息
|
//发送微信模板消息
|
||||||
public const string MessageSendWxMessageTemplet = "MessageSendWxMessageTempletQueue";
|
public const string MessageSendWxMessageTemplet = "MessageSendWxMessageTempletQueue";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 支付宝支付成功后推送到接口进行数据处理
|
||||||
|
/// </summary>
|
||||||
|
public const string AliPayNotice = "AliPayNoticeQueue";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ namespace CoreCms.Net.Core.AOP
|
|||||||
}
|
}
|
||||||
response ??= string.Empty;
|
response ??= string.Empty;
|
||||||
|
|
||||||
_cache.Set(cacheKey, response, TimeSpan.FromMinutes(qCachingAttribute.AbsoluteExpiration)).Wait();
|
_cache.SetAsync(cacheKey, response, TimeSpan.FromMinutes(qCachingAttribute.AbsoluteExpiration)).Wait();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ namespace CoreCms.Net.Core.Config
|
|||||||
typeof(SendWxTemplateMessageSubscribe),
|
typeof(SendWxTemplateMessageSubscribe),
|
||||||
typeof(AfterSalesReviewSubscribe),
|
typeof(AfterSalesReviewSubscribe),
|
||||||
typeof(AfterSalesReviewForPointSubscribe),
|
typeof(AfterSalesReviewForPointSubscribe),
|
||||||
|
typeof(AliPayNoticeSubscribe),
|
||||||
};
|
};
|
||||||
//显示日志
|
//显示日志
|
||||||
m.ShowLog = false;
|
m.ShowLog = false;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
* Description: 暂无
|
* Description: 暂无
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
|
using System.Threading.Tasks;
|
||||||
using CoreCms.Net.Model.Entities;
|
using CoreCms.Net.Model.Entities;
|
||||||
using CoreCms.Net.Model.ViewModels.UI;
|
using CoreCms.Net.Model.ViewModels.UI;
|
||||||
|
|
||||||
@@ -23,6 +24,6 @@ namespace CoreCms.Net.IServices
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="entity">实体数据</param>
|
/// <param name="entity">实体数据</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
WebApiCallBack PubPay(CoreCmsBillPayments entity);
|
Task<WebApiCallBack> PubPay(CoreCmsBillPayments entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
using CoreCms.Net.Model.Entities;
|
using CoreCms.Net.Model.Entities;
|
||||||
|
|
||||||
namespace CoreCms.Net.Model.FromBody
|
namespace CoreCms.Net.Model.FromBody
|
||||||
@@ -20,8 +21,9 @@ namespace CoreCms.Net.Model.FromBody
|
|||||||
public class FMWxPost
|
public class FMWxPost
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 页面编码
|
/// 用户前端编码
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[Required(ErrorMessage = "请提交合法数据")]
|
||||||
public string code { get; set; }
|
public string code { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Essensoft.Paylink.Alipay" Version="4.0.12" />
|
||||||
<PackageReference Include="Essensoft.Paylink.WeChatPay" Version="4.0.12" />
|
<PackageReference Include="Essensoft.Paylink.WeChatPay" Version="4.0.12" />
|
||||||
<PackageReference Include="InitQ" Version="1.0.0.12" />
|
<PackageReference Include="InitQ" Version="1.0.0.12" />
|
||||||
<PackageReference Include="Qc.YilianyunSdk" Version="1.0.7" />
|
<PackageReference Include="Qc.YilianyunSdk" Version="1.0.7" />
|
||||||
|
|||||||
76
CoreCms.Net.RedisMQ/Subscribe/AliPayNoticeSubscribe.cs
Normal file
76
CoreCms.Net.RedisMQ/Subscribe/AliPayNoticeSubscribe.cs
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
* Project: CoreCms
|
||||||
|
* ProjectName: 核心内容管理系统
|
||||||
|
* Web: https://www.corecms.net
|
||||||
|
* Author: 大灰灰
|
||||||
|
* Email: jianweie@163.com
|
||||||
|
* CreateTime: 2022/1/31 21:45:10
|
||||||
|
* Description: 暂无
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using CoreCms.Net.Configuration;
|
||||||
|
using CoreCms.Net.IServices;
|
||||||
|
using CoreCms.Net.Loging;
|
||||||
|
using Essensoft.Paylink.Alipay;
|
||||||
|
using Essensoft.Paylink.Alipay.Notify;
|
||||||
|
using InitQ.Abstractions;
|
||||||
|
using InitQ.Attributes;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace CoreCms.Net.RedisMQ.Subscribe
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 支付宝支付成功后推送到接口进行数据处理
|
||||||
|
/// </summary>
|
||||||
|
public class AliPayNoticeSubscribe : IRedisSubscribe
|
||||||
|
{
|
||||||
|
private readonly ICoreCmsBillPaymentsServices _billPaymentsServices;
|
||||||
|
|
||||||
|
public AliPayNoticeSubscribe(ICoreCmsBillPaymentsServices billPaymentsServices)
|
||||||
|
{
|
||||||
|
_billPaymentsServices = billPaymentsServices;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 支付宝支付成功后推送到接口进行数据处理
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="msg"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[Subscribe(RedisMessageQueueKey.AliPayNotice)]
|
||||||
|
private async Task AliPayNotice(string msg)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var notify = JsonConvert.DeserializeObject<AlipayTradeAppPayNotify>(msg);
|
||||||
|
if (notify is { TradeStatus: AlipayTradeStatus.Success })
|
||||||
|
{
|
||||||
|
if (notify.TradeStatus == AlipayTradeStatus.Success)
|
||||||
|
{
|
||||||
|
var money = decimal.Parse(notify.TotalAmount);
|
||||||
|
await _billPaymentsServices.ToUpdate(notify.OutTradeNo,
|
||||||
|
(int)GlobalEnumVars.BillPaymentsStatus.Payed,
|
||||||
|
GlobalEnumVars.PaymentsTypes.alipay.ToString(), money, notify.TradeStatus,notify.TradeNo);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var money = decimal.Parse(notify.TotalAmount);
|
||||||
|
var message = notify.TradeStatus;
|
||||||
|
await _billPaymentsServices.ToUpdate(notify.OutTradeNo,
|
||||||
|
(int)GlobalEnumVars.BillPaymentsStatus.Other,
|
||||||
|
GlobalEnumVars.PaymentsTypes.alipay.ToString(), money, message, notify.TradeNo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NLogUtil.WriteAll(NLog.LogLevel.Info, LogType.RedisMessageQueue, "支付宝支付成功后推送到接口进行数据处理", msg);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
NLogUtil.WriteAll(NLog.LogLevel.Error, LogType.RedisMessageQueue, "支付宝支付成功后推送到接口进行数据处理", msg, ex);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
await Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -479,7 +479,7 @@ namespace CoreCms.Net.Services
|
|||||||
//支付宝支付
|
//支付宝支付
|
||||||
else if (paymentCode == GlobalEnumVars.PaymentsTypes.alipay.ToString())
|
else if (paymentCode == GlobalEnumVars.PaymentsTypes.alipay.ToString())
|
||||||
{
|
{
|
||||||
jm = aliPayServices.PubPay(billPayments);
|
jm = await aliPayServices.PubPay(billPayments);
|
||||||
|
|
||||||
}
|
}
|
||||||
//余额支付
|
//余额支付
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.13.0" />
|
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.13.0" />
|
||||||
|
<PackageReference Include="Essensoft.Paylink.Alipay" Version="4.0.12" />
|
||||||
<PackageReference Include="Essensoft.Paylink.WeChatPay" Version="4.0.12" />
|
<PackageReference Include="Essensoft.Paylink.WeChatPay" Version="4.0.12" />
|
||||||
<PackageReference Include="Flurl.Http" Version="3.2.4" />
|
<PackageReference Include="Flurl.Http" Version="3.2.4" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
|
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
|
||||||
|
|||||||
@@ -8,10 +8,21 @@
|
|||||||
* Description: 暂无
|
* Description: 暂无
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
|
using CoreCms.Net.Configuration;
|
||||||
using CoreCms.Net.IRepository;
|
using CoreCms.Net.IRepository;
|
||||||
using CoreCms.Net.IServices;
|
using CoreCms.Net.IServices;
|
||||||
using CoreCms.Net.Model.Entities;
|
using CoreCms.Net.Model.Entities;
|
||||||
using CoreCms.Net.Model.ViewModels.UI;
|
using CoreCms.Net.Model.ViewModels.UI;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using NLog;
|
||||||
|
using System;
|
||||||
|
using Essensoft.Paylink.Alipay;
|
||||||
|
using Essensoft.Paylink.Alipay.Domain;
|
||||||
|
using Essensoft.Paylink.Alipay.Request;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Essensoft.Paylink.WeChatPay;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
|
||||||
namespace CoreCms.Net.Services
|
namespace CoreCms.Net.Services
|
||||||
{
|
{
|
||||||
@@ -20,20 +31,57 @@ namespace CoreCms.Net.Services
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class AliPayServices : BaseServices<CoreCmsSetting>, IAliPayServices
|
public class AliPayServices : BaseServices<CoreCmsSetting>, IAliPayServices
|
||||||
{
|
{
|
||||||
public AliPayServices(IWeChatPayRepository dal)
|
private readonly IAlipayClient _client;
|
||||||
|
private readonly IServiceProvider _serviceProvider;
|
||||||
|
private readonly IOptions<AlipayOptions> _optionsAccessor;
|
||||||
|
|
||||||
|
|
||||||
|
public AliPayServices(IWeChatPayRepository dal, IServiceProvider serviceProvider, IAlipayClient client, IOptions<AlipayOptions> optionsAccessor)
|
||||||
{
|
{
|
||||||
|
_serviceProvider = serviceProvider;
|
||||||
|
_client = client;
|
||||||
|
_optionsAccessor = optionsAccessor;
|
||||||
BaseDal = dal;
|
BaseDal = dal;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 发起支付
|
/// 发起支付宝支付
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="entity">实体数据</param>
|
/// <param name="entity">实体数据</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public WebApiCallBack PubPay(CoreCmsBillPayments entity)
|
public async Task<WebApiCallBack> PubPay(CoreCmsBillPayments entity)
|
||||||
{
|
{
|
||||||
var jm = new WebApiCallBack();
|
var jm = new WebApiCallBack();
|
||||||
|
using var container = _serviceProvider.CreateScope();
|
||||||
|
var billPaymentsServices = container.ServiceProvider.GetService<ICoreCmsBillPaymentsServices>();
|
||||||
|
var payment = await billPaymentsServices.QueryByClauseAsync(p => p.paymentId == entity.paymentId);
|
||||||
|
var allPayUrl = AppSettingsConstVars.PayCallBackAlipayUrl;
|
||||||
|
var allPayReturnUrl = AppSettingsConstVars.PayCallBackAlipayUrl;
|
||||||
|
if (string.IsNullOrEmpty(allPayUrl))
|
||||||
|
{
|
||||||
|
jm.msg = "未获取到配置的回调地址";
|
||||||
|
return jm;
|
||||||
|
}
|
||||||
|
var model = new AlipayTradeAppPayModel
|
||||||
|
{
|
||||||
|
OutTradeNo = entity.paymentId,
|
||||||
|
Subject = entity.payTitle.Length > 40 ? entity.payTitle[..40] : entity.payTitle,
|
||||||
|
ProductCode = entity.paymentCode,
|
||||||
|
TotalAmount = entity.money.ToString(),
|
||||||
|
Body = entity.payTitle.Length > 40 ? entity.payTitle[..40] : entity.payTitle
|
||||||
|
};
|
||||||
|
var req = new AlipayTradeAppPayRequest();
|
||||||
|
req.SetBizModel(model);
|
||||||
|
req.SetNotifyUrl(allPayUrl);
|
||||||
|
Loging.NLogUtil.WriteAll(LogLevel.Trace, Loging.LogType.Order, "支付宝支付拼接APP入参", JsonConvert.SerializeObject(model));
|
||||||
|
var response = await _client.SdkExecuteAsync(req, _optionsAccessor.Value);
|
||||||
|
Loging.NLogUtil.WriteAll(LogLevel.Trace, Loging.LogType.Order, "支付宝支付返回数据", JsonConvert.SerializeObject(response));
|
||||||
|
jm.data = response.Body;
|
||||||
|
response.TradeNo = entity.paymentId;
|
||||||
|
jm.otherData = response;
|
||||||
|
jm.status = true;
|
||||||
return jm;
|
return jm;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -100,7 +100,7 @@ namespace CoreCms.Net.Task
|
|||||||
entity.updateTimestamp = DateTimeOffset.Now.ToUnixTimeSeconds();
|
entity.updateTimestamp = DateTimeOffset.Now.ToUnixTimeSeconds();
|
||||||
await _weChatAccessTokenServices.UpdateAsync(entity);
|
await _weChatAccessTokenServices.UpdateAsync(entity);
|
||||||
}
|
}
|
||||||
await _redisOperationRepository.Set(GlobalEnumVars.AccessTokenEnum.WeiXinAccessToken.ToString(), entity, TimeSpan.FromMinutes(120));
|
await _redisOperationRepository.SetAsync(GlobalEnumVars.AccessTokenEnum.WeiXinAccessToken.ToString(), entity, TimeSpan.FromMinutes(120));
|
||||||
|
|
||||||
//插入日志
|
//插入日志
|
||||||
var model = new SysTaskLog
|
var model = new SysTaskLog
|
||||||
@@ -162,7 +162,7 @@ namespace CoreCms.Net.Task
|
|||||||
await _weChatAccessTokenServices.UpdateAsync(entity);
|
await _weChatAccessTokenServices.UpdateAsync(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
await _redisOperationRepository.Set(
|
await _redisOperationRepository.SetAsync(
|
||||||
GlobalEnumVars.AccessTokenEnum.WxOpenAccessToken.ToString(), entity,
|
GlobalEnumVars.AccessTokenEnum.WxOpenAccessToken.ToString(), entity,
|
||||||
TimeSpan.FromMinutes(120));
|
TimeSpan.FromMinutes(120));
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
<u-icon name="arrow-left" size="19" @click="goNavigateBack"></u-icon>
|
<u-icon name="arrow-left" size="19" @click="goNavigateBack"></u-icon>
|
||||||
<u-line direction="column" :hairline="false" margin="0 8px"></u-line>
|
<u-line direction="column" :hairline="false" margin="0 8px"></u-line>
|
||||||
<u-icon name="home" size="22" @click="goHome"></u-icon>
|
<u-icon name="home" size="22" @click="goHome"></u-icon>
|
||||||
|
<u-line direction="column" :hairline="false" margin="0 8px"></u-line>
|
||||||
|
<u-icon name="share" size="22" @click="goShare"></u-icon>
|
||||||
</view>
|
</view>
|
||||||
<view slot="right">
|
<view slot="right">
|
||||||
</view>
|
</view>
|
||||||
@@ -19,8 +21,19 @@
|
|||||||
<text class="coreshop-font-16">¥</text>
|
<text class="coreshop-font-16">¥</text>
|
||||||
<text class="coreshop-font-24">{{ product.price || '0.00' }}</text>
|
<text class="coreshop-font-24">{{ product.price || '0.00' }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="coreshop-flex-sub coreshop-text-left coreshop-margin-left-12 coreshop-margin-top-6">
|
<view class="coreshop-flex-sub coreshop-flex coreshop-text-left coreshop-margin-left-12 coreshop-margin-top-6 coreshop-justify-start coreshop-align-center">
|
||||||
<text class="coreshop-font-16 coreshop-text-gray coreshop-text-through">{{ priceSection }}</text>
|
<view class="coreshop-font-16 coreshop-text-gray coreshop-text-through">{{ priceSection }}</view>
|
||||||
|
<view class="coreshop-flex coreshop-flex-wrap coreshop-flex-direction-column coreshop-margin-left-12" v-if="pointSwitch==1 && pointExchangeModel==2 && pointShowExchangePrice==1 && product.pointsDeduction > 0">
|
||||||
|
<view class="coreshop-padding-bottom-5 coreshop-font-12">
|
||||||
|
兑换价:{{pointDiscountedProportion * product.pointsDeduction }}{{ pointShowName}}+{{ product.price - product.pointsDeduction}} 元
|
||||||
|
</view>
|
||||||
|
<view class="coreshop-font-12" v-if="pointSwitch==1 && pointGetModel==2 && pointShowPoint==1 && product.points > 0">买就送:{{product.points}}{{ pointShowName}}</view>
|
||||||
|
</view>
|
||||||
|
<view class="coreshop-flex coreshop-flex-wrap coreshop-flex-direction-column coreshop-margin-left-12" v-else>
|
||||||
|
<view class="coreshop-flex coreshop-flex-wrap coreshop-flex-direction-row">
|
||||||
|
<view class="coreshop-font-12" v-if="pointSwitch==1 && pointGetModel==2 && pointShowPoint==1 && product.points > 0">买就送:{{product.points}}{{ pointShowName}}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="coreshop-flex coreshop-align-center">
|
<view class="coreshop-flex coreshop-align-center">
|
||||||
<u-icon name="star-fill" :size="20" label="收藏" :labelSize="14" labelPos="right" @click="collection" v-if="isfav"></u-icon>
|
<u-icon name="star-fill" :size="20" label="收藏" :labelSize="14" labelPos="right" @click="collection" v-if="isfav"></u-icon>
|
||||||
@@ -33,14 +46,10 @@
|
|||||||
<view class="coreshop-margin-top-8 coreshop-single-line-clamp">
|
<view class="coreshop-margin-top-8 coreshop-single-line-clamp">
|
||||||
<text class="coreshop-font-14 coreshop-text-gray">{{ goodsInfo.brief || '' }}</text>
|
<text class="coreshop-font-14 coreshop-text-gray">{{ goodsInfo.brief || '' }}</text>
|
||||||
</view>
|
</view>
|
||||||
|
<view class="coreshop-flex coreshop-margin-top-8" v-if="goodsInfo.brand || goodsInfo.labels">
|
||||||
<view class="coreshop-flex coreshop-margin-top-8">
|
|
||||||
<u-tag :text="goodsInfo.brand.name" v-if="goodsInfo.brand"></u-tag>
|
<u-tag :text="goodsInfo.brand.name" v-if="goodsInfo.brand"></u-tag>
|
||||||
<view class="tag-64 cp832" wx:if="{{$root.m1}}">
|
<view class="coreshop-margin-left-6" v-for="item in goodsInfo.labels" :key="item.id">
|
||||||
<text class="font-color-orange">832产品</text>
|
<u-tag :text="item.name" :bgColor="item.style" :borderColor="item.style"></u-tag>
|
||||||
</view>
|
|
||||||
<view class="tag-64 shitang" wx:if="{{$root.m2}}">
|
|
||||||
<text class="font-color-blue">食堂专供</text>
|
|
||||||
</view>
|
</view>
|
||||||
</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-16 coreshop-padding-top-16 coreshop-solid-top coreshop-flex coreshop-justify-between coreshop-align-center coreshop-text-gray">
|
||||||
@@ -60,46 +69,6 @@
|
|||||||
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
|
||||||
<!--限时秒杀-->
|
|
||||||
<!--<view class="coreshop-limited-seckill-box coreshop-bg-red coreshop-flex coreshop-justify-start">-->
|
|
||||||
<!--<text class="coreshop-text-price coreshop-font-20">{{ product.price || '0.00' }}</text>-->
|
|
||||||
<!--<text class="coreshop-text-price coreshop-font-20">{{ priceSection }}</text>
|
|
||||||
<view class="coreshop-font-xs price-4 coreshop-margin-left-20">
|
|
||||||
<view v-if="pointSwitch==1 && pointExchangeModel==2 && pointShowExchangePrice==1 && product.pointsDeduction > 0">
|
|
||||||
<view class="coreshop-padding-bottom-5 coreshop-font-14">
|
|
||||||
兑换价:{{pointDiscountedProportion * product.pointsDeduction }}{{ pointShowName}}+{{ product.price - product.pointsDeduction}} 元
|
|
||||||
</view>
|
|
||||||
<view class="coreshop-flex coreshop-flex-wrap coreshop-flex-direction-row">
|
|
||||||
<view class="coreshop-text-through coreshop-padding-bottom-5">原价¥{{ product.mktprice || '0.00'}}</view>
|
|
||||||
<view class="coreshop-margin-left-10">{{ goodsInfo.buyCount || '0' }} 人已购买</view>
|
|
||||||
<view class="coreshop-margin-left-10" v-if="pointSwitch==1 && pointGetModel==2 && pointShowPoint==1 && product.points > 0">购买赠送:{{product.points}}{{ pointShowName}}</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view v-else>
|
|
||||||
<view class="coreshop-text-through coreshop-padding-bottom-5">原价¥{{ product.mktprice || '0.00'}}</view>
|
|
||||||
<view class="coreshop-flex coreshop-flex-wrap coreshop-flex-direction-row">
|
|
||||||
<view>{{ goodsInfo.buyCount || '0' }} 人已购买</view>
|
|
||||||
<view class="coreshop-margin-left-10" v-if="pointSwitch==1 && pointGetModel==2 && pointShowPoint==1 && product.points > 0">购买赠送:{{product.points}}{{ pointShowName}}</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="coreshop-text-right coreshop-share-right">
|
|
||||||
<u-icon name="share" @click="goShare()" label="分享" size="20" labelSize="11" color="#fff" labelColor="#fff" labelPos="bottom"></u-icon>
|
|
||||||
</view>
|
|
||||||
</view>-->
|
|
||||||
|
|
||||||
<!--标题-->
|
|
||||||
<!--<view class="coreshop-bg-white coreshop-common-view-box coreshop-good-title-view-box">
|
|
||||||
<view class="title-view coreshop-text-black coreshop-font-lg coreshop-text-bold">
|
|
||||||
<view class="brand-tag" v-if="goodsInfo.brand"><u-tag :text="goodsInfo.brand.name" type="error" size="mini" /></view>
|
|
||||||
{{ goodsInfo.name || '' }}
|
|
||||||
</view>
|
|
||||||
<view class="coreshop-bg-red-light radius coreshop-margin-top-10 coreshop-title-tip-box">
|
|
||||||
<text class="coreshop-font-sm">{{ goodsInfo.brief || '' }}</text>
|
|
||||||
</view>
|
|
||||||
</view>-->
|
|
||||||
|
|
||||||
<!--促销-->
|
<!--促销-->
|
||||||
<view class="coreshop-margin-top-10 coreshop-bg-white coreshop-common-view-box" v-if="promotion.length > 0" @tap="promotionTap">
|
<view class="coreshop-margin-top-10 coreshop-bg-white coreshop-common-view-box" v-if="promotion.length > 0" @tap="promotionTap">
|
||||||
<view class="coreshop-flex coreshop-flex-wrap coreshop-font-sm coreshop-flex-direction-row">
|
<view class="coreshop-flex coreshop-flex-wrap coreshop-font-sm coreshop-flex-direction-row">
|
||||||
@@ -342,7 +311,7 @@
|
|||||||
<!--底部操作-->
|
<!--底部操作-->
|
||||||
<view class="coreshop-good-footer-fixed">
|
<view class="coreshop-good-footer-fixed">
|
||||||
<view class="tabbar">
|
<view class="tabbar">
|
||||||
<view class="coreshop-flex coreshop-align-center coreshop-flex-direction-row coreshop-justify-between coreshop-basis-5">
|
<view class="coreshop-flex coreshop-align-center coreshop-flex-direction-row coreshop-justify-between coreshop-basis-4">
|
||||||
<!-- 客服按钮 -->
|
<!-- 客服按钮 -->
|
||||||
<!-- #ifdef H5 || APP-PLUS-NVUE || APP-PLUS -->
|
<!-- #ifdef H5 || APP-PLUS-NVUE || APP-PLUS -->
|
||||||
<view class="action" @click="showChat()">
|
<view class="action" @click="showChat()">
|
||||||
@@ -358,12 +327,6 @@
|
|||||||
</button>
|
</button>
|
||||||
</view>
|
</view>
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
<view class="action" @click="collection">
|
|
||||||
<button class="noButtonStyle">
|
|
||||||
<u-icon name="star-fill" :size="20" label="已收藏" :labelSize="12" labelPos="bottom" v-if="isfav"></u-icon>
|
|
||||||
<u-icon name="star" :size="20" label="加收藏" :labelSize="12" labelPos="bottom" v-else></u-icon>
|
|
||||||
</button>
|
|
||||||
</view>
|
|
||||||
<view class="action" @click="redirectCart">
|
<view class="action" @click="redirectCart">
|
||||||
<button class="noButtonStyle">
|
<button class="noButtonStyle">
|
||||||
<u-badge type="warning" :value="cartNums" showZero="false" absolute="true" :offset="[1, 4]"></u-badge>
|
<u-badge type="warning" :value="cartNums" showZero="false" absolute="true" :offset="[1, 4]"></u-badge>
|
||||||
@@ -702,7 +665,7 @@
|
|||||||
if (res.data.minPrice != res.data.maxPrice) {
|
if (res.data.minPrice != res.data.maxPrice) {
|
||||||
_this.priceSection = res.data.minPrice + '~' + res.data.maxPrice;
|
_this.priceSection = res.data.minPrice + '~' + res.data.maxPrice;
|
||||||
} else {
|
} else {
|
||||||
_this.priceSection = res.data.product.price;
|
_this.priceSection = res.data.product.mktprice;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_this.goodsInfo.album) {
|
if (_this.goodsInfo.album) {
|
||||||
|
|||||||
@@ -139,18 +139,21 @@
|
|||||||
switch (code) {
|
switch (code) {
|
||||||
case 'alipay':
|
case 'alipay':
|
||||||
/**
|
/**
|
||||||
* 支付宝支付需要模拟GET提交数据
|
* 支付宝支付需要模拟GET提交数据
|
||||||
*/
|
*/
|
||||||
|
console.log("支付宝支付入参app", data)
|
||||||
_this.$u.api.pay(data).then(res => {
|
_this.$u.api.pay(data).then(res => {
|
||||||
|
//console.log("支付宝支付返回参数app", res)
|
||||||
|
//console.log("支付宝app支付get提交数据", res.data)
|
||||||
if (res.status) {
|
if (res.status) {
|
||||||
uni.requestPayment({
|
uni.requestPayment({
|
||||||
provider: "alipay",
|
provider: "alipay",
|
||||||
orderInfo: res.data.data,
|
orderInfo: res.data,
|
||||||
success: function (data) {
|
success: function (data) {
|
||||||
_this.$refs.uToast.show({
|
_this.$refs.uToast.show({
|
||||||
message: '支付成功', type: 'success', complete: function () {
|
message: '支付成功', type: 'success', complete: function () {
|
||||||
_this.redirectHandler(res.data.paymentId)
|
console.log("支付id", res.otherData.tradeNo)
|
||||||
|
_this.redirectHandler(res.otherData.tradeNo)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -162,7 +165,7 @@
|
|||||||
})
|
})
|
||||||
break
|
break
|
||||||
case 'wechatpay':
|
case 'wechatpay':
|
||||||
|
|
||||||
// 微信app支付
|
// 微信app支付
|
||||||
_this.$u.api.pay(data).then(res => {
|
_this.$u.api.pay(data).then(res => {
|
||||||
if (res.status) {
|
if (res.status) {
|
||||||
|
|||||||
@@ -14,16 +14,16 @@
|
|||||||
"PassWord": "CoreShopProfessional"
|
"PassWord": "CoreShopProfessional"
|
||||||
},
|
},
|
||||||
"AppConfig": {
|
"AppConfig": {
|
||||||
"AppUrl": "https://admin.pro.coreshop.cn/", //后端管理地址
|
"AppUrl": "https://admin.test.pro.coreshop.cn/", //后端管理地址
|
||||||
"AppInterFaceUrl": "https://api.pro.coreshop.cn/", //接口请求地址
|
"AppInterFaceUrl": "https://api.test.pro.coreshop.cn/", //接口请求地址
|
||||||
"AppVersion": "CoreShopProfessional v0.5.5"
|
"AppVersion": "CoreShopProfessional v0.6.0"
|
||||||
},
|
},
|
||||||
//redis为必须启动项,请保持redis为正常可用
|
//redis为必须启动项,请保持redis为正常可用
|
||||||
"RedisConfig": {
|
"RedisConfig": {
|
||||||
"UseCache": true, //启用redis作为内存选择
|
"UseCache": true, //启用redis作为内存选择
|
||||||
"UseTimedTask": true, //启用redis作为定时任务
|
"UseTimedTask": true, //启用redis作为定时任务
|
||||||
// 如果采用容器化部署Service 要写成redis的服务名,否则写地址
|
// 如果采用容器化部署Service 要写成redis的服务名,否则写地址
|
||||||
"ConnectionString": "127.0.0.1:6379,password=CoreShop,connectTimeout=3000,connectRetry=1,syncTimeout=10000,DefaultDatabase=9,abortConnect=false" //redis数据库连接字符串
|
"ConnectionString": "127.0.0.1:6379,password=coreshop,connectTimeout=30000,responseTimeout=30000,abortConnect=false,connectRetry=1,syncTimeout=10000,DefaultDatabase=9" //redis数据库连接字符串
|
||||||
},
|
},
|
||||||
//jwt授权认证的一些设置
|
//jwt授权认证的一些设置
|
||||||
"JwtConfig": {
|
"JwtConfig": {
|
||||||
@@ -220,11 +220,11 @@
|
|||||||
},
|
},
|
||||||
"PayCallBack": {
|
"PayCallBack": {
|
||||||
//微信支付回调
|
//微信支付回调
|
||||||
"WeChatPayUrl": "https://api.pro.coreshop.cn/Notify/WeChatPay/Unifiedorder",
|
"WeChatPayUrl": "https://api.test.pro.coreshop.cn/Notify/WeChatPay/Unifiedorder",
|
||||||
//微信退款回调
|
//微信退款回调
|
||||||
"WeChatRefundUrl": "https://api.pro.coreshop.cn/Notify/WeChatPay/Refund",
|
"WeChatRefundUrl": "https://api.test.pro.coreshop.cn/Notify/WeChatPay/Refund",
|
||||||
//支付宝支付回调
|
//支付宝支付回调
|
||||||
"AlipayUrl": "",
|
"AlipayUrl": "https://api.test.pro.coreshop.cn/Notify/AliPay/Unifiedorder",
|
||||||
//支付宝退款回调
|
//支付宝退款回调
|
||||||
"AlipayRefundUrl": ""
|
"AlipayRefundUrl": ""
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ using System;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using CoreCms.Net.Auth.HttpContextUser;
|
using CoreCms.Net.Auth.HttpContextUser;
|
||||||
|
using CoreCms.Net.Caching.AutoMate.RedisCache;
|
||||||
using CoreCms.Net.Configuration;
|
using CoreCms.Net.Configuration;
|
||||||
using CoreCms.Net.IServices;
|
using CoreCms.Net.IServices;
|
||||||
using CoreCms.Net.Model.Entities;
|
using CoreCms.Net.Model.Entities;
|
||||||
@@ -47,6 +48,7 @@ namespace CoreCms.Net.Web.WebApi.Controllers
|
|||||||
private readonly ICoreCmsGoodsServices _goodsServices;
|
private readonly ICoreCmsGoodsServices _goodsServices;
|
||||||
private readonly ICoreCmsStoreServices _storeServices;
|
private readonly ICoreCmsStoreServices _storeServices;
|
||||||
private readonly ICoreCmsOrderDistributionModelServices _orderDistributionModelServices;
|
private readonly ICoreCmsOrderDistributionModelServices _orderDistributionModelServices;
|
||||||
|
private readonly IRedisOperationRepository _redisOperationRepository;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -59,7 +61,7 @@ namespace CoreCms.Net.Web.WebApi.Controllers
|
|||||||
, ICoreCmsSettingServices settingServices
|
, ICoreCmsSettingServices settingServices
|
||||||
, ICoreCmsAreaServices areaServices
|
, ICoreCmsAreaServices areaServices
|
||||||
, ICoreCmsBillReshipServices reshipServices, ICoreCmsShipServices shipServices
|
, ICoreCmsBillReshipServices reshipServices, ICoreCmsShipServices shipServices
|
||||||
, ICoreCmsBillDeliveryServices billDeliveryServices, ICoreCmsLogisticsServices logisticsServices, ICoreCmsGoodsServices goodsServices, ICoreCmsStoreServices storeServices, ICoreCmsOrderDistributionModelServices orderDistributionModelServices)
|
, ICoreCmsBillDeliveryServices billDeliveryServices, ICoreCmsLogisticsServices logisticsServices, ICoreCmsGoodsServices goodsServices, ICoreCmsStoreServices storeServices, ICoreCmsOrderDistributionModelServices orderDistributionModelServices, IRedisOperationRepository redisOperationRepository)
|
||||||
{
|
{
|
||||||
_user = user;
|
_user = user;
|
||||||
_orderServices = orderServices;
|
_orderServices = orderServices;
|
||||||
@@ -73,6 +75,7 @@ namespace CoreCms.Net.Web.WebApi.Controllers
|
|||||||
_goodsServices = goodsServices;
|
_goodsServices = goodsServices;
|
||||||
_storeServices = storeServices;
|
_storeServices = storeServices;
|
||||||
_orderDistributionModelServices = orderDistributionModelServices;
|
_orderDistributionModelServices = orderDistributionModelServices;
|
||||||
|
_redisOperationRepository = redisOperationRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -155,53 +158,82 @@ namespace CoreCms.Net.Web.WebApi.Controllers
|
|||||||
{
|
{
|
||||||
var jm = new WebApiCallBack();
|
var jm = new WebApiCallBack();
|
||||||
|
|
||||||
var type = entity.receiptType;
|
var lockKey = "LOCK_CreateOrder:user_" + _user.ID;
|
||||||
if (type == (int)GlobalEnumVars.OrderReceiptType.Logistics || type == (int)GlobalEnumVars.OrderReceiptType.IntraCityService)
|
var lockHolder = Guid.NewGuid().ToString("N"); //锁持有者
|
||||||
|
var redisUserLock = await _redisOperationRepository.LockTakeAsync(lockKey, lockHolder, TimeSpan.FromSeconds(10));
|
||||||
|
if (redisUserLock)
|
||||||
{
|
{
|
||||||
//收货地址id
|
try
|
||||||
if (entity.ushipId == 0)
|
|
||||||
{
|
{
|
||||||
jm.data = 13001;
|
var type = entity.receiptType;
|
||||||
jm.msg = GlobalErrorCodeVars.Code13001;
|
switch (type)
|
||||||
|
{
|
||||||
|
case (int)GlobalEnumVars.OrderReceiptType.Logistics:
|
||||||
|
case (int)GlobalEnumVars.OrderReceiptType.IntraCityService:
|
||||||
|
{
|
||||||
|
//收货地址id
|
||||||
|
if (entity.ushipId == 0)
|
||||||
|
{
|
||||||
|
jm.data = 13001;
|
||||||
|
jm.msg = GlobalErrorCodeVars.Code13001;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (int)GlobalEnumVars.OrderReceiptType.SelfDelivery:
|
||||||
|
{
|
||||||
|
//提货门店
|
||||||
|
if (entity.storeId == 0)
|
||||||
|
{
|
||||||
|
jm.data = 13001;
|
||||||
|
jm.msg = GlobalErrorCodeVars.Code13001;
|
||||||
|
}
|
||||||
|
|
||||||
|
//提货人姓名 提货人电话
|
||||||
|
if (string.IsNullOrEmpty(entity.ladingName))
|
||||||
|
{
|
||||||
|
jm.data = 13001;
|
||||||
|
jm.msg = "请输入姓名";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(entity.ladingMobile))
|
||||||
|
{
|
||||||
|
jm.data = 13001;
|
||||||
|
jm.msg = "请输入电话";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
jm.data = 13001;
|
||||||
|
jm.msg = "未查询到配送方式";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(entity.cartIds))
|
||||||
|
{
|
||||||
|
jm.data = 10000;
|
||||||
|
jm.msg = GlobalErrorCodeVars.Code10000;
|
||||||
|
}
|
||||||
|
|
||||||
|
jm = await _orderServices.ToAdd(_user.ID, entity.orderType, entity.cartIds, entity.receiptType,
|
||||||
|
entity.ushipId, entity.storeId, entity.ladingName, entity.ladingMobile, entity.memo,
|
||||||
|
entity.point, entity.couponCode, entity.source, entity.scene, entity.taxType, entity.taxName,
|
||||||
|
entity.taxCode, entity.objectId, entity.teamId, entity.requireOrder, entity.requiredFundType,
|
||||||
|
entity.traceId);
|
||||||
}
|
}
|
||||||
}
|
catch (Exception e)
|
||||||
else if (type == (int)GlobalEnumVars.OrderReceiptType.SelfDelivery)
|
|
||||||
{
|
|
||||||
//提货门店
|
|
||||||
if (entity.storeId == 0)
|
|
||||||
{
|
{
|
||||||
jm.data = 13001;
|
jm.msg = "数据处理异常";
|
||||||
jm.msg = GlobalErrorCodeVars.Code13001;
|
jm.otherData = e;
|
||||||
}
|
}
|
||||||
//提货人姓名 提货人电话
|
finally
|
||||||
if (string.IsNullOrEmpty(entity.ladingName))
|
|
||||||
{
|
{
|
||||||
jm.data = 13001;
|
await _redisOperationRepository.LockReleaseAsync(lockKey, lockHolder);
|
||||||
jm.msg = "请输入姓名";
|
|
||||||
}
|
|
||||||
if (string.IsNullOrEmpty(entity.ladingMobile))
|
|
||||||
{
|
|
||||||
jm.data = 13001;
|
|
||||||
jm.msg = "请输入电话";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
jm.data = 13001;
|
jm.msg = "当前请求太频繁_请稍后再试";
|
||||||
jm.msg = "未查询到配送方式";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(entity.cartIds))
|
|
||||||
{
|
|
||||||
jm.data = 10000;
|
|
||||||
jm.msg = GlobalErrorCodeVars.Code10000;
|
|
||||||
}
|
|
||||||
jm = await _orderServices.ToAdd(_user.ID, entity.orderType, entity.cartIds, entity.receiptType,
|
|
||||||
entity.ushipId, entity.storeId, entity.ladingName, entity.ladingMobile, entity.memo,
|
|
||||||
entity.point, entity.couponCode, entity.source, entity.scene, entity.taxType, entity.taxName,
|
|
||||||
entity.taxCode, entity.objectId, entity.teamId, entity.requireOrder, entity.requiredFundType, entity.traceId);
|
|
||||||
//jm.otherData = entity;
|
|
||||||
|
|
||||||
return jm;
|
return jm;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@@ -7,38 +7,76 @@
|
|||||||
* CreateTime: 2021/1/31 21:45:10
|
* CreateTime: 2021/1/31 21:45:10
|
||||||
* Description: 暂无
|
* Description: 暂无
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
|
using CoreCms.Net.Caching.AutoMate.RedisCache;
|
||||||
|
using CoreCms.Net.Configuration;
|
||||||
|
using CoreCms.Net.Loging;
|
||||||
using Essensoft.Paylink.Alipay;
|
using Essensoft.Paylink.Alipay;
|
||||||
using Essensoft.Paylink.Alipay.Notify;
|
using Essensoft.Paylink.Alipay.Notify;
|
||||||
using Essensoft.Paylink.Alipay.Utility;
|
using Essensoft.Paylink.Alipay.Utility;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using NLog;
|
||||||
|
|
||||||
namespace CoreCms.Net.Web.WebApi.Controllers.PayNotify
|
namespace CoreCms.Net.Web.WebApi.Controllers.PayNotify
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 支付宝异步通知
|
/// 支付宝异步通知
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Route("Notify/[controller]/[action]")]
|
[Route("Notify/[controller]/[action]")]
|
||||||
public class AliPayController : ControllerBase
|
public class AliPayController : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly IAlipayNotifyClient _client;
|
private readonly IAlipayNotifyClient _client;
|
||||||
private readonly IOptions<AlipayOptions> _optionsAccessor;
|
private readonly IOptions<AlipayOptions> _optionsAccessor;
|
||||||
|
private readonly IRedisOperationRepository _redisOperationRepository;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 构造函数
|
/// 构造函数
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="client"></param>
|
/// <param name="client"></param>
|
||||||
/// <param name="optionsAccessor"></param>
|
/// <param name="optionsAccessor"></param>
|
||||||
public AliPayController(IAlipayNotifyClient client, IOptions<AlipayOptions> optionsAccessor)
|
/// <param name="redisOperationRepository"></param>
|
||||||
|
public AliPayController(IAlipayNotifyClient client, IOptions<AlipayOptions> optionsAccessor, IRedisOperationRepository redisOperationRepository)
|
||||||
{
|
{
|
||||||
_client = client;
|
_client = client;
|
||||||
_optionsAccessor = optionsAccessor;
|
_optionsAccessor = optionsAccessor;
|
||||||
|
_redisOperationRepository = redisOperationRepository;
|
||||||
|
}
|
||||||
|
#region 支付宝统一回调接口
|
||||||
|
/// <summary>
|
||||||
|
/// APP支付统一下单支付结果通知
|
||||||
|
/// https://api.pro.coreshop.cn/Notify/AliPay/Unifiedorder
|
||||||
|
/// </summary>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IActionResult> Unifiedorder()
|
||||||
|
{
|
||||||
|
NLogUtil.WriteAll(LogLevel.Trace, LogType.Order, "支付宝支付回调开始", "支付宝回调开始数据标记");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var notify = await _client.ExecuteAsync<AlipayTradeAppPayNotify>(Request, _optionsAccessor.Value);
|
||||||
|
NLogUtil.WriteAll(LogLevel.Trace, LogType.Order, "支付宝支付回调支付宝返回的参数", JsonConvert.SerializeObject(notify));
|
||||||
|
if (notify.TradeStatus == AlipayTradeStatus.Success)
|
||||||
|
{
|
||||||
|
NLogUtil.WriteAll(LogLevel.Trace, LogType.Order, "支付宝支付回调开始处理订单业务,队列名称:", RedisMessageQueueKey.AliPayNotice);
|
||||||
|
await _redisOperationRepository.ListLeftPushAsync(RedisMessageQueueKey.AliPayNotice, JsonConvert.SerializeObject(notify));
|
||||||
|
return AlipayNotifyResult.Success;
|
||||||
|
}
|
||||||
|
NLogUtil.WriteAll(LogLevel.Trace, LogType.Order, "支付宝支付成功回调", JsonConvert.SerializeObject(notify));
|
||||||
|
return NoContent();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
NLogUtil.WriteAll(LogLevel.Trace, LogType.Order, "支付宝支付成功回调", "统一下单支付结果通知", ex);
|
||||||
|
return NoContent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 其他
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 应用网关
|
/// 应用网关
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -57,7 +95,7 @@ namespace CoreCms.Net.Web.WebApi.Controllers.PayNotify
|
|||||||
var options = _optionsAccessor.Value;
|
var options = _optionsAccessor.Value;
|
||||||
|
|
||||||
// 获取参数
|
// 获取参数
|
||||||
var parameters =await _client.GetParametersAsync(Request);
|
var parameters = await _client.GetParametersAsync(Request);
|
||||||
var sign = parameters["sign"];
|
var sign = parameters["sign"];
|
||||||
parameters.Remove("sign");
|
parameters.Remove("sign");
|
||||||
|
|
||||||
@@ -146,17 +184,18 @@ namespace CoreCms.Net.Web.WebApi.Controllers.PayNotify
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var notify = await _client.CertificateExecuteAsync<AlipayTradePrecreateNotify>(Request, _optionsAccessor.Value);
|
var notify = await _client.ExecuteAsync<AlipayTradeAppPayNotify>(Request, _optionsAccessor.Value);
|
||||||
if (notify.TradeStatus == AlipayTradeStatus.Success)
|
if (notify.TradeStatus == AlipayTradeStatus.Success)
|
||||||
{
|
{
|
||||||
Console.WriteLine("OutTradeNo: " + notify.OutTradeNo);
|
await _redisOperationRepository.ListLeftPushAsync(RedisMessageQueueKey.AliPayNotice, JsonConvert.SerializeObject(notify));
|
||||||
|
|
||||||
return AlipayNotifyResult.Success;
|
return AlipayNotifyResult.Success;
|
||||||
}
|
}
|
||||||
|
NLogUtil.WriteAll(LogLevel.Trace, LogType.Order, "支付宝支付成功回调", JsonConvert.SerializeObject(notify));
|
||||||
return NoContent();
|
return NoContent();
|
||||||
}
|
}
|
||||||
catch
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
NLogUtil.WriteAll(LogLevel.Trace, LogType.Order, "支付宝支付成功回调", "统一下单支付结果通知", ex);
|
||||||
return NoContent();
|
return NoContent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -183,7 +222,6 @@ namespace CoreCms.Net.Web.WebApi.Controllers.PayNotify
|
|||||||
return NoContent();
|
return NoContent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 电脑网站支付异步通知
|
/// 电脑网站支付异步通知
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -278,6 +316,6 @@ namespace CoreCms.Net.Web.WebApi.Controllers.PayNotify
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -20,6 +20,7 @@ using System.Threading.Tasks;
|
|||||||
using CoreCms.Net.Auth.HttpContextUser;
|
using CoreCms.Net.Auth.HttpContextUser;
|
||||||
using CoreCms.Net.Auth.Policys;
|
using CoreCms.Net.Auth.Policys;
|
||||||
using CoreCms.Net.Caching.AccressToken;
|
using CoreCms.Net.Caching.AccressToken;
|
||||||
|
using CoreCms.Net.Caching.AutoMate.RedisCache;
|
||||||
using CoreCms.Net.Configuration;
|
using CoreCms.Net.Configuration;
|
||||||
using CoreCms.Net.IServices;
|
using CoreCms.Net.IServices;
|
||||||
using CoreCms.Net.Loging;
|
using CoreCms.Net.Loging;
|
||||||
@@ -35,6 +36,7 @@ using CoreCms.Net.WeChat.Service.HttpClients;
|
|||||||
using CoreCms.Net.WeChat.Service.Models;
|
using CoreCms.Net.WeChat.Service.Models;
|
||||||
using CoreCms.Net.WeChat.Service.Options;
|
using CoreCms.Net.WeChat.Service.Options;
|
||||||
using CoreCms.Net.WeChat.Service.Utilities;
|
using CoreCms.Net.WeChat.Service.Utilities;
|
||||||
|
using DotLiquid.Util;
|
||||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
@@ -87,11 +89,7 @@ namespace CoreCms.Net.Web.WebApi.Controllers
|
|||||||
private readonly ICoreCmsOrderServices _orderServices;
|
private readonly ICoreCmsOrderServices _orderServices;
|
||||||
private readonly IWeChatApiHttpClientFactory _weChatApiHttpClientFactory;
|
private readonly IWeChatApiHttpClientFactory _weChatApiHttpClientFactory;
|
||||||
private readonly WeChatOptions _weChatOptions;
|
private readonly WeChatOptions _weChatOptions;
|
||||||
|
private readonly IRedisOperationRepository _redisOperationRepository;
|
||||||
|
|
||||||
private readonly AsyncLock _mutex = new AsyncLock();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 构造函数
|
/// 构造函数
|
||||||
@@ -122,7 +120,7 @@ namespace CoreCms.Net.Web.WebApi.Controllers
|
|||||||
, ICoreCmsSettingServices settingServices
|
, ICoreCmsSettingServices settingServices
|
||||||
, ICoreCmsServicesServices servicesServices
|
, ICoreCmsServicesServices servicesServices
|
||||||
, IOptions<WeChatOptions> weChatOptions
|
, IOptions<WeChatOptions> weChatOptions
|
||||||
, ICoreCmsUserServicesOrderServices userServicesOrderServices, ICoreCmsUserServicesTicketServices userServicesTicketServices, ICoreCmsStoreServices storeServices, ICoreCmsCouponServices couponServices, ICoreCmsOrderServices orderServices, IWeChatApiHttpClientFactory weChatApiHttpClientFactory)
|
, ICoreCmsUserServicesOrderServices userServicesOrderServices, ICoreCmsUserServicesTicketServices userServicesTicketServices, ICoreCmsStoreServices storeServices, ICoreCmsCouponServices couponServices, ICoreCmsOrderServices orderServices, IWeChatApiHttpClientFactory weChatApiHttpClientFactory, IRedisOperationRepository redisOperationRepository)
|
||||||
{
|
{
|
||||||
_user = user;
|
_user = user;
|
||||||
_userWeChatInfoServices = userWeChatInfoServices;
|
_userWeChatInfoServices = userWeChatInfoServices;
|
||||||
@@ -154,6 +152,7 @@ namespace CoreCms.Net.Web.WebApi.Controllers
|
|||||||
_couponServices = couponServices;
|
_couponServices = couponServices;
|
||||||
_orderServices = orderServices;
|
_orderServices = orderServices;
|
||||||
_weChatApiHttpClientFactory = weChatApiHttpClientFactory;
|
_weChatApiHttpClientFactory = weChatApiHttpClientFactory;
|
||||||
|
_redisOperationRepository = redisOperationRepository;
|
||||||
_weChatOptions = weChatOptions.Value;
|
_weChatOptions = weChatOptions.Value;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -170,86 +169,111 @@ namespace CoreCms.Net.Web.WebApi.Controllers
|
|||||||
{
|
{
|
||||||
var jm = new WebApiCallBack();
|
var jm = new WebApiCallBack();
|
||||||
|
|
||||||
var client = _weChatApiHttpClientFactory.CreateWxOpenClient();
|
var lockKey = "LOCK_OnLogin:user_" + entity.code;
|
||||||
var accessToken = WeChatCacheAccessTokenHelper.GetWxOpenAccessToken();
|
var lockHolder = Guid.NewGuid().ToString("N"); //锁持有者
|
||||||
var request = new SnsJsCode2SessionRequest();
|
var redisUserLock = await _redisOperationRepository.LockTakeAsync(lockKey, lockHolder, TimeSpan.FromSeconds(10));
|
||||||
request.JsCode = entity.code;
|
if (redisUserLock)
|
||||||
request.AccessToken = accessToken;
|
|
||||||
|
|
||||||
var response = await client.ExecuteSnsJsCode2SessionAsync(request, HttpContext.RequestAborted);
|
|
||||||
if (response.ErrorCode == (int)WeChatReturnCode.ReturnCode.请求成功)
|
|
||||||
{
|
{
|
||||||
using (await _mutex.LockAsync())
|
try
|
||||||
{
|
{
|
||||||
var userInfo = await _userWeChatInfoServices.QueryByClauseAsync(p => p.openid == response.OpenId);
|
var client = _weChatApiHttpClientFactory.CreateWxOpenClient();
|
||||||
if (userInfo == null)
|
var accessToken = WeChatCacheAccessTokenHelper.GetWxOpenAccessToken();
|
||||||
|
var request = new SnsJsCode2SessionRequest
|
||||||
{
|
{
|
||||||
userInfo = new CoreCmsUserWeChatInfo();
|
JsCode = entity.code,
|
||||||
userInfo.openid = response.OpenId;
|
AccessToken = accessToken
|
||||||
userInfo.type = (int)GlobalEnumVars.UserAccountTypes.微信小程序;
|
};
|
||||||
userInfo.sessionKey = response.SessionKey;
|
|
||||||
userInfo.gender = 1;
|
|
||||||
userInfo.createTime = DateTime.Now;
|
|
||||||
userInfo.unionId = response.UnionId;
|
|
||||||
await _userWeChatInfoServices.InsertAsync(userInfo);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (userInfo.sessionKey != response.SessionKey)
|
|
||||||
{
|
|
||||||
await _userWeChatInfoServices.UpdateAsync(
|
|
||||||
p => new CoreCmsUserWeChatInfo() { sessionKey = response.SessionKey, updateTime = DateTime.Now },
|
|
||||||
p => p.openid == userInfo.openid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (userInfo is { userId: > 0 })
|
var response = await client.ExecuteSnsJsCode2SessionAsync(request, HttpContext.RequestAborted);
|
||||||
|
if (response.ErrorCode == (int)WeChatReturnCode.ReturnCode.请求成功)
|
||||||
{
|
{
|
||||||
var user = await _userServices.QueryByClauseAsync(p => p.id == userInfo.userId);
|
var userInfo = await _userWeChatInfoServices.QueryByClauseAsync(p => p.openid == response.OpenId);
|
||||||
if (user != null)
|
if (userInfo == null)
|
||||||
{
|
{
|
||||||
var claims = new List<Claim> {
|
userInfo = new CoreCmsUserWeChatInfo
|
||||||
|
{
|
||||||
|
openid = response.OpenId,
|
||||||
|
type = (int)GlobalEnumVars.UserAccountTypes.微信小程序,
|
||||||
|
sessionKey = response.SessionKey,
|
||||||
|
gender = 1,
|
||||||
|
createTime = DateTime.Now,
|
||||||
|
unionId = response.UnionId
|
||||||
|
};
|
||||||
|
await _userWeChatInfoServices.InsertAsync(userInfo);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (userInfo.sessionKey != response.SessionKey)
|
||||||
|
{
|
||||||
|
await _userWeChatInfoServices.UpdateAsync(
|
||||||
|
p => new CoreCmsUserWeChatInfo() { sessionKey = response.SessionKey, updateTime = DateTime.Now },
|
||||||
|
p => p.openid == userInfo.openid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userInfo is { userId: > 0 })
|
||||||
|
{
|
||||||
|
var user = await _userServices.QueryByClauseAsync(p => p.id == userInfo.userId);
|
||||||
|
if (user != null)
|
||||||
|
{
|
||||||
|
var claims = new List<Claim> {
|
||||||
new Claim(ClaimTypes.Name, user.nickName),
|
new Claim(ClaimTypes.Name, user.nickName),
|
||||||
new Claim(JwtRegisteredClaimNames.Jti, user.id.ToString()),
|
new Claim(JwtRegisteredClaimNames.Jti, user.id.ToString()),
|
||||||
new Claim(ClaimTypes.Expiration, DateTime.Now.AddSeconds(_permissionRequirement.Expiration.TotalSeconds).ToString(CultureInfo.InvariantCulture)) };
|
new Claim(ClaimTypes.Expiration, DateTime.Now.AddSeconds(_permissionRequirement.Expiration.TotalSeconds).ToString(CultureInfo.InvariantCulture)) };
|
||||||
|
|
||||||
//用户标识
|
//用户标识
|
||||||
var identity = new ClaimsIdentity(JwtBearerDefaults.AuthenticationScheme);
|
var identity = new ClaimsIdentity(JwtBearerDefaults.AuthenticationScheme);
|
||||||
identity.AddClaims(claims);
|
identity.AddClaims(claims);
|
||||||
jm.status = true;
|
jm.status = true;
|
||||||
jm.data = new
|
jm.data = new
|
||||||
{
|
{
|
||||||
auth = JwtToken.BuildJwtToken(claims.ToArray(), _permissionRequirement),
|
auth = JwtToken.BuildJwtToken(claims.ToArray(), _permissionRequirement),
|
||||||
user
|
user
|
||||||
};
|
};
|
||||||
jm.otherData = response.OpenId;
|
jm.otherData = response.OpenId;
|
||||||
|
|
||||||
//录入登录日志
|
//录入登录日志
|
||||||
var log = new CoreCmsUserLog();
|
var log = new CoreCmsUserLog
|
||||||
log.userId = user.id;
|
{
|
||||||
log.state = (int)GlobalEnumVars.UserLogTypes.登录;
|
userId = user.id,
|
||||||
log.ip = _httpContextAccessor.HttpContext?.Connection.RemoteIpAddress != null ? _httpContextAccessor.HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString() : "127.0.0.1";
|
state = (int)GlobalEnumVars.UserLogTypes.登录,
|
||||||
log.createTime = DateTime.Now;
|
ip = _httpContextAccessor.HttpContext?.Connection.RemoteIpAddress != null ? _httpContextAccessor.HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString() : "127.0.0.1",
|
||||||
log.parameters = GlobalEnumVars.UserLogTypes.登录.ToString();
|
createTime = DateTime.Now,
|
||||||
await _userLogServices.InsertAsync(log);
|
parameters = GlobalEnumVars.UserLogTypes.登录.ToString()
|
||||||
|
};
|
||||||
|
await _userLogServices.InsertAsync(log);
|
||||||
|
|
||||||
return jm;
|
return jm;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
//注意:生产环境下SessionKey属于敏感信息,不能进行传输!
|
||||||
|
//return new JsonResult(new { success = true, msg = "OK", sessionAuthId = sessionBag.Key, sessionKey = sessionBag.SessionKey, data = jsonResult, sessionBag = sessionBag });
|
||||||
|
jm.status = true;
|
||||||
|
jm.data = response.OpenId;
|
||||||
|
jm.otherData = response.OpenId;
|
||||||
|
//jm.methodDescription = JsonConvert.SerializeObject(sessionBag);
|
||||||
|
jm.msg = "OK";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
jm.msg = response.ErrorMessage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//注意:生产环境下SessionKey属于敏感信息,不能进行传输!
|
catch (Exception e)
|
||||||
//return new JsonResult(new { success = true, msg = "OK", sessionAuthId = sessionBag.Key, sessionKey = sessionBag.SessionKey, data = jsonResult, sessionBag = sessionBag });
|
{
|
||||||
jm.status = true;
|
jm.msg = "数据处理异常";
|
||||||
jm.data = response.OpenId;
|
jm.otherData = e;
|
||||||
jm.otherData = response.OpenId;
|
}
|
||||||
//jm.methodDescription = JsonConvert.SerializeObject(sessionBag);
|
finally
|
||||||
jm.msg = "OK";
|
{
|
||||||
|
await _redisOperationRepository.LockReleaseAsync(lockKey, lockHolder);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
jm.msg = response.ErrorMessage;
|
jm.msg = "当前请求太频繁_请稍后再试";
|
||||||
}
|
}
|
||||||
|
|
||||||
return jm;
|
return jm;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@@ -14,16 +14,16 @@
|
|||||||
"PassWord": "CoreShopProfessional"
|
"PassWord": "CoreShopProfessional"
|
||||||
},
|
},
|
||||||
"AppConfig": {
|
"AppConfig": {
|
||||||
"AppUrl": "https://admin.pro.coreshop.cn/", //后端管理地址
|
"AppUrl": "https://admin.test.pro.coreshop.cn/", //后端管理地址
|
||||||
"AppInterFaceUrl": "https://api.pro.coreshop.cn/", //接口请求地址
|
"AppInterFaceUrl": "https://api.test.pro.coreshop.cn/", //接口请求地址
|
||||||
"AppVersion": "CoreShopProfessional v0.5.5"
|
"AppVersion": "CoreShopProfessional v0.6.0"
|
||||||
},
|
},
|
||||||
//redis为必须启动项,请保持redis为正常可用
|
//redis为必须启动项,请保持redis为正常可用
|
||||||
"RedisConfig": {
|
"RedisConfig": {
|
||||||
"UseCache": true, //启用redis作为内存选择
|
"UseCache": true, //启用redis作为内存选择
|
||||||
"UseTimedTask": true, //启用redis作为定时任务
|
"UseTimedTask": true, //启用redis作为定时任务
|
||||||
// 如果采用容器化部署Service 要写成redis的服务名,否则写地址
|
// 如果采用容器化部署Service 要写成redis的服务名,否则写地址
|
||||||
"ConnectionString": "127.0.0.1:6379,password=CoreShop,connectTimeout=3000,connectRetry=1,syncTimeout=10000,DefaultDatabase=9,abortConnect=false" //redis数据库连接字符串
|
"ConnectionString": "127.0.0.1:6379,password=coreshop,connectTimeout=30000,responseTimeout=30000,abortConnect=false,connectRetry=1,syncTimeout=10000,DefaultDatabase=9" //redis数据库连接字符串
|
||||||
},
|
},
|
||||||
//jwt授权认证的一些设置
|
//jwt授权认证的一些设置
|
||||||
"JwtConfig": {
|
"JwtConfig": {
|
||||||
@@ -220,11 +220,11 @@
|
|||||||
},
|
},
|
||||||
"PayCallBack": {
|
"PayCallBack": {
|
||||||
//微信支付回调
|
//微信支付回调
|
||||||
"WeChatPayUrl": "https://api.pro.coreshop.cn/Notify/WeChatPay/Unifiedorder",
|
"WeChatPayUrl": "https://api.test.pro.coreshop.cn/Notify/WeChatPay/Unifiedorder",
|
||||||
//微信退款回调
|
//微信退款回调
|
||||||
"WeChatRefundUrl": "https://api.pro.coreshop.cn/Notify/WeChatPay/Refund",
|
"WeChatRefundUrl": "https://api.test.pro.coreshop.cn/Notify/WeChatPay/Refund",
|
||||||
//支付宝支付回调
|
//支付宝支付回调
|
||||||
"AlipayUrl": "",
|
"AlipayUrl": "https://api.test.pro.coreshop.cn/Notify/AliPay/Unifiedorder",
|
||||||
//支付宝退款回调
|
//支付宝退款回调
|
||||||
"AlipayRefundUrl": ""
|
"AlipayRefundUrl": ""
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user