【新增】增加MySql.Data组件,防止出现Nlog新版mysql不写入的问题。

【优化】优化本地上传写入文件夹缺少反斜杠的问题。
【修复】修复appsetting.json微信公众号配置项命名错误的问题。
【新增】定时任务增加微信公众号获取JS-Token并且全局缓存功能。
【新增】增加微信公众号获取JS-SDK使用权限签名算法。
【新增】新增微信公众号【微信被动回复消息】功能,用于关于公众号提醒,微信聊天被动关键词回复等。
【新增】新增微信公众号【微信菜单管理】功能,用于管理公众号底部三列五横的链接。
【新增】新增微信公众号【消息推送】接口及业务处理。用于接收从微信公众号推送的事件交互。
【新增】新增微信公众号【授权鉴权跳转】功能,用于验证是否为微信公众号访问,及获取openid等信息。
【新增】新增微信公众号用户accressToekn存储机制。
【新增】新增微信公众号发送模板消息方法。
【新增】数据库新增【WeChatMessageResponse】【WeChatUserAccessToken】两个表,【CoreCmsUserWeChatInfo】增加【isSubscribe】是否关注字段。
【新增】商品品牌管理品牌logo增加原图上传 
【新增】商品分类管理分类图片增加原图上传
【新增】新增最新后台左侧管理菜单目录脚本,完整数据库脚本备份新增最新商品商品示例。
This commit is contained in:
大灰灰
2022-12-30 02:32:10 +08:00
parent 4430e6f4e0
commit 7d49668037
52 changed files with 7302 additions and 21 deletions

View File

@@ -19,6 +19,14 @@ namespace CoreCms.Net.Configuration
/// </summary>
public static readonly string AppConfigAppUrl = AppSettingsHelper.GetContent("AppConfig", "AppUrl");
/// <summary>
/// PC端地址
/// </summary>
public static readonly string AppConfigAppPcUrl = AppSettingsHelper.GetContent("AppConfig", "AppPcUrl");
/// <summary>
/// H5端地址
/// </summary>
public static readonly string AppConfigAppH5Url = AppSettingsHelper.GetContent("AppConfig", "AppH5Url");
/// <summary>
/// 系统接口地址
/// </summary>
public static readonly string AppConfigAppInterFaceUrl = AppSettingsHelper.GetContent("AppConfig", "AppInterFaceUrl");

View File

@@ -3152,5 +3152,128 @@ namespace CoreCms.Net.Configuration
#endregion
#region
/// <summary>
/// 公众号所属类型
/// </summary>
public enum WeChatSubscriberEnum
{
/// <summary>
/// 测试号
/// </summary>
[Description("测试号")]
Test = 0,
/// <summary>
/// 个人订阅号
/// </summary>
[Description("公众号")]
PersonalSubscriber = 1,
/// <summary>
/// 小程序
/// </summary>
[Description("小程序")]
MiniProgram = 2
}
/// <summary>
/// 微信消息回复类型
/// </summary>
public enum WeChatReplyCategory
{
//文本
[Description("文本")]
Text = 1,
//图文
[Description("图文")]
Image = 2,
//语音
[Description("语音")]
Voice = 3,
//相等,用于回复关键字
[Description("相等")]
Equal = 4,
//包含,用于回复关键字
[Description("包含")]
Contain = 5
}
/// <summary>
/// 微信消息回复类型
/// </summary>
public enum WeChatReplyType
{
//文本
[Description("文本")]
Text = 1,
//图文
[Description("图文")]
Image = 2,
//语音
//[Description("语音")]
//Voice = 3
}
/// <summary>
/// 微信消息回复类型
/// </summary>
public enum WeChatReplyMatchKeyType
{
//相等,用于回复关键字
[Description("相等")]
Equal = 4,
//包含,用于回复关键字
[Description("包含")]
Contain = 5
}
/// <summary>
/// 微信消息回复类型
/// </summary>
public enum WeChatRequestRuleEnum
{
/// <summary>
/// 默认回复,没有处理的
/// </summary>
[Description("默认回复")]
Default = 0,
/// <summary>
/// 关注回复
/// </summary>
[Description("关注回复")]
Subscriber = 1,
/// <summary>
/// 文本回复
/// </summary>
[Description("文本回复")]
Text = 2,
/// <summary>
/// 图片回复
/// </summary>
[Description("图片回复")]
Image = 3,
///// <summary>
///// 语音回复
///// </summary>
[Description("语音回复")]
Voice = 4,
///// <summary>
///// 视频回复
///// </summary>
//Video = 5,
///// <summary>
///// 超链接回复
///// </summary>
//Link = 6,
///// <summary>
///// LBS位置回复
///// </summary>
//Location = 7,
}
#endregion
}
}

View File

@@ -0,0 +1,82 @@
/***********************************************************************
* Project: CoreCms
* ProjectName: 核心内容管理系统
* Web: https://www.corecms.net
* Author: 大灰灰
* Email: jianweie@163.com
* CreateTime: 2022/12/14 0:36:13
* Description: 暂无
***********************************************************************/
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
using CoreCms.Net.Model.Entities;
using CoreCms.Net.Model.ViewModels.Basics;
using CoreCms.Net.Model.ViewModels.UI;
using SqlSugar;
namespace CoreCms.Net.IRepository
{
/// <summary>
/// 微信自动回复消息表 工厂接口
/// </summary>
public interface IWeChatMessageResponseRepository : IBaseRepository<WeChatMessageResponse>
{
#region ===========================================================
/// <summary>
/// 重写异步插入方法
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
Task<AdminUiCallBack> InsertAsync(WeChatMessageResponse entity);
/// <summary>
/// 重写异步更新方法
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
Task<AdminUiCallBack> UpdateAsync(WeChatMessageResponse entity);
/// <summary>
/// 重写删除指定ID的数据
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
Task<AdminUiCallBack> DeleteByIdAsync(object id);
#endregion
#region ==========================================================
/// <summary>
/// 获取缓存的所有数据
/// </summary>
/// <returns></returns>
Task<List<WeChatMessageResponse>> GetCaChe();
#endregion
/// <summary>
/// 重写根据条件查询分页数据
/// </summary>
/// <param name="predicate">判断集合</param>
/// <param name="orderByType">排序方式</param>
/// <param name="pageIndex">当前页面索引</param>
/// <param name="pageSize">分布大小</param>
/// <param name="orderByExpression"></param>
/// <param name="blUseNoLock">是否使用WITH(NOLOCK)</param>
/// <returns></returns>
Task<IPageList<WeChatMessageResponse>> QueryPageAsync(
Expression<Func<WeChatMessageResponse, bool>> predicate,
Expression<Func<WeChatMessageResponse, object>> orderByExpression, OrderByType orderByType, int pageIndex = 1,
int pageSize = 20, bool blUseNoLock = false);
}
}

View File

@@ -0,0 +1,98 @@
/***********************************************************************
* Project: CoreCms
* ProjectName: 核心内容管理系统
* Web: https://www.corecms.net
* Author: 大灰灰
* Email: jianweie@163.com
* CreateTime: 2022/12/14 21:20:57
* Description: 暂无
***********************************************************************/
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
using CoreCms.Net.Model.Entities;
using CoreCms.Net.Model.ViewModels.Basics;
using CoreCms.Net.Model.ViewModels.UI;
using SqlSugar;
namespace CoreCms.Net.IRepository
{
/// <summary>
/// 微信用户交互授权 工厂接口
/// </summary>
public interface IWeChatUserAccessTokenRepository : IBaseRepository<WeChatUserAccessToken>
{
#region ===========================================================
/// <summary>
/// 重写异步插入方法
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
Task<AdminUiCallBack> InsertAsync(WeChatUserAccessToken entity);
/// <summary>
/// 重写异步更新方法
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
Task<AdminUiCallBack> UpdateAsync(WeChatUserAccessToken entity);
/// <summary>
/// 重写异步更新方法
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
Task<AdminUiCallBack> UpdateAsync(List<WeChatUserAccessToken> entity);
/// <summary>
/// 重写删除指定ID的数据
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
Task<AdminUiCallBack> DeleteByIdAsync(object id);
/// <summary>
/// 重写删除指定ID集合的数据(批量删除)
/// </summary>
/// <param name="ids"></param>
/// <returns></returns>
Task<AdminUiCallBack> DeleteByIdsAsync(int[] ids);
#endregion
#region ==========================================================
/// <summary>
/// 获取缓存的所有数据
/// </summary>
/// <returns></returns>
Task<List<WeChatUserAccessToken>> GetCaChe();
#endregion
/// <summary>
/// 重写根据条件查询分页数据
/// </summary>
/// <param name="predicate">判断集合</param>
/// <param name="orderByType">排序方式</param>
/// <param name="pageIndex">当前页面索引</param>
/// <param name="pageSize">分布大小</param>
/// <param name="orderByExpression"></param>
/// <param name="blUseNoLock">是否使用WITH(NOLOCK)</param>
/// <returns></returns>
Task<IPageList<WeChatUserAccessToken>> QueryPageAsync(
Expression<Func<WeChatUserAccessToken, bool>> predicate,
Expression<Func<WeChatUserAccessToken, object>> orderByExpression, OrderByType orderByType, int pageIndex = 1,
int pageSize = 20, bool blUseNoLock = false);
}
}

View File

@@ -0,0 +1,80 @@
/***********************************************************************
* Project: CoreCms
* ProjectName: 核心内容管理系统
* Web: https://www.corecms.net
* Author: 大灰灰
* Email: jianweie@163.com
* CreateTime: 2022/12/14 0:36:13
* Description: 暂无
***********************************************************************/
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
using CoreCms.Net.Model.Entities;
using CoreCms.Net.Model.ViewModels.Basics;
using CoreCms.Net.Model.ViewModels.UI;
using SqlSugar;
namespace CoreCms.Net.IServices
{
/// <summary>
/// 微信自动回复消息表 服务工厂接口
/// </summary>
public interface IWeChatMessageResponseServices : IBaseServices<WeChatMessageResponse>
{
#region ===========================================================
/// <summary>
/// 重写异步插入方法
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
Task<AdminUiCallBack> InsertAsync(WeChatMessageResponse entity);
/// <summary>
/// 重写异步更新方法
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
Task<AdminUiCallBack> UpdateAsync(WeChatMessageResponse entity);
/// <summary>
/// 重写删除指定ID的数据
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
Task<AdminUiCallBack> DeleteByIdAsync(object id);
#endregion
#region ==========================================================
/// <summary>
/// 获取缓存的所有数据
/// </summary>
/// <returns></returns>
Task<List<WeChatMessageResponse>> GetCaChe();
#endregion
#region
/// <summary>
/// 重写根据条件查询分页数据
/// </summary>
/// <param name="predicate">判断集合</param>
/// <param name="orderByType">排序方式</param>
/// <param name="pageIndex">当前页面索引</param>
/// <param name="pageSize">分布大小</param>
/// <param name="orderByExpression"></param>
/// <param name="blUseNoLock">是否使用WITH(NOLOCK)</param>
/// <returns></returns>
Task<IPageList<WeChatMessageResponse>> QueryPageAsync(
Expression<Func<WeChatMessageResponse, bool>> predicate,
Expression<Func<WeChatMessageResponse, object>> orderByExpression, OrderByType orderByType, int pageIndex = 1,
int pageSize = 20, bool blUseNoLock = false);
#endregion
}
}

View File

@@ -0,0 +1,94 @@
/***********************************************************************
* Project: CoreCms
* ProjectName: 核心内容管理系统
* Web: https://www.corecms.net
* Author: 大灰灰
* Email: jianweie@163.com
* CreateTime: 2022/12/14 21:20:57
* Description: 暂无
***********************************************************************/
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
using CoreCms.Net.Model.Entities;
using CoreCms.Net.Model.ViewModels.Basics;
using CoreCms.Net.Model.ViewModels.UI;
using SqlSugar;
namespace CoreCms.Net.IServices
{
/// <summary>
/// 微信用户交互授权 服务工厂接口
/// </summary>
public interface IWeChatUserAccessTokenServices : IBaseServices<WeChatUserAccessToken>
{
#region ===========================================================
/// <summary>
/// 重写异步插入方法
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
Task<AdminUiCallBack> InsertAsync(WeChatUserAccessToken entity);
/// <summary>
/// 重写异步更新方法
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
Task<AdminUiCallBack> UpdateAsync(WeChatUserAccessToken entity);
/// <summary>
/// 重写异步更新方法
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
Task<AdminUiCallBack> UpdateAsync(List<WeChatUserAccessToken> entity);
/// <summary>
/// 重写删除指定ID的数据
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
Task<AdminUiCallBack> DeleteByIdAsync(object id);
/// <summary>
/// 重写删除指定ID集合的数据(批量删除)
/// </summary>
/// <param name="ids"></param>
/// <returns></returns>
Task<AdminUiCallBack> DeleteByIdsAsync(int[] ids);
#endregion
#region ==========================================================
/// <summary>
/// 获取缓存的所有数据
/// </summary>
/// <returns></returns>
Task<List<WeChatUserAccessToken>> GetCaChe();
#endregion
#region
/// <summary>
/// 重写根据条件查询分页数据
/// </summary>
/// <param name="predicate">判断集合</param>
/// <param name="orderByType">排序方式</param>
/// <param name="pageIndex">当前页面索引</param>
/// <param name="pageSize">分布大小</param>
/// <param name="orderByExpression"></param>
/// <param name="blUseNoLock">是否使用WITH(NOLOCK)</param>
/// <returns></returns>
Task<IPageList<WeChatUserAccessToken>> QueryPageAsync(
Expression<Func<WeChatUserAccessToken, bool>> predicate,
Expression<Func<WeChatUserAccessToken, object>> orderByExpression, OrderByType orderByType, int pageIndex = 1,
int pageSize = 20, bool blUseNoLock = false);
#endregion
}
}

View File

@@ -50,6 +50,8 @@ namespace CoreCms.Net.Loging
WxPost,
[Description("PC网站")]
PcWeb,
[Description("微信公众号")]
WeChat,
}
public static class NLogUtil
{

View File

@@ -5,6 +5,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="SKIT.FlurlHttpClient.Wechat.Api" Version="2.20.1" />
<PackageReference Include="sqlSugarCore" Version="5.1.3.32" />
</ItemGroup>

View File

@@ -141,5 +141,12 @@ namespace CoreCms.Net.Model.Entities
[Display(Name = "更新时间")]
[SugarColumn(ColumnDescription = "更新时间", IsNullable = true)]
public System.DateTime? updateTime { get; set; }
/// <summary>
/// 是否订阅
/// </summary>
[Display(Name = "是否订阅")]
[SugarColumn(ColumnDescription = "是否订阅", IsNullable = true)]
public System.Boolean isSubscribe { get; set; }
}
}

View File

@@ -0,0 +1,212 @@
/***********************************************************************
* Project: CoreCms
* ProjectName: 核心内容管理系统
* Web: https://www.corecms.net
* Author: 大灰灰
* Email: jianweie@163.com
* CreateTime: 2022/12/28 22:34:52
* Description: 暂无
***********************************************************************/
using SqlSugar;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
namespace CoreCms.Net.Model.Entities
{
/// <summary>
/// 微信自动回复消息表
/// </summary>
public partial class WeChatMessageResponse
{
/// <summary>
/// 构造函数
/// </summary>
public WeChatMessageResponse()
{
}
/// <summary>
/// 序列
/// </summary>
[Display(Name = "序列")]
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
[Required(ErrorMessage = "请输入{0}")]
public System.Int32 id { get; set; }
/// <summary>
/// 消息类型
/// </summary>
[Display(Name = "消息类型")]
public System.Int32? messageRule { get; set; }
/// <summary>
/// 分类
/// </summary>
[Display(Name = "分类")]
public System.Int32? category { get; set; }
/// <summary>
/// 匹配字符
/// </summary>
[Display(Name = "匹配字符")]
[StringLength(maximumLength:100,ErrorMessage = "{0}不能超过{1}字")]
public System.String matchKey { get; set; }
/// <summary>
/// 文本回复内容
/// </summary>
[Display(Name = "文本回复内容")]
public System.String textContent { get; set; }
/// <summary>
/// 图片回复内容
/// </summary>
[Display(Name = "图片回复内容")]
public System.String imgTextContext { get; set; }
/// <summary>
/// 图片回复图片地址
/// </summary>
[Display(Name = "图片回复图片地址")]
[StringLength(maximumLength:1000,ErrorMessage = "{0}不能超过{1}字")]
public System.String imgTextUrl { get; set; }
/// <summary>
/// 图片回复超链接
/// </summary>
[Display(Name = "图片回复超链接")]
[StringLength(maximumLength:1000,ErrorMessage = "{0}不能超过{1}字")]
public System.String imgTextLink { get; set; }
/// <summary>
/// 语音回复地址
/// </summary>
[Display(Name = "语音回复地址")]
[StringLength(maximumLength:1000,ErrorMessage = "{0}不能超过{1}字")]
public System.String meidaUrl { get; set; }
/// <summary>
/// 语音回复超链接
/// </summary>
[Display(Name = "语音回复超链接")]
[StringLength(maximumLength:1000,ErrorMessage = "{0}不能超过{1}字")]
public System.String meidaLink { get; set; }
/// <summary>
/// 是否启用
/// </summary>
[Display(Name = "是否启用")]
[Required(ErrorMessage = "请输入{0}")]
public System.Boolean enable { get; set; }
/// <summary>
/// 是否默认
/// </summary>
[Display(Name = "是否默认")]
[Required(ErrorMessage = "请输入{0}")]
public System.Boolean isDefault { get; set; }
/// <summary>
/// 备注
/// </summary>
[Display(Name = "备注")]
[StringLength(maximumLength:1000,ErrorMessage = "{0}不能超过{1}字")]
public System.String remark { get; set; }
/// <summary>
/// 排序
/// </summary>
[Display(Name = "排序")]
[Required(ErrorMessage = "请输入{0}")]
public System.Int32 sort { get; set; }
/// <summary>
/// 创建时间
/// </summary>
[Display(Name = "创建时间")]
[Required(ErrorMessage = "请输入{0}")]
public System.DateTime createTime { get; set; }
}
}

View File

@@ -0,0 +1,140 @@
/***********************************************************************
* Project: CoreCms
* ProjectName: 核心内容管理系统
* Web: https://www.corecms.net
* Author: 大灰灰
* Email: jianweie@163.com
* CreateTime: 2022/12/28 22:34:42
* Description: 暂无
***********************************************************************/
using SqlSugar;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
namespace CoreCms.Net.Model.Entities
{
/// <summary>
/// 微信用户交互授权
/// </summary>
public partial class WeChatUserAccessToken
{
/// <summary>
/// 构造函数
/// </summary>
public WeChatUserAccessToken()
{
}
/// <summary>
/// 序列
/// </summary>
[Display(Name = "序列")]
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
[Required(ErrorMessage = "请输入{0}")]
public System.Int32 id { get; set; }
/// <summary>
/// 网页授权接口调用凭证
/// </summary>
[Display(Name = "网页授权接口调用凭证")]
[Required(ErrorMessage = "请输入{0}")]
[StringLength(maximumLength:120,ErrorMessage = "{0}不能超过{1}字")]
public System.String access_token { get; set; }
/// <summary>
/// 超时时间秒
/// </summary>
[Display(Name = "超时时间秒")]
[Required(ErrorMessage = "请输入{0}")]
public System.Int32 expires_in { get; set; }
/// <summary>
/// 用户刷新access_token
/// </summary>
[Display(Name = "用户刷新access_token")]
[StringLength(maximumLength:120,ErrorMessage = "{0}不能超过{1}字")]
public System.String refresh_token { get; set; }
/// <summary>
/// 需刷新时间
/// </summary>
[Display(Name = "需刷新时间")]
[Required(ErrorMessage = "请输入{0}")]
public System.DateTime refresh_DateTime { get; set; }
/// <summary>
/// 用户唯一标识
/// </summary>
[Display(Name = "用户唯一标识")]
[StringLength(maximumLength:50,ErrorMessage = "{0}不能超过{1}字")]
public System.String openid { get; set; }
/// <summary>
/// 用户授权的作用域
/// </summary>
[Display(Name = "用户授权的作用域")]
[StringLength(maximumLength:50,ErrorMessage = "{0}不能超过{1}字")]
public System.String scope { get; set; }
/// <summary>
/// 是否为快照页模式虚拟账号
/// </summary>
[Display(Name = "是否为快照页模式虚拟账号")]
public System.Int32? is_snapshotuser { get; set; }
/// <summary>
/// 用户统一标识
/// </summary>
[Display(Name = "用户统一标识")]
[StringLength(maximumLength:50,ErrorMessage = "{0}不能超过{1}字")]
public System.String unionid { get; set; }
}
}

View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SKIT.FlurlHttpClient.Wechat.Api.Models;
namespace CoreCms.Net.Model.WeChatEntites
{
public class MenuFull_ButtonGroupForSkit
{
public List<CgibinMenuCreateRequest.Types.Button> button { get; set; }
}
}

View File

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CoreCms.Net.Model
{
public class TmpMsgModel
{
public string OpenId { get; set; }
public string TemplateId { get; set; }
public string First { get; set; }
public string Keyword1 { get; set; } = string.Empty;
public string Keyword2 { get; set; } = string.Empty;
public string Keyword3 { get; set; } = string.Empty;
public string Keyword4 { get; set; } = string.Empty;
public string Keyword5 { get; set; } = string.Empty;
public string Keyword6 { get; set; } = string.Empty;
public string Keyword7 { get; set; } = string.Empty;
public string Keyword8 { get; set; } = string.Empty;
public string Keyword9 { get; set; } = string.Empty;
public string Keyword10 { get; set; } = string.Empty;
public string Remark { get; set; } = string.Empty;
public string Url { get; set; } = string.Empty;
}
}

View File

@@ -0,0 +1,215 @@
/***********************************************************************
* Project: CoreCms
* ProjectName: 核心内容管理系统
* Web: https://www.corecms.net
* Author: 大灰灰
* Email: jianweie@163.com
* CreateTime: 2022/12/14 0:36:13
* Description: 暂无
***********************************************************************/
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
using CoreCms.Net.Caching.Manual;
using CoreCms.Net.Configuration;
using CoreCms.Net.Model.Entities;
using CoreCms.Net.Model.ViewModels.Basics;
using CoreCms.Net.IRepository;
using CoreCms.Net.IRepository.UnitOfWork;
using CoreCms.Net.Model.ViewModels.UI;
using SqlSugar;
namespace CoreCms.Net.Repository
{
/// <summary>
/// 微信自动回复消息表 接口实现
/// </summary>
public class WeChatMessageResponseRepository : BaseRepository<WeChatMessageResponse>, IWeChatMessageResponseRepository
{
private readonly IUnitOfWork _unitOfWork;
public WeChatMessageResponseRepository(IUnitOfWork unitOfWork) : base(unitOfWork)
{
_unitOfWork = unitOfWork;
}
#region ==========================================================
/// <summary>
/// 重写异步插入方法
/// </summary>
/// <param name="entity">实体数据</param>
/// <returns></returns>
public async Task<AdminUiCallBack> InsertAsync(WeChatMessageResponse entity)
{
var jm = new AdminUiCallBack();
entity.createTime = DateTime.Now;
var bl = await DbClient.Insertable(entity).ExecuteReturnIdentityAsync() > 0;
jm.code = bl ? 0 : 1;
jm.msg = bl ? GlobalConstVars.CreateSuccess : GlobalConstVars.CreateFailure;
if (bl && entity.category == (int)GlobalEnumVars.WeChatRequestRuleEnum.Default && entity.isDefault == true)
{
await DbClient.Updateable<WeChatMessageResponse>(p => new WeChatMessageResponse() { isDefault = false })
.Where(p => p.isDefault == true && p.category == (int)GlobalEnumVars.WeChatRequestRuleEnum.Default)
.ExecuteCommandAsync();
}
return jm;
}
/// <summary>
/// 重写异步更新方法
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public async Task<AdminUiCallBack> UpdateAsync(WeChatMessageResponse entity)
{
var jm = new AdminUiCallBack();
var oldModel = await DbClient.Queryable<WeChatMessageResponse>().In(entity.id).SingleAsync();
if (oldModel == null)
{
jm.msg = "不存在此信息";
return jm;
}
//事物处理过程开始
//oldModel.id = entity.id;
oldModel.messageRule = entity.messageRule;
oldModel.category = entity.category;
oldModel.matchKey = entity.matchKey;
oldModel.textContent = entity.textContent;
oldModel.imgTextContext = entity.imgTextContext;
oldModel.imgTextUrl = entity.imgTextUrl;
oldModel.imgTextLink = entity.imgTextLink;
oldModel.meidaUrl = entity.meidaUrl;
oldModel.meidaLink = entity.meidaLink;
oldModel.enable = entity.enable;
oldModel.isDefault = entity.isDefault;
oldModel.remark = entity.remark;
oldModel.sort = entity.sort;
oldModel.createTime = entity.createTime;
//事物处理过程结束
var bl = await DbClient.Updateable(oldModel).ExecuteCommandHasChangeAsync();
jm.code = bl ? 0 : 1;
jm.msg = bl ? GlobalConstVars.EditSuccess : GlobalConstVars.EditFailure;
if (bl && entity.category == (int)GlobalEnumVars.WeChatRequestRuleEnum.Default && entity.isDefault == true)
{
await DbClient.Updateable<WeChatMessageResponse>(p => new WeChatMessageResponse() { isDefault = false })
.Where(p => p.isDefault == true && p.category == (int)GlobalEnumVars.WeChatRequestRuleEnum.Default)
.ExecuteCommandAsync();
}
return jm;
}
/// <summary>
/// 重写删除指定ID的数据
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task<AdminUiCallBack> DeleteByIdAsync(object id)
{
var jm = new AdminUiCallBack();
var bl = await DbClient.Deleteable<WeChatMessageResponse>(id).ExecuteCommandHasChangeAsync();
jm.code = bl ? 0 : 1;
jm.msg = bl ? GlobalConstVars.DeleteSuccess : GlobalConstVars.DeleteFailure;
return jm;
}
#endregion
#region ==========================================================
/// <summary>
/// 获取缓存的所有数据
/// </summary>
/// <returns></returns>
public async Task<List<WeChatMessageResponse>> GetCaChe()
{
var list = await DbClient.Queryable<WeChatMessageResponse>().With(SqlWith.NoLock).WithCache().ToListAsync();
return list;
}
#endregion
#region
/// <summary>
/// 重写根据条件查询分页数据
/// </summary>
/// <param name="predicate">判断集合</param>
/// <param name="orderByType">排序方式</param>
/// <param name="pageIndex">当前页面索引</param>
/// <param name="pageSize">分布大小</param>
/// <param name="orderByExpression"></param>
/// <param name="blUseNoLock">是否使用WITH(NOLOCK)</param>
/// <returns></returns>
public async Task<IPageList<WeChatMessageResponse>> QueryPageAsync(Expression<Func<WeChatMessageResponse, bool>> predicate,
Expression<Func<WeChatMessageResponse, object>> orderByExpression, OrderByType orderByType, int pageIndex = 1,
int pageSize = 20, bool blUseNoLock = false)
{
RefAsync<int> totalCount = 0;
List<WeChatMessageResponse> page;
if (blUseNoLock)
{
page = await DbClient.Queryable<WeChatMessageResponse>()
.OrderByIF(orderByExpression != null, orderByExpression, orderByType)
.WhereIF(predicate != null, predicate).Select(p => new WeChatMessageResponse
{
id = p.id,
messageRule = p.messageRule,
category = p.category,
matchKey = p.matchKey,
textContent = p.textContent,
imgTextContext = p.imgTextContext,
imgTextUrl = p.imgTextUrl,
imgTextLink = p.imgTextLink,
meidaUrl = p.meidaUrl,
meidaLink = p.meidaLink,
enable = p.enable,
isDefault = p.isDefault,
remark = p.remark,
sort = p.sort,
createTime = p.createTime
}).With(SqlWith.NoLock).ToPageListAsync(pageIndex, pageSize, totalCount);
}
else
{
page = await DbClient.Queryable<WeChatMessageResponse>()
.OrderByIF(orderByExpression != null, orderByExpression, orderByType)
.WhereIF(predicate != null, predicate).Select(p => new WeChatMessageResponse
{
id = p.id,
messageRule = p.messageRule,
category = p.category,
matchKey = p.matchKey,
textContent = p.textContent,
imgTextContext = p.imgTextContext,
imgTextUrl = p.imgTextUrl,
imgTextLink = p.imgTextLink,
meidaUrl = p.meidaUrl,
meidaLink = p.meidaLink,
enable = p.enable,
isDefault = p.isDefault,
remark = p.remark,
sort = p.sort,
createTime = p.createTime
}).ToPageListAsync(pageIndex, pageSize, totalCount);
}
var list = new PageList<WeChatMessageResponse>(page, pageIndex, pageSize, totalCount);
return list;
}
#endregion
}
}

View File

@@ -0,0 +1,211 @@
/***********************************************************************
* Project: CoreCms
* ProjectName: 核心内容管理系统
* Web: https://www.corecms.net
* Author: 大灰灰
* Email: jianweie@163.com
* CreateTime: 2022/12/14 21:20:57
* Description: 暂无
***********************************************************************/
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
using CoreCms.Net.Caching.Manual;
using CoreCms.Net.Configuration;
using CoreCms.Net.Model.Entities;
using CoreCms.Net.Model.ViewModels.Basics;
using CoreCms.Net.IRepository;
using CoreCms.Net.IRepository.UnitOfWork;
using CoreCms.Net.Model.ViewModels.UI;
using SqlSugar;
namespace CoreCms.Net.Repository
{
/// <summary>
/// 微信用户交互授权 接口实现
/// </summary>
public class WeChatUserAccessTokenRepository : BaseRepository<WeChatUserAccessToken>, IWeChatUserAccessTokenRepository
{
private readonly IUnitOfWork _unitOfWork;
public WeChatUserAccessTokenRepository(IUnitOfWork unitOfWork) : base(unitOfWork)
{
_unitOfWork = unitOfWork;
}
#region ==========================================================
/// <summary>
/// 重写异步插入方法
/// </summary>
/// <param name="entity">实体数据</param>
/// <returns></returns>
public async Task<AdminUiCallBack> InsertAsync(WeChatUserAccessToken entity)
{
var jm = new AdminUiCallBack();
var bl = await DbClient.Insertable(entity).ExecuteReturnIdentityAsync() > 0;
jm.code = bl ? 0 : 1;
jm.msg = bl ? GlobalConstVars.CreateSuccess : GlobalConstVars.CreateFailure;
return jm;
}
/// <summary>
/// 重写异步更新方法
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public async Task<AdminUiCallBack> UpdateAsync(WeChatUserAccessToken entity)
{
var jm = new AdminUiCallBack();
var oldModel = await DbClient.Queryable<WeChatUserAccessToken>().In(entity.id).SingleAsync();
if (oldModel == null)
{
jm.msg = "不存在此信息";
return jm;
}
//事物处理过程开始
oldModel.id = entity.id;
oldModel.access_token = entity.access_token;
oldModel.expires_in = entity.expires_in;
oldModel.refresh_token = entity.refresh_token;
oldModel.openid = entity.openid;
oldModel.scope = entity.scope;
oldModel.is_snapshotuser = entity.is_snapshotuser;
oldModel.unionid = entity.unionid;
//事物处理过程结束
var bl = await DbClient.Updateable(oldModel).ExecuteCommandHasChangeAsync();
jm.code = bl ? 0 : 1;
jm.msg = bl ? GlobalConstVars.EditSuccess : GlobalConstVars.EditFailure;
return jm;
}
/// <summary>
/// 重写异步更新方法
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public async Task<AdminUiCallBack> UpdateAsync(List<WeChatUserAccessToken> entity)
{
var jm = new AdminUiCallBack();
var bl = await DbClient.Updateable(entity).ExecuteCommandHasChangeAsync();
jm.code = bl ? 0 : 1;
jm.msg = bl ? GlobalConstVars.EditSuccess : GlobalConstVars.EditFailure;
return jm;
}
/// <summary>
/// 重写删除指定ID的数据
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task<AdminUiCallBack> DeleteByIdAsync(object id)
{
var jm = new AdminUiCallBack();
var bl = await DbClient.Deleteable<WeChatUserAccessToken>(id).ExecuteCommandHasChangeAsync();
jm.code = bl ? 0 : 1;
jm.msg = bl ? GlobalConstVars.DeleteSuccess : GlobalConstVars.DeleteFailure;
return jm;
}
/// <summary>
/// 重写删除指定ID集合的数据(批量删除)
/// </summary>
/// <param name="ids"></param>
/// <returns></returns>
public async Task<AdminUiCallBack> DeleteByIdsAsync(int[] ids)
{
var jm = new AdminUiCallBack();
var bl = await DbClient.Deleteable<WeChatUserAccessToken>().In(ids).ExecuteCommandHasChangeAsync();
jm.code = bl ? 0 : 1;
jm.msg = bl ? GlobalConstVars.DeleteSuccess : GlobalConstVars.DeleteFailure;
return jm;
}
#endregion
#region ==========================================================
/// <summary>
/// 获取缓存的所有数据
/// </summary>
/// <returns></returns>
public async Task<List<WeChatUserAccessToken>> GetCaChe()
{
var list = await DbClient.Queryable<WeChatUserAccessToken>().With(SqlWith.NoLock).WithCache().ToListAsync();
return list;
}
#endregion
#region
/// <summary>
/// 重写根据条件查询分页数据
/// </summary>
/// <param name="predicate">判断集合</param>
/// <param name="orderByType">排序方式</param>
/// <param name="pageIndex">当前页面索引</param>
/// <param name="pageSize">分布大小</param>
/// <param name="orderByExpression"></param>
/// <param name="blUseNoLock">是否使用WITH(NOLOCK)</param>
/// <returns></returns>
public async Task<IPageList<WeChatUserAccessToken>> QueryPageAsync(Expression<Func<WeChatUserAccessToken, bool>> predicate,
Expression<Func<WeChatUserAccessToken, object>> orderByExpression, OrderByType orderByType, int pageIndex = 1,
int pageSize = 20, bool blUseNoLock = false)
{
RefAsync<int> totalCount = 0;
List<WeChatUserAccessToken> page;
if (blUseNoLock)
{
page = await DbClient.Queryable<WeChatUserAccessToken>()
.OrderByIF(orderByExpression != null, orderByExpression, orderByType)
.WhereIF(predicate != null, predicate).Select(p => new WeChatUserAccessToken
{
id = p.id,
access_token = p.access_token,
expires_in = p.expires_in,
refresh_token = p.refresh_token,
openid = p.openid,
scope = p.scope,
is_snapshotuser = p.is_snapshotuser,
unionid = p.unionid,
}).With(SqlWith.NoLock).ToPageListAsync(pageIndex, pageSize, totalCount);
}
else
{
page = await DbClient.Queryable<WeChatUserAccessToken>()
.OrderByIF(orderByExpression != null, orderByExpression, orderByType)
.WhereIF(predicate != null, predicate).Select(p => new WeChatUserAccessToken
{
id = p.id,
access_token = p.access_token,
expires_in = p.expires_in,
refresh_token = p.refresh_token,
openid = p.openid,
scope = p.scope,
is_snapshotuser = p.is_snapshotuser,
unionid = p.unionid,
}).ToPageListAsync(pageIndex, pageSize, totalCount);
}
var list = new PageList<WeChatUserAccessToken>(page, pageIndex, pageSize, totalCount);
return list;
}
#endregion
}
}

View File

@@ -0,0 +1,109 @@
/***********************************************************************
* Project: CoreCms
* ProjectName: 核心内容管理系统
* Web: https://www.corecms.net
* Author: 大灰灰
* Email: jianweie@163.com
* CreateTime: 2022/12/14 0:36:13
* Description: 暂无
***********************************************************************/
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
using CoreCms.Net.Configuration;
using CoreCms.Net.IRepository;
using CoreCms.Net.IRepository.UnitOfWork;
using CoreCms.Net.IServices;
using CoreCms.Net.Model.Entities;
using CoreCms.Net.Model.ViewModels.Basics;
using CoreCms.Net.Model.ViewModels.UI;
using SqlSugar;
namespace CoreCms.Net.Services
{
/// <summary>
/// 微信自动回复消息表 接口实现
/// </summary>
public class WeChatMessageResponseServices : BaseServices<WeChatMessageResponse>, IWeChatMessageResponseServices
{
private readonly IWeChatMessageResponseRepository _dal;
private readonly IUnitOfWork _unitOfWork;
public WeChatMessageResponseServices(IUnitOfWork unitOfWork, IWeChatMessageResponseRepository dal)
{
this._dal = dal;
base.BaseDal = dal;
_unitOfWork = unitOfWork;
}
#region ==========================================================
/// <summary>
/// 重写异步插入方法
/// </summary>
/// <param name="entity">实体数据</param>
/// <returns></returns>
public async Task<AdminUiCallBack> InsertAsync(WeChatMessageResponse entity)
{
return await _dal.InsertAsync(entity);
}
/// <summary>
/// 重写异步更新方法方法
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public async Task<AdminUiCallBack> UpdateAsync(WeChatMessageResponse entity)
{
return await _dal.UpdateAsync(entity);
}
/// <summary>
/// 重写删除指定ID的数据
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task<AdminUiCallBack> DeleteByIdAsync(object id)
{
return await _dal.DeleteByIdAsync(id);
}
#endregion
#region ==========================================================
/// <summary>
/// 获取缓存的所有数据
/// </summary>
/// <returns></returns>
public async Task<List<WeChatMessageResponse>> GetCaChe()
{
return await _dal.GetCaChe();
}
#endregion
#region
/// <summary>
/// 重写根据条件查询分页数据
/// </summary>
/// <param name="predicate">判断集合</param>
/// <param name="orderByType">排序方式</param>
/// <param name="pageIndex">当前页面索引</param>
/// <param name="pageSize">分布大小</param>
/// <param name="orderByExpression"></param>
/// <param name="blUseNoLock">是否使用WITH(NOLOCK)</param>
/// <returns></returns>
public async Task<IPageList<WeChatMessageResponse>> QueryPageAsync(Expression<Func<WeChatMessageResponse, bool>> predicate,
Expression<Func<WeChatMessageResponse, object>> orderByExpression, OrderByType orderByType, int pageIndex = 1,
int pageSize = 20, bool blUseNoLock = false)
{
return await _dal.QueryPageAsync(predicate, orderByExpression, orderByType, pageIndex, pageSize, blUseNoLock);
}
#endregion
}
}

View File

@@ -0,0 +1,129 @@
/***********************************************************************
* Project: CoreCms
* ProjectName: 核心内容管理系统
* Web: https://www.corecms.net
* Author: 大灰灰
* Email: jianweie@163.com
* CreateTime: 2022/12/14 21:20:57
* Description: 暂无
***********************************************************************/
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
using CoreCms.Net.Configuration;
using CoreCms.Net.IRepository;
using CoreCms.Net.IRepository.UnitOfWork;
using CoreCms.Net.IServices;
using CoreCms.Net.Model.Entities;
using CoreCms.Net.Model.ViewModels.Basics;
using CoreCms.Net.Model.ViewModels.UI;
using SqlSugar;
namespace CoreCms.Net.Services
{
/// <summary>
/// 微信用户交互授权 接口实现
/// </summary>
public class WeChatUserAccessTokenServices : BaseServices<WeChatUserAccessToken>, IWeChatUserAccessTokenServices
{
private readonly IWeChatUserAccessTokenRepository _dal;
private readonly IUnitOfWork _unitOfWork;
public WeChatUserAccessTokenServices(IUnitOfWork unitOfWork, IWeChatUserAccessTokenRepository dal)
{
this._dal = dal;
base.BaseDal = dal;
_unitOfWork = unitOfWork;
}
#region ==========================================================
/// <summary>
/// 重写异步插入方法
/// </summary>
/// <param name="entity">实体数据</param>
/// <returns></returns>
public async Task<AdminUiCallBack> InsertAsync(WeChatUserAccessToken entity)
{
return await _dal.InsertAsync(entity);
}
/// <summary>
/// 重写异步更新方法方法
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public async Task<AdminUiCallBack> UpdateAsync(WeChatUserAccessToken entity)
{
return await _dal.UpdateAsync(entity);
}
/// <summary>
/// 重写异步更新方法方法
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public async Task<AdminUiCallBack> UpdateAsync(List<WeChatUserAccessToken> entity)
{
return await _dal.UpdateAsync(entity);
}
/// <summary>
/// 重写删除指定ID的数据
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task<AdminUiCallBack> DeleteByIdAsync(object id)
{
return await _dal.DeleteByIdAsync(id);
}
/// <summary>
/// 重写删除指定ID集合的数据(批量删除)
/// </summary>
/// <param name="ids"></param>
/// <returns></returns>
public async Task<AdminUiCallBack> DeleteByIdsAsync(int[] ids)
{
return await _dal.DeleteByIdsAsync(ids);
}
#endregion
#region ==========================================================
/// <summary>
/// 获取缓存的所有数据
/// </summary>
/// <returns></returns>
public async Task<List<WeChatUserAccessToken>> GetCaChe()
{
return await _dal.GetCaChe();
}
#endregion
#region
/// <summary>
/// 重写根据条件查询分页数据
/// </summary>
/// <param name="predicate">判断集合</param>
/// <param name="orderByType">排序方式</param>
/// <param name="pageIndex">当前页面索引</param>
/// <param name="pageSize">分布大小</param>
/// <param name="orderByExpression"></param>
/// <param name="blUseNoLock">是否使用WITH(NOLOCK)</param>
/// <returns></returns>
public async Task<IPageList<WeChatUserAccessToken>> QueryPageAsync(Expression<Func<WeChatUserAccessToken, bool>> predicate,
Expression<Func<WeChatUserAccessToken, object>> orderByExpression, OrderByType orderByType, int pageIndex = 1,
int pageSize = 20, bool blUseNoLock = false)
{
return await _dal.QueryPageAsync(predicate, orderByExpression, orderByType, pageIndex, pageSize, blUseNoLock);
}
#endregion
}
}

View File

@@ -10,13 +10,12 @@
showLoginTip: false,
},
onLaunch() {
const version = '0.6.6'
//版本设置
const version = '0.6.7'
// 开发环境才提示,生产环境不会提示
if (process.env.NODE_ENV === 'development') {
console.log(`\n %c \u6838\u5fc3\u5546\u57ce\u7cfb\u7edf\u0020\u0043\u006f\u0072\u0065\u0053\u0068\u006f\u0070 V${version} %c \u0068\u0074\u0074\u0070\u0073\u003a\u002f\u002f\u0077\u0077\u0077\u002e\u0063\u006f\u0072\u0065\u0073\u0068\u006f\u0070\u002e\u0063\u006e\u002f \n\n`, 'color: #ffffff; background: #3c9cff; padding:5px 0;', 'color: #3c9cff;background: #f1f1f1; padding:5px 0;');
}
// #ifdef MP-WEIXIN
this.autoUpdate();
// #endif

View File

@@ -0,0 +1,184 @@
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
using CoreCms.Net.Auth.HttpContextUser;
using CoreCms.Net.Configuration;
using CoreCms.Net.Filter;
using CoreCms.Net.IServices;
using CoreCms.Net.Loging;
using CoreCms.Net.Model.FromBody;
using CoreCms.Net.Model.ViewModels.UI;
using Microsoft.AspNetCore.Authorization;
using CoreCms.Net.Caching.AccressToken;
using CoreCms.Net.Model.WeChatEntites;
using SKIT.FlurlHttpClient.Wechat.Api.Models;
using CoreCms.Net.WeChat.Service.HttpClients;
using CoreCms.Net.WeChat.Service.Enums;
using SKIT.FlurlHttpClient.Wechat.Api;
namespace CoreCms.Net.Web.Admin.Controllers.Api.WeChat
{
/// <summary>
/// 微信菜单
///</summary>
[Description("微信菜单")]
[Route("api/[controller]/[action]")]
[RequiredErrorForAdmin]
[Authorize]
public class WeChatMenuController : ControllerBase
{
private readonly IWeChatApiHttpClientFactory _weChatApiHttpClientFactory;
/// <summary>
/// 构造函数
/// </summary>
public WeChatMenuController(IWeChatApiHttpClientFactory weChatApiHttpClientFactory)
{
_weChatApiHttpClientFactory = weChatApiHttpClientFactory;
}
#region ============================================================
// POST: Api/WC_Group/GetIndex
/// <summary>
/// 首页数据
/// </summary>
/// <returns></returns>
[HttpPost]
[Description("首页数据")]
public AdminUiCallBack GetIndex()
{
//返回数据
var jm = new AdminUiCallBack { code = 0 };
return jm;
}
#endregion
/// <summary>
/// 创建菜单
/// </summary>
/// <returns></returns>
[Description("创建菜单")]
[HttpPost]
public async Task<AdminUiCallBack> CreateMenu(MenuFull_ButtonGroupForSkit menu)
{
var jm = new AdminUiCallBack();
try
{
var client = _weChatApiHttpClientFactory.CreateWeXinClient();
var accessToken = WeChatCacheAccessTokenHelper.GetWeChatAccessToken();
var request = new CgibinMenuCreateRequest()
{
AccessToken = accessToken,
ButtonList = menu.button
};
var response = await client.ExecuteCgibinMenuCreateAsync(request, HttpContext.RequestAborted);
if (response.ErrorCode == (int)WeChatReturnCode.ReturnCode.)
{
jm.code = 0;
jm.data = response;
jm.otherData = menu;
jm.msg = "更新成功";
return jm;
}
else
{
jm.msg = response.ErrorMessage;
jm.otherData = menu;
return jm;
}
}
catch (Exception ex)
{
jm.msg = $"更新失败:{ex.Message}";
jm.otherData = menu;
return jm;
}
}
/// <summary>
/// 获取菜单
/// </summary>
[HttpPost]
[Description("获取菜单")]
public async Task<AdminUiCallBack> GetMenu()
{
var jm = new AdminUiCallBack();
try
{
var client = _weChatApiHttpClientFactory.CreateWeXinClient();
var accessToken = WeChatCacheAccessTokenHelper.GetWeChatAccessToken();
var request = new CgibinMenuGetRequest()
{
AccessToken = accessToken
};
var response = await client.ExecuteCgibinMenuGetAsync(request, HttpContext.RequestAborted);
if (response.ErrorCode == (int)WeChatReturnCode.ReturnCode.)
{
jm.code = 0;
jm.data = response;
return jm;
}
else
{
jm.msg = response.ErrorMessage;
return jm;
}
}
catch (Exception ex)
{
jm.msg = "菜单不存在或验证失败!";
jm.otherData = ex.Message;
return jm;
}
}
/// <summary>
/// 删除菜单
/// </summary>
/// <returns></returns>
[Description("删除菜单")]
[HttpPost]
public async Task<AdminUiCallBack> DeleteMenu()
{
var jm = new AdminUiCallBack();
try
{
var client = _weChatApiHttpClientFactory.CreateWeXinClient();
var accessToken = WeChatCacheAccessTokenHelper.GetWeChatAccessToken();
var request = new CgibinMenuDeleteRequest()
{
AccessToken = accessToken
};
var response = await client.ExecuteCgibinMenuDeleteAsync(request, HttpContext.RequestAborted);
if (response.ErrorCode == (int)WeChatReturnCode.ReturnCode.)
{
jm.code = 0;
jm.data = response;
return jm;
}
else
{
jm.msg = response.ErrorMessage;
return jm;
}
}
catch (Exception ex)
{
jm.msg = "菜单不存在或验证失败!";
jm.otherData = ex.Message;
return jm;
}
}
}
}

View File

@@ -0,0 +1,460 @@
/***********************************************************************
* Project: CoreCms
* ProjectName: 核心内容管理系统
* Web: https://www.corecms.net
* Author: 大灰灰
* Email: jianweie@163.com
* CreateTime: 2022/12/14 0:36:13
* Description: 暂无
***********************************************************************/
using System;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using CoreCms.Net.Configuration;
using CoreCms.Net.Model.Entities;
using CoreCms.Net.Model.Entities.Expression;
using CoreCms.Net.Model.FromBody;
using CoreCms.Net.Model.ViewModels.UI;
using CoreCms.Net.Filter;
using CoreCms.Net.Loging;
using CoreCms.Net.IServices;
using CoreCms.Net.Utility.Helper;
using CoreCms.Net.Utility.Extensions;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using NPOI.HSSF.UserModel;
using SqlSugar;
namespace CoreCms.Net.Admin.Admin.Controllers
{
/// <summary>
/// 微信自动回复消息表
///</summary>
[Description("微信自动回复消息表")]
[Route("api/[controller]/[action]")]
[ApiController]
[RequiredErrorForAdmin]
[Authorize]
public class WeChatMessageResponseController : ControllerBase
{
private readonly IWebHostEnvironment _webHostEnvironment;
private readonly IWeChatMessageResponseServices _weChatMessageResponseServices;
/// <summary>
/// 构造函数
///</summary>
public WeChatMessageResponseController(IWebHostEnvironment webHostEnvironment
, IWeChatMessageResponseServices weChatMessageResponseServices
)
{
_webHostEnvironment = webHostEnvironment;
_weChatMessageResponseServices = weChatMessageResponseServices;
}
#region ============================================================
// POST: Api/WeChatMessageResponse/GetPageList
/// <summary>
/// 获取列表
/// </summary>
/// <returns></returns>
[HttpPost]
[Description("获取列表")]
public async Task<AdminUiCallBack> GetPageList()
{
var jm = new AdminUiCallBack();
var pageCurrent = Request.Form["page"].FirstOrDefault().ObjectToInt(1);
var pageSize = Request.Form["limit"].FirstOrDefault().ObjectToInt(30);
var where = PredicateBuilder.True<WeChatMessageResponse>();
//获取排序字段
var orderField = Request.Form["orderField"].FirstOrDefault();
Expression<Func<WeChatMessageResponse, object>> orderEx = orderField switch
{
"id" => p => p.id,
"messageRule" => p => p.messageRule,
"category" => p => p.category,
"matchKey" => p => p.matchKey,
"textContent" => p => p.textContent,
"imgTextContext" => p => p.imgTextContext,
"imgTextUrl" => p => p.imgTextUrl,
"imgTextLink" => p => p.imgTextLink,
"meidaUrl" => p => p.meidaUrl,
"meidaLink" => p => p.meidaLink,
"enable" => p => p.enable,
"isDefault" => p => p.isDefault,
"remark" => p => p.remark,
"sort" => p => p.sort,
"createTime" => p => p.createTime,
_ => p => p.id
};
//设置排序方式
var orderDirection = Request.Form["orderDirection"].FirstOrDefault();
var orderBy = orderDirection switch
{
"asc" => OrderByType.Asc,
"desc" => OrderByType.Desc,
_ => OrderByType.Desc
};
//查询筛选
//序列 int
var id = Request.Form["id"].FirstOrDefault().ObjectToInt(0);
if (id > 0)
{
where = where.And(p => p.id == id);
}
//消息类型 int
var messageRule = Request.Form["messageRule"].FirstOrDefault().ObjectToInt(0);
if (messageRule > 0)
{
where = where.And(p => p.messageRule == messageRule);
}
//分类 int
var category = Request.Form["category"].FirstOrDefault().ObjectToInt(0);
if (category > 0)
{
where = where.And(p => p.category == category);
}
//匹配字符 nvarchar
var matchKey = Request.Form["matchKey"].FirstOrDefault();
if (!string.IsNullOrEmpty(matchKey))
{
where = where.And(p => p.matchKey.Contains(matchKey));
}
//文本回复内容 nvarchar
var textContent = Request.Form["textContent"].FirstOrDefault();
if (!string.IsNullOrEmpty(textContent))
{
where = where.And(p => p.textContent.Contains(textContent));
}
//图片回复内容 nvarchar
var imgTextContext = Request.Form["imgTextContext"].FirstOrDefault();
if (!string.IsNullOrEmpty(imgTextContext))
{
where = where.And(p => p.imgTextContext.Contains(imgTextContext));
}
//图片回复图片地址 nvarchar
var imgTextUrl = Request.Form["imgTextUrl"].FirstOrDefault();
if (!string.IsNullOrEmpty(imgTextUrl))
{
where = where.And(p => p.imgTextUrl.Contains(imgTextUrl));
}
//图片回复超链接 nvarchar
var imgTextLink = Request.Form["imgTextLink"].FirstOrDefault();
if (!string.IsNullOrEmpty(imgTextLink))
{
where = where.And(p => p.imgTextLink.Contains(imgTextLink));
}
//语音回复地址 nvarchar
var meidaUrl = Request.Form["meidaUrl"].FirstOrDefault();
if (!string.IsNullOrEmpty(meidaUrl))
{
where = where.And(p => p.meidaUrl.Contains(meidaUrl));
}
//语音回复超链接 nvarchar
var meidaLink = Request.Form["meidaLink"].FirstOrDefault();
if (!string.IsNullOrEmpty(meidaLink))
{
where = where.And(p => p.meidaLink.Contains(meidaLink));
}
//是否启用 bit
var enable = Request.Form["enable"].FirstOrDefault();
if (!string.IsNullOrEmpty(enable) && enable.ToLowerInvariant() == "true")
{
where = where.And(p => p.enable == true);
}
else if (!string.IsNullOrEmpty(enable) && enable.ToLowerInvariant() == "false")
{
where = where.And(p => p.enable == false);
}
//是否默认 bit
var isDefault = Request.Form["isDefault"].FirstOrDefault();
if (!string.IsNullOrEmpty(isDefault) && isDefault.ToLowerInvariant() == "true")
{
where = where.And(p => p.isDefault == true);
}
else if (!string.IsNullOrEmpty(isDefault) && isDefault.ToLowerInvariant() == "false")
{
where = where.And(p => p.isDefault == false);
}
//备注 nvarchar
var remark = Request.Form["remark"].FirstOrDefault();
if (!string.IsNullOrEmpty(remark))
{
where = where.And(p => p.remark.Contains(remark));
}
//排序 int
var sort = Request.Form["sort"].FirstOrDefault().ObjectToInt(0);
if (sort > 0)
{
where = where.And(p => p.sort == sort);
}
//创建时间 datetime
var createTime = Request.Form["createTime"].FirstOrDefault();
if (!string.IsNullOrEmpty(createTime))
{
if (createTime.Contains("到"))
{
var dts = createTime.Split("到");
var dtStart = dts[0].Trim().ObjectToDate();
where = where.And(p => p.createTime > dtStart);
var dtEnd = dts[1].Trim().ObjectToDate();
where = where.And(p => p.createTime < dtEnd);
}
else
{
var dt = createTime.ObjectToDate();
where = where.And(p => p.createTime > dt);
}
}
//获取数据
var list = await _weChatMessageResponseServices.QueryPageAsync(where, orderEx, orderBy, pageCurrent, pageSize, true);
//返回数据
jm.data = list;
jm.code = 0;
jm.count = list.TotalCount;
jm.msg = "数据调用成功!";
return jm;
}
#endregion
#region ============================================================
// POST: Api/WeChatMessageResponse/GetIndex
/// <summary>
/// 首页数据
/// </summary>
/// <returns></returns>
[HttpPost]
[Description("首页数据")]
public AdminUiCallBack GetIndex()
{
//返回数据
var jm = new AdminUiCallBack { code = 0 };
var weChatRequestRuleEnum = EnumHelper.EnumToList<GlobalEnumVars.WeChatRequestRuleEnum>();
var weChatReplyCategory = EnumHelper.EnumToList<GlobalEnumVars.WeChatReplyCategory>();
jm.data = new
{
weChatRequestRuleEnum,
weChatReplyCategory,
};
return jm;
}
#endregion
#region ============================================================
// POST: Api/WeChatMessageResponse/GetCreate
/// <summary>
/// 创建数据
/// </summary>
/// <returns></returns>
[HttpPost]
[Description("创建数据")]
public AdminUiCallBack GetCreate()
{
//返回数据
var jm = new AdminUiCallBack { code = 0 };
var weChatRequestRuleEnum = EnumHelper.EnumToList<GlobalEnumVars.WeChatRequestRuleEnum>();
var weChatReplyMatchKeyType = EnumHelper.EnumToList<GlobalEnumVars.WeChatReplyMatchKeyType>();
var weChatReplyType = EnumHelper.EnumToList<GlobalEnumVars.WeChatReplyType>();
jm.data = new
{
weChatRequestRuleEnum,
weChatReplyMatchKeyType,
weChatReplyType,
};
return jm;
}
#endregion
#region ============================================================
// POST: Api/WeChatMessageResponse/DoCreate
/// <summary>
/// 创建提交
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
[HttpPost]
[Description("创建提交")]
public async Task<AdminUiCallBack> DoCreate([FromBody] WeChatMessageResponse entity)
{
var jm = await _weChatMessageResponseServices.InsertAsync(entity);
return jm;
}
#endregion
#region ============================================================
// POST: Api/WeChatMessageResponse/GetEdit
/// <summary>
/// 编辑数据
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
[HttpPost]
[Description("编辑数据")]
public async Task<AdminUiCallBack> GetEdit([FromBody] FMIntId entity)
{
var jm = new AdminUiCallBack();
var model = await _weChatMessageResponseServices.QueryByIdAsync(entity.id, false);
if (model == null)
{
jm.msg = "不存在此信息";
return jm;
}
var weChatRequestRuleEnum = EnumHelper.EnumToList<GlobalEnumVars.WeChatRequestRuleEnum>();
var weChatReplyMatchKeyType = EnumHelper.EnumToList<GlobalEnumVars.WeChatReplyMatchKeyType>();
var weChatReplyType = EnumHelper.EnumToList<GlobalEnumVars.WeChatReplyType>();
jm.data = new
{
model,
weChatRequestRuleEnum,
weChatReplyMatchKeyType,
weChatReplyType,
};
jm.code = 0;
return jm;
return jm;
}
#endregion
#region ============================================================
// POST: Api/WeChatMessageResponse/Edit
/// <summary>
/// 编辑提交
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
[HttpPost]
[Description("编辑提交")]
public async Task<AdminUiCallBack> DoEdit([FromBody] WeChatMessageResponse entity)
{
var jm = await _weChatMessageResponseServices.UpdateAsync(entity);
return jm;
}
#endregion
#region ============================================================
// POST: Api/WeChatMessageResponse/DoDelete/10
/// <summary>
/// 单选删除
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
[HttpPost]
[Description("单选删除")]
public async Task<AdminUiCallBack> DoDelete([FromBody] FMIntId entity)
{
var jm = new AdminUiCallBack();
var model = await _weChatMessageResponseServices.ExistsAsync(p => p.id == entity.id, true);
if (!model)
{
jm.msg = GlobalConstVars.DataisNo;
return jm;
}
jm = await _weChatMessageResponseServices.DeleteByIdAsync(entity.id);
return jm;
}
#endregion
#region ============================================================
// POST: Api/WeChatMessageResponse/GetDetails/10
/// <summary>
/// 预览数据
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
[HttpPost]
[Description("预览数据")]
public async Task<AdminUiCallBack> GetDetails([FromBody] FMIntId entity)
{
var jm = new AdminUiCallBack();
var model = await _weChatMessageResponseServices.QueryByIdAsync(entity.id, false);
if (model == null)
{
jm.msg = "不存在此信息";
return jm;
}
jm.code = 0;
jm.data = model;
return jm;
}
#endregion
#region ============================================================
// POST: Api/WeChatMessageResponse/DoSetenable/10
/// <summary>
/// 设置是否启用
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
[HttpPost]
[Description("设置是否启用")]
public async Task<AdminUiCallBack> DoSetenable([FromBody] FMUpdateBoolDataByIntId entity)
{
var jm = new AdminUiCallBack();
var oldModel = await _weChatMessageResponseServices.QueryByIdAsync(entity.id, false);
if (oldModel == null)
{
jm.msg = "不存在此信息";
return jm;
}
oldModel.enable = (bool)entity.data;
var bl = await _weChatMessageResponseServices.UpdateAsync(p => new WeChatMessageResponse() { enable = oldModel.enable }, p => p.id == oldModel.id);
jm.code = bl ? 0 : 1;
jm.msg = bl ? GlobalConstVars.EditSuccess : GlobalConstVars.EditFailure;
return jm;
}
#endregion
#region ============================================================
// POST: Api/WeChatMessageResponse/DoSetisDefault/10
/// <summary>
/// 设置是否默认
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
[HttpPost]
[Description("设置是否默认")]
public async Task<AdminUiCallBack> DoSetisDefault([FromBody] FMUpdateBoolDataByIntId entity)
{
var jm = new AdminUiCallBack();
var oldModel = await _weChatMessageResponseServices.QueryByIdAsync(entity.id, false);
if (oldModel == null)
{
jm.msg = "不存在此信息";
return jm;
}
oldModel.isDefault = (bool)entity.data;
var bl = await _weChatMessageResponseServices.UpdateAsync(p => new WeChatMessageResponse() { isDefault = oldModel.isDefault }, p => p.id == oldModel.id);
jm.code = bl ? 0 : 1;
jm.msg = bl ? GlobalConstVars.EditSuccess : GlobalConstVars.EditFailure;
return jm;
}
#endregion
}
}

View File

@@ -0,0 +1,633 @@
/***********************************************************************
* Project: CoreCms
* ProjectName: 核心内容管理系统
* Web: https://www.corecms.net
* Author: 大灰灰
* Email: jianweie@163.com
* CreateTime: 2022/12/14 21:20:57
* Description: 暂无
***********************************************************************/
using System;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using CoreCms.Net.Configuration;
using CoreCms.Net.Model.Entities;
using CoreCms.Net.Model.Entities.Expression;
using CoreCms.Net.Model.FromBody;
using CoreCms.Net.Model.ViewModels.UI;
using CoreCms.Net.Filter;
using CoreCms.Net.Loging;
using CoreCms.Net.IServices;
using CoreCms.Net.Utility.Helper;
using CoreCms.Net.Utility.Extensions;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using NPOI.HSSF.UserModel;
using SqlSugar;
namespace CoreCms.Net.Admin.Admin.Controllers
{
/// <summary>
/// 微信用户交互授权
///</summary>
[Description("微信用户交互授权")]
[Route("api/[controller]/[action]")]
[ApiController]
[RequiredErrorForAdmin]
[Authorize]
public class WeChatUserAccessTokenController : ControllerBase
{
private readonly IWebHostEnvironment _webHostEnvironment;
private readonly IWeChatUserAccessTokenServices _weChatUserAccessTokenServices;
/// <summary>
/// 构造函数
///</summary>
public WeChatUserAccessTokenController(IWebHostEnvironment webHostEnvironment
,IWeChatUserAccessTokenServices weChatUserAccessTokenServices
)
{
_webHostEnvironment = webHostEnvironment;
_weChatUserAccessTokenServices = weChatUserAccessTokenServices;
}
#region ============================================================
// POST: Api/WeChatUserAccessToken/GetPageList
/// <summary>
/// 获取列表
/// </summary>
/// <returns></returns>
[HttpPost]
[Description("获取列表")]
public async Task<AdminUiCallBack> GetPageList()
{
var jm = new AdminUiCallBack();
var pageCurrent = Request.Form["page"].FirstOrDefault().ObjectToInt(1);
var pageSize = Request.Form["limit"].FirstOrDefault().ObjectToInt(30);
var where = PredicateBuilder.True<WeChatUserAccessToken>();
//获取排序字段
var orderField = Request.Form["orderField"].FirstOrDefault();
Expression<Func<WeChatUserAccessToken, object>> orderEx = orderField switch
{
"id" => p => p.id,"access_token" => p => p.access_token,"expires_in" => p => p.expires_in,"refresh_token" => p => p.refresh_token,"openid" => p => p.openid,"scope" => p => p.scope,"is_snapshotuser" => p => p.is_snapshotuser,"unionid" => p => p.unionid,
_ => p => p.id
};
//设置排序方式
var orderDirection = Request.Form["orderDirection"].FirstOrDefault();
var orderBy = orderDirection switch
{
"asc" => OrderByType.Asc,
"desc" => OrderByType.Desc,
_ => OrderByType.Desc
};
//查询筛选
//序列 int
var id = Request.Form["id"].FirstOrDefault().ObjectToInt(0);
if (id > 0)
{
where = where.And(p => p.id == id);
}
//网页授权接口调用凭证 nvarchar
var access_token = Request.Form["access_token"].FirstOrDefault();
if (!string.IsNullOrEmpty(access_token))
{
where = where.And(p => p.access_token.Contains(access_token));
}
//超时时间秒 int
var expires_in = Request.Form["expires_in"].FirstOrDefault().ObjectToInt(0);
if (expires_in > 0)
{
where = where.And(p => p.expires_in == expires_in);
}
//用户刷新access_token nvarchar
var refresh_token = Request.Form["refresh_token"].FirstOrDefault();
if (!string.IsNullOrEmpty(refresh_token))
{
where = where.And(p => p.refresh_token.Contains(refresh_token));
}
//用户唯一标识 nvarchar
var openid = Request.Form["openid"].FirstOrDefault();
if (!string.IsNullOrEmpty(openid))
{
where = where.And(p => p.openid.Contains(openid));
}
//用户授权的作用域 nvarchar
var scope = Request.Form["scope"].FirstOrDefault();
if (!string.IsNullOrEmpty(scope))
{
where = where.And(p => p.scope.Contains(scope));
}
//是否为快照页模式虚拟账号 int
var is_snapshotuser = Request.Form["is_snapshotuser"].FirstOrDefault().ObjectToInt(0);
if (is_snapshotuser > 0)
{
where = where.And(p => p.is_snapshotuser == is_snapshotuser);
}
//用户统一标识 nvarchar
var unionid = Request.Form["unionid"].FirstOrDefault();
if (!string.IsNullOrEmpty(unionid))
{
where = where.And(p => p.unionid.Contains(unionid));
}
//获取数据
var list = await _weChatUserAccessTokenServices.QueryPageAsync(where, orderEx, orderBy, pageCurrent, pageSize, true);
//返回数据
jm.data = list;
jm.code = 0;
jm.count = list.TotalCount;
jm.msg = "数据调用成功!";
return jm;
}
#endregion
#region ============================================================
// POST: Api/WeChatUserAccessToken/GetIndex
/// <summary>
/// 首页数据
/// </summary>
/// <returns></returns>
[HttpPost]
[Description("首页数据")]
public AdminUiCallBack GetIndex()
{
//返回数据
var jm = new AdminUiCallBack { code = 0 };
return jm;
}
#endregion
#region ============================================================
// POST: Api/WeChatUserAccessToken/GetCreate
/// <summary>
/// 创建数据
/// </summary>
/// <returns></returns>
[HttpPost]
[Description("创建数据")]
public AdminUiCallBack GetCreate()
{
//返回数据
var jm = new AdminUiCallBack { code = 0 };
return jm;
}
#endregion
#region ============================================================
// POST: Api/WeChatUserAccessToken/DoCreate
/// <summary>
/// 创建提交
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
[HttpPost]
[Description("创建提交")]
public async Task<AdminUiCallBack> DoCreate([FromBody]WeChatUserAccessToken entity)
{
var jm = await _weChatUserAccessTokenServices.InsertAsync(entity);
return jm;
}
#endregion
#region ============================================================
// POST: Api/WeChatUserAccessToken/GetEdit
/// <summary>
/// 编辑数据
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
[HttpPost]
[Description("编辑数据")]
public async Task<AdminUiCallBack> GetEdit([FromBody]FMIntId entity)
{
var jm = new AdminUiCallBack();
var model = await _weChatUserAccessTokenServices.QueryByIdAsync(entity.id, false);
if (model == null)
{
jm.msg = "不存在此信息";
return jm;
}
jm.code = 0;
jm.data = model;
return jm;
}
#endregion
#region ============================================================
// POST: Api/WeChatUserAccessToken/Edit
/// <summary>
/// 编辑提交
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
[HttpPost]
[Description("编辑提交")]
public async Task<AdminUiCallBack> DoEdit([FromBody]WeChatUserAccessToken entity)
{
var jm = await _weChatUserAccessTokenServices.UpdateAsync(entity);
return jm;
}
#endregion
#region ============================================================
// POST: Api/WeChatUserAccessToken/DoDelete/10
/// <summary>
/// 单选删除
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
[HttpPost]
[Description("单选删除")]
public async Task<AdminUiCallBack> DoDelete([FromBody]FMIntId entity)
{
var jm = new AdminUiCallBack();
var model = await _weChatUserAccessTokenServices.ExistsAsync(p => p.id == entity.id, true);
if (!model)
{
jm.msg = GlobalConstVars.DataisNo;
return jm;
}
jm = await _weChatUserAccessTokenServices.DeleteByIdAsync(entity.id);
return jm;
}
#endregion
#region ============================================================
// POST: Api/WeChatUserAccessToken/DoBatchDelete/10,11,20
/// <summary>
/// 批量删除
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
[HttpPost]
[Description("批量删除")]
public async Task<AdminUiCallBack> DoBatchDelete([FromBody]FMArrayIntIds entity)
{
var jm = await _weChatUserAccessTokenServices.DeleteByIdsAsync(entity.id);
return jm;
}
#endregion
#region ============================================================
// POST: Api/WeChatUserAccessToken/GetDetails/10
/// <summary>
/// 预览数据
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
[HttpPost]
[Description("预览数据")]
public async Task<AdminUiCallBack> GetDetails([FromBody]FMIntId entity)
{
var jm = new AdminUiCallBack();
var model = await _weChatUserAccessTokenServices.QueryByIdAsync(entity.id, false);
if (model == null)
{
jm.msg = "不存在此信息";
return jm;
}
jm.code = 0;
jm.data = model;
return jm;
}
#endregion
#region ============================================================
// POST: Api/WeChatUserAccessToken/SelectExportExcel/10
/// <summary>
/// 选择导出
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
[HttpPost]
[Description("选择导出")]
public async Task<AdminUiCallBack> SelectExportExcel([FromBody]FMArrayIntIds entity)
{
var jm = new AdminUiCallBack();
//创建Excel文件的对象
var book = new HSSFWorkbook();
//添加一个sheet
var mySheet = book.CreateSheet("Sheet1");
//获取list数据
var listModel = await _weChatUserAccessTokenServices.QueryListByClauseAsync(p => entity.id.Contains(p.id), p => p.id, OrderByType.Asc, true);
//给sheet1添加第一行的头部标题
var headerRow = mySheet.CreateRow(0);
var headerStyle = ExcelHelper.GetHeaderStyle(book);
var cell0 = headerRow.CreateCell(0);
cell0.SetCellValue("序列");
cell0.CellStyle = headerStyle;
mySheet.SetColumnWidth(0, 10 * 256);
var cell1 = headerRow.CreateCell(1);
cell1.SetCellValue("网页授权接口调用凭证");
cell1.CellStyle = headerStyle;
mySheet.SetColumnWidth(1, 10 * 256);
var cell2 = headerRow.CreateCell(2);
cell2.SetCellValue("超时时间秒");
cell2.CellStyle = headerStyle;
mySheet.SetColumnWidth(2, 10 * 256);
var cell3 = headerRow.CreateCell(3);
cell3.SetCellValue("用户刷新access_token");
cell3.CellStyle = headerStyle;
mySheet.SetColumnWidth(3, 10 * 256);
var cell4 = headerRow.CreateCell(4);
cell4.SetCellValue("用户唯一标识");
cell4.CellStyle = headerStyle;
mySheet.SetColumnWidth(4, 10 * 256);
var cell5 = headerRow.CreateCell(5);
cell5.SetCellValue("用户授权的作用域");
cell5.CellStyle = headerStyle;
mySheet.SetColumnWidth(5, 10 * 256);
var cell6 = headerRow.CreateCell(6);
cell6.SetCellValue("是否为快照页模式虚拟账号");
cell6.CellStyle = headerStyle;
mySheet.SetColumnWidth(6, 10 * 256);
var cell7 = headerRow.CreateCell(7);
cell7.SetCellValue("用户统一标识");
cell7.CellStyle = headerStyle;
mySheet.SetColumnWidth(7, 10 * 256);
headerRow.Height = 30 * 20;
var commonCellStyle = ExcelHelper.GetCommonStyle(book);
//将数据逐步写入sheet1各个行
for (var i = 0; i < listModel.Count; i++)
{
var rowTemp = mySheet.CreateRow(i + 1);
var rowTemp0 = rowTemp.CreateCell(0);
rowTemp0.SetCellValue(listModel[i].id.ToString());
rowTemp0.CellStyle = commonCellStyle;
var rowTemp1 = rowTemp.CreateCell(1);
rowTemp1.SetCellValue(listModel[i].access_token.ToString());
rowTemp1.CellStyle = commonCellStyle;
var rowTemp2 = rowTemp.CreateCell(2);
rowTemp2.SetCellValue(listModel[i].expires_in.ToString());
rowTemp2.CellStyle = commonCellStyle;
var rowTemp3 = rowTemp.CreateCell(3);
rowTemp3.SetCellValue(listModel[i].refresh_token.ToString());
rowTemp3.CellStyle = commonCellStyle;
var rowTemp4 = rowTemp.CreateCell(4);
rowTemp4.SetCellValue(listModel[i].openid.ToString());
rowTemp4.CellStyle = commonCellStyle;
var rowTemp5 = rowTemp.CreateCell(5);
rowTemp5.SetCellValue(listModel[i].scope.ToString());
rowTemp5.CellStyle = commonCellStyle;
var rowTemp6 = rowTemp.CreateCell(6);
rowTemp6.SetCellValue(listModel[i].is_snapshotuser.ToString());
rowTemp6.CellStyle = commonCellStyle;
var rowTemp7 = rowTemp.CreateCell(7);
rowTemp7.SetCellValue(listModel[i].unionid.ToString());
rowTemp7.CellStyle = commonCellStyle;
}
// 导出excel
string webRootPath = _webHostEnvironment.WebRootPath;
string tpath = "/files/" + DateTime.Now.ToString("yyyy-MM-dd") + "/";
string fileName = DateTime.Now.ToString("yyyyMMddHHmmssfff") + "-WeChatUserAccessToken导出(选择结果).xls";
string filePath = webRootPath + tpath;
DirectoryInfo di = new DirectoryInfo(filePath);
if (!di.Exists)
{
di.Create();
}
FileStream fileHssf = new FileStream(filePath + fileName, FileMode.Create);
book.Write(fileHssf);
fileHssf.Close();
jm.code = 0;
jm.msg = GlobalConstVars.ExcelExportSuccess;
jm.data = tpath + fileName;
return jm;
}
#endregion
#region ============================================================
// POST: Api/WeChatUserAccessToken/QueryExportExcel/10
/// <summary>
/// 查询导出
/// </summary>
/// <returns></returns>
[HttpPost]
[Description("查询导出")]
public async Task<AdminUiCallBack> QueryExportExcel()
{
var jm = new AdminUiCallBack();
var where = PredicateBuilder.True<WeChatUserAccessToken>();
//查询筛选
//序列 int
var id = Request.Form["id"].FirstOrDefault().ObjectToInt(0);
if (id > 0)
{
where = where.And(p => p.id == id);
}
//网页授权接口调用凭证 nvarchar
var access_token = Request.Form["access_token"].FirstOrDefault();
if (!string.IsNullOrEmpty(access_token))
{
where = where.And(p => p.access_token.Contains(access_token));
}
//超时时间秒 int
var expires_in = Request.Form["expires_in"].FirstOrDefault().ObjectToInt(0);
if (expires_in > 0)
{
where = where.And(p => p.expires_in == expires_in);
}
//用户刷新access_token nvarchar
var refresh_token = Request.Form["refresh_token"].FirstOrDefault();
if (!string.IsNullOrEmpty(refresh_token))
{
where = where.And(p => p.refresh_token.Contains(refresh_token));
}
//用户唯一标识 nvarchar
var openid = Request.Form["openid"].FirstOrDefault();
if (!string.IsNullOrEmpty(openid))
{
where = where.And(p => p.openid.Contains(openid));
}
//用户授权的作用域 nvarchar
var scope = Request.Form["scope"].FirstOrDefault();
if (!string.IsNullOrEmpty(scope))
{
where = where.And(p => p.scope.Contains(scope));
}
//是否为快照页模式虚拟账号 int
var is_snapshotuser = Request.Form["is_snapshotuser"].FirstOrDefault().ObjectToInt(0);
if (is_snapshotuser > 0)
{
where = where.And(p => p.is_snapshotuser == is_snapshotuser);
}
//用户统一标识 nvarchar
var unionid = Request.Form["unionid"].FirstOrDefault();
if (!string.IsNullOrEmpty(unionid))
{
where = where.And(p => p.unionid.Contains(unionid));
}
//获取数据
//创建Excel文件的对象
var book = new HSSFWorkbook();
//添加一个sheet
var mySheet = book.CreateSheet("Sheet1");
//获取list数据
var listModel = await _weChatUserAccessTokenServices.QueryListByClauseAsync(where, p => p.id, OrderByType.Asc, true);
//给sheet1添加第一行的头部标题
var headerRow = mySheet.CreateRow(0);
var headerStyle = ExcelHelper.GetHeaderStyle(book);
var cell0 = headerRow.CreateCell(0);
cell0.SetCellValue("序列");
cell0.CellStyle = headerStyle;
mySheet.SetColumnWidth(0, 10 * 256);
var cell1 = headerRow.CreateCell(1);
cell1.SetCellValue("网页授权接口调用凭证");
cell1.CellStyle = headerStyle;
mySheet.SetColumnWidth(1, 10 * 256);
var cell2 = headerRow.CreateCell(2);
cell2.SetCellValue("超时时间秒");
cell2.CellStyle = headerStyle;
mySheet.SetColumnWidth(2, 10 * 256);
var cell3 = headerRow.CreateCell(3);
cell3.SetCellValue("用户刷新access_token");
cell3.CellStyle = headerStyle;
mySheet.SetColumnWidth(3, 10 * 256);
var cell4 = headerRow.CreateCell(4);
cell4.SetCellValue("用户唯一标识");
cell4.CellStyle = headerStyle;
mySheet.SetColumnWidth(4, 10 * 256);
var cell5 = headerRow.CreateCell(5);
cell5.SetCellValue("用户授权的作用域");
cell5.CellStyle = headerStyle;
mySheet.SetColumnWidth(5, 10 * 256);
var cell6 = headerRow.CreateCell(6);
cell6.SetCellValue("是否为快照页模式虚拟账号");
cell6.CellStyle = headerStyle;
mySheet.SetColumnWidth(6, 10 * 256);
var cell7 = headerRow.CreateCell(7);
cell7.SetCellValue("用户统一标识");
cell7.CellStyle = headerStyle;
mySheet.SetColumnWidth(7, 10 * 256);
headerRow.Height = 30 * 20;
var commonCellStyle = ExcelHelper.GetCommonStyle(book);
//将数据逐步写入sheet1各个行
for (var i = 0; i < listModel.Count; i++)
{
var rowTemp = mySheet.CreateRow(i + 1);
var rowTemp0 = rowTemp.CreateCell(0);
rowTemp0.SetCellValue(listModel[i].id.ToString());
rowTemp0.CellStyle = commonCellStyle;
var rowTemp1 = rowTemp.CreateCell(1);
rowTemp1.SetCellValue(listModel[i].access_token.ToString());
rowTemp1.CellStyle = commonCellStyle;
var rowTemp2 = rowTemp.CreateCell(2);
rowTemp2.SetCellValue(listModel[i].expires_in.ToString());
rowTemp2.CellStyle = commonCellStyle;
var rowTemp3 = rowTemp.CreateCell(3);
rowTemp3.SetCellValue(listModel[i].refresh_token.ToString());
rowTemp3.CellStyle = commonCellStyle;
var rowTemp4 = rowTemp.CreateCell(4);
rowTemp4.SetCellValue(listModel[i].openid.ToString());
rowTemp4.CellStyle = commonCellStyle;
var rowTemp5 = rowTemp.CreateCell(5);
rowTemp5.SetCellValue(listModel[i].scope.ToString());
rowTemp5.CellStyle = commonCellStyle;
var rowTemp6 = rowTemp.CreateCell(6);
rowTemp6.SetCellValue(listModel[i].is_snapshotuser.ToString());
rowTemp6.CellStyle = commonCellStyle;
var rowTemp7 = rowTemp.CreateCell(7);
rowTemp7.SetCellValue(listModel[i].unionid.ToString());
rowTemp7.CellStyle = commonCellStyle;
}
// 写入到excel
string webRootPath = _webHostEnvironment.WebRootPath;
string tpath = "/files/" + DateTime.Now.ToString("yyyy-MM-dd") + "/";
string fileName = DateTime.Now.ToString("yyyyMMddHHmmssfff") + "-WeChatUserAccessToken导出(查询结果).xls";
string filePath = webRootPath + tpath;
DirectoryInfo di = new DirectoryInfo(filePath);
if (!di.Exists)
{
di.Create();
}
FileStream fileHssf = new FileStream(filePath + fileName, FileMode.Create);
book.Write(fileHssf);
fileHssf.Close();
jm.code = 0;
jm.msg = GlobalConstVars.ExcelExportSuccess;
jm.data = tpath + fileName;
return jm;
}
#endregion
}
}

View File

@@ -613,6 +613,7 @@
<None Include="wwwroot\lib\layuiAdmin\style\dtree\font\dtreefont.svg" />
<None Include="wwwroot\lib\layuiAdmin\style\imgs\logo.psd" />
<None Include="wwwroot\lib\layuiAdmin\style\imgs\noImage.psd" />
<None Include="wwwroot\lib\wechatmenu\jquery.form.js" />
<None Include="wwwroot\static\css\documentEditor.less" />
<None Include="wwwroot\static\css\overWrite.less" />
<None Include="wwwroot\static\js\common.js" />
@@ -630,10 +631,6 @@
</None>
</ItemGroup>
<ItemGroup>
<Folder Include="Controllers\" />
</ItemGroup>
<ProjectExtensions><VisualStudio><UserProperties /></VisualStudio></ProjectExtensions>

View File

@@ -5503,6 +5503,39 @@
<param name="entity"></param>
<returns></returns>
</member>
<member name="T:CoreCms.Net.Web.Admin.Controllers.Api.WeChat.WeChatMenuController">
<summary>
微信菜单
</summary>
</member>
<member name="M:CoreCms.Net.Web.Admin.Controllers.Api.WeChat.WeChatMenuController.#ctor(CoreCms.Net.WeChat.Service.HttpClients.IWeChatApiHttpClientFactory)">
<summary>
构造函数
</summary>
</member>
<member name="M:CoreCms.Net.Web.Admin.Controllers.Api.WeChat.WeChatMenuController.GetIndex">
<summary>
首页数据
</summary>
<returns></returns>
</member>
<member name="M:CoreCms.Net.Web.Admin.Controllers.Api.WeChat.WeChatMenuController.CreateMenu(CoreCms.Net.Model.WeChatEntites.MenuFull_ButtonGroupForSkit)">
<summary>
创建菜单
</summary>
<returns></returns>
</member>
<member name="M:CoreCms.Net.Web.Admin.Controllers.Api.WeChat.WeChatMenuController.GetMenu">
<summary>
获取菜单
</summary>
</member>
<member name="M:CoreCms.Net.Web.Admin.Controllers.Api.WeChat.WeChatMenuController.DeleteMenu">
<summary>
删除菜单
</summary>
<returns></returns>
</member>
<member name="T:CoreCms.Net.Web.Admin.Controllers.WeChat.WeChatTransactionComponentAccountController">
<summary>
自定义交易组件上传类目资质
@@ -5868,5 +5901,165 @@
</summary>
<returns></returns>
</member>
<member name="T:CoreCms.Net.Admin.Admin.Controllers.WeChatMessageResponseController">
<summary>
微信自动回复消息表
</summary>
</member>
<member name="M:CoreCms.Net.Admin.Admin.Controllers.WeChatMessageResponseController.#ctor(Microsoft.AspNetCore.Hosting.IWebHostEnvironment,CoreCms.Net.IServices.IWeChatMessageResponseServices)">
<summary>
构造函数
</summary>
</member>
<member name="M:CoreCms.Net.Admin.Admin.Controllers.WeChatMessageResponseController.GetPageList">
<summary>
获取列表
</summary>
<returns></returns>
</member>
<member name="M:CoreCms.Net.Admin.Admin.Controllers.WeChatMessageResponseController.GetIndex">
<summary>
首页数据
</summary>
<returns></returns>
</member>
<member name="M:CoreCms.Net.Admin.Admin.Controllers.WeChatMessageResponseController.GetCreate">
<summary>
创建数据
</summary>
<returns></returns>
</member>
<member name="M:CoreCms.Net.Admin.Admin.Controllers.WeChatMessageResponseController.DoCreate(CoreCms.Net.Model.Entities.WeChatMessageResponse)">
<summary>
创建提交
</summary>
<param name="entity"></param>
<returns></returns>
</member>
<member name="M:CoreCms.Net.Admin.Admin.Controllers.WeChatMessageResponseController.GetEdit(CoreCms.Net.Model.FromBody.FMIntId)">
<summary>
编辑数据
</summary>
<param name="entity"></param>
<returns></returns>
</member>
<member name="M:CoreCms.Net.Admin.Admin.Controllers.WeChatMessageResponseController.DoEdit(CoreCms.Net.Model.Entities.WeChatMessageResponse)">
<summary>
编辑提交
</summary>
<param name="entity"></param>
<returns></returns>
</member>
<member name="M:CoreCms.Net.Admin.Admin.Controllers.WeChatMessageResponseController.DoDelete(CoreCms.Net.Model.FromBody.FMIntId)">
<summary>
单选删除
</summary>
<param name="entity"></param>
<returns></returns>
</member>
<member name="M:CoreCms.Net.Admin.Admin.Controllers.WeChatMessageResponseController.GetDetails(CoreCms.Net.Model.FromBody.FMIntId)">
<summary>
预览数据
</summary>
<param name="entity"></param>
<returns></returns>
</member>
<member name="M:CoreCms.Net.Admin.Admin.Controllers.WeChatMessageResponseController.DoSetenable(CoreCms.Net.Model.FromBody.FMUpdateBoolDataByIntId)">
<summary>
设置是否启用
</summary>
<param name="entity"></param>
<returns></returns>
</member>
<member name="M:CoreCms.Net.Admin.Admin.Controllers.WeChatMessageResponseController.DoSetisDefault(CoreCms.Net.Model.FromBody.FMUpdateBoolDataByIntId)">
<summary>
设置是否默认
</summary>
<param name="entity"></param>
<returns></returns>
</member>
<member name="T:CoreCms.Net.Admin.Admin.Controllers.WeChatUserAccessTokenController">
<summary>
微信用户交互授权
</summary>
</member>
<member name="M:CoreCms.Net.Admin.Admin.Controllers.WeChatUserAccessTokenController.#ctor(Microsoft.AspNetCore.Hosting.IWebHostEnvironment,CoreCms.Net.IServices.IWeChatUserAccessTokenServices)">
<summary>
构造函数
</summary>
</member>
<member name="M:CoreCms.Net.Admin.Admin.Controllers.WeChatUserAccessTokenController.GetPageList">
<summary>
获取列表
</summary>
<returns></returns>
</member>
<member name="M:CoreCms.Net.Admin.Admin.Controllers.WeChatUserAccessTokenController.GetIndex">
<summary>
首页数据
</summary>
<returns></returns>
</member>
<member name="M:CoreCms.Net.Admin.Admin.Controllers.WeChatUserAccessTokenController.GetCreate">
<summary>
创建数据
</summary>
<returns></returns>
</member>
<member name="M:CoreCms.Net.Admin.Admin.Controllers.WeChatUserAccessTokenController.DoCreate(CoreCms.Net.Model.Entities.WeChatUserAccessToken)">
<summary>
创建提交
</summary>
<param name="entity"></param>
<returns></returns>
</member>
<member name="M:CoreCms.Net.Admin.Admin.Controllers.WeChatUserAccessTokenController.GetEdit(CoreCms.Net.Model.FromBody.FMIntId)">
<summary>
编辑数据
</summary>
<param name="entity"></param>
<returns></returns>
</member>
<member name="M:CoreCms.Net.Admin.Admin.Controllers.WeChatUserAccessTokenController.DoEdit(CoreCms.Net.Model.Entities.WeChatUserAccessToken)">
<summary>
编辑提交
</summary>
<param name="entity"></param>
<returns></returns>
</member>
<member name="M:CoreCms.Net.Admin.Admin.Controllers.WeChatUserAccessTokenController.DoDelete(CoreCms.Net.Model.FromBody.FMIntId)">
<summary>
单选删除
</summary>
<param name="entity"></param>
<returns></returns>
</member>
<member name="M:CoreCms.Net.Admin.Admin.Controllers.WeChatUserAccessTokenController.DoBatchDelete(CoreCms.Net.Model.FromBody.FMArrayIntIds)">
<summary>
批量删除
</summary>
<param name="entity"></param>
<returns></returns>
</member>
<member name="M:CoreCms.Net.Admin.Admin.Controllers.WeChatUserAccessTokenController.GetDetails(CoreCms.Net.Model.FromBody.FMIntId)">
<summary>
预览数据
</summary>
<param name="entity"></param>
<returns></returns>
</member>
<member name="M:CoreCms.Net.Admin.Admin.Controllers.WeChatUserAccessTokenController.SelectExportExcel(CoreCms.Net.Model.FromBody.FMArrayIntIds)">
<summary>
选择导出
</summary>
<param name="entity"></param>
<returns></returns>
</member>
<member name="M:CoreCms.Net.Admin.Admin.Controllers.WeChatUserAccessTokenController.QueryExportExcel">
<summary>
查询导出
</summary>
<returns></returns>
</member>
</members>
</doc>

View File

@@ -14,7 +14,7 @@
dbProvider="Microsoft.Data.SqlClient.SqlConnection, Microsoft.Data.SqlClient"
connectionString="Server=127.0.0.1;Database=BaseMIS;User ID=sa;Password=123456"
-->
<target name="log_database" xsi:type="Database" dbProvider="Microsoft.Data.SqlClient.SqlConnection, Microsoft.Data.SqlClient" connectionString="Server=127.0.0.1;uid=CoreShopProfessional;pwd=CoreShopProfessional;Database=CoreShopProfessional;MultipleActiveResultSets=true;pooling=true;min pool size=5;max pool size=32767;connect timeout=20;Encrypt=True;TrustServerCertificate=True;">
<target name="log_database" xsi:type="Database" dbProvider="MySql.Data.MySqlClient.MySqlConnection,Mysql.Data" connectionString="Server=rm-wz92918pm46bsbc37mo.mysql.rds.aliyuncs.com;Port=3306;Database=coreshop;Uid=coreshop;Pwd=coreshop;CharSet=utf8;pooling=true;SslMode=None;Allow User Variables=true;Convert Zero Datetime=True;Allow Zero Datetime=True;">
<commandText>
INSERT INTO SysNLogRecords
(LogDate,LogLevel,LogType,LogTitle,Logger,Message,MachineName,MachineIp,NetRequestMethod

View File

@@ -1,11 +1,11 @@
{
"ConnectionStrings": {
"DbType": "SqlServer", //数据库将支持两种模式【SqlServer,MySql】
"SqlConnection": "Server=127.0.0.1;uid=CoreShopProfessional;pwd=CoreShopProfessional;Database=CoreShopProfessional;MultipleActiveResultSets=true;pooling=true;min pool size=5;max pool size=32767;connect timeout=20;Encrypt=True;TrustServerCertificate=True;"
"DbType": "MySql", //数据库将支持两种模式【SqlServer,MySql】
//"SqlConnection": "Server=127.0.0.1;uid=CoreShopProfessional;pwd=CoreShopProfessional;Database=CoreShopProfessional;MultipleActiveResultSets=true;pooling=true;min pool size=5;max pool size=32767;connect timeout=20;Encrypt=True;TrustServerCertificate=True;"
//SqlServer数据库连接字符串需要开启数据库连接复用【MultipleActiveResultSets=true】
// 如果采用容器化部署Service 要写成mysql的服务名否则写地址
//"SqlConnection": "Server=127.0.0.1;Port=3306;Database=CoreShopProfessional;Uid=CoreShopProfessional;Pwd=CoreShopProfessional;CharSet=utf8;pooling=true;SslMode=None;Allow User Variables=true;Convert Zero Datetime=True;Allow Zero Datetime=True;"
"SqlConnection": "Server=rm-wz92918pm46bsbc37mo.mysql.rds.aliyuncs.com;Port=3306;Database=coreshop;Uid=coreshop;Pwd=coreshop;CharSet=utf8;pooling=true;SslMode=None;Allow User Variables=true;Convert Zero Datetime=True;Allow Zero Datetime=True;"
// Mysql数据库链接字符串请保持后面的属性别少。经过测试mysql版本需要5.7或以上
},
//定时任务管理面板的账户密码
@@ -16,7 +16,7 @@
"AppConfig": {
"AppUrl": "https://admin.test.pro.coreshop.cn/", //后端管理地址
"AppInterFaceUrl": "https://api.test.pro.coreshop.cn/", //接口请求地址
"AppVersion": "CoreShopProfessional v0.6.6"
"AppVersion": "CoreShopProfessional v0.6.7"
},
//redis为必须启动项请保持redis为正常可用
"RedisConfig": {

View File

@@ -23,7 +23,7 @@ layui.define(['all'], function (exports) {
pageTabs: false, // 是否开启页面选项卡功能。单页版不推荐开启
name: '核心商城系统',
version: 'CoreShop v1.0',
version: 'CoreShopProfessional v0.6.7',
name: 'layuiAdmin',
tableName: 'CoreShop', // 本地存储表名
MOD_NAME: 'admin', // 模块事件名

File diff suppressed because it is too large Load Diff

View File

@@ -15,8 +15,9 @@
<div class="layui-input-inline">
<div class="layui-upload">
<button type="button" class="layui-btn" id="upBtnlogoImageUrl">上传图片</button>
<button type="button" class="layui-btn" id="upBtnOriginal">原图上传</button>
<div class="layui-upload-list">
<img class="layui-upload-img" id="viewImgBoxlogoImageUrl">
<img class="layui-upload-img" id="viewImgBoxlogoImageUrl" src="{{ layui.setter.noImagePicUrl }}">
<p id="viewTextBoxlogoImageUrl"></p>
</div>
</div>
@@ -80,6 +81,25 @@
});
});
//原图上传
upload.render({
elem: '#upBtnOriginal'
, url: layui.setter.apiUrl + 'Api/Tools/UploadFiles'
, done: function (res) {
if (res.code > 0) { return layer.msg('上传失败'); }
layer.msg('上传成功');
$('#viewImgBoxlogoImageUrl').attr('src', res.data.fileUrl);
$("#logoImageUrl").val(res.data.fileUrl);
}
, error: function () {
var viewTextBox = $('#viewTextBox');
viewTextBox.html('<span style="color: #FF5722;">上传失败</span> <a class="layui-btn layui-btn-xs demo-reload">重试</a>');
viewTextBox.find('.demo-reload').on('click', function () {
uploadInst.upload();
});
}
});
laydate.render({
elem: '#createTime-CoreCmsBrand-createTime',
type: 'datetime'

View File

@@ -16,7 +16,8 @@
</div>
<div class="layui-input-inline">
<div class="layui-upload">
<button type="button" class="layui-btn" id="upBtnlogoImageUrl">上传图片</button>
<button type="button" class="layui-btn" id="upBtnlogoImageUrl">裁剪上传</button>
<button type="button" class="layui-btn" id="upBtnOriginal">原图上传</button>
<div class="layui-upload-list">
<img class="layui-upload-img" id="viewImgBoxlogoImageUrl" src="{{d.params.data.logoImageUrl || layui.setter.noImagePicUrl }}">
<p id="viewTextBoxlogoImageUrl"></p>
@@ -83,6 +84,25 @@
});
});
//原图上传
upload.render({
elem: '#upBtnOriginal'
, url: layui.setter.apiUrl + 'Api/Tools/UploadFiles'
, done: function (res) {
if (res.code > 0) { return layer.msg('上传失败'); }
layer.msg('上传成功');
$('#viewImgBoxlogoImageUrl').attr('src', res.data.fileUrl);
$("#logoImageUrl").val(res.data.fileUrl);
}
, error: function () {
var viewTextBox = $('#viewTextBox');
viewTextBox.html('<span style="color: #FF5722;">上传失败</span> <a class="layui-btn layui-btn-xs demo-reload">重试</a>');
viewTextBox.find('.demo-reload').on('click', function () {
uploadInst.upload();
});
}
});
laydate.render({
elem: '#editTime-CoreCmsBrand-createTime',
type: 'datetime'

View File

@@ -43,7 +43,8 @@
</div>
<div class="layui-input-inline">
<div class="layui-upload">
<button type="button" class="layui-btn" id="upBtnimageUrl">上传图片</button>
<button type="button" class="layui-btn" id="upBtnimageUrl">裁剪上传</button>
<button type="button" class="layui-btn" id="upBtnOriginal">原图上传</button>
<div class="layui-upload-list">
<img class="layui-upload-img" id="viewImgBoximageUrl" src="{{ layui.setter.noImagePicUrl }}">
<p id="viewTextBoximageUrl"></p>
@@ -70,7 +71,7 @@
//开启调试情况下获取接口赋值数据
if (debug) { console.log(d.params.data); }
layui.use(['admin', 'form', 'laydate', 'upload', 'coreHelper', 'xmSelect','cropperImg'],
layui.use(['admin', 'form', 'laydate', 'upload', 'coreHelper', 'xmSelect', 'cropperImg'],
function () {
var $ = layui.$
, form = layui.form
@@ -103,6 +104,26 @@
});
});
//原图上传
upload.render({
elem: '#upBtnOriginal'
, url: layui.setter.apiUrl + 'Api/Tools/UploadFiles'
, done: function (res) {
if (res.code > 0) { return layer.msg('上传失败'); }
layer.msg('上传成功');
$('#viewImgBoximageUrl').attr('src', res.data.fileUrl);
$("#imageUrl").val(res.data.fileUrl);
}
, error: function () {
var viewTextBox = $('#viewTextBox');
viewTextBox.html('<span style="color: #FF5722;">上传失败</span> <a class="layui-btn layui-btn-xs demo-reload">重试</a>');
viewTextBox.find('.demo-reload').on('click', function () {
uploadInst.upload();
});
}
});
form.verify({
verifyname: [/^[\S]{0,20}$/, '分类名称最大只允许输入20位字符且不能出现空格'],

View File

@@ -44,7 +44,8 @@
</div>
<div class="layui-input-inline">
<div class="layui-upload">
<button type="button" class="layui-btn" id="upBtnimageUrl">上传图片</button>
<button type="button" class="layui-btn" id="upBtnimageUrl">裁剪上传</button>
<button type="button" class="layui-btn" id="upBtnOriginal">原图上传</button>
<div class="layui-upload-list">
<img class="layui-upload-img" id="viewImgBoximageUrl" src="{{d.params.data.model.imageUrl || layui.setter.noImagePicUrl }}">
<p id="viewTextBoximageUrl"></p>
@@ -104,6 +105,25 @@
});
});
//原图上传
upload.render({
elem: '#upBtnOriginal'
, url: layui.setter.apiUrl + 'Api/Tools/UploadFiles'
, done: function (res) {
if (res.code > 0) { return layer.msg('上传失败'); }
layer.msg('上传成功');
$('#viewImgBoximageUrl').attr('src', res.data.fileUrl);
$("#imageUrl").val(res.data.fileUrl);
}
, error: function () {
var viewTextBox = $('#viewTextBox');
viewTextBox.html('<span style="color: #FF5722;">上传失败</span> <a class="layui-btn layui-btn-xs demo-reload">重试</a>');
viewTextBox.find('.demo-reload').on('click', function () {
uploadInst.upload();
});
}
});
form.verify({
verifyname: [/^[\S]{0,20}$/, '分类名称最大只允许输入20位字符且不能出现空格'],

View File

@@ -0,0 +1,426 @@
<title>标题</title>
<!--当前位置开始-->
<div class="layui-card layadmin-header">
<div class="layui-breadcrumb" lay-filter="breadcrumb">
<script type="text/html" template lay-done="layui.data.updateMainBreadcrumb();">
</script>
</div>
</div>
<!--当前位置结束-->
<style>
.mydiv { margin-top: 10px; }
.mydiv p { width: 100%; line-height: 30px; margin-bottom: 5px; }
</style>
<script type="text/html" template lay-type="Post" lay-url="Api/WeChatMenu/GetIndex" lay-done="layui.data.done(d);">
<div class="layui-fluid">
<div class="layui-row layui-col-space15">
<div class="layui-col-md12">
<div class="layui-card">
<div class="layui-card-header">使用说明及规则请仔细阅读</div>
<div class="layui-card-body">
<blockquote class="layui-elem-quote">
<p>官方要求1一级菜单按钮个数为2-32如果设置了二级菜单子按钮个数为2-53按钮描述既按钮名字不超过16个字节子菜单不超过40个字节</p>
<p>如果name不填此按钮将被忽略</p>
<p>如果一级菜单为空该列所有设置的二级菜单都会被忽略key仅在SingleButton单击按钮无下级菜单的状态下设置</p>
<p>如果此按钮有下级菜单key将被忽略所有二级菜单都为SingleButton</p>
<p>如果要快速看到微信上的菜单最新状态需要重新关注否则需要静静等待N小时</p>
</blockquote>
</div>
</div>
</div>
<div class="layui-col-md12">
<div id="menuEditor">
<form action="/Api/WeChatMenu/CreateMenu" id="form_Menu" method="post" _lpchecked="1">
<div class="layui-col-md12">
<div class="layui-card">
<div class="layui-card-header" style="padding: 10px 10px">
<div class="layui-form-item">
<div class="layui-input-inline layui-inline-10">
<button id="btnGetMenu" class="layui-btn layui-btn-sm" type="button">获取当前菜单</button>
<button type="button" class="layui-btn layui-btn-sm" id="submitMenu">更新到服务器</button>
<button id="btnDeleteMenu" class="layui-btn layui-btn-danger layui-btn-sm" type="button">删除全部菜单(谨慎操作)</button>
</div>
<div class="layui-input-inline"> <input id="tokenStr" name="token" value="" class="layui-input" style="width: 400px;" type="hidden" readonly="readonly" /> </div>
</div>
</div>
<div class="layui-card-body">
<p class="menu-state layui-elem-quote">
操作状态<strong id="menuState">-</strong>
</p>
</div>
</div>
</div>
<div class="layui-row layui-col-space15">
<div class="layui-col-md7 menu-list">
<div class="layui-card">
<div class="layui-card-body">
<table id="menuTable" class="layui-table">
<thead>
<tr>
<th></th>
<th>第一列</th>
<th>第二列</th>
<th>第三列</th>
</tr>
</thead>
<tbody>
{{# for (var i = 0; i < 6; i++) { }}
<tr id="{{ i == 5? ' subMenuRow_'+i:'rootMenuRow' }}">
<td class="menuRowTip {{ i == 5? ' rootMenu':'' }}">
{{ i == 5? '一级菜单按钮':'二级菜单No.'+(i + 1) }}
</td>
{{# for (var j = 0; j < 3; j++) { }}
<td>
<input type="hidden" class="layui-input" name="{{ i == 5? 'menu.button['+j+']':'menu.button['+j+'].sub_button['+i+']' }}.key" id="{{ i == 5? 'menu_button'+j:'menu_button'+j+'_sub_button'+i }}_key" />
<input type="hidden" class="layui-input" name="{{ i == 5? 'menu.button['+j+']':'menu.button['+j+'].sub_button['+i+']' }}.type" id="{{ i == 5? 'menu_button'+j:'menu_button'+j+'_sub_button'+i }}_type" value="click" />
<input type="hidden" class="layui-input" name="{{ i == 5? 'menu.button['+j+']':'menu.button['+j+'].sub_button['+i+']' }}.url" id="{{ i == 5? 'menu_button'+j:'menu_button'+j+'_sub_button'+i }}_url" />
<input type="hidden" class="layui-input" name="{{ i == 5? 'menu.button['+j+']':'menu.button['+j+'].sub_button['+i+']' }}.appid" id="{{ i == 5? 'menu_button'+j:'menu_button'+j+'_sub_button'+i }}_appid" />
<input type="hidden" class="layui-input" name="{{ i == 5? 'menu.button['+j+']':'menu.button['+j+'].sub_button['+i+']' }}.pagepath" id="{{ i == 5? 'menu_button'+j:'menu_button'+j+'_sub_button'+i }}_pagepath" />
<input type="hidden" class="layui-input" name="{{ i == 5? 'menu.button['+j+']':'menu.button['+j+'].sub_button['+i+']' }}.media_id" id="{{ i == 5? 'menu_button'+j:'menu_button'+j+'_sub_button'+i }}_mediaid" />
<input type="text" class="layui-input txtButton" name="{{ i == 5? 'menu.button['+j+']':'menu.button['+j+'].sub_button['+i+']' }}.name" id="{{ i == 5? 'menu_button'+j:'menu_button'+j+'_sub_button'+i }}_name" data-i="{{ i }}" data-j="{{ j }}" {{ i == 5? 'data-root='+j+'':'' }} />
</td>
{{# } }}
</tr>
{{# } }}
</tbody>
</table>
</div>
</div>
</div>
<div class="layui-col-md5" id="buttonDetails">
<div class="layui-card">
<div class="layui-card-body">
<div class="layui-card-header">按钮其他参数</div>
<div class="mydiv">
<div class="layui-form-item">
<label for="Name" class="layui-form-label layui-form-required">Name</label>
<div class="layui-input-inline">
<input type="text" id="buttonDetails_name" class="layui-input txtButton" disabled="disabled" />
</div>
</div>
<div class="layui-form-item">
<label for="Name" class="layui-form-label layui-form-required">Type</label>
<div class="layui-input-inline">
<select id="buttonDetails_type" class="dllButtonDetails layui-select">
<option value="click" selected="selected">点击事件传回服务器</option>
<option value="view">访问网页直接跳转</option>
<option value="miniprogram">小程序直接跳转</option>
<option value="location_select">弹出地理位置选择器</option>
<option value="pic_photo_or_album">弹出拍照或者相册发图</option>
<option value="pic_sysphoto">弹出系统拍照发图</option>
<option value="pic_weixin">弹出微信相册发图器</option>
<option value="scancode_push">扫码推事件</option>
<option value="scancode_waitmsg">扫码推事件且弹出消息接收中提示框</option>
<option value="media_id">下发消息除文本消息</option>
<option value="view_limited">跳转图文消息URL</option>
</select>
</div>
</div>
<div class="layui-form-item" id="buttonDetails_key_area">
<label for="Name" class="layui-form-label layui-form-required">Key</label>
<div class="layui-input-block">
<input id="buttonDetails_key" class="layui-input txtButtonDetails" type="text" />
</div>
</div>
<div class="layui-form-item" id="buttonDetails_url_area">
<label for="Name" class="layui-form-label layui-form-required">Url</label>
<div class="layui-input-block">
<input id="buttonDetails_url" class="layui-input txtButtonDetails" type="text" />
</div>
</div>
<div class="layui-form-item" id="buttonDetails_miniprogram_appid_area">
<label for="Name" class="layui-form-label layui-form-required">小程序AppId</label>
<div class="layui-input-block">
<input id="buttonDetails_miniprogram_appid" class="layui-input txtButtonDetails" type="text" />
</div>
</div>
<div class="layui-form-item" id="buttonDetails_miniprogram_pagepath_area">
<label for="Name" class="layui-form-label layui-form-required">小程序PagePath</label>
<div class="layui-input-block">
<input id="buttonDetails_miniprogram_pagepath" class="layui-input txtButtonDetails" type="text" />
</div>
</div>
<div class="layui-form-item" id="buttonDetails_mediaId_area">
<label for="Name" class="layui-form-label layui-form-required">MediaId</label>
<div class="layui-input-block">
<input id="buttonDetails_mediaId" class="layui-input txtButtonDetails" type="text" />
</div>
</div>
<div class="layui-form-item" id="rootButtonNotice">
<label for="Name" class="layui-form-label layui-form-required">说明</label>
<div class="layui-form-mid layui-word-aux"> 如果还有下级菜单请忽略上述Type和KeyUrl等参数</div>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</script>
<script src="/lib/jquery/jquery-2.1.4.js"></script>
<script src="/lib/wechatmenu/jquery.form.js"></script>
<script>
var debug = layui.setter.debug;
layui.data.done = function (d) {
//开启调试情况下获取接口赋值数据
if (debug) { console.log(d.data); }
layui.use(['admin', 'form', 'laydate', 'upload', 'coreHelper', 'cropperImg'],
function () {
var $ = layui.$
, form = layui.form
, admin = layui.admin
, laydate = layui.laydate
, upload = layui.upload
, cropperImg = layui.cropperImg
, coreHelper = layui.coreHelper;
var csWeChat = {};
var maxSubMenuCount = 5;
var menuState;
csWeChat.menu = {
token: '',
init: function () {
menuState = $('#menuState');
$('#buttonDetails').hide();
//$('#menuEditor').hide();
$("#buttonDetails_type").change(csWeChat.menu.typeChanged);
$(':input[id^=menu_button]').click(function () {
$('#buttonDetails').show();
var idPrefix = $(this).attr('data-root')
? ('menu_button' + $(this).attr('data-root'))
: ('menu_button' + $(this).attr('data-j') + '_sub_button' + $(this).attr('data-i'));
var keyId = idPrefix + "_key";
console.log(idPrefix);
var nameId = idPrefix + "_name";
var typeId = idPrefix + "_type";
var urlId = idPrefix + "_url";
var mediaIdId = idPrefix + "_mediaid";
var appidId = idPrefix + "_appid";
var pagepathId = idPrefix + "_pagepath";
var txtDetailsKey = $('#buttonDetails_key');
var txtDetailsName = $('#buttonDetails_name');
var ddlDetailsType = $('#buttonDetails_type');
var txtDetailsUrl = $('#buttonDetails_url');
var txtMediaId = $('#buttonDetails_mediaId');
var txtDetailsAppid = $('#buttonDetails_miniprogram_appid');
var txtDetailsPagepath = $('#buttonDetails_miniprogram_pagepath');
var hiddenButtonKey = $('#' + keyId);
var hiddenButtonType = $('#' + typeId);
var hiddenButtonUrl = $('#' + urlId);
var hiddenButtonMediaId = $('#' + mediaIdId);
var hiddenButtonAppid = $('#' + appidId);
var hiddenButtonPagepath = $('#' + pagepathId);
txtDetailsKey.val(hiddenButtonKey.val());
txtDetailsName.val($('#' + nameId).val());
ddlDetailsType.val(hiddenButtonType.val());
txtDetailsUrl.val(hiddenButtonUrl.val());
txtMediaId.val(hiddenButtonMediaId.val());
txtDetailsAppid.val(hiddenButtonAppid.val());
txtDetailsPagepath.val(hiddenButtonPagepath.val());
csWeChat.menu.typeChanged();
txtDetailsKey.unbind('blur').blur(function () {
hiddenButtonKey.val($(this).val());
});
ddlDetailsType.unbind('blur').blur(function () {
hiddenButtonType.val($(this).val());
});
txtDetailsUrl.unbind('blur').blur(function () {
hiddenButtonUrl.val($(this).val());
});
txtMediaId.unbind('blur').blur(function () {
hiddenButtonMediaId.val($(this).val());
});
txtDetailsAppid.unbind('blur').blur(function () {
hiddenButtonAppid.val($(this).val());
});
txtDetailsPagepath.unbind('blur').blur(function () {
hiddenButtonPagepath.val($(this).val());
});
//修改当前行列样式
var row = parseInt($(this).attr('data-i'));
var column = parseInt($(this).attr('data-j'));
$('#menuTable input').removeClass('currentMenuInput');
$('#menuTable thead th').removeClass('currentMenuItem');
$('#menuTable tbody td').removeClass('currentMenuItem');
$(this).addClass('currentMenuInput');
$('#menuTable thead th').eq(column + 1).addClass('currentMenuItem');
$('#menuTable tbody tr').eq(row).find('td').eq(0).addClass('currentMenuItem');
//一级菜单提示
if (row === 5) {
$('#rootButtonNotice').show();
} else {
$('#rootButtonNotice').hide();
}
});
//获取菜单中
$('#btnGetMenu').click(function () {
menuState.html('获取菜单中...');
coreHelper.Post("Api/WeChatMenu/GetMenu", null, function (e) {
console.log(e);
if (e.code === 0 && e.data.errcode == 0) {
$(':input[id^=menu_button]:not([id$=_type])').val('');
$('#buttonDetails:input').val('');
var buttons = e.data.menu.button;
//此处i与j和页面中反转
for (var i = 0; i < buttons.length; i++) {
var button = buttons[i];
$('#menu_button' + i + '_name').val(button.name);
$('#menu_button' + i + '_key').val(button.key);
$('#menu_button' + i + '_type').val(button.type || 'click');
$('#menu_button' + i + '_url').val(button.url);
$('#menu_button' + i + '_appid').val(button.appid);
$('#menu_button' + i + '_pagepath').val(button.pagepath);
$('#menu_button' + i + '_mediaid').val(button.media_id);
if (button.sub_button && button.sub_button.length > 0) {
//二级菜单
for (var j = 0; j < button.sub_button.length; j++) {
var subButton = button.sub_button[j];
var idPrefix = '#menu_button' + i + '_sub_button' + j;
$(idPrefix + "_name").val(subButton.name);
$(idPrefix + "_type").val(subButton.type || 'click');
$(idPrefix + "_key").val(subButton.key);
$(idPrefix + "_url").val(subButton.url);
$(idPrefix + "_appid").val(subButton.appid);
$(idPrefix + "_pagepath").val(subButton.pagepath);
$(idPrefix + "_mediaid").val(subButton.media_id);
}
} else {
//底部菜单
//...
}
}
//显示JSON
//$('#txtReveiceJSON').text(JSON.stringify(json));
menuState.html('菜单获取已完成');
} else {
menuState.html(e.msg || '执行过程有错误,请检查!');
}
});
});
//删除菜单
$('#btnDeleteMenu').click(function () {
if (!confirm('确定要删除菜单吗?此操作无法撤销!')) {
return;
}
menuState.html('删除菜单中...');
coreHelper.Post("Api/WeChatMenu/DeleteMenu", null, function (e) {
console.log(e);
if (e.code === 0) {
menuState.html('删除成功,如果是误删,并且界面上有最新的菜单状态,可以立即点击【更新到服务器】按钮。');
} else {
menuState.html(e.msg + e.otherData);
}
});
});
//更新到服务器
$('#submitMenu').click(function () {
if (!confirm('确定要提交吗?此操作无法撤销的哦!')) {
return;
}
var headers = {};
headers[layui.setter.request.tokenName] = layui.data(layui.setter.tableName)[layui.setter.request.tokenName];
menuState.html('上传中...');
$('#form_Menu').ajaxSubmit({
dataType: 'json',
headers: headers, //添加请求头部
success: function (json) {
if (json.Success) {
menuState.html('上传成功。' + json.msg);
} else {
menuState.html(json.msg);
}
}
});
});
$('#menuTable .control-input').hover(function () {
var row = parseInt($(this).attr('data-i'));
var column = parseInt($(this).attr('data-j'));
$('#menuTable thead th').removeClass('hoverMenuItem');
$('#menuTable tbody td').removeClass('hoverMenuItem');
$('#menuTable thead th').eq(column + 1).addClass('hoverMenuItem');
$('#menuTable tbody tr').eq(row).find('td').eq(0).addClass('hoverMenuItem');
}, function () {
$('#menuTable thead th').removeClass('hoverMenuItem');
$('#menuTable tbody td').removeClass('hoverMenuItem');
});
},
typeChanged: function () {
var val = $('#buttonDetails_type').val().toUpperCase();
switch (val) {
case 'CLICK':
$('#buttonDetails_key_area').slideDown(100);
$('#buttonDetails_url_area').slideUp(100);
$('#buttonDetails_miniprogram_appid_area').slideUp(100);
$('#buttonDetails_miniprogram_pagepath_area').slideUp(100);
$('#buttonDetails_mediaId_area').slideUp(100);
break;
case 'VIEW':
$('#buttonDetails_key_area').slideUp(100);
$('#buttonDetails_url_area').slideDown(100);
$('#buttonDetails_miniprogram_appid_area').slideUp(100);
$('#buttonDetails_miniprogram_pagepath_area').slideUp(100);
$('#buttonDetails_mediaId_area').slideUp(100);
break;
case 'MINIPROGRAM':
$('#buttonDetails_key_area').slideUp(100);
$('#buttonDetails_url_area').slideDown(100);
$('#buttonDetails_miniprogram_appid_area').slideDown(100);
$('#buttonDetails_miniprogram_pagepath_area').slideDown(100);
$('#buttonDetails_mediaId_area').slideUp(100);
break;
case 'MEDIA_ID':
case 'VIEW_LIMITED':
$('#buttonDetails_key_area').slideUp(100);
$('#buttonDetails_url_area').slideUp(100);
$('#buttonDetails_miniprogram_appid_area').slideUp(100);
$('#buttonDetails_miniprogram_pagepath_area').slideUp(100);
$('#buttonDetails_mediaId_area').slideDown(100);
break;
default:
$('#buttonDetails_key_area').slideDown(100);
$('#buttonDetails_url_area').slideUp(100);
$('#buttonDetails_miniprogram_appid_area').slideUp(100);
$('#buttonDetails_miniprogram_pagepath_area').slideUp(100);
$('#buttonDetails_mediaId_area').slideUp(100);
break;
}
},
setToken: function (token) {
csWeChat.menu.token = token;
$('#menuEditor').show();
$('#menuLogin').hide();
}
};
//初始化操作
csWeChat.menu.init();
//重载form
form.render();
})
};
</script>

View File

@@ -0,0 +1,244 @@
<script type="text/html" template lay-done="layui.data.done(d);">
<div class="layui-form coreshop-form layui-form-pane" lay-filter="LAY-app-WeChatMessageResponse-createForm" id="LAY-app-WeChatMessageResponse-createForm">
<div class="layui-form-item">
<label for="messageRule" class="layui-form-label ">消息类型</label>
<div class="layui-input-block">
<select name="messageRule" lay-filter="messageRuleFilter" lay-verType="tips" lay-verify="required|number" lay-reqText="请选择消息类型">
{{# layui.each(d.params.data.weChatRequestRuleEnum, function(index, item){ }}
<option value="{{item.value}}">{{item.description}}</option>
{{# }); }}
</select>
</div>
</div>
<div class="layui-form-item" id="categoryBox">
<label for="category" class="layui-form-label ">类型</label>
<div class="layui-input-block">
<select name="category" id="category" lay-filter="categoryFilter"></select>
</div>
</div>
<div class="layui-form-item" id="matchKeyBox">
<label for="matchKey" class="layui-form-label ">匹配字符</label>
<div class="layui-input-block">
<input name="matchKey" class="layui-input" />
</div>
</div>
<div class="layui-form-item layui-form-text" id="textContentBox">
<label for="textContent" class="layui-form-label ">文本回复内容</label>
<div class="layui-input-block">
<textarea name="textContent" lay-verType="tips" class="layui-textarea" placeholder="请输入文本回复内容" lay-reqText="请输入文本回复内容" />
</div>
</div>
<div id="ImgBox">
<div class="layui-form-item layui-form-text">
<label for="imgTextTitle" class="layui-form-label ">图片回复标题</label>
<div class="layui-input-block">
<input name="imgTextTitle" class="layui-input" placeholder="请输入图片回复标题" lay-reqText="请输入图片回复标题" />
</div>
</div>
<div class="layui-form-item layui-form-text">
<label for="ImgTextContext" class="layui-form-label ">图片回复内容</label>
<div class="layui-input-block">
<textarea name="ImgTextContext" class="layui-textarea" placeholder="请输入图片回复内容" lay-reqText="请输入图片回复内容" />
</div>
</div>
<div class="layui-form-item">
<label for="imgTextUrl" class="layui-form-label ">图片地址</label>
<div class="layui-input-inline layui-inline-5">
<input name="imgTextUrl" id="thumbnailInput" class="layui-input" placeholder="请输入图片回复图片地址" lay-reqText="请输入图片回复图片地址" />
</div>
<div class="layui-input-inline">
<div class="layui-upload">
<button type="button" class="layui-btn" id="upBtnthumbnail" lay-active="doCropperImg">上传图片</button>
<div class="layui-upload-list">
<img class="layui-upload-img" id="viewImgBoxthumbnail" src="{{ layui.setter.noImagePicUrl }}">
<p id="viewTextBoxthumbnail"></p>
</div>
</div>
</div>
</div>
<div class="layui-form-item">
<label for="imgTextLink" class="layui-form-label ">超链接</label>
<div class="layui-input-block">
<input name="imgTextLink" class="layui-input" placeholder="请输入图片回复超链接" lay-reqText="请输入图片回复超链接" />
</div>
</div>
</div>
<div class="layui-form-item">
<label for="enable" class="layui-form-label ">是否启用</label>
<div class="layui-input-inline layui-inline-2">
<input type="checkbox" lay-filter="switch" name="enable" lay-skin="switch" lay-text="开启|关闭" checked="checked">
</div>
<label for="isDefault" class="layui-form-label ">是否默认</label>
<div class="layui-input-inline layui-inline-2">
<input type="checkbox" lay-filter="switch" name="isDefault" lay-skin="switch" lay-text="开启|关闭">
</div>
</div>
<div class="layui-form-item">
<label for="remark" class="layui-form-label ">备注</label>
<div class="layui-input-block">
<input name="remark" lay-verType="tips" class="layui-input" placeholder="请输入备注" lay-reqText="请输入备注" />
</div>
</div>
<div class="layui-form-item">
<label for="sort" class="layui-form-label ">排序</label>
<div class="layui-input-block">
<input type="number" min="0" max="999999" name="sort" lay-verType="tips" lay-verify="required|number" class="layui-input" value="1" placeholder="请输入排序" lay-reqText="请输入排序并为数字" />
</div>
</div>
<div class="layui-form-item text-right core-hidden">
<input type="button" class="layui-btn" lay-submit lay-filter="LAY-app-WeChatMessageResponse-createForm-submit" id="LAY-app-WeChatMessageResponse-createForm-submit" value="确认添加">
</div>
</div>
</script>
<script>
var debug = layui.setter.debug;
layui.data.done = function (d) {
//开启调试情况下获取接口赋值数据
if (debug) { console.log(d.params.data); }
layui.use(['admin', 'form', 'laydate', 'upload', 'coreHelper', 'cropperImg'],
function () {
var $ = layui.$
, form = layui.form
, admin = layui.admin
, laydate = layui.laydate
, upload = layui.upload
, cropperImg = layui.cropperImg
, coreHelper = layui.coreHelper;
$('#categoryBox').show();
categoryContent(false)
$('#matchKeyBox').hide();
$('#textContentBox').show();
$('#ImgBox').hide();
form.on('select(messageRuleFilter)', function (data) {
if (data.value == 0) { //默认
categoryContent(false)
$('#categoryBox').show();
$('#matchKeyBox').hide();
} else if (data.value == 1) { //关注回复
categoryContent(false)
$('#categoryBox').show();
$('#matchKeyBox').hide();
} else if (data.value == 2) { //文本回复
categoryContent(true)
$('#categoryBox').show();
$('#matchKeyBox').show();
$('#textContentBox').show();
$('#ImgBox').hide();
$('#category').val(4);
} else if (data.value == 3) { //图片回复
categoryContent(true)
$('#categoryBox').show();
$('#matchKeyBox').show();
$('#textContentBox').hide();
$('#ImgBox').show();
$('#category').val(4);
}
form.render();
});
form.on('select(categoryFilter)', function (data) {
if (data.value == 1) { //文本
$('#matchKeyBox').hide();
$('#textContentBox').show();
$('#ImgBox').hide();
} else if (data.value == 2) { //图文
$('#matchKeyBox').hide();
$('#textContentBox').hide();
$('#ImgBox').show();
} else if (data.value == 3) { //语音
//不做处理
} else if (data.value == 4) { //相等
$('#matchKeyBox').show();
} else if (data.value == 5) { //包含
$('#matchKeyBox').show();
}
form.render();
});
//是否使用匹配模式
function categoryContent(bl) {
//清空 Select:
$("#category").empty();
if (bl) {
layui.each(d.params.data.weChatReplymatchKeyType, function (index, item) {
$("#category").append("<option value='" + item.value + "'>" + item.description + "</option>");
});
} else {
layui.each(d.params.data.weChatReplyType, function (index, item) {
$("#category").append("<option value='" + item.value + "'>" + item.description + "</option>");
});
}
form.render();
}
//项目缩略图图片上传
$('#upBtnthumbnail').click(function () {
cropperImg.cropImg({
aspectRatio: 1 / 1,
imgSrc: $('#viewImgBoxthumbnail').attr('src'),
onCrop: function (data) {
var loadIndex = layer.load(2);
coreHelper.Post("api/Tools/UploadFilesFByBase64", { base64: data }, function (res) {
if (0 === res.code) {
$('#viewImgBoxthumbnail').attr('src', res.data.fileUrl);
$("#thumbnailInput").val(res.data.fileUrl);
layer.msg(res.msg);
layer.close(loadIndex);
} else {
layer.close(loadIndex);
layer.msg(res.msg, { icon: 2, anim: 6 });
}
});
}
});
});
laydate.render({
elem: '#createTime-WeChatMessageResponse-createTime',
type: 'datetime'
});
laydate.render({
elem: '#createTime-WeChatMessageResponse-modifyTime',
type: 'datetime'
});
form.verify({
verifymatchKey: [/^.{0,100}$/, '匹配字符最大只允许输入100位字符'],
verifyimgTextUrl: [/^.{0,1000}$/, '图片回复图片地址最大只允许输入1000位字符'],
verifyimgTextLink: [/^.{0,1000}$/, '图片回复超链接最大只允许输入1000位字符'],
verifymeidaUrl: [/^.{0,1000}$/, '语音回复地址最大只允许输入1000位字符'],
verifymeidaLink: [/^.{0,1000}$/, '语音回复超链接最大只允许输入1000位字符'],
verifyremark: [/^.{0,1000}$/, '备注最大只允许输入1000位字符'],
verifycreateBy: [/^.{0,100}$/, '创建来源最大只允许输入100位字符'],
verifymodifyBy: [/^.{0,100}$/, '修改来源最大只允许输入100位字符'],
});
//重载form
form.render(null, 'LAY-app-WeChatMessageResponse-createForm');
})
};
</script>

View File

@@ -0,0 +1,189 @@
<script type="text/html" template lay-done="layui.data.done(d);">
<table class="layui-table layui-form" lay-filter="LAY-app-WeChatMessageResponse-detailsForm" id="LAY-app-WeChatMessageResponse-detailsForm">
<colgroup>
<col width="100">
<col>
</colgroup>
<tbody>
<tr>
<td>
<label for="id">序列</label>
</td>
<td>
{{ d.params.data.id || '' }}
</td>
</tr>
<tr>
<td>
<label for="messageRule">消息类型</label>
</td>
<td>
{{ d.params.data.messageRule || '' }}
</td>
</tr>
<tr>
<td>
<label for="category">分类</label>
</td>
<td>
{{ d.params.data.category || '' }}
</td>
</tr>
<tr>
<td>
<label for="matchKey">匹配字符</label>
</td>
<td>
{{ d.params.data.matchKey || '' }}
</td>
</tr>
<tr>
<td>
<label for="textContent">文本回复内容</label>
</td>
<td>
{{ d.params.data.textContent || '' }}
</td>
</tr>
<tr>
<td>
<label for="imgTextContext">图片回复内容</label>
</td>
<td>
{{ d.params.data.imgTextContext || '' }}
</td>
</tr>
<tr>
<td>
<label for="imgTextUrl">图片回复图片地址</label>
</td>
<td>
{{ d.params.data.imgTextUrl || '' }}
</td>
</tr>
<tr>
<td>
<label for="imgTextLink">图片回复超链接</label>
</td>
<td>
{{ d.params.data.imgTextLink || '' }}
</td>
</tr>
<tr>
<td>
<label for="meidaUrl">语音回复地址</label>
</td>
<td>
{{ d.params.data.meidaUrl || '' }}
</td>
</tr>
<tr>
<td>
<label for="meidaLink">语音回复超链接</label>
</td>
<td>
{{ d.params.data.meidaLink || '' }}
</td>
</tr>
<tr>
<td>
<label for="enable">是否启用</label>
</td>
<td>
<input type="checkbox" disabled name="enable" value="{{d.params.data.enable}}" lay-skin="switch" lay-text="开启|关闭" lay-filter="enable" {{ d.params.data.enable ? 'checked' : '' }}>
</td>
</tr>
<tr>
<td>
<label for="isDefault">是否默认</label>
</td>
<td>
<input type="checkbox" disabled name="isDefault" value="{{d.params.data.isDefault}}" lay-skin="switch" lay-text="开启|关闭" lay-filter="isDefault" {{ d.params.data.isDefault ? 'checked' : '' }}>
</td>
</tr>
<tr>
<td>
<label for="remark">备注</label>
</td>
<td>
{{ d.params.data.remark || '' }}
</td>
</tr>
<tr>
<td>
<label for="sort">排序</label>
</td>
<td>
{{ d.params.data.sort || '' }}
</td>
</tr>
<tr>
<td>
<label for="createTime">创建时间</label>
</td>
<td>
{{ d.params.data.createTime || '' }}
</td>
</tr>
<tr>
<td>
<label for="createBy">创建来源</label>
</td>
<td>
{{ d.params.data.createBy || '' }}
</td>
</tr>
<tr>
<td>
<label for="modifyTime">修改时间</label>
</td>
<td>
{{ d.params.data.modifyTime || '' }}
</td>
</tr>
<tr>
<td>
<label for="modifyBy">修改来源</label>
</td>
<td>
{{ d.params.data.modifyBy || '' }}
</td>
</tr>
</tbody>
</table>
</script>
<script>
var debug= layui.setter.debug;
layui.data.done = function (d) {
//开启调试情况下获取接口赋值数据
if (debug) { console.log(d.params.data); }
layui.use(['admin', 'form', 'coreHelper'], function () {
var $ = layui.$
, setter = layui.setter
, admin = layui.admin
, coreHelper = layui.coreHelper
, form = layui.form;
form.render(null, 'LAY-app-WeChatMessageResponse-detailsForm');
});
};
</script>

View File

@@ -0,0 +1,271 @@
<script type="text/html" template lay-done="layui.data.sendParams(d);">
<div class="layui-form coreshop-form layui-form-pane" lay-filter="LAY-app-WeChatMessageResponse-editForm" id="LAY-app-WeChatMessageResponse-editForm">
<input type="hidden" name="id" value="{{d.params.data.model.id || '' }}" />
<div class="layui-form-item">
<label for="messageRule" class="layui-form-label ">消息类型</label>
<div class="layui-input-block">
<select name="messageRule" lay-filter="messageRuleFilter" lay-verType="tips" lay-verify="required|number" lay-reqText="请选择消息类型">
{{# layui.each(d.params.data.weChatRequestRuleEnum, function(index, item){ }}
<option value="{{item.value}}" {{d.params.data.model.messageRule==item.value ? 'selected="selected"':''}}>{{item.description}}</option>
{{# }); }}
</select>
</div>
</div>
<div class="layui-form-item" id="categoryBox">
<label for="category" class="layui-form-label ">类型</label>
<div class="layui-input-block">
<select name="category" id="category" lay-filter="categoryFilter">
</select>
</div>
</div>
<div class="layui-form-item" id="matchKeyBox">
<label for="matchKey" class="layui-form-label">匹配字符</label>
<div class="layui-input-block">
<input name="matchKey" lay-verType="tips" class="layui-input" placeholder="请输入匹配字符" lay-reqText="请输入匹配字符" value="{{d.params.data.model.matchKey || '' }}" />
</div>
</div>
<div class="layui-form-item layui-form-text" id="textContentBox">
<label for="textContent" class="layui-form-label">文本回复内容</label>
<div class="layui-input-block">
<input name="textContent" lay-verType="tips" class="layui-input" placeholder="请输入文本回复内容" lay-reqText="请输入文本回复内容" value="{{d.params.data.model.textContent || '' }}" />
</div>
</div>
<div id="ImgBox">
<div class="layui-form-item layui-form-text">
<label for="imgTextTitle" class="layui-form-label ">图片回复标题</label>
<div class="layui-input-block">
<input name="imgTextTitle" value="{{ d.params.data.model.messageRule == 3 || d.params.data.model.category == 2 ? d.params.data.model.textContent : ''}}" class="layui-input" placeholder="请输入图片回复标题" lay-reqText="请输入图片回复标题" />
</div>
</div>
<div class="layui-form-item layui-form-text">
<label for="imgTextContext" class="layui-form-label">图片回复内容</label>
<div class="layui-input-block">
<input name="imgTextContext" lay-verType="tips" class="layui-input" placeholder="请输入图片回复内容" lay-reqText="请输入图片回复内容" value="{{d.params.data.model.imgTextContext || '' }}" />
</div>
</div>
<div class="layui-form-item">
<label for="imgTextUrl" class="layui-form-label">图片回复图片地址</label>
<div class="layui-input-inline layui-inline-5">
<input name="imgTextUrl" id="thumbnailInput" lay-verType="tips" class="layui-input" placeholder="请输入图片回复图片地址" lay-reqText="请输入图片回复图片地址" value="{{d.params.data.model.imgTextUrl || '' }}" />
</div>
<div class="layui-input-inline">
<div class="layui-upload">
<button type="button" class="layui-btn" id="upBtnthumbnail" lay-active="doCropperImg">上传图片</button>
<div class="layui-upload-list">
<img class="layui-upload-img" id="viewImgBoxthumbnail" src="{{ d.params.data.model.imgTextUrl || layui.setter.noImagePicUrl }}">
<p id="viewTextBoxthumbnail"></p>
</div>
</div>
</div>
</div>
<div class="layui-form-item">
<label for="imgTextLink" class="layui-form-label">图片回复超链接</label>
<div class="layui-input-block">
<input name="imgTextLink" lay-verType="tips" class="layui-input" placeholder="请输入图片回复超链接" lay-reqText="请输入图片回复超链接" value="{{d.params.data.model.imgTextLink || '' }}" />
</div>
</div>
</div>
<div class="layui-form-item">
<label for="enable" class="layui-form-label">是否启用</label>
<div class="layui-input-inline layui-inline-2">
<input type="checkbox" lay-filter="switch" name="enable" {{ d.params.data.model.enable ? 'checked' : '' }} lay-skin="switch" lay-text="开启|关闭">
</div>
<label for="isDefault" class="layui-form-label">是否默认</label>
<div class="layui-input-inline layui-inline-2">
<input type="checkbox" lay-filter="switch" name="isDefault" {{ d.params.data.model.isDefault ? 'checked' : '' }} lay-skin="switch" lay-text="开启|关闭">
</div>
</div>
<div class="layui-form-item">
<label for="remark" class="layui-form-label">备注</label>
<div class="layui-input-block">
<input name="remark" lay-verType="tips" class="layui-input" placeholder="请输入备注" lay-reqText="请输入备注" value="{{d.params.data.model.remark || '' }}" />
</div>
</div>
<div class="layui-form-item">
<label for="Sort" class="layui-form-label">排序</label>
<div class="layui-input-block">
<input type="number" min="0" max="999999" name="sort" lay-verType="tips" lay-verify="required|number" class="layui-input" value="{{d.params.data.model.sort || '' }}" placeholder="请输入排序" lay-reqText="请输入排序并为数字" />
</div>
</div>
<div class="layui-form-item text-right core-hidden">
<input type="button" class="layui-btn" lay-submit lay-filter="LAY-app-WeChatMessageResponse-editForm-submit" id="LAY-app-WeChatMessageResponse-editForm-submit" value="确认编辑">
</div>
</div>
</script>
<script>
var debug = layui.setter.debug;
layui.data.sendParams = function (d) {
//开启调试情况下获取接口赋值数据
if (debug) { console.log(d.params.data); }
layui.use(['admin', 'form', 'laydate', 'upload', 'coreHelper', 'cropperImg'],
function () {
var $ = layui.$
, form = layui.form
, admin = layui.admin
, laydate = layui.laydate
, upload = layui.upload
, cropperImg = layui.cropperImg
, coreHelper = layui.coreHelper;
$('#categoryBox').hide();
$('#matchKeyBox').show();
$('#textContentBox').hide();
$('#ImgBox').hide();
getmessageRuleFilterData(d.params.data.model.messageRule);
form.on('select(messageRuleFilter)', function (data) {
getmessageRuleFilterData(data.value);
});
function getmessageRuleFilterData(value) {
console.log(value);
if (value == 0) { //默认
categoryContent(false)
$('#categoryBox').show();
$('#matchKeyBox').hide();
var categoryId = $('#category').val();
if (categoryId == 1) {
$('#textContentBox').show();
$('#ImgBox').hide();
} else if (categoryId == 2) {
$('#textContentBox').hide();
$('#ImgBox').show();
}
} else if (value == 1) { //关注回复
categoryContent(false)
$('#categoryBox').show();
$('#matchKeyBox').hide();
var categoryId = $('#category').val();
if (categoryId == 1) {
$('#textContentBox').show();
$('#ImgBox').hide();
} else if (categoryId == 2) {
$('#textContentBox').hide();
$('#ImgBox').show();
}
} else if (value == 2) { //文本回复
categoryContent(true)
$('#categoryBox').show();
$('#matchKeyBox').show();
$('#textContentBox').show();
$('#ImgBox').hide();
$('#category').val(4);
} else if (value == 3) { //图片回复
categoryContent(true)
$('#categoryBox').show();
$('#matchKeyBox').show();
$('#textContentBox').hide();
$('#ImgBox').show();
$('#category').val(4);
}
form.render();
}
form.on('select(categoryFilter)', function (data) {
if (data.value == 1) { //文本
$('#matchKeyBox').hide();
$('#textContentBox').show();
$('#ImgBox').hide();
} else if (data.value == 2) { //图文
$('#matchKeyBox').hide();
$('#textContentBox').hide();
$('#ImgBox').show();
} else if (data.value == 3) { //语音
//不做处理
} else if (data.value == 4) { //相等
$('#matchKeyBox').show();
} else if (data.value == 5) { //包含
$('#matchKeyBox').show();
}
form.render();
});
//是否使用匹配模式
function categoryContent(bl) {
//清空 Select:
$("#category").empty();
if (bl) {
layui.each(d.params.data.weChatReplymatchKeyType, function (index, item) {
if (item.Value == d.params.data.model.category) {
$("#category").append("<option value='" + item.value + "' selected='selected'>" + item.Des + "</option>");
} else {
$("#category").append("<option value='" + item.value + "'>" + item.description + "</option>");
}
});
} else {
layui.each(d.params.data.weChatReplyType, function (index, item) {
if (item.Value == d.params.data.model.category) {
$("#category").append("<option value='" + item.value + "' selected='selected'>" + item.Des + "</option>");
} else {
$("#category").append("<option value='" + item.value + "'>" + item.description + "</option>");
}
});
}
form.render();
}
//项目缩略图图片上传
$('#upBtnthumbnail').click(function () {
cropperImg.cropImg({
aspectRatio: 1 / 1,
imgSrc: $('#viewImgBoxthumbnail').attr('src'),
onCrop: function (data) {
var loadIndex = layer.load(2);
coreHelper.Post("api/Tools/UploadFilesFByBase64", { base64: data }, function (res) {
if (0 === res.code) {
$('#viewImgBoxthumbnail').attr('src', res.data.fileUrl);
$("#thumbnailInput").val(res.data.fileUrl);
layer.msg(res.msg);
layer.close(loadIndex);
} else {
layer.close(loadIndex);
layer.msg(res.msg, { icon: 2, anim: 6 });
}
});
}
});
});
form.verify({
verifymatchKey: [/^.{0,100}$/, '匹配字符最大只允许输入100位字符'],
verifyimgTextUrl: [/^.{0,1000}$/, '图片回复图片地址最大只允许输入1000位字符'],
verifyimgTextLink: [/^.{0,1000}$/, '图片回复超链接最大只允许输入1000位字符'],
verifymeidaUrl: [/^.{0,1000}$/, '语音回复地址最大只允许输入1000位字符'],
verifymeidaLink: [/^.{0,1000}$/, '语音回复超链接最大只允许输入1000位字符'],
verifyremark: [/^.{0,1000}$/, '备注最大只允许输入1000位字符'],
verifycreateBy: [/^.{0,100}$/, '创建来源最大只允许输入100位字符'],
verifymodifyBy: [/^.{0,100}$/, '修改来源最大只允许输入100位字符'],
});
//重载form
form.render(null, 'LAY-app-WeChatMessageResponse-editForm');
})
};
</script>

View File

@@ -0,0 +1,468 @@
<title>微信自动回复消息表</title>
<!--当前位置开始-->
<div class="layui-card layadmin-header">
<div class="layui-breadcrumb" lay-filter="breadcrumb">
<script type="text/html" template lay-done="layui.data.updateMainBreadcrumb();">
</script>
</div>
</div>
<!--当前位置结束-->
<style>
/* 重写样式 */
</style>
<script type="text/html" template lay-type="Post" lay-url="Api/WeChatMessageResponse/GetIndex" lay-done="layui.data.done(d);">
</script>
<div class="table-body">
<table id="LAY-app-WeChatMessageResponse-tableBox" lay-filter="LAY-app-WeChatMessageResponse-tableBox"></table>
</div>
<script type="text/html" id="LAY-app-WeChatMessageResponse-toolbar">
<div class="layui-form coreshop-toolbar-search-form">
<div class="layui-form-item">
<div class="layui-inline">
<div class="layui-input-inline">
<select name="messageRule">
<option value="">请选择消息类型</option>
{{# layui.each(indexData.weChatRequestRuleEnum, function(index, item){ }}
<option value="{{item.value}}">{{item.description}}</option>
{{# }); }}
</select>
</div>
</div>
<div class="layui-inline">
<div class="layui-input-inline">
<select name="category">
<option value="">请选择分类</option>
{{# layui.each(indexData.weChatReplyCategory, function(index, item){ }}
<option value="{{item.value}}">{{item.description}}</option>
{{# }); }}
</select>
</div>
</div>
<div class="layui-inline">
<div class="layui-input-inline">
<input type="text" name="matchKey" placeholder="请输入匹配字符" class="layui-input">
</div>
</div>
<div class="layui-inline">
<div class="layui-input-inline">
<select name="enable">
<option value="">请选择是否启用</option>
<option value="True"></option>
<option value="False"></option>
</select>
</div>
</div>
<div class="layui-inline">
<div class="layui-input-inline">
<select name="isDefault">
<option value="">请选择是否默认</option>
<option value="True"></option>
<option value="False"></option>
</select>
</div>
</div>
<div class="layui-inline">
<button class="layui-btn layui-btn-sm" lay-submit lay-filter="LAY-app-WeChatMessageResponse-search"><i class="layui-icon layui-icon-search"></i></button>
</div>
</div>
</div>
</script>
<script type="text/html" id="LAY-app-WeChatMessageResponse-pagebar">
<div class="layui-btn-container">
<button class="layui-btn layui-btn-sm" lay-event="addData"><i class="layui-icon layui-icon-add-1"></i></button>
<button class="layui-btn layui-btn-sm" lay-event="batchDelete"><i class="layui-icon layui-icon-delete"></i></button>
<button class="layui-btn layui-btn-sm" lay-event="selectExportExcel"><i class="layui-icon layui-icon-add-circle"></i></button>
<button class="layui-btn layui-btn-sm" lay-event="queryExportExcel"><i class="layui-icon layui-icon-download-circle"></i></button>
</div>
</script>
<script type="text/html" id="LAY-app-WeChatMessageResponse-tableBox-bar">
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="detail">查看</a>
<a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>
<a class="layui-btn layui-btn-danger layui-btn-xs" data-dropdown="#WeChatMessageResponseTbDelDrop{{d.LAY_INDEX}}" no-shade="true">删除</a>
<div class="dropdown-menu-nav dropdown-popconfirm dropdown-top-right layui-hide" id="WeChatMessageResponseTbDelDrop{{d.LAY_INDEX}}"
style="max-width: 200px;white-space: normal;min-width: auto;margin-left: 10px;">
<div class="dropdown-anchor"></div>
<div class="dropdown-popconfirm-title">
<i class="layui-icon layui-icon-help"></i>
确定要删除吗
</div>
<div class="dropdown-popconfirm-btn">
<a class="layui-btn layui-btn-primary cursor" btn-cancel>取消</a>
<a class="layui-btn layui-btn-normal cursor" lay-event="del">确定</a>
</div>
</div>
</script>
<script>
var indexData;
var debug = layui.setter.debug;
layui.data.done = function (d) {
//开启调试情况下获取接口赋值数据
if (debug) { console.log(d); }
indexData = d.data;
layui.use(['index', 'table', 'laydate', 'util', 'coredropdown', 'coreHelper'],
function () {
var $ = layui.$
, admin = layui.admin
, table = layui.table
, form = layui.form
, laydate = layui.laydate
, setter = layui.setter
, coreHelper = layui.coreHelper
, util = layui.util
, view = layui.view;
var searchwhere;
//监听搜索
form.on('submit(LAY-app-WeChatMessageResponse-search)',
function (data) {
var field = data.field;
searchwhere = field;
//执行重载
table.reloadData('LAY-app-WeChatMessageResponse-tableBox', { where: field });
});
//数据绑定
table.render({
elem: '#LAY-app-WeChatMessageResponse-tableBox',
url: layui.setter.apiUrl + 'Api/WeChatMessageResponse/GetPageList',
method: 'POST',
toolbar: '#LAY-app-WeChatMessageResponse-toolbar',
pagebar: '#LAY-app-WeChatMessageResponse-pagebar',
className: 'pagebarbox',
defaultToolbar: ['filter', 'print', 'exports'],
height: 'full-127',//面包屑142px,搜索框4行172,3行137,2行102,1行67
page: true,
limit: 30,
limits: [10, 15, 20, 25, 30, 50, 100, 200],
text: { none: '暂无相关数据' },
cols: [
[
{ type: "checkbox", fixed: "left" },
{ field: 'id', title: '序列', width: 60, sort: false },
//{ field: 'messageRule', title: '消息类型', sort: false, width: 105 },
{
field: 'messageRule', title: '消息类型', sort: false, width: 80, templet: function (data) {
for (var i = 0; i < d.data.weChatRequestRuleEnum.length; i++) {
if (d.data.weChatRequestRuleEnum[i].value == data.messageRule) {
return d.data.weChatRequestRuleEnum[i].description;
}
}
return "";
}
},
//{ field: 'category', title: '分类', sort: false, width: 105 },
{
field: 'category', title: '分类', sort: false, width: 80, templet: function (data) {
for (var i = 0; i < d.data.weChatReplyCategory.length; i++) {
if (d.data.weChatReplyCategory[i].value == data.category) {
return d.data.weChatReplyCategory[i].description;
}
}
return "";
}
},
{ field: 'matchKey', title: '匹配字符', sort: false, width: 105 },
{ field: 'textContent', title: '文本回复内容', sort: false },
{ field: 'imgTextContext', title: '图片回复内容', sort: false, width: 105 },
//{ field: 'imgTextUrl', title: '图片回复图片地址', sort: false, width: 105 },
{
field: 'imgTextUrl', title: '图片回复内容', sort: false,
templet: function (d) {
if (d.imgTextUrl) {
return '<a href="javascript:void(0);" onclick=layui.coreHelper.viewImage("' + d.imgTextUrl + '")><image style="max-width:28px;max-height:28px;" src="' + d.imgTextUrl + '" /></a>';
} else {
return '<a href="javascript:void(0);" onclick=layui.coreHelper.viewImage("' + setter.noImagePicUrl + '")><image style="max-width:30px;max-height:30px;" src="' + setter.noImagePicUrl + '" /></a>';
}
}, width: 105
},
{ field: 'imgTextLink', title: '图片回复超链接', sort: false, width: 105 },
{ field: 'meidaUrl', title: '语音回复地址', sort: false, width: 105 },
{ field: 'meidaLink', title: '语音回复超链接', sort: false, width: 105 },
{ field: 'enable', title: '是否启用', width: 95, templet: '#switch_enable', sort: false, unresize: true },
{ field: 'isDefault', title: '是否默认', width: 95, templet: '#switch_isDefault', sort: false, unresize: true },
{ field: 'remark', title: '备注', sort: false, width: 105 },
{ field: 'sort', title: '排序', sort: false, width: 105 },
{ field: 'createTime', title: '创建时间', width: 130, sort: false },
{ width: 162, align: 'center', title: '操作', fixed: 'right', toolbar: '#LAY-app-WeChatMessageResponse-tableBox-bar' }
]
]
});
//监听排序事件
table.on('sort(LAY-app-WeChatMessageResponse-tableBox)', function (obj) {
table.reloadData('LAY-app-WeChatMessageResponse-tableBox', {
initSort: obj, //记录初始排序,如果不设的话,将无法标记表头的排序状态。
where: { //请求参数(注意:这里面的参数可任意定义,并非下面固定的格式)
orderField: obj.field, //排序字段
orderDirection: obj.type //排序方式
}
});
});
//监听行双击事件
table.on('rowDouble(LAY-app-WeChatMessageResponse-tableBox)', function (obj) {
//查看详情
doDetails(obj);
});
//头工具栏事件
table.on('pagebar(LAY-app-WeChatMessageResponse-tableBox)', function (obj) {
var checkStatus = table.checkStatus(obj.config.id);
switch (obj.event) {
case 'addData':
doCreate();
break;
case 'batchDelete':
doBatchDelete(checkStatus);
break;
case 'selectExportExcel':
doSelectExportExcel(checkStatus);
break;
case 'queryExportExcel':
doQueryExportexcel();
break;
};
});
//监听工具条
table.on('tool(LAY-app-WeChatMessageResponse-tableBox)',
function (obj) {
if (obj.event === 'detail') {
doDetails(obj);
} else if (obj.event === 'del') {
doDelete(obj);
} else if (obj.event === 'edit') {
doEdit(obj)
}
});
//执行创建操作
function doCreate() {
coreHelper.Post("Api/WeChatMessageResponse/GetCreate", null, function (e) {
if (e.code === 0) {
admin.popup({
shadeClose: false,
title: '创建数据',
area: ['800px', '90%'],
id: 'LAY-popup-WeChatMessageResponse-create',
success: function (layero, index) {
view(this.id).render('wechatoffiaccount/messageresponse/create', { data: e.data }).done(function () {
//监听提交
form.on('submit(LAY-app-WeChatMessageResponse-createForm-submit)',
function (data) {
var field = data.field; //获取提交的字段
field.enable = field.enable == 'on';
field.isDefault = field.isDefault == 'on';
if (debug) { console.log(field); } //开启调试返回数据
//提交 Ajax 成功后,关闭当前弹层并重载表格
coreHelper.Post("Api/WeChatMessageResponse/DoCreate", field, function (e) {
console.log(e)
if (e.code === 0) {
layui.table.reloadData('LAY-app-WeChatMessageResponse-tableBox'); //重载表格
layer.close(index); //再执行关闭
layer.msg(e.msg);
} else {
layer.msg(e.msg);
}
});
});
});
// 禁止弹窗出现滚动条
$(layero).children('.layui-layer-content').css('overflow', 'visible');
}
, btn: ['确定', '取消']
, yes: function (index, layero) {
layero.contents().find("#LAY-app-WeChatMessageResponse-createForm-submit").click();
}
});
} else {
layer.msg(e.msg);
}
});
}
//执行编辑操作
function doEdit(obj) {
coreHelper.Post("Api/WeChatMessageResponse/GetEdit", { id: obj.data.id }, function (e) {
if (e.code === 0) {
admin.popup({
shadeClose: false,
title: '编辑数据',
area: ['800px', '90%'],
id: 'LAY-popup-WeChatMessageResponse-edit',
success: function (layero, index) {
view(this.id).render('wechatoffiaccount/messageresponse/edit', { data: e.data }).done(function () {
//监听提交
form.on('submit(LAY-app-WeChatMessageResponse-editForm-submit)',
function (data) {
var field = data.field; //获取提交的字段
field.enable = field.enable == 'on';
field.isDefault = field.isDefault == 'on';
if (debug) { console.log(field); } //开启调试返回数据
//提交 Ajax 成功后,关闭当前弹层并重载表格
coreHelper.Post("Api/WeChatMessageResponse/DoEdit", field, function (e) {
console.log(e)
if (e.code === 0) {
layui.table.reloadData('LAY-app-WeChatMessageResponse-tableBox'); //重载表格
layer.close(index); //再执行关闭
layer.msg(e.msg);
} else {
layer.msg(e.msg);
}
});
});
})
// 禁止弹窗出现滚动条
$(layero).children('.layui-layer-content').css('overflow', 'visible');
}
, btn: ['确定', '取消']
, yes: function (index, layero) {
layero.contents().find("#LAY-app-WeChatMessageResponse-editForm-submit").click();
}
});
} else {
layer.msg(e.msg);
}
});
}
//执行预览操作
function doDetails(obj) {
coreHelper.Post("Api/WeChatMessageResponse/GetDetails", { id: obj.data.id }, function (e) {
if (e.code === 0) {
admin.popup({
shadeClose: false,
title: '查看详情',
area: ['800px', '90%'],
id: 'LAY-popup-WeChatMessageResponse-details',
success: function (layero, index) {
view(this.id).render('wechatoffiaccount/messageresponse/details', { data: e.data }).done(function () {
form.render();
});
// 禁止弹窗出现滚动条
$(layero).children('.layui-layer-content').css('overflow', 'visible');
}
});
} else {
layer.msg(e.msg);
}
});
}
//执行单个删除
function doDelete(obj) {
coreHelper.Post("Api/WeChatMessageResponse/DoDelete", { id: obj.data.id }, function (e) {
if (debug) { console.log(e); } //开启调试返回数据
table.reloadData('LAY-app-WeChatMessageResponse-tableBox');
layer.msg(e.msg);
});
}
//执行批量删除
function doBatchDelete(checkStatus) {
var checkData = checkStatus.data;
if (checkData.length === 0) {
return layer.msg('请选择要删除的数据');
}
layer.confirm('确定删除吗?删除后将无法恢复。',
function (index) {
var delidsStr = [];
layui.each(checkData,
function (index, item) {
delidsStr.push(item.id);
});
coreHelper.Post("Api/WeChatMessageResponse/DoBatchDelete", { id: delidsStr }, function (e) {
if (debug) { console.log(e); } //开启调试返回数据
table.reloadData('LAY-app-WeChatMessageResponse-tableBox');
layer.msg(e.msg);
});
});
}
//执行查询条件导出excel
function doQueryExportexcel() {
layer.confirm('确定根据当前的查询条件导出数据吗?',
function (index) {
var field = searchwhere;
coreHelper.PostForm("Api/WeChatMessageResponse/QueryExportExcel", field, function (e) {
if (debug) { console.log(e); } //开启调试返回数据
if (e.code === 0) {
window.open(e.data);
} else {
layer.msg(e.msg);
}
});
});
}
//执行选择目录导出数据
function doSelectExportExcel(checkStatus) {
var checkData = checkStatus.data;
if (checkData.length === 0) {
return layer.msg('请选择您要导出的数据');
}
layer.confirm('确定导出选择的内容吗?',
function (index) {
var delidsStr = [];
layui.each(checkData,
function (index, item) {
delidsStr.push(item.id);
});
layer.close(index);
coreHelper.Post("Api/WeChatMessageResponse/SelectExportExcel", { id: delidsStr }, function (e) {
if (debug) { console.log(e); } //开启调试返回数据
if (e.code === 0) {
window.open(e.data);
} else {
layer.msg(e.msg);
}
});
});
}
laydate.render({
elem: '#searchTime-WeChatMessageResponse-createTime',
type: 'datetime',
range: '到',
});
laydate.render({
elem: '#searchTime-WeChatMessageResponse-modifyTime',
type: 'datetime',
range: '到',
});
//监听 表格复选框操作
layui.form.on('switch(switch_enable)', function (obj) {
coreHelper.Post("Api/WeChatMessageResponse/DoSetenable", { id: this.value, data: obj.elem.checked }, function (e) {
if (debug) { console.log(e); } //开启调试返回数据
//table.reloadData('LAY-app-WeChatMessageResponse-tableBox');
layer.msg(e.msg);
});
});
layui.form.on('switch(switch_isDefault)', function (obj) {
coreHelper.Post("Api/WeChatMessageResponse/DoSetisDefault", { id: this.value, data: obj.elem.checked }, function (e) {
if (debug) { console.log(e); } //开启调试返回数据
//table.reloadData('LAY-app-WeChatMessageResponse-tableBox');
layer.msg(e.msg);
});
});
//重载form
form.render();
});
};
</script>
<!--设置是否启用-->
<script type="text/html" id="switch_enable">
<input type="checkbox" name="switch_enable" value="{{d.id}}" lay-skin="switch" lay-text="开启|关闭" disabled="disabled">
</script>
<!--设置是否默认-->
<script type="text/html" id="switch_isDefault">
<input type="checkbox" name="switch_isDefault" value="{{d.id}}" lay-skin="switch" lay-text="开启|关闭" disabled="disabled">
</script>

View File

@@ -0,0 +1,92 @@
<script type="text/html" template lay-done="layui.data.done(d);">
<div class="layui-form coreshop-form layui-form-pane" lay-filter="LAY-app-WeChatUserAccessToken-createForm" id="LAY-app-WeChatUserAccessToken-createForm">
<div class="layui-form-item">
<label for="id" class="layui-form-label layui-form-required">序列</label>
<div class="layui-input-block">
<input type="number" min="0" max="999999" name="id" lay-verType="tips" lay-verify="required|number" class="layui-input" value="1" placeholder="请输入序列" lay-reqText="请输入序列并为数字" />
</div>
</div>
<div class="layui-form-item">
<label for="access_token" class="layui-form-label layui-form-required">网页授权接口调用凭证</label>
<div class="layui-input-block">
<input name="access_token" lay-verType="tips" lay-verify="required|verifyaccess_token" class="layui-input" lay-reqText="请输入网页授权接口调用凭证" placeholder="请输入网页授权接口调用凭证"/>
</div>
</div>
<div class="layui-form-item">
<label for="expires_in" class="layui-form-label layui-form-required">超时时间秒</label>
<div class="layui-input-block">
<input type="number" min="0" max="999999" name="expires_in" lay-verType="tips" lay-verify="required|number" class="layui-input" value="1" placeholder="请输入超时时间秒" lay-reqText="请输入超时时间秒并为数字" />
</div>
</div>
<div class="layui-form-item">
<label for="refresh_token" class="layui-form-label layui-form-required">用户刷新access_token</label>
<div class="layui-input-block">
<input name="refresh_token" lay-verType="tips" lay-verify="required|verifyrefresh_token" class="layui-input" lay-reqText="请输入用户刷新access_token" placeholder="请输入用户刷新access_token"/>
</div>
</div>
<div class="layui-form-item">
<label for="openid" class="layui-form-label layui-form-required">用户唯一标识</label>
<div class="layui-input-block">
<input name="openid" lay-verType="tips" lay-verify="required|verifyopenid" class="layui-input" lay-reqText="请输入用户唯一标识" placeholder="请输入用户唯一标识"/>
</div>
</div>
<div class="layui-form-item">
<label for="scope" class="layui-form-label layui-form-required">用户授权的作用域</label>
<div class="layui-input-block">
<input name="scope" lay-verType="tips" lay-verify="required|verifyscope" class="layui-input" lay-reqText="请输入用户授权的作用域" placeholder="请输入用户授权的作用域"/>
</div>
</div>
<div class="layui-form-item">
<label for="is_snapshotuser" class="layui-form-label layui-form-required">是否为快照页模式虚拟账号</label>
<div class="layui-input-block">
<input type="number" min="0" max="999999" name="is_snapshotuser" lay-verType="tips" lay-verify="required|number" class="layui-input" value="1" placeholder="请输入是否为快照页模式虚拟账号" lay-reqText="请输入是否为快照页模式虚拟账号并为数字" />
</div>
</div>
<div class="layui-form-item">
<label for="unionid" class="layui-form-label layui-form-required">用户统一标识</label>
<div class="layui-input-block">
<input name="unionid" lay-verType="tips" lay-verify="required|verifyunionid" class="layui-input" lay-reqText="请输入用户统一标识" placeholder="请输入用户统一标识"/>
</div>
</div>
<div class="layui-form-item text-right core-hidden">
<input type="button" class="layui-btn" lay-submit lay-filter="LAY-app-WeChatUserAccessToken-createForm-submit" id="LAY-app-WeChatUserAccessToken-createForm-submit" value="确认添加">
</div>
</div>
</script>
<script>
var debug= layui.setter.debug;
layui.data.done = function (d) {
//开启调试情况下获取接口赋值数据
if (debug) { console.log(d.params.data); }
layui.use(['admin', 'form', 'laydate', 'upload', 'coreHelper', 'cropperImg'],
function () {
var $ = layui.$
, form = layui.form
, admin = layui.admin
, laydate = layui.laydate
, upload = layui.upload
, cropperImg = layui.cropperImg
, coreHelper = layui.coreHelper;
form.verify({
verifyaccess_token: [/^.{0,50}$/,'网页授权接口调用凭证最大只允许输入50位字符'],
verifyrefresh_token: [/^.{0,100}$/,'用户刷新access_token最大只允许输入100位字符'],
verifyopenid: [/^.{0,50}$/,'用户唯一标识最大只允许输入50位字符'],
verifyscope: [/^.{0,50}$/,'用户授权的作用域最大只允许输入50位字符'],
verifyunionid: [/^.{0,50}$/,'用户统一标识最大只允许输入50位字符'],
});
//重载form
form.render(null, 'LAY-app-WeChatUserAccessToken-createForm');
})
};
</script>

View File

@@ -0,0 +1,99 @@
<script type="text/html" template lay-done="layui.data.done(d);">
<table class="layui-table layui-form" lay-filter="LAY-app-WeChatUserAccessToken-detailsForm" id="LAY-app-WeChatUserAccessToken-detailsForm">
<colgroup>
<col width="100">
<col>
</colgroup>
<tbody>
<tr>
<td>
<label for="id">序列</label>
</td>
<td>
{{ d.params.data.id || '' }}
</td>
</tr>
<tr>
<td>
<label for="access_token">网页授权接口调用凭证</label>
</td>
<td>
{{ d.params.data.access_token || '' }}
</td>
</tr>
<tr>
<td>
<label for="expires_in">超时时间秒</label>
</td>
<td>
{{ d.params.data.expires_in || '' }}
</td>
</tr>
<tr>
<td>
<label for="refresh_token">用户刷新access_token</label>
</td>
<td>
{{ d.params.data.refresh_token || '' }}
</td>
</tr>
<tr>
<td>
<label for="openid">用户唯一标识</label>
</td>
<td>
{{ d.params.data.openid || '' }}
</td>
</tr>
<tr>
<td>
<label for="scope">用户授权的作用域</label>
</td>
<td>
{{ d.params.data.scope || '' }}
</td>
</tr>
<tr>
<td>
<label for="is_snapshotuser">是否为快照页模式虚拟账号</label>
</td>
<td>
{{ d.params.data.is_snapshotuser || '' }}
</td>
</tr>
<tr>
<td>
<label for="unionid">用户统一标识</label>
</td>
<td>
{{ d.params.data.unionid || '' }}
</td>
</tr>
</tbody>
</table>
</script>
<script>
var debug= layui.setter.debug;
layui.data.done = function (d) {
//开启调试情况下获取接口赋值数据
if (debug) { console.log(d.params.data); }
layui.use(['admin', 'form', 'coreHelper'], function () {
var $ = layui.$
, setter = layui.setter
, admin = layui.admin
, coreHelper = layui.coreHelper
, form = layui.form;
form.render(null, 'LAY-app-WeChatUserAccessToken-detailsForm');
});
};
</script>

View File

@@ -0,0 +1,92 @@
<script type="text/html" template lay-done="layui.data.sendParams(d);">
<div class="layui-form coreshop-form layui-form-pane" lay-filter="LAY-app-WeChatUserAccessToken-editForm" id="LAY-app-WeChatUserAccessToken-editForm">
<input type="hidden" name="id" value="{{d.params.data.id || '' }}" />
<div class="layui-form-item">
<label for="id" class="layui-form-label layui-form-required">序列</label>
<div class="layui-input-block">
<input type="number" min="0" max="999999" name="id" lay-verType="tips" lay-verify="required|number" class="layui-input" value="{{d.params.data.id || '' }}" placeholder="请输入序列" lay-reqText="请输入序列并为数字" />
</div>
</div>
<div class="layui-form-item">
<label for="access_token" class="layui-form-label layui-form-required">网页授权接口调用凭证</label>
<div class="layui-input-block">
<input name="access_token" lay-verType="tips" lay-verify="required|verifyaccess_token" class="layui-input" placeholder="请输入网页授权接口调用凭证" lay-reqText="请输入网页授权接口调用凭证" value="{{d.params.data.access_token || '' }}" />
</div>
</div>
<div class="layui-form-item">
<label for="expires_in" class="layui-form-label layui-form-required">超时时间秒</label>
<div class="layui-input-block">
<input type="number" min="0" max="999999" name="expires_in" lay-verType="tips" lay-verify="required|number" class="layui-input" value="{{d.params.data.expires_in || '' }}" placeholder="请输入超时时间秒" lay-reqText="请输入超时时间秒并为数字" />
</div>
</div>
<div class="layui-form-item">
<label for="refresh_token" class="layui-form-label layui-form-required">用户刷新access_token</label>
<div class="layui-input-block">
<input name="refresh_token" lay-verType="tips" lay-verify="required|verifyrefresh_token" class="layui-input" placeholder="请输入用户刷新access_token" lay-reqText="请输入用户刷新access_token" value="{{d.params.data.refresh_token || '' }}" />
</div>
</div>
<div class="layui-form-item">
<label for="openid" class="layui-form-label layui-form-required">用户唯一标识</label>
<div class="layui-input-block">
<input name="openid" lay-verType="tips" lay-verify="required|verifyopenid" class="layui-input" placeholder="请输入用户唯一标识" lay-reqText="请输入用户唯一标识" value="{{d.params.data.openid || '' }}" />
</div>
</div>
<div class="layui-form-item">
<label for="scope" class="layui-form-label layui-form-required">用户授权的作用域</label>
<div class="layui-input-block">
<input name="scope" lay-verType="tips" lay-verify="required|verifyscope" class="layui-input" placeholder="请输入用户授权的作用域" lay-reqText="请输入用户授权的作用域" value="{{d.params.data.scope || '' }}" />
</div>
</div>
<div class="layui-form-item">
<label for="is_snapshotuser" class="layui-form-label layui-form-required">是否为快照页模式虚拟账号</label>
<div class="layui-input-block">
<input type="number" min="0" max="999999" name="is_snapshotuser" lay-verType="tips" lay-verify="required|number" class="layui-input" value="{{d.params.data.is_snapshotuser || '' }}" placeholder="请输入是否为快照页模式虚拟账号" lay-reqText="请输入是否为快照页模式虚拟账号并为数字" />
</div>
</div>
<div class="layui-form-item">
<label for="unionid" class="layui-form-label layui-form-required">用户统一标识</label>
<div class="layui-input-block">
<input name="unionid" lay-verType="tips" lay-verify="required|verifyunionid" class="layui-input" placeholder="请输入用户统一标识" lay-reqText="请输入用户统一标识" value="{{d.params.data.unionid || '' }}" />
</div>
</div>
<div class="layui-form-item text-right core-hidden">
<input type="button" class="layui-btn" lay-submit lay-filter="LAY-app-WeChatUserAccessToken-editForm-submit" id="LAY-app-WeChatUserAccessToken-editForm-submit" value="确认编辑">
</div>
</div>
</script>
<script>
var debug= layui.setter.debug;
layui.data.sendParams = function (d) {
//开启调试情况下获取接口赋值数据
if (debug) { console.log(d.params.data); }
layui.use(['admin', 'form', 'laydate', 'upload', 'coreHelper', 'cropperImg'],
function () {
var $ = layui.$
, form = layui.form
, admin = layui.admin
, laydate = layui.laydate
, upload = layui.upload
, cropperImg = layui.cropperImg
, coreHelper = layui.coreHelper;
form.verify({
verifyaccess_token: [/^.{0,50}$/,'网页授权接口调用凭证最大只允许输入50位字符'],
verifyrefresh_token: [/^.{0,100}$/,'用户刷新access_token最大只允许输入100位字符'],
verifyopenid: [/^.{0,50}$/,'用户唯一标识最大只允许输入50位字符'],
verifyscope: [/^.{0,50}$/,'用户授权的作用域最大只允许输入50位字符'],
verifyunionid: [/^.{0,50}$/,'用户统一标识最大只允许输入50位字符'],
});
//重载form
form.render(null, 'LAY-app-WeChatUserAccessToken-editForm');
})
};
</script>

View File

@@ -0,0 +1,396 @@
<title>微信用户交互授权</title>
<!--当前位置开始-->
<div class="layui-card layadmin-header">
<div class="layui-breadcrumb" lay-filter="breadcrumb">
<script type="text/html" template lay-done="layui.data.updateMainBreadcrumb();">
</script>
</div>
</div>
<!--当前位置结束-->
<style>
/* 重写样式 */
</style>
<script type="text/html" template lay-type="Post" lay-url="Api/WeChatUserAccessToken/GetIndex" lay-done="layui.data.done(d);">
</script>
<div class="table-body">
<table id="LAY-app-WeChatUserAccessToken-tableBox" lay-filter="LAY-app-WeChatUserAccessToken-tableBox"></table>
</div>
<script type="text/html" id="LAY-app-WeChatUserAccessToken-toolbar">
<div class="layui-form coreshop-toolbar-search-form">
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label" for="id">序列</label>
<div class="layui-input-inline">
<input type="text" name="id" placeholder="请输入序列" class="layui-input">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label" for="access_token">网页授权接口调用凭证</label>
<div class="layui-input-inline">
<input type="text" name="access_token" placeholder="请输入网页授权接口调用凭证" class="layui-input">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label" for="expires_in">超时时间秒</label>
<div class="layui-input-inline">
<input type="text" name="expires_in" placeholder="请输入超时时间秒" class="layui-input">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label" for="refresh_token">用户刷新access_token</label>
<div class="layui-input-inline">
<input type="text" name="refresh_token" placeholder="请输入用户刷新access_token" class="layui-input">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label" for="openid">用户唯一标识</label>
<div class="layui-input-inline">
<input type="text" name="openid" placeholder="请输入用户唯一标识" class="layui-input">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label" for="scope">用户授权的作用域</label>
<div class="layui-input-inline">
<input type="text" name="scope" placeholder="请输入用户授权的作用域" class="layui-input">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label" for="is_snapshotuser">是否为快照页模式虚拟账号</label>
<div class="layui-input-inline">
<input type="text" name="is_snapshotuser" placeholder="请输入是否为快照页模式虚拟账号" class="layui-input">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label" for="unionid">用户统一标识</label>
<div class="layui-input-inline">
<input type="text" name="unionid" placeholder="请输入用户统一标识" class="layui-input">
</div>
</div>
<div class="layui-inline">
<button class="layui-btn layui-btn-sm" lay-submit lay-filter="LAY-app-WeChatUserAccessToken-search"><i class="layui-icon layui-icon-search"></i></button>
</div>
</div>
</div>
</script>
<script type="text/html" id="LAY-app-WeChatUserAccessToken-pagebar">
<div class="layui-btn-container">
<button class="layui-btn layui-btn-sm" lay-event="addData"><i class="layui-icon layui-icon-add-1"></i></button>
<button class="layui-btn layui-btn-sm" lay-event="batchDelete"><i class="layui-icon layui-icon-delete"></i></button>
<button class="layui-btn layui-btn-sm" lay-event="selectExportExcel"><i class="layui-icon layui-icon-add-circle"></i></button>
<button class="layui-btn layui-btn-sm" lay-event="queryExportExcel"><i class="layui-icon layui-icon-download-circle"></i></button>
</div>
</script>
<script type="text/html" id="LAY-app-WeChatUserAccessToken-tableBox-bar">
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="detail">查看</a>
<a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>
<a class="layui-btn layui-btn-danger layui-btn-xs" data-dropdown="#WeChatUserAccessTokenTbDelDrop{{d.LAY_INDEX}}" no-shade="true">删除</a>
<div class="dropdown-menu-nav dropdown-popconfirm dropdown-top-right layui-hide" id="WeChatUserAccessTokenTbDelDrop{{d.LAY_INDEX}}"
style="max-width: 200px;white-space: normal;min-width: auto;margin-left: 10px;">
<div class="dropdown-anchor"></div>
<div class="dropdown-popconfirm-title">
<i class="layui-icon layui-icon-help"></i>
确定要删除吗
</div>
<div class="dropdown-popconfirm-btn">
<a class="layui-btn layui-btn-primary cursor" btn-cancel>取消</a>
<a class="layui-btn layui-btn-normal cursor" lay-event="del">确定</a>
</div>
</div>
</script>
<script>
var indexData;
var debug= layui.setter.debug;
layui.data.done = function (d) {
//开启调试情况下获取接口赋值数据
if (debug) { console.log(d); }
indexData = d.data;
layui.use(['index', 'table', 'laydate', 'util', 'coredropdown', 'coreHelper'],
function () {
var $ = layui.$
, admin = layui.admin
, table = layui.table
, form = layui.form
, laydate = layui.laydate
, setter = layui.setter
, coreHelper = layui.coreHelper
, util = layui.util
, view = layui.view;
var searchwhere;
//监听搜索
form.on('submit(LAY-app-WeChatUserAccessToken-search)',
function(data) {
var field = data.field;
searchwhere = field;
//执行重载
table.reloadData('LAY-app-WeChatUserAccessToken-tableBox',{ where: field });
});
//数据绑定
table.render({
elem: '#LAY-app-WeChatUserAccessToken-tableBox',
url: layui.setter.apiUrl + 'Api/WeChatUserAccessToken/GetPageList',
method: 'POST',
toolbar: '#LAY-app-WeChatUserAccessToken-toolbar',
pagebar: '#LAY-app-WeChatUserAccessToken-pagebar',
className: 'pagebarbox',
defaultToolbar: ['filter', 'print', 'exports'],
height: 'full-127',//面包屑142px,搜索框4行172,3行137,2行102,1行67
page: true,
limit: 30,
limits: [10, 15, 20, 25, 30, 50, 100, 200],
text: {none: '暂无相关数据'},
cols: [
[
{ type: "checkbox", fixed: "left" },
{ field: 'id', title: '序列', width: 60, sort: false},
{ field: 'access_token', title: '网页授权接口调用凭证', sort: false,width: 105 },
{ field: 'expires_in', title: '超时时间秒', sort: false,width: 105 },
{ field: 'refresh_token', title: '用户刷新access_token', sort: false,width: 105 },
{ field: 'openid', title: '用户唯一标识', sort: false,width: 105 },
{ field: 'scope', title: '用户授权的作用域', sort: false,width: 105 },
{ field: 'is_snapshotuser', title: '是否为快照页模式虚拟账号', sort: false,width: 105 },
{ field: 'unionid', title: '用户统一标识', sort: false,width: 105 },
{ width: 162, align: 'center', title:'操作', fixed: 'right', toolbar: '#LAY-app-WeChatUserAccessToken-tableBox-bar' }
]
]
});
//监听排序事件
table.on('sort(LAY-app-WeChatUserAccessToken-tableBox)', function(obj){
table.reloadData('LAY-app-WeChatUserAccessToken-tableBox', {
initSort: obj, //记录初始排序,如果不设的话,将无法标记表头的排序状态。
where: { //请求参数(注意:这里面的参数可任意定义,并非下面固定的格式)
orderField: obj.field, //排序字段
orderDirection: obj.type //排序方式
}
});
});
//监听行双击事件
table.on('rowDouble(LAY-app-WeChatUserAccessToken-tableBox)', function (obj) {
//查看详情
doDetails(obj);
});
//头工具栏事件
table.on('pagebar(LAY-app-WeChatUserAccessToken-tableBox)', function (obj) {
var checkStatus = table.checkStatus(obj.config.id);
switch (obj.event) {
case 'addData':
doCreate();
break;
case 'batchDelete':
doBatchDelete(checkStatus);
break;
case 'selectExportExcel':
doSelectExportExcel(checkStatus);
break;
case 'queryExportExcel':
doQueryExportexcel();
break;
};
});
//监听工具条
table.on('tool(LAY-app-WeChatUserAccessToken-tableBox)',
function(obj) {
if (obj.event === 'detail') {
doDetails(obj);
} else if (obj.event === 'del') {
doDelete(obj);
} else if (obj.event === 'edit') {
doEdit(obj)
}
});
//执行创建操作
function doCreate(){
coreHelper.Post("Api/WeChatUserAccessToken/GetCreate", null, function (e) {
if (e.code === 0) {
admin.popup({
shadeClose: false,
title: '创建数据',
area: ['1200px', '90%'],
id: 'LAY-popup-WeChatUserAccessToken-create',
success: function (layero, index) {
view(this.id).render('base/WeChatUserAccessToken/create', { data: e.data }).done(function () {
//监听提交
form.on('submit(LAY-app-WeChatUserAccessToken-createForm-submit)',
function(data) {
var field = data.field; //获取提交的字段
if (debug) { console.log(field); } //开启调试返回数据
//提交 Ajax 成功后,关闭当前弹层并重载表格
coreHelper.Post("Api/WeChatUserAccessToken/DoCreate", field, function (e) {
console.log(e)
if (e.code === 0) {
layui.table.reloadData('LAY-app-WeChatUserAccessToken-tableBox'); //重载表格
layer.close(index); //再执行关闭
layer.msg(e.msg);
} else {
layer.msg(e.msg);
}
});
});
});
// 禁止弹窗出现滚动条
$(layero).children('.layui-layer-content').css('overflow', 'visible');
}
, btn: ['确定', '取消']
, yes: function (index, layero) {
layero.contents().find("#LAY-app-WeChatUserAccessToken-createForm-submit").click();
}
});
} else {
layer.msg(e.msg);
}
});
}
//执行编辑操作
function doEdit(obj){
coreHelper.Post("Api/WeChatUserAccessToken/GetEdit", {id:obj.data.id}, function (e) {
if (e.code === 0) {
admin.popup({
shadeClose: false,
title: '编辑数据',
area: ['1200px', '90%'],
id: 'LAY-popup-WeChatUserAccessToken-edit',
success: function (layero, index) {
view(this.id).render('base/WeChatUserAccessToken/edit', { data: e.data }).done(function () {
//监听提交
form.on('submit(LAY-app-WeChatUserAccessToken-editForm-submit)',
function(data) {
var field = data.field; //获取提交的字段
if (debug) { console.log(field); } //开启调试返回数据
//提交 Ajax 成功后,关闭当前弹层并重载表格
coreHelper.Post("Api/WeChatUserAccessToken/DoEdit", field, function (e) {
console.log(e)
if (e.code === 0) {
layui.table.reloadData('LAY-app-WeChatUserAccessToken-tableBox'); //重载表格
layer.close(index); //再执行关闭
layer.msg(e.msg);
} else {
layer.msg(e.msg);
}
});
});
})
// 禁止弹窗出现滚动条
$(layero).children('.layui-layer-content').css('overflow', 'visible');
}
, btn: ['确定', '取消']
, yes: function (index, layero) {
layero.contents().find("#LAY-app-WeChatUserAccessToken-editForm-submit").click();
}
});
} else {
layer.msg(e.msg);
}
});
}
//执行预览操作
function doDetails(obj) {
coreHelper.Post("Api/WeChatUserAccessToken/GetDetails", { id: obj.data.id }, function (e) {
if (e.code === 0) {
admin.popup({
shadeClose: false,
title: '查看详情',
area: ['1200px', '90%'],
id: 'LAY-popup-WeChatUserAccessToken-details',
success: function (layero, index) {
view(this.id).render('base/WeChatUserAccessToken/details', { data: e.data }).done(function () {
form.render();
});
// 禁止弹窗出现滚动条
$(layero).children('.layui-layer-content').css('overflow', 'visible');
}
});
} else {
layer.msg(e.msg);
}
});
}
//执行单个删除
function doDelete(obj){
coreHelper.Post("Api/WeChatUserAccessToken/DoDelete", { id: obj.data.id }, function (e) {
if (debug) { console.log(e); } //开启调试返回数据
table.reloadData('LAY-app-WeChatUserAccessToken-tableBox');
layer.msg(e.msg);
});
}
//执行批量删除
function doBatchDelete(checkStatus){
var checkData = checkStatus.data;
if (checkData.length === 0) {
return layer.msg('请选择要删除的数据');
}
layer.confirm('确定删除吗?删除后将无法恢复。',
function(index) {
var delidsStr = [];
layui.each(checkData,
function(index, item) {
delidsStr.push(item.id);
});
coreHelper.Post("Api/WeChatUserAccessToken/DoBatchDelete", { id: delidsStr }, function (e) {
if (debug) { console.log(e); } //开启调试返回数据
table.reloadData('LAY-app-WeChatUserAccessToken-tableBox');
layer.msg(e.msg);
});
});
}
//执行查询条件导出excel
function doQueryExportexcel(){
layer.confirm('确定根据当前的查询条件导出数据吗?',
function(index) {
var field = searchwhere;
coreHelper.PostForm("Api/WeChatUserAccessToken/QueryExportExcel", field, function (e) {
if (debug) { console.log(e); } //开启调试返回数据
if (e.code === 0) {
window.open(e.data);
} else {
layer.msg(e.msg);
}
});
});
}
//执行选择目录导出数据
function doSelectExportExcel(checkStatus){
var checkData = checkStatus.data;
if (checkData.length === 0) {
return layer.msg('请选择您要导出的数据');
}
layer.confirm('确定导出选择的内容吗?',
function(index) {
var delidsStr = [];
layui.each(checkData,
function(index, item) {
delidsStr.push(item.id);
});
layer.close(index);
coreHelper.Post("Api/WeChatUserAccessToken/SelectExportExcel", { id: delidsStr }, function (e) {
if (debug) { console.log(e); } //开启调试返回数据
if (e.code === 0) {
window.open(e.data);
} else {
layer.msg(e.msg);
}
});
});
}
//监听 表格复选框操作
//重载form
form.render();
});
};
</script>

View File

@@ -0,0 +1,407 @@
using System;
using CoreCms.Net.WeChat.Service.HttpClients;
using Microsoft.AspNetCore.Mvc;
using SKIT.FlurlHttpClient.Wechat.Api;
using SKIT.FlurlHttpClient.Wechat.Api.Events;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using CoreCms.Net.Caching.AccressToken;
using CoreCms.Net.Configuration;
using CoreCms.Net.IServices;
using CoreCms.Net.Loging;
using CoreCms.Net.Model.Entities;
using CoreCms.Net.Utility.Helper;
using CoreCms.Net.WeChat.Service.Configuration;
using CoreCms.Net.WeChat.Service.Mediator;
using CoreCms.Net.WeChat.Service.Models;
using CoreCms.Net.WeChat.Service.Options;
using CoreCms.Net.WeChat.Service.Utilities;
using MediatR;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using SKIT.FlurlHttpClient.Wechat.Api.Models;
using LogLevel = NLog.LogLevel;
using CoreCms.Net.Services;
using SqlSugar;
namespace CoreCms.Net.Web.Controllers.WeChat
{
/// <summary>
/// 微信公众号消息推送对接
/// </summary>
public class WeChatOffiaccountNotifyController : Controller
{
private readonly IWeChatApiHttpClientFactory _weChatApiHttpClientFactory;
private readonly WeChatOptions _weChatOptions;
private readonly IMediator _mediator;
private readonly ICoreCmsUserWeChatInfoServices _weChatUserInfoServices;
/// <summary>
/// 原始的加密请求如果不加密则为null
/// </summary>
public XDocument? EcryptRequestDocument { get; set; } = null;
/// <summary>
/// 是否使用加密
/// </summary>
public bool UsingEncryptMessage = false;
/// <summary>
/// 是否取消执行
/// </summary>
public bool CancelExecute = false;
/// <summary>
/// 是否使用兼容模式
/// </summary>
public bool UsingCompatibilityModelEncryptMessage = false;
/// <summary>
/// 构造函数
/// </summary>
public WeChatOffiaccountNotifyController(IWeChatApiHttpClientFactory weChatApiHttpClientFactory, IOptions<WeChatOptions> weChatOptions, IMediator mediator, ICoreCmsUserWeChatInfoServices weChatUserInfoServices)
{
_weChatApiHttpClientFactory = weChatApiHttpClientFactory;
_mediator = mediator;
_weChatUserInfoServices = weChatUserInfoServices;
_weChatOptions = weChatOptions.Value;
}
/// <summary>
/// GET请求用于处理微信公众号后台的URL验证
/// </summary>
/// <returns></returns>
[HttpGet]
[ActionName("Index")]
public ActionResult Get([FromQuery(Name = "timestamp")] string timestamp,
[FromQuery(Name = "nonce")] string nonce,
[FromQuery(Name = "signature")] string signature,
[FromQuery(Name = "echostr")] string echoString)
{
// 验证服务器推送
// 文档https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Access_Overview.html
NLogUtil.WriteFileLog(LogLevel.Info, LogType.WeChat, "GET接收到微信推送的数据", JsonConvert.SerializeObject(new
{
timestamp,
nonce,
signature,
echoString
}));
var client = _weChatApiHttpClientFactory.CreateWeXinClient();
var valid = client.VerifyEventSignatureForEcho(callbackTimestamp: timestamp, callbackNonce: nonce, callbackSignature: signature);
return Content(!valid ? "fail" : echoString);
}
/// <summary>
/// 接收服务器推送
/// </summary>
/// <returns></returns>
[HttpPost]
[ActionName("Index")]
public async Task<IActionResult> Post(PostModel postModel)
{
// 接收服务器推送
// 文档https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Receiving_event_pushes.html
if (!CheckSignature.Check(postModel.Signature, postModel.Timestamp, postModel.Nonce, _weChatOptions.WeiXinToken))
{
NLogUtil.WriteFileLog(LogLevel.Error, LogType.WeChat, "Post接收服务器推送签名错误", JsonConvert.SerializeObject(postModel));
return Content("fail");
}
else
{
NLogUtil.WriteFileLog(LogLevel.Info, LogType.WeChat, "Post接收服务器推送签名成功", JsonConvert.SerializeObject(postModel));
}
postModel.Token = _weChatOptions.WeiXinToken;//根据自己后台的设置保持一致
postModel.EncodingAESKey = _weChatOptions.WeiXinEncodingAesKey;//根据自己后台的设置保持一致
postModel.AppId = _weChatOptions.WeiXinAppId;//根据自己后台的设置保持一致(必须提供)
//获取流数据转xml流
XDocument postDataDocument = XmlUtility.Convert(Request.GetRequestStream());
var msgXml = string.Empty;
var callbackXml = Init(postDataDocument, postModel, ref msgXml);
//怕出现误判,所以将最优结果判断
if (callbackXml != null && CancelExecute == false && !string.IsNullOrEmpty(msgXml))
{
/* 如果是 XML 格式的通知内容 */
NLogUtil.WriteFileLog(LogLevel.Info, LogType.WeChat, "接收服务器推送XML格式的通知内容", JsonConvert.SerializeObject(callbackXml));
var callBack = await ExecuteProcess(callbackXml, msgXml);
NLogUtil.WriteFileLog(LogLevel.Info, LogType.WeChat, "接收服务器推送XML通知微信服务器", callBack.Data);
return Content(callBack.Data);
}
else
{
NLogUtil.WriteFileLog(LogLevel.Info, LogType.WeChat, "接收服务器推送(解密失败)", JsonConvert.SerializeObject(callbackXml));
return Content("fail");
}
}
#region xml内容
/// <summary>
/// 对解密后的xml数据进行筛选并分发处理结果
/// </summary>
public async Task<WeChatApiCallBack> ExecuteProcess(XDocument sourceXml, string msgXml)
{
//被动回复消息
//文件https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Passive_user_reply_message.html
var requestType = sourceXml.Root?.Element("MsgType")?.Value;
WeChatApiCallBack callBack = new WeChatApiCallBack();
if (!string.IsNullOrEmpty(requestType))
{
var client = _weChatApiHttpClientFactory.CreateWeXinClient();
switch (requestType)
{
case RequestMsgType.Text:
{
var eventModel = client.DeserializeEventFromXml<TextMessageEvent>(msgXml);
var replyModel = new TextMessageReply()
{
ToUserName = eventModel.FromUserName,
FromUserName = eventModel.ToUserName,
CreateTimestamp = CommonHelper.GetTimeStampByTotalSeconds(),
Content = "您发送的消息是" + eventModel.Content
};
var replyXml = client.SerializeEventToXml(replyModel, false);
callBack.Data = replyXml;
}
break;
case RequestMsgType.Location:
{
var eventModel = client.DeserializeEventFromXml<LocationMessageEvent>(msgXml);
}
break;
case RequestMsgType.Image:
{
var eventModel = client.DeserializeEventFromXml<ImageMessageEvent>(msgXml);
var replyModel = new ImageMessageReply()
{
ToUserName = eventModel.FromUserName,
FromUserName = eventModel.ToUserName,
CreateTimestamp = CommonHelper.GetTimeStampByTotalSeconds(),
};
var replyXml = client.SerializeEventToXml(replyModel, false);
callBack.Data = replyXml;
}
break;
case RequestMsgType.Voice:
{
var eventModel = client.DeserializeEventFromXml<VoiceMessageEvent>(msgXml);
var replyModel = new VoiceMessageReply()
{
ToUserName = eventModel.FromUserName,
FromUserName = eventModel.ToUserName,
CreateTimestamp = CommonHelper.GetTimeStampByTotalSeconds(),
};
var replyXml = client.SerializeEventToXml(replyModel, false);
callBack.Data = replyXml;
}
break;
case RequestMsgType.Video:
{
var eventModel = client.DeserializeEventFromXml<VideoMessageEvent>(msgXml);
var replyModel = new VideoMessageReply()
{
ToUserName = eventModel.FromUserName,
FromUserName = eventModel.ToUserName,
CreateTimestamp = CommonHelper.GetTimeStampByTotalSeconds(),
};
var replyXml = client.SerializeEventToXml(replyModel, false);
callBack.Data = replyXml;
}
break;
case RequestMsgType.ShortVideo:
{
var eventModel = client.DeserializeEventFromXml<ShortVideoMessageEvent>(msgXml);
}
break;
case RequestMsgType.Link:
{
var eventModel = client.DeserializeEventFromXml<VoiceMessageEvent>(msgXml);
}
break;
case RequestMsgType.MessageEvent:
{
var eventType = sourceXml.Root?.Element("Event")?.Value;
if (!string.IsNullOrEmpty(eventType))
{
switch (eventType)
{
//订阅(关注)事件
case EventType.Subscribe:
{
var eventModel = client.DeserializeEventFromXml<SubscribePushEvent>(msgXml);
var accessToken = WeChatCacheAccessTokenHelper.GetWeChatAccessToken();
if (eventModel.FromUserName != null)
{
var request = new CgibinUserInfoRequest() { AccessToken = accessToken, OpenId = eventModel.FromUserName };
var response = await client.ExecuteCgibinUserInfoAsync(request, cancellationToken: HttpContext.RequestAborted);
if (!response.IsSuccessful())
{
NLogUtil.WriteFileLog(LogLevel.Info, LogType.WeChat, "获取用户基本信息失败", @"获取用户基本信息失败(状态码:{response.RawStatus},错误代码:{response.ErrorCode},错误描述:{ response.ErrorMessage})。");
}
else
{
var userInfo = await _weChatUserInfoServices.QueryByClauseAsync(p => p.openid == eventModel.FromUserName);
if (userInfo == null)
{
userInfo = new Model.Entities.CoreCmsUserWeChatInfo()
{
isSubscribe = response.IsSubscribed,
openid = response.OpenId,
language = response.Language,
//createTime = response.SubscribeTimestamp,
type = (int)GlobalEnumVars.UserAccountTypes.,
//sessionKey = response.s,
gender = 1,
createTime = DateTime.Now,
unionId = response.UnionId,
};
var id = await _weChatUserInfoServices.InsertAsync(userInfo);
if (id > 0)
{
await _weChatUserInfoServices.UpdateAsync(
p => new Model.Entities.CoreCmsUserWeChatInfo()
{
userId = id
}, p => p.id == id);
}
}
else
{
userInfo.isSubscribe = response.IsSubscribed;
userInfo.unionId = response.UnionId;
userInfo.updateTime = DateTime.Now;
await _weChatUserInfoServices.UpdateAsync(userInfo);
}
}
}
}
break;
// 退订
// 实际上用户无法收到非订阅账号的消息,所以这里可以随便写。
// unsubscribe事件的意义在于及时删除网站应用中已经记录的OpenID绑定消除冗余数据。并且关注用户流失的情况。
case EventType.Unsubscribe:
{
}
break;
case EventType.Localtion:
{
}
break;
case EventType.Click:
{
var eventModel = client.DeserializeEventFromXml<ClickPushEvent>(msgXml);
var replyModel = new TextMessageReply()
{
ToUserName = eventModel.FromUserName,
FromUserName = eventModel.ToUserName,
CreateTimestamp = CommonHelper.GetTimeStampByTotalSeconds(),
Content = "您刚才发送了ENTER事件请求"
};
var replyXml = client.SerializeEventToXml(replyModel, false);
callBack.Data = replyXml;
}
break;
default:
NLogUtil.WriteFileLog(LogLevel.Info, LogType.WeChat, "接收服务器推送处理xml内容/Event无匹配", JsonConvert.SerializeObject(sourceXml));
break;
}
}
}
break;
default:
NLogUtil.WriteFileLog(LogLevel.Info, LogType.WeChat, "接收服务器推送处理xml内容/MsgType无匹配", JsonConvert.SerializeObject(sourceXml));
break;
}
}
else
{
NLogUtil.WriteFileLog(LogLevel.Info, LogType.WeChat, "接收服务器推送处理xml内容/获取MsgType失败", JsonConvert.SerializeObject(sourceXml));
}
return callBack;
}
#endregion
#region xml文本数据
/// <summary>
/// 初始化获取xml文本数据
/// </summary>
/// <param name="postDataDocument"></param>
/// <param name="postModel"></param>
/// <param name="msgXml"></param>
/// <returns></returns>
private XDocument? Init(XDocument postDataDocument, PostModel postModel, ref string msgXml)
{
//进行加密判断并处理
var postDataStr = postDataDocument.ToString();
XDocument decryptDoc = postDataDocument;
if (postDataDocument.Root?.Element("Encrypt") != null && !string.IsNullOrEmpty(postDataDocument.Root.Element("Encrypt")?.Value))
{
//使用了加密
UsingEncryptMessage = true;
EcryptRequestDocument = postDataDocument;
WXBizMsgCrypt msgCrype = new WXBizMsgCrypt(postModel.Token, postModel.EncodingAESKey, postModel.AppId);
var result = msgCrype.DecryptMsg(postModel.Msg_Signature, postModel.Timestamp, postModel.Nonce, postDataStr, ref msgXml);
//判断result类型
if (result != 0)
{
//验证没有通过,取消执行
CancelExecute = true;
return null;
}
if (postDataDocument.Root.Element("FromUserName") != null && !string.IsNullOrEmpty(postDataDocument.Root.Element("FromUserName")?.Value))
{
//TODO使用了兼容模式进行验证即可
UsingCompatibilityModelEncryptMessage = true;
}
decryptDoc = XDocument.Parse(msgXml);//完成解密
}
return decryptDoc;
}
#endregion
}
}

View File

@@ -0,0 +1,190 @@
using System;
using Microsoft.AspNetCore.Mvc;
using System.Text;
using System.Threading.Tasks;
using CoreCms.Net.Configuration;
using CoreCms.Net.Caching.AccressToken;
using CoreCms.Net.IServices;
using CoreCms.Net.Loging;
using CoreCms.Net.Model.Entities;
using CoreCms.Net.WeChat.Service.HttpClients;
using CoreCms.Net.WeChat.Service.Enums;
using CoreCms.Net.WeChat.Service.Models;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using SKIT.FlurlHttpClient.Wechat.Api.Models;
using SKIT.FlurlHttpClient.Wechat.Api;
using LogLevel = NLog.LogLevel;
namespace CoreCms.Net.Web.Controllers.WeChat
{
/// <summary>
/// 微信公众号用户授权事件
/// </summary>
public class WeChatOffiaccountOAuth2Controller : Controller
{
//private readonly string _weChatAppId = AppSettingsConstVars.WeiXinAppId;
//private readonly string _weChatSecret = AppSettingsConstVars.WeiXinAppSecret;
//private readonly string _weChatOAuth2CallBackUrl = AppSettingsConstVars.AppConfigAppInterFaceUrl + "/WeCharOAuth2/UserInfoCallback";
private readonly IWeChatApiHttpClientFactory _weChatApiHttpClientFactory;
private readonly IWeChatUserAccessTokenServices _weChatUserAccessTokenServices;
private readonly ICoreCmsUserWeChatInfoServices _weChatUserInfoServices;
/// <summary>
/// 构造函数
/// </summary>
public WeChatOffiaccountOAuth2Controller(IWeChatApiHttpClientFactory weChatApiHttpClientFactory, IWeChatUserAccessTokenServices weChatUserAccessTokenServices, ICoreCmsUserWeChatInfoServices weChatUserInfoServices)
{
_weChatApiHttpClientFactory = weChatApiHttpClientFactory;
_weChatUserAccessTokenServices = weChatUserAccessTokenServices;
_weChatUserInfoServices = weChatUserInfoServices;
}
/// <summary>
/// OAuthScope.snsapi_userinfo方式回调
/// </summary>
/// <param name="code"></param>
/// <param name="state"></param>
/// <param name="bkUrl"></param>
/// <returns></returns>
public async Task<ActionResult> UserInfoCallback(string code, string state, string bkUrl)
{
if (string.IsNullOrEmpty(code))
{
return Content("您拒绝了授权!");
}
//if (!state.Contains(","))
//{
// //这里的state其实是会暴露给客户端的验证能力很弱这里只是演示一下
// //实际上可以存任何想传递的数据比如用户ID并且需要结合例如下面的Session["OAuthAccessToken"]进行验证
// return Content("验证失败!请从正规途径进入!");
//}
var client = _weChatApiHttpClientFactory.CreateWeXinClient();
var accessToken = WeChatCacheAccessTokenHelper.GetWeChatAccessToken();
var request = new SnsOAuth2AccessTokenRequest()
{
AccessToken = accessToken,
Code = code
};
var response = await client.ExecuteSnsOAuth2AccessTokenAsync(request, HttpContext.RequestAborted);
if (response.ErrorCode != (int)WeChatReturnCode.ReturnCode.)
{
return Content("错误:" + response.ErrorMessage);
}
NLogUtil.WriteFileLog(LogLevel.Info, LogType.WeChat, "获取用户accessToken", JsonConvert.SerializeObject(response));
var accessTokenModel = await _weChatUserAccessTokenServices.QueryByClauseAsync(p => p.openid == response.OpenId);
if (accessTokenModel == null)
{
accessTokenModel = new WeChatUserAccessToken();
accessTokenModel.access_token = response.AccessToken;
accessTokenModel.expires_in = response.ExpiresIn;
accessTokenModel.openid = response.OpenId;
accessTokenModel.refresh_token = response.RefreshToken;
accessTokenModel.scope = response.Scope;
accessTokenModel.unionid = response.UnionId;
accessTokenModel.refresh_DateTime = DateTime.Now.AddSeconds(response.ExpiresIn);
await _weChatUserAccessTokenServices.InsertAsync(accessTokenModel);
}
else
{
accessTokenModel.access_token = response.AccessToken;
accessTokenModel.expires_in = response.ExpiresIn;
//accessTokenModel.openid = response.OpenId;
accessTokenModel.refresh_token = response.RefreshToken;
accessTokenModel.scope = response.Scope;
accessTokenModel.unionid = response.UnionId;
accessTokenModel.refresh_DateTime = DateTime.Now.AddSeconds(response.ExpiresIn);
await _weChatUserAccessTokenServices.UpdateAsync(accessTokenModel);
}
//因为第一步选择的是OAuthScope.snsapi_userinfo这里可以进一步获取用户详细信息
try
{
var userInfoRequest = new SnsUserInfoRequest()
{
AccessToken = response.AccessToken,
OpenId = response.OpenId
};
var userInfoResponse = await client.ExecuteSnsUserInfoAsync(userInfoRequest, HttpContext.RequestAborted);
if (userInfoResponse.ErrorCode == (int)WeChatReturnCode.ReturnCode.)
{
var weChatUserInfo = await _weChatUserInfoServices.QueryByClauseAsync(p => p.openid == response.OpenId);
if (weChatUserInfo == null)
{
weChatUserInfo = new CoreCmsUserWeChatInfo()
{
createTime = DateTime.Now,
type = (int)GlobalEnumVars.UserAccountTypes.,
//city = userInfoResponse.City,
//country = userInfoResponse.Country,
//province = userInfoResponse.Province,
nickName = userInfoResponse.Nickname,
//gender = userInfoResponse.Sex,
avatar = userInfoResponse.HeadImageUrl,
unionId = userInfoResponse.UnionId,
openid = userInfoResponse.OpenId,
gender = 1,
//isSubscribe = userInfoResponse.PrivilegeList,
};
var id = await _weChatUserInfoServices.InsertAsync(weChatUserInfo);
if (id > 0)
{
await _weChatUserInfoServices.UpdateAsync(
p => new CoreCmsUserWeChatInfo()
{
userId = id
}, p => p.id == id);
}
}
else
{
if (weChatUserInfo.nickName != userInfoResponse.Nickname || weChatUserInfo.avatar != userInfoResponse.HeadImageUrl || weChatUserInfo.unionId != userInfoResponse.UnionId)
{
weChatUserInfo.nickName = userInfoResponse.Nickname;
weChatUserInfo.avatar = userInfoResponse.HeadImageUrl;
weChatUserInfo.unionId = userInfoResponse.UnionId;
await _weChatUserInfoServices.UpdateAsync(weChatUserInfo);
}
}
}
else
{
return Content("错误:" + response.ErrorMessage);
}
var option = new CookieOptions
{
Expires = DateTime.Now.AddSeconds(1440)
};
Response.Cookies.Append(GlobalConstVars.CookieOpenId, userInfoResponse.OpenId, option);
if (!string.IsNullOrEmpty(bkUrl))
{
var outBase64String = Convert.FromBase64String(bkUrl);
var orgStr = Encoding.Default.GetString(outBase64String);
return Redirect(orgStr);
}
else
{
return Redirect(AppSettingsConstVars.AppConfigAppH5Url);
}
}
catch (Exception ex)
{
return Content(ex.Message);
}
}
}
}

View File

@@ -1,9 +1,18 @@
using CoreCms.Net.Caching.AccressToken;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading.Tasks;
using CoreCms.Net.Caching.AccressToken;
using CoreCms.Net.Model;
using CoreCms.Net.WeChat.Service.Enums;
using CoreCms.Net.WeChat.Service.HttpClients;
using CoreCms.Net.WeChat.Service.Options;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using SKIT.FlurlHttpClient.Wechat.Api;
using SKIT.FlurlHttpClient.Wechat.Api.Models;
namespace CoreCms.Net.Web.WebApi.Controllers
{
@@ -14,14 +23,17 @@ namespace CoreCms.Net.Web.WebApi.Controllers
[ApiController]
public class WeChatOffiaccountController : Controller
{
private readonly IWeChatApiHttpClientFactory _weChatApiHttpClientFactory;
private readonly WeChatOptions _weChatOptions;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="weChatOptions"></param>
public WeChatOffiaccountController(IOptions<WeChatOptions> weChatOptions)
/// <param name="weChatApiHttpClientFactory"></param>
public WeChatOffiaccountController(IOptions<WeChatOptions> weChatOptions, IWeChatApiHttpClientFactory weChatApiHttpClientFactory)
{
_weChatApiHttpClientFactory = weChatApiHttpClientFactory;
_weChatOptions = weChatOptions.Value;
}
@@ -54,6 +66,93 @@ namespace CoreCms.Net.Web.WebApi.Controllers
});
}
/// <summary>
/// 通用发送模板消息方法
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public async Task<ActionResult> Send(TmpMsgModel model)
{
try
{
var client = _weChatApiHttpClientFactory.CreateWeXinClient();
var accessToken = WeChatCacheAccessTokenHelper.GetWeChatAccessToken();
var request = new CgibinMessageTemplateSendRequest
{
AccessToken = accessToken,
ToUserOpenId = model.OpenId,
TemplateId = model.TemplateId,
MiniProgram = null,
Data = new ConcurrentDictionary<string, CgibinMessageTemplateSendRequest.Types.DataItem>()
};
if (!string.IsNullOrEmpty(model.Url))
{
request.Url = model.Url;
}
const string color = "#CCC";
if (!string.IsNullOrEmpty(model.First))
{
request.Data.Add(new KeyValuePair<string, CgibinMessageTemplateSendRequest.Types.DataItem>("first", new CgibinMessageTemplateSendRequest.Types.DataItem() { Color = color, Value = model.First }));
}
if (!string.IsNullOrEmpty(model.Keyword1))
{
request.Data.Add(new KeyValuePair<string, CgibinMessageTemplateSendRequest.Types.DataItem>("keyword1", new CgibinMessageTemplateSendRequest.Types.DataItem() { Color = color, Value = model.Keyword1 }));
}
if (!string.IsNullOrEmpty(model.Keyword2))
{
request.Data.Add(new KeyValuePair<string, CgibinMessageTemplateSendRequest.Types.DataItem>("keyword2", new CgibinMessageTemplateSendRequest.Types.DataItem() { Color = color, Value = model.Keyword2 }));
}
if (!string.IsNullOrEmpty(model.Keyword3))
{
request.Data.Add(new KeyValuePair<string, CgibinMessageTemplateSendRequest.Types.DataItem>("keyword3", new CgibinMessageTemplateSendRequest.Types.DataItem() { Color = color, Value = model.Keyword3 }));
}
if (!string.IsNullOrEmpty(model.Keyword4))
{
request.Data.Add(new KeyValuePair<string, CgibinMessageTemplateSendRequest.Types.DataItem>("keyword4", new CgibinMessageTemplateSendRequest.Types.DataItem() { Color = color, Value = model.Keyword4 }));
}
if (!string.IsNullOrEmpty(model.Keyword5))
{
request.Data.Add(new KeyValuePair<string, CgibinMessageTemplateSendRequest.Types.DataItem>("keyword5", new CgibinMessageTemplateSendRequest.Types.DataItem() { Color = color, Value = model.Keyword5 }));
}
if (!string.IsNullOrEmpty(model.Keyword6))
{
request.Data.Add(new KeyValuePair<string, CgibinMessageTemplateSendRequest.Types.DataItem>("keyword6", new CgibinMessageTemplateSendRequest.Types.DataItem() { Color = color, Value = model.Keyword6 }));
}
if (!string.IsNullOrEmpty(model.Keyword7))
{
request.Data.Add(new KeyValuePair<string, CgibinMessageTemplateSendRequest.Types.DataItem>("keyword7", new CgibinMessageTemplateSendRequest.Types.DataItem() { Color = color, Value = model.Keyword7 }));
}
if (!string.IsNullOrEmpty(model.Keyword8))
{
request.Data.Add(new KeyValuePair<string, CgibinMessageTemplateSendRequest.Types.DataItem>("keyword8", new CgibinMessageTemplateSendRequest.Types.DataItem() { Color = color, Value = model.Keyword8 }));
}
if (!string.IsNullOrEmpty(model.Keyword9))
{
request.Data.Add(new KeyValuePair<string, CgibinMessageTemplateSendRequest.Types.DataItem>("keyword9", new CgibinMessageTemplateSendRequest.Types.DataItem() { Color = color, Value = model.Keyword9 }));
}
if (!string.IsNullOrEmpty(model.Keyword10))
{
request.Data.Add(new KeyValuePair<string, CgibinMessageTemplateSendRequest.Types.DataItem>("keyword10", new CgibinMessageTemplateSendRequest.Types.DataItem() { Color = color, Value = model.Keyword10 }));
}
if (!string.IsNullOrEmpty(model.Remark))
{
request.Data.Add(new KeyValuePair<string, CgibinMessageTemplateSendRequest.Types.DataItem>("remark", new CgibinMessageTemplateSendRequest.Types.DataItem() { Color = color, Value = model.Remark }));
}
var response = await client.ExecuteCgibinMessageTemplateSendAsync(request, HttpContext.RequestAborted);
return response.ErrorCode != (int)WeChatReturnCode.ReturnCode.
? Json(new { ResultCode = "1", Msg = "错误:" + response.ErrorMessage })
: Json(new { ResultCode = "0", Msg = "已发送成功", Data = response.MessageId });
}
catch (Exception ex)
{
return Json(new { ResultCode = "1", Msg = ex.ToString() });
}
}
}
}

View File

@@ -1 +1 @@
UPDATE dbo.CoreCmsGoods SET spesDesc = REPLACE(spesDesc, '.', '&&'), parameters = REPLACE(parameters, '.', '&&'), newSpec = REPLACE(newSpec, '.', '&&');
UPDATE CoreCmsGoods SET spesDesc = REPLACE(spesDesc, '.', '&&'), parameters = REPLACE(parameters, '.', '&&'), newSpec = REPLACE(newSpec, '.', '&&');

Binary file not shown.

View File

@@ -1,3 +1,8 @@
2022-12-30
【新增】新增表【WeChatMessageResponse】微信公众号回复消息表。
【新增】新增表【WeChatUserAccessToken】微信用户accessToken表。
【新增】表【CoreCmsUserWeChatInfo】增加【isSubscribe】是否关注字段
2022-11-04
【更新数据】更新表【CoreCmsGoods】数据将小写逗号【.】,批量替换为【&&】允许sku使用小写逗号。

Binary file not shown.

View File

@@ -1,3 +1,8 @@
2022-12-30
【新增】新增表【WeChatMessageResponse】微信公众号回复消息表。
【新增】新增表【WeChatUserAccessToken】微信用户accessToken表。
【新增】表【CoreCmsUserWeChatInfo】增加【isSubscribe】是否关注字段
2022-11-04
【更新数据】更新表【CoreCmsGoods】数据将小写逗号【.】,批量替换为【&&】允许sku使用小写逗号。