Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
166975802b | ||
|
|
c9ee8d8cc3 | ||
|
|
22ba88a92c | ||
|
|
a97c647b91 | ||
|
|
ec1061f700 | ||
|
|
82aafaea8f | ||
|
|
bb806063a0 | ||
|
|
eb32117b8c | ||
|
|
3555833ae7 | ||
|
|
a605e704e9 | ||
|
|
6fd004cd35 | ||
|
|
7828f5995e | ||
|
|
d2077762d1 | ||
|
|
321619763e | ||
|
|
075bdb8667 | ||
|
|
6a3547dad2 | ||
|
|
77c57dc459 | ||
|
|
1bed8cd217 | ||
|
|
013b6ea4db | ||
|
|
e462b00e8e | ||
|
|
e14182c883 | ||
|
|
283472b424 | ||
|
|
acc10fde4a | ||
|
|
6e8e649e88 | ||
|
|
314eb40ed9 | ||
|
|
76c53b9915 | ||
|
|
7bbb076c0e | ||
|
|
af07ffc5d1 | ||
|
|
261955e605 | ||
|
|
b7b32f509f | ||
|
|
35219931b0 | ||
|
|
9c89842ede | ||
|
|
dd01e00bb6 | ||
|
|
989700cb30 | ||
|
|
9dddbd874b | ||
|
|
c273ec2d25 | ||
|
|
e0c223d9e3 | ||
|
|
1c366f51c4 | ||
|
|
8c474aa450 | ||
|
|
cc3b329c3e | ||
|
|
ef6ad49cec | ||
|
|
e9b249c7ad | ||
|
|
8492d1f2b6 | ||
|
|
5e3d6a3c84 | ||
|
|
c6d8909994 | ||
|
|
267469dc55 | ||
|
|
06b81d5f5e | ||
|
|
8c8b438ad4 | ||
|
|
3d457bc8c5 | ||
|
|
57eb5d6da5 | ||
|
|
5c9b44727b | ||
|
|
f3724848eb | ||
|
|
a054dea93c | ||
|
|
6c2b4bc56f | ||
|
|
c067951d50 | ||
|
|
748b9065db | ||
|
|
2a84f7d322 | ||
|
|
a7a0e5c16b | ||
|
|
87163ae93a | ||
|
|
58a4a54ed0 | ||
|
|
1de9db2b77 | ||
|
|
ae6ef55378 | ||
|
|
30566d8562 | ||
|
|
d4cbd437f7 | ||
|
|
4754253e7c | ||
|
|
d4288331b4 | ||
|
|
ae31b3ec69 | ||
|
|
31cee32404 | ||
|
|
356ceb514f | ||
|
|
6a209ec308 | ||
|
|
e98bde7ad5 | ||
|
|
3981fa2303 | ||
|
|
015fac766e | ||
|
|
9d2c669bf5 |
@@ -269,3 +269,4 @@ __pycache__/
|
||||
/ZR.Admin.WebApi/Properties/launchSettings.json
|
||||
/ZR.Admin.WebApi/ZRAdmin.xml
|
||||
/ZR.Admin.WebApi/DataProtection
|
||||
/Quartz.NET.WindowsService
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Infrastructure
|
||||
{
|
||||
public class AppSettings
|
||||
{
|
||||
static IConfiguration Configuration { get; set; }
|
||||
|
||||
public AppSettings(IConfiguration configuration)
|
||||
{
|
||||
Configuration = configuration;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 封装要操作的字符
|
||||
/// </summary>
|
||||
/// <param name="sections">节点配置</param>
|
||||
/// <returns></returns>
|
||||
public static string App(params string[] sections)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (sections.Any())
|
||||
{
|
||||
return Configuration[string.Join(":", sections)];
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 递归获取配置信息数组
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="sections"></param>
|
||||
/// <returns></returns>
|
||||
public static List<T> App<T>(params string[] sections)
|
||||
{
|
||||
List<T> list = new();
|
||||
// 引用 Microsoft.Extensions.Configuration.Binder 包
|
||||
Configuration.Bind(string.Join(":", sections), list);
|
||||
return list;
|
||||
}
|
||||
public static T Bind<T>(string key, T t)
|
||||
{
|
||||
Configuration.Bind(key, t);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
public static T GetAppConfig<T>(string key, T defaultValue = default)
|
||||
{
|
||||
T setting = (T)Convert.ChangeType(Configuration[key], typeof(T));
|
||||
var value = setting;
|
||||
if (setting == null)
|
||||
value = defaultValue;
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取配置文件
|
||||
/// </summary>
|
||||
/// <param name="key">eg: WeChat:Token</param>
|
||||
/// <returns></returns>
|
||||
public static string GetConfig(string key)
|
||||
{
|
||||
return Configuration[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// 需要引用包
|
||||
/// Microsoft.Extensions.Configuration;
|
||||
/// Microsoft.Extensions.DependencyInjection;
|
||||
namespace Infrastructure
|
||||
{
|
||||
public class ConfigUtils
|
||||
{
|
||||
#region 单例访问
|
||||
|
||||
static ConfigUtils()
|
||||
{
|
||||
Configuration = App.ServiceProvider.GetRequiredService<IConfiguration>();
|
||||
|
||||
if (Instance == null)
|
||||
Instance = new ConfigUtils();
|
||||
}
|
||||
|
||||
public static ConfigUtils Instance { get; private set; }
|
||||
#endregion
|
||||
private static IConfiguration Configuration { get; set; }
|
||||
|
||||
public T GetAppConfig<T>(string key, T defaultValue = default(T))
|
||||
{
|
||||
T setting = (T)Convert.ChangeType(Configuration[key], typeof(T));
|
||||
var value = setting;
|
||||
if (setting == null)
|
||||
value = defaultValue;
|
||||
return value;
|
||||
}
|
||||
public T Bind<T>(string key, T t)
|
||||
{
|
||||
Configuration.Bind(key, t);
|
||||
|
||||
return t;
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取配置文件
|
||||
/// </summary>
|
||||
/// <param name="key">eg: WeChat:Token</param>
|
||||
/// <returns></returns>
|
||||
public string GetConfig(string key)
|
||||
{
|
||||
return Configuration[key];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取数据库字符串连接串
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public string GetConnectionString(string key)
|
||||
{
|
||||
return Configuration.GetConnectionString(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Infrastructure.Constant
|
||||
{
|
||||
public class HubsConstant
|
||||
{
|
||||
private const string V = "receiveNotice";
|
||||
public static string ReceiveNotice = V;
|
||||
public static string OnlineNum = "onlineNum";
|
||||
public static string MoreNotice = "moreNotice";
|
||||
}
|
||||
}
|
||||
@@ -25,5 +25,33 @@ namespace Infrastructure
|
||||
/// 用户权限缓存key
|
||||
/// </summary>
|
||||
public static string UserPermKEY = "CACHE-USER-PERM";
|
||||
|
||||
/// <summary>
|
||||
/// 欢迎语
|
||||
/// </summary>
|
||||
public static string[] WelcomeMessages = new string[] {
|
||||
"祝你开心每一天!",
|
||||
"忙碌了一周,停一停脚步!",
|
||||
"世间美好,与你环环相扣!",
|
||||
"永远相信美好的事情即将发生!",
|
||||
"每一天,遇见更好的自己!",
|
||||
"保持热爱,奔赴山海!",
|
||||
"生活明朗,万物可爱!",
|
||||
"愿每一天醒来都是美好的开始!",
|
||||
"没有希望的地方,就没有奋斗!",
|
||||
"我最珍贵的时光都行走在路上!",
|
||||
"成功,往往住在失败的隔壁!",
|
||||
"人只要不失去方向,就不会失去自己!",
|
||||
"每条堵住的路,都有一个出口!",
|
||||
"没有谁能击垮你,除非你自甘堕落!",
|
||||
"微笑着的人并非没有痛苦!",
|
||||
"生活变的再糟糕,也不妨碍我变得更好!",
|
||||
"你要悄悄努力,然后惊艳众人!",
|
||||
"人与人之间最大的信任是精诚相见",
|
||||
"人生就像爬坡,要一步一步来。",
|
||||
"今天的目标完成了吗?",
|
||||
"高效工作,告别996",
|
||||
"销售是从别人拒绝开始的!"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,45 @@ namespace Infrastructure
|
||||
}
|
||||
return dateTime ?? DateTime.Now;
|
||||
}
|
||||
#region 时间戳转换
|
||||
|
||||
/// <summary>
|
||||
/// 时间戳转本地时间-时间戳精确到秒
|
||||
/// </summary>
|
||||
public static DateTime ToLocalTimeDateBySeconds(long unix)
|
||||
{
|
||||
var dto = DateTimeOffset.FromUnixTimeSeconds(unix);
|
||||
return dto.ToLocalTime().DateTime;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 时间转时间戳Unix-时间戳精确到秒
|
||||
/// </summary>
|
||||
public static long ToUnixTimestampBySeconds(DateTime dt)
|
||||
{
|
||||
DateTimeOffset dto = new DateTimeOffset(dt);
|
||||
return dto.ToUnixTimeSeconds();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 时间戳转本地时间-时间戳精确到毫秒
|
||||
/// </summary>
|
||||
public static DateTime ToLocalTimeDateByMilliseconds(long unix)
|
||||
{
|
||||
var dto = DateTimeOffset.FromUnixTimeMilliseconds(unix);
|
||||
return dto.ToLocalTime().DateTime;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 时间转时间戳Unix-时间戳精确到毫秒
|
||||
/// </summary>
|
||||
public static long ToUnixTimestampByMilliseconds(DateTime dt)
|
||||
{
|
||||
DateTimeOffset dto = new DateTimeOffset(dt);
|
||||
return dto.ToUnixTimeMilliseconds();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 毫秒转天时分秒
|
||||
/// <summary>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<PackageReference Include="AspectCore.Abstractions" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.2.7" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="5.0.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -111,6 +111,11 @@ namespace Infrastructure.Model
|
||||
/// <param name="msg"></param>
|
||||
/// <returns></returns>
|
||||
public static ApiResult Error(string msg) { return new ApiResult((int)ResultCode.CUSTOM_ERROR, msg); }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"msg={Msg},data={Data}";
|
||||
}
|
||||
}
|
||||
|
||||
public class ApiResult<T> : ApiResult
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
|
||||
</startup>
|
||||
<appSettings>
|
||||
<add key="url" value="http://127.0.0.1:8085/Health/index"/>
|
||||
<add key="interval" value="1"/><!--执行时间间隔(分钟)-->
|
||||
</appSettings>
|
||||
</configuration>
|
||||
@@ -1,5 +0,0 @@
|
||||
%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\installutil.exe G:\live_zhaorui\ZrryAdmin\ZrryAdmin_api\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe
|
||||
|
||||
Net Start Quartz.Net
|
||||
|
||||
sc config Quartz.Net start= auto
|
||||
@@ -1,316 +0,0 @@
|
||||
|
||||
正在运行事务处理安装。
|
||||
|
||||
正在开始安装的“安装”阶段。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
“安装”阶段已成功完成,正在开始“提交”阶段。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
“提交”阶段已成功完成。
|
||||
|
||||
已完成事务处理安装。
|
||||
|
||||
|
||||
正在开始卸载。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
卸载完成。
|
||||
|
||||
正在运行事务处理安装。
|
||||
|
||||
正在开始安装的“安装”阶段。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
“安装”阶段已成功完成,正在开始“提交”阶段。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
“提交”阶段已成功完成。
|
||||
|
||||
已完成事务处理安装。
|
||||
|
||||
|
||||
正在开始卸载。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
卸载完成。
|
||||
|
||||
正在运行事务处理安装。
|
||||
|
||||
正在开始安装的“安装”阶段。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
“安装”阶段已成功完成,正在开始“提交”阶段。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
“提交”阶段已成功完成。
|
||||
|
||||
已完成事务处理安装。
|
||||
|
||||
|
||||
正在开始卸载。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
卸载完成。
|
||||
|
||||
正在运行事务处理安装。
|
||||
|
||||
正在开始安装的“安装”阶段。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
“安装”阶段已成功完成,正在开始“提交”阶段。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
“提交”阶段已成功完成。
|
||||
|
||||
已完成事务处理安装。
|
||||
|
||||
|
||||
正在开始卸载。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
卸载完成。
|
||||
|
||||
正在运行事务处理安装。
|
||||
|
||||
正在开始安装的“安装”阶段。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
“安装”阶段已成功完成,正在开始“提交”阶段。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
“提交”阶段已成功完成。
|
||||
|
||||
已完成事务处理安装。
|
||||
|
||||
正在运行事务处理安装。
|
||||
|
||||
正在开始安装的“安装”阶段。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
在“安装”阶段发生异常。
|
||||
System.ComponentModel.Win32Exception: 指定的服务已存在。
|
||||
|
||||
正在开始安装的“回退”阶段。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
“回退”阶段已成功完成。
|
||||
|
||||
已完成事务处理安装。
|
||||
|
||||
|
||||
正在开始卸载。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
卸载完成。
|
||||
|
||||
正在运行事务处理安装。
|
||||
|
||||
正在开始安装的“安装”阶段。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
“安装”阶段已成功完成,正在开始“提交”阶段。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
“提交”阶段已成功完成。
|
||||
|
||||
已完成事务处理安装。
|
||||
|
||||
正在运行事务处理安装。
|
||||
|
||||
正在开始安装的“安装”阶段。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
在“安装”阶段发生异常。
|
||||
System.ComponentModel.Win32Exception: 指定的服务已存在。
|
||||
|
||||
正在开始安装的“回退”阶段。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
“回退”阶段已成功完成。
|
||||
|
||||
已完成事务处理安装。
|
||||
|
||||
|
||||
正在开始卸载。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
卸载完成。
|
||||
|
||||
正在运行事务处理安装。
|
||||
|
||||
正在开始安装的“安装”阶段。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
“安装”阶段已成功完成,正在开始“提交”阶段。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
“提交”阶段已成功完成。
|
||||
|
||||
已完成事务处理安装。
|
||||
|
||||
|
||||
正在开始卸载。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
卸载完成。
|
||||
|
||||
正在运行事务处理安装。
|
||||
|
||||
正在开始安装的“安装”阶段。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
“安装”阶段已成功完成,正在开始“提交”阶段。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
“提交”阶段已成功完成。
|
||||
|
||||
已完成事务处理安装。
|
||||
|
||||
|
||||
正在开始卸载。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
卸载完成。
|
||||
|
||||
正在运行事务处理安装。
|
||||
|
||||
正在开始安装的“安装”阶段。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
“安装”阶段已成功完成,正在开始“提交”阶段。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
“提交”阶段已成功完成。
|
||||
|
||||
已完成事务处理安装。
|
||||
|
||||
正在运行事务处理安装。
|
||||
|
||||
正在开始安装的“安装”阶段。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
在“安装”阶段发生异常。
|
||||
System.ComponentModel.Win32Exception: 指定的服务已存在。
|
||||
|
||||
正在开始安装的“回退”阶段。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
“回退”阶段已成功完成。
|
||||
|
||||
已完成事务处理安装。
|
||||
|
||||
|
||||
正在开始卸载。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
卸载完成。
|
||||
|
||||
正在运行事务处理安装。
|
||||
|
||||
正在开始安装的“安装”阶段。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
“安装”阶段已成功完成,正在开始“提交”阶段。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
“提交”阶段已成功完成。
|
||||
|
||||
已完成事务处理安装。
|
||||
|
||||
|
||||
正在开始卸载。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
卸载完成。
|
||||
|
||||
正在运行事务处理安装。
|
||||
|
||||
正在开始安装的“安装”阶段。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
“安装”阶段已成功完成,正在开始“提交”阶段。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
“提交”阶段已成功完成。
|
||||
|
||||
已完成事务处理安装。
|
||||
|
||||
正在运行事务处理安装。
|
||||
|
||||
正在开始安装的“安装”阶段。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
在“安装”阶段发生异常。
|
||||
System.ComponentModel.Win32Exception: 指定的服务已存在。
|
||||
|
||||
正在开始安装的“回退”阶段。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
“回退”阶段已成功完成。
|
||||
|
||||
已完成事务处理安装。
|
||||
|
||||
|
||||
正在开始卸载。
|
||||
查看日志文件的内容以获得 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
卸载完成。
|
||||
|
||||
正在运行事务处理安装。
|
||||
|
||||
正在开始安装的“安装”阶段。
|
||||
查看日志文件的内容以获得 G:\live_zhaorui\ZrryAdmin\ZrryAdmin_api\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 G:\live_zhaorui\ZrryAdmin\ZrryAdmin_api\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
在“安装”阶段发生异常。
|
||||
System.Security.SecurityException: 未找到源,但未能搜索某些或全部事件日志。 不可访问的日志: Security。
|
||||
|
||||
正在开始安装的“回退”阶段。
|
||||
查看日志文件的内容以获得 G:\live_zhaorui\ZrryAdmin\ZrryAdmin_api\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe 程序集的进度。
|
||||
该文件位于 G:\live_zhaorui\ZrryAdmin\ZrryAdmin_api\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.InstallLog。
|
||||
|
||||
“回退”阶段已成功完成。
|
||||
|
||||
已完成事务处理安装。
|
||||
@@ -1,25 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.ServiceProcess;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Quartz.NET.WindowsService
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// 应用程序的主入口点。
|
||||
/// </summary>
|
||||
static void Main()
|
||||
{
|
||||
ServiceBase[] ServicesToRun;
|
||||
ServicesToRun = new ServiceBase[]
|
||||
{
|
||||
new Service1()
|
||||
};
|
||||
ServiceBase.Run(ServicesToRun);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
namespace Quartz.NET.WindowsService
|
||||
{
|
||||
partial class ProjectInstaller
|
||||
{
|
||||
/// <summary>
|
||||
/// 必需的设计器变量。
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// 清理所有正在使用的资源。
|
||||
/// </summary>
|
||||
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region 组件设计器生成的代码
|
||||
|
||||
/// <summary>
|
||||
/// 设计器支持所需的方法 - 不要修改
|
||||
/// 使用代码编辑器修改此方法的内容。
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.serviceProcessInstaller1 = new System.ServiceProcess.ServiceProcessInstaller();
|
||||
this.Quartz定时作业 = new System.ServiceProcess.ServiceInstaller();
|
||||
//
|
||||
// serviceProcessInstaller1
|
||||
//
|
||||
this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalService;
|
||||
this.serviceProcessInstaller1.Password = null;
|
||||
this.serviceProcessInstaller1.Username = null;
|
||||
//
|
||||
// Quartz定时作业
|
||||
//
|
||||
this.Quartz定时作业.ServiceName = "Quartz.Net";
|
||||
//
|
||||
// ProjectInstaller
|
||||
//
|
||||
this.Installers.AddRange(new System.Configuration.Install.Installer[] {
|
||||
this.serviceProcessInstaller1,
|
||||
this.Quartz定时作业});
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.ServiceProcess.ServiceProcessInstaller serviceProcessInstaller1;
|
||||
private System.ServiceProcess.ServiceInstaller Quartz定时作业;
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Configuration.Install;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Quartz.NET.WindowsService
|
||||
{
|
||||
[RunInstaller(true)]
|
||||
public partial class ProjectInstaller : System.Configuration.Install.Installer
|
||||
{
|
||||
public ProjectInstaller()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,129 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="serviceProcessInstaller1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<metadata name="Quartz定时作业.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>243, 17</value>
|
||||
</metadata>
|
||||
<metadata name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
</root>
|
||||
@@ -1,36 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// 有关程序集的一般信息由以下
|
||||
// 控制。更改这些特性值可修改
|
||||
// 与程序集关联的信息。
|
||||
[assembly: AssemblyTitle("Quartz.NET.WindowsService")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Microsoft")]
|
||||
[assembly: AssemblyProduct("Quartz.NET.WindowsService")]
|
||||
[assembly: AssemblyCopyright("Copyright © Microsoft 2019")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// 将 ComVisible 设置为 false 会使此程序集中的类型
|
||||
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
|
||||
//请将此类型的 ComVisible 特性设置为 true。
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
|
||||
[assembly: Guid("3040dd22-663e-44cb-909b-3d0043867361")]
|
||||
|
||||
// 程序集的版本信息由下列四个值组成:
|
||||
//
|
||||
// 主版本
|
||||
// 次版本
|
||||
// 生成号
|
||||
// 修订号
|
||||
//
|
||||
// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
|
||||
// 方法是按如下所示使用“*”: :
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -1,108 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{3040DD22-663E-44CB-909B-3D0043867361}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<RootNamespace>Quartz.NET.WindowsService</RootNamespace>
|
||||
<AssemblyName>Quartz.NET.WindowsService</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<Deterministic>true</Deterministic>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<AutorunEnabled>true</AutorunEnabled>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
<SccProjectName>SAK</SccProjectName>
|
||||
<SccLocalPath>SAK</SccLocalPath>
|
||||
<SccAuxPath>SAK</SccAuxPath>
|
||||
<SccProvider>SAK</SccProvider>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Configuration.Install" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Management" />
|
||||
<Reference Include="System.Runtime.Remoting" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.ServiceProcess" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ProjectInstaller.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="ProjectInstaller.Designer.cs">
|
||||
<DependentUpon>ProjectInstaller.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Service1.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Service1.Designer.cs">
|
||||
<DependentUpon>Service1.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="ProjectInstaller.resx">
|
||||
<DependentUpon>ProjectInstaller.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include=".NETFramework,Version=v4.6.1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Microsoft .NET Framework 4.6.1 %28x86 和 x64%29</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
-37
@@ -1,37 +0,0 @@
|
||||
namespace Quartz.NET.WindowsService
|
||||
{
|
||||
partial class Service1
|
||||
{
|
||||
/// <summary>
|
||||
/// 必需的设计器变量。
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// 清理所有正在使用的资源。
|
||||
/// </summary>
|
||||
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region 组件设计器生成的代码
|
||||
|
||||
/// <summary>
|
||||
/// 设计器支持所需的方法 - 不要修改
|
||||
/// 使用代码编辑器修改此方法的内容。
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
components = new System.ComponentModel.Container();
|
||||
this.ServiceName = "Service1";
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
using System;
|
||||
using System.Configuration;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.ServiceProcess;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Quartz.NET.WindowsService
|
||||
{
|
||||
public partial class Service1 : ServiceBase
|
||||
{
|
||||
public Service1()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
protected override void OnStart(string[] args)
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
Start();
|
||||
});
|
||||
}
|
||||
private void Start()
|
||||
{
|
||||
string path = AppDomain.CurrentDomain.BaseDirectory + "\\log\\";
|
||||
//默认1分钟调用一次
|
||||
int interval = 1;
|
||||
string message = "";
|
||||
string url = "";
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
ConfigurationManager.RefreshSection("appSettings");
|
||||
url = ConfigurationManager.AppSettings["url"];
|
||||
interval = Convert.ToInt32(ConfigurationManager.AppSettings["interval"]);
|
||||
|
||||
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
|
||||
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
|
||||
{
|
||||
Stream responseStream = response.GetResponseStream();
|
||||
StreamReader streamReader = new StreamReader(responseStream, Encoding.UTF8);
|
||||
message = streamReader.ReadToEnd();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
message= url+ ",interval:["+ interval + "],"+ ex.Message;
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
message = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "__" + message + "\r\n";
|
||||
WriteFile(path, DateTime.Now.ToString("yyyy-MM-dd") + ".txt", message, true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
}
|
||||
Thread.Sleep(new TimeSpan(0,interval,0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriteFile(string path, string fileName, string content, bool appendToLast = false)
|
||||
{
|
||||
if (!Directory.Exists(path))//如果不存在就创建file文件夹
|
||||
{
|
||||
Directory.CreateDirectory(path);
|
||||
}
|
||||
|
||||
using (FileStream stream = File.Open(path + fileName, FileMode.OpenOrCreate, FileAccess.Write))
|
||||
{
|
||||
byte[] by = Encoding.Default.GetBytes(content);
|
||||
if (appendToLast)
|
||||
{
|
||||
stream.Position = stream.Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
stream.SetLength(0);
|
||||
}
|
||||
stream.Write(by, 0, by.Length);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnStop()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\installutil.exe /u E:\Quartz.NET\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe
|
||||
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Newtonsoft.Json" version="11.0.2" targetFramework="net461" />
|
||||
<package id="Quartz" version="3.0.7" targetFramework="net461" />
|
||||
<package id="Quartz.Serialization.Json" version="3.0.7" targetFramework="net461" />
|
||||
</packages>
|
||||
@@ -1,9 +0,0 @@
|
||||
如果你只是将本项目发布到IIS,IIS应用池回收后就不能执行任务了,那么可以使用此windows服务器定时调用本项目的站点
|
||||
|
||||
1、修改App.config中的url属性value值为你当前部署的quertz.net的站点+/Common/Health
|
||||
2、用记事本打开Install.bat文件修改 项目发布后的目录\bin\Debug\Quartz.NET.WindowsService.exe
|
||||
改为:(这里填写你项目所在路径)\Quartz.NET.WindowsService\bin\Debug\Quartz.NET.WindowsService.exe
|
||||
3、编译项目
|
||||
4、点击Install.bat安装windows服务
|
||||
|
||||
卸载服务:运行Uninstall.bat(运行前按上面一样将修改Quartz.NET.WindowsService.exe路径)
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## 🍟概述
|
||||
* 本项目适合有一定NetCore和 vue基础的开发人员
|
||||
* 基于.NET 5实现的通用权限管理平台(RBAC模式)。整合最新技术高效快速开发,前后端分离模式,开箱即用。
|
||||
* 基于.NET5/.NET6实现的通用权限管理平台(RBAC模式)。整合最新技术高效快速开发,前后端分离模式,开箱即用。
|
||||
* 代码量少、学习简单、通俗易懂、功能强大、易扩展、轻量级,让web开发更快速、简单高效(从此告别996),解决70%的重复工作,专注您的业务,轻松开发从现在开始!
|
||||
* 前端采用Vue2.0、Element UI。
|
||||
* 后端采用Net5、Sqlsugar、MySQL。
|
||||
@@ -29,7 +29,7 @@
|
||||
Vue版前端技术栈 :基于vue、vuex、vue-router 、vue-cli 、axios 和 element-ui,前端采用vscode工具开发
|
||||
|
||||
## 🍀后端技术
|
||||
核心框架:.Net5.0 + Web API + sqlsugar + swagger
|
||||
核心框架:.Net5.0/.Net6 + Web API + sqlsugar + swagger + signalR
|
||||
|
||||
定时计划任务:Quartz.Net组件
|
||||
|
||||
@@ -56,7 +56,7 @@ Vue版前端技术栈 :基于vue、vuex、vue-router 、vue-cli 、axios 和 e
|
||||
12. 文章管理:可以写文章记录。
|
||||
13. 代码生成:可以一键生成前后端代码(.cs、.vue、.js、SQL文件等),支持下载,自定义配置前端展示控件、让开发更快捷高效。
|
||||
14. 文件管理:可以上传文件
|
||||
15. 通知管理:系统通知公告信息发布维护。
|
||||
15. 通知管理:系统通知公告信息发布维护,使用signalr实现对用户实时通知。
|
||||
16. 参数管理:对系统动态配置常用参数。
|
||||
|
||||
## 🍻项目结构
|
||||
|
||||
@@ -12,7 +12,6 @@ using ZR.Admin.WebApi.Filters;
|
||||
|
||||
namespace ZR.Admin.WebApi.Controllers
|
||||
{
|
||||
[LogActionFilter]
|
||||
public class BaseController : ControllerBase
|
||||
{
|
||||
public static string TIME_FORMAT_FULL = "yyyy-MM-dd HH:mm:ss";
|
||||
|
||||
@@ -7,9 +7,11 @@ using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Newtonsoft.Json;
|
||||
using Snowflake.Core;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using ZR.Admin.WebApi.Extensions;
|
||||
using ZR.Admin.WebApi.Filters;
|
||||
using ZR.Common;
|
||||
@@ -158,25 +160,29 @@ namespace ZR.Admin.WebApi.Controllers
|
||||
[HttpPost]
|
||||
[Verify]
|
||||
[ActionPermissionFilter(Permission = "common")]
|
||||
public IActionResult UploadFileAliyun([FromForm(Name = "file")] IFormFile formFile, string fileName = "", string fileDir = "")
|
||||
public async Task<IActionResult> UploadFileAliyun([FromForm(Name = "file")] IFormFile formFile, string fileName = "", string fileDir = "")
|
||||
{
|
||||
if (fileDir.IsEmpty()) fileDir = "uploads";
|
||||
if (formFile == null) throw new CustomException(ResultCode.PARAM_ERROR, "上传文件不能为空");
|
||||
string fileExt = Path.GetExtension(formFile.FileName);
|
||||
string[] AllowedFileExtensions = new string[] { ".jpg", ".gif", ".png", ".jpeg", ".webp", ".svga", ".xls", ".doc", ".zip", ".json", ".txt", ".bundle" };
|
||||
int MaxContentLength = 1024 * 1024 * 15;
|
||||
double fileSize = formFile.Length / 1024;
|
||||
if (!AllowedFileExtensions.Contains(fileExt))
|
||||
string fileExt = Path.GetExtension(formFile.FileName);//文件后缀
|
||||
double fileSize = formFile.Length / 1024.0;//文件大小KB
|
||||
string[] NotAllowedFileExtensions = new string[] { ".bat", ".exe", ".jar", ".js" };
|
||||
int MaxContentLength = 15;
|
||||
if (NotAllowedFileExtensions.Contains(fileExt))
|
||||
{
|
||||
return ToResponse(ResultCode.CUSTOM_ERROR, "上传失败,未经允许上传类型");
|
||||
}
|
||||
|
||||
if (formFile.Length > MaxContentLength)
|
||||
if ((fileSize / 1024) > MaxContentLength)
|
||||
{
|
||||
return ToResponse(ResultCode.CUSTOM_ERROR, "上传文件过大,不能超过 " + (MaxContentLength / 1024).ToString() + " MB");
|
||||
return ToResponse(ResultCode.CUSTOM_ERROR, "上传文件过大,不能超过 " + MaxContentLength + " MB");
|
||||
}
|
||||
|
||||
(bool, string, string) result = SysFileService.SaveFile(fileDir, formFile, fileName);
|
||||
long fileId = SysFileService.InsertFile(new SysFile()
|
||||
(bool, string, string) result = new();
|
||||
await Task.Run(() =>
|
||||
{
|
||||
result = SysFileService.SaveFile(fileDir, formFile, fileName, "");
|
||||
});
|
||||
long id = SysFileService.InsertFile(new SysFile()
|
||||
{
|
||||
AccessUrl = result.Item2,
|
||||
Create_by = HttpContext.GetName(),
|
||||
@@ -193,7 +199,7 @@ namespace ZR.Admin.WebApi.Controllers
|
||||
{
|
||||
url = result.Item2,
|
||||
fileName = result.Item3,
|
||||
fileId
|
||||
fileId = id
|
||||
});
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -54,6 +54,27 @@ namespace ZR.Admin.WebApi.Controllers
|
||||
return SUCCESS(response);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询最新文章列表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("newList")]
|
||||
public IActionResult QueryNew()
|
||||
{
|
||||
//开始拼装查询条件
|
||||
var predicate = Expressionable.Create<Article>();
|
||||
|
||||
//搜索条件
|
||||
predicate = predicate.And(m => m.Status == "1");
|
||||
|
||||
var response = _ArticleService.Queryable()
|
||||
.Where(predicate.ToExpression())
|
||||
.Take(10)
|
||||
.OrderBy(f => f.UpdateTime, OrderByType.Desc).ToList();
|
||||
|
||||
return SUCCESS(response);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取文章目录,前端没用到
|
||||
/// </summary>
|
||||
|
||||
@@ -237,7 +237,7 @@ namespace ZR.Admin.WebApi.Controllers
|
||||
var genTableInfo = GenTableService.GetGenTableInfo(dto.TableId);
|
||||
genTableInfo.Columns = GenTableColumnService.GenTableColumns(dto.TableId);
|
||||
|
||||
dto.DbType = ConfigUtils.Instance.GetAppConfig(OptionsSetting.ConnBusDbType, 0);
|
||||
dto.DbType = AppSettings.GetAppConfig(OptionsSetting.ConnBusDbType, 0);
|
||||
dto.GenTable = genTableInfo;
|
||||
dto.IsPreview = true;
|
||||
//生成代码
|
||||
@@ -263,7 +263,7 @@ namespace ZR.Admin.WebApi.Controllers
|
||||
var genTableInfo = GenTableService.GetGenTableInfo(dto.TableId);
|
||||
genTableInfo.Columns = GenTableColumnService.GenTableColumns(dto.TableId);
|
||||
|
||||
dto.DbType = ConfigUtils.Instance.GetAppConfig(OptionsSetting.ConnBusDbType, 0);
|
||||
dto.DbType = AppSettings.GetAppConfig(OptionsSetting.ConnBusDbType, 0);
|
||||
dto.GenTable = genTableInfo;
|
||||
//自定义路径
|
||||
if (genTableInfo.GenType == "1")
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace ZR.Admin.WebApi.Controllers
|
||||
predicate = predicate.AndIF(parm.FileId != null, m => m.Id == parm.FileId);
|
||||
|
||||
//搜索条件查询语法参考Sqlsugar
|
||||
var response = _SysFileService.GetPages(predicate.ToExpression(), parm);
|
||||
var response = _SysFileService.GetPages(predicate.ToExpression(), parm, x => x.Id, OrderByType.Desc);
|
||||
return SUCCESS(response);
|
||||
}
|
||||
|
||||
@@ -57,74 +57,13 @@ namespace ZR.Admin.WebApi.Controllers
|
||||
/// <returns></returns>
|
||||
[HttpGet("{Id}")]
|
||||
[ActionPermissionFilter(Permission = "tool:file:query")]
|
||||
public IActionResult GetSysFile(int Id)
|
||||
public IActionResult GetSysFile(long Id)
|
||||
{
|
||||
var response = _SysFileService.GetFirst(x => x.Id == Id);
|
||||
|
||||
return SUCCESS(response);
|
||||
}
|
||||
|
||||
///// <summary>
|
||||
///// 添加文件存储
|
||||
///// </summary>
|
||||
///// <returns></returns>
|
||||
//[HttpPost]
|
||||
//[ActionPermissionFilter(Permission = "tool:file:add")]
|
||||
//[Log(Title = "文件存储", BusinessType = BusinessType.INSERT)]
|
||||
//public IActionResult AddSysFile([FromBody] SysFileDto parm)
|
||||
//{
|
||||
// if (parm == null)
|
||||
// {
|
||||
// throw new CustomException("请求参数错误");
|
||||
// }
|
||||
// //从 Dto 映射到 实体
|
||||
// var model = parm.Adapt<SysFile>().ToCreate(HttpContext);
|
||||
|
||||
// var response = _SysFileService.Insert(model, it => new
|
||||
// {
|
||||
// it.FileName,
|
||||
// it.FileUrl,
|
||||
// it.StorePath,
|
||||
// it.FileSize,
|
||||
// it.FileExt,
|
||||
// it.Create_by,
|
||||
// it.Create_time,
|
||||
// it.StoreType,
|
||||
// it.AccessUrl,
|
||||
// });
|
||||
// return ToResponse(response);
|
||||
//}
|
||||
|
||||
///// <summary>
|
||||
///// 更新文件存储
|
||||
///// </summary>
|
||||
///// <returns></returns>
|
||||
//[HttpPut]
|
||||
//[ActionPermissionFilter(Permission = "tool:file:update")]
|
||||
//[Log(Title = "文件存储", BusinessType = BusinessType.UPDATE)]
|
||||
//public IActionResult UpdateSysFile([FromBody] SysFileDto parm)
|
||||
//{
|
||||
// if (parm == null)
|
||||
// {
|
||||
// throw new CustomException("请求实体不能为空");
|
||||
// }
|
||||
// //从 Dto 映射到 实体
|
||||
// var model = parm.Adapt<SysFile>().ToUpdate(HttpContext);
|
||||
|
||||
// var response = _SysFileService.Update(w => w.Id == model.Id, it => new SysFile()
|
||||
// {
|
||||
// //Update 字段映射
|
||||
// FileUrl = model.FileUrl,
|
||||
// StorePath = model.StorePath,
|
||||
// FileSize = model.FileSize,
|
||||
// FileExt = model.FileExt,
|
||||
// StoreType = model.StoreType,
|
||||
// AccessUrl = model.AccessUrl,
|
||||
// });
|
||||
|
||||
// return ToResponse(response);
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// 删除文件存储
|
||||
/// </summary>
|
||||
@@ -134,7 +73,7 @@ namespace ZR.Admin.WebApi.Controllers
|
||||
[Log(Title = "文件存储", BusinessType = BusinessType.DELETE)]
|
||||
public IActionResult DeleteSysFile(string ids)
|
||||
{
|
||||
int[] idsArr = Tools.SpitIntArrary(ids);
|
||||
long[] idsArr = Tools.SpitLongArrary(ids);
|
||||
if (idsArr.Length <= 0) { return ToResponse(ApiResult.Error($"删除失败Id 不能为空")); }
|
||||
|
||||
var response = _SysFileService.Delete(idsArr);
|
||||
|
||||
@@ -17,6 +17,8 @@ using Hei.Captcha;
|
||||
using ZR.Common;
|
||||
using ZR.Service.System;
|
||||
using Microsoft.Extensions.Options;
|
||||
using UAParser;
|
||||
using IPTools.Core;
|
||||
|
||||
namespace ZR.Admin.WebApi.Controllers.System
|
||||
{
|
||||
@@ -66,7 +68,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
/// <returns></returns>
|
||||
[Route("login")]
|
||||
[HttpPost]
|
||||
[Log(Title = "登录")]
|
||||
//[Log(Title = "登录")]
|
||||
public IActionResult Login([FromBody] LoginBodyDto loginBody)
|
||||
{
|
||||
if (loginBody == null) { throw new CustomException("请求参数错误"); }
|
||||
@@ -77,13 +79,11 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
return ToResponse(ResultCode.CAPTCHA_ERROR, "验证码错误");
|
||||
}
|
||||
|
||||
var user = sysLoginService.Login(loginBody, AsyncFactory.RecordLogInfo(httpContextAccessor.HttpContext, "0", "login"));
|
||||
var user = sysLoginService.Login(loginBody, RecordLogInfo(httpContextAccessor.HttpContext));
|
||||
|
||||
#region 存入cookie Action校验权限使用
|
||||
List<SysRole> roles = roleService.SelectUserRoleListByUserId(user.UserId);
|
||||
//权限集合 eg *:*:*,system:user:list
|
||||
List<string> permissions = permissionService.GetMenuPermission(user);
|
||||
#endregion
|
||||
|
||||
LoginUser loginUser = new(user, roles, permissions);
|
||||
CacheHelper.SetCache(GlobalConstant.UserPermKEY + user.UserId, loginUser);
|
||||
@@ -104,9 +104,10 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
// await HttpContext.SignOutAsync();
|
||||
//}).Wait();
|
||||
var id = HttpContext.GetUId();
|
||||
var name = HttpContext.GetName();
|
||||
|
||||
CacheHelper.Remove(GlobalConstant.UserPermKEY + id);
|
||||
return SUCCESS(1);
|
||||
return SUCCESS(new { name , id});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -125,7 +126,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
List<string> roles = permissionService.GetRolePermission(user);
|
||||
//权限集合 eg *:*:*,system:user:list
|
||||
List<string> permissions = permissionService.GetMenuPermission(user);
|
||||
|
||||
user.WelcomeContent = GlobalConstant.WelcomeMessages[new Random().Next(0, GlobalConstant.WelcomeMessages.Length)];
|
||||
return SUCCESS(new { user, roles, permissions });
|
||||
}
|
||||
|
||||
@@ -179,5 +180,27 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
|
||||
return ToJson(1, obj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录用户登陆信息
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <returns></returns>
|
||||
public SysLogininfor RecordLogInfo(HttpContext context)
|
||||
{
|
||||
var ipAddr = context.GetClientUserIp();
|
||||
var ip_info = IpTool.Search(ipAddr);
|
||||
ClientInfo clientInfo = context.GetClientInfo();
|
||||
SysLogininfor sysLogininfor = new()
|
||||
{
|
||||
browser = clientInfo.Device.Family,
|
||||
os = clientInfo.OS.ToString(),
|
||||
ipaddr = ipAddr,
|
||||
userName = context.GetName(),
|
||||
loginLocation = ip_info.Province + "-" + ip_info.City
|
||||
};
|
||||
|
||||
return sysLogininfor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Infrastructure;
|
||||
using Infrastructure.Attribute;
|
||||
using Infrastructure.Enums;
|
||||
@@ -15,6 +12,9 @@ using ZR.Common;
|
||||
using ZR.Model.Dto;
|
||||
using ZR.Model.Models;
|
||||
using ZR.Service.System.IService;
|
||||
using ZR.Admin.WebApi.Hubs;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using Infrastructure.Constant;
|
||||
|
||||
namespace ZR.Admin.WebApi.Controllers.System
|
||||
{
|
||||
@@ -26,10 +26,28 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
/// 通知公告表接口
|
||||
/// </summary>
|
||||
private readonly ISysNoticeService _SysNoticeService;
|
||||
private readonly IHubContext<MessageHub> _hubContext;
|
||||
|
||||
public SysNoticeController(ISysNoticeService SysNoticeService)
|
||||
public SysNoticeController(ISysNoticeService SysNoticeService, IHubContext<MessageHub> hubContext)
|
||||
{
|
||||
_SysNoticeService = SysNoticeService;
|
||||
_hubContext = hubContext;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询通知公告表列表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("queryNotice")]
|
||||
public IActionResult QueryNotice([FromQuery] SysNoticeQueryDto parm)
|
||||
{
|
||||
//开始拼装查询条件
|
||||
var predicate = Expressionable.Create<SysNotice>();
|
||||
|
||||
//搜索条件查询语法参考Sqlsugar
|
||||
predicate = predicate.And(m => m.Status == "0");
|
||||
var response = _SysNoticeService.GetPages(predicate.ToExpression(), parm);
|
||||
return SUCCESS(response);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -47,6 +65,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.NoticeTitle), m => m.NoticeTitle.Contains(parm.NoticeTitle));
|
||||
predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.NoticeType), m => m.NoticeType == parm.NoticeType);
|
||||
predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.CreateBy), m => m.Create_by.Contains(parm.CreateBy) || m.Update_by.Contains(parm.CreateBy));
|
||||
predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.Status), m => m.Status == parm.Status);
|
||||
var response = _SysNoticeService.GetPages(predicate.ToExpression(), parm);
|
||||
return SUCCESS(response);
|
||||
}
|
||||
@@ -79,11 +98,11 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
throw new CustomException("请求参数错误");
|
||||
}
|
||||
//从 Dto 映射到 实体
|
||||
var model = parm.Adapt<SysNotice>().ToCreate(HttpContext);
|
||||
model.Create_by = User.Identity.Name;
|
||||
model.Create_time = DateTime.Now;
|
||||
var modal = parm.Adapt<SysNotice>().ToCreate(HttpContext);
|
||||
modal.Create_by = User.Identity.Name;
|
||||
modal.Create_time = DateTime.Now;
|
||||
|
||||
return SUCCESS(_SysNoticeService.Insert(model, it => new
|
||||
int result = _SysNoticeService.Insert(modal, it => new
|
||||
{
|
||||
it.NoticeTitle,
|
||||
it.NoticeType,
|
||||
@@ -92,7 +111,9 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
it.Remark,
|
||||
it.Create_by,
|
||||
it.Create_time
|
||||
}));
|
||||
});
|
||||
|
||||
return SUCCESS(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -125,6 +146,26 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
|
||||
return SUCCESS(response);
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送通知公告表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPut("send/{NoticeId}")]
|
||||
[ActionPermissionFilter(Permission = "system:notice:update")]
|
||||
[Log(Title = "通知公告表", BusinessType = BusinessType.OTHER)]
|
||||
public IActionResult SendNotice(int NoticeId = 0)
|
||||
{
|
||||
if (NoticeId <= 0)
|
||||
{
|
||||
throw new CustomException("请求实体不能为空");
|
||||
}
|
||||
var response = _SysNoticeService.GetFirst(x => x.NoticeId == NoticeId);
|
||||
if (response != null && response.Status == "0")
|
||||
{
|
||||
_hubContext.Clients.All.SendAsync(HubsConstant.ReceiveNotice, response.NoticeTitle, response.NoticeContent);
|
||||
}
|
||||
return SUCCESS(response);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除通知公告表
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPut]
|
||||
[ActionPermissionFilter(Permission = "system")]
|
||||
[ActionPermissionFilter(Permission = "common")]
|
||||
[Log(Title = "修改信息", BusinessType = BusinessType.UPDATE)]
|
||||
public IActionResult UpdateProfile([FromBody] SysUserDto userDto)
|
||||
{
|
||||
@@ -89,7 +89,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPut("updatePwd")]
|
||||
[ActionPermissionFilter(Permission = "system")]
|
||||
[ActionPermissionFilter(Permission = "common")]
|
||||
[Log(Title = "修改密码", BusinessType = BusinessType.UPDATE)]
|
||||
public IActionResult UpdatePwd(string oldPassword, string newPassword)
|
||||
{
|
||||
@@ -122,7 +122,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
/// <param name="formFile"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("Avatar")]
|
||||
[ActionPermissionFilter(Permission = "system")]
|
||||
[ActionPermissionFilter(Permission = "common")]
|
||||
[Log(Title = "修改头像", BusinessType = BusinessType.UPDATE, IsSaveRequestData = false)]
|
||||
public IActionResult Avatar([FromForm(Name = "picture")] IFormFile formFile)
|
||||
{
|
||||
@@ -133,7 +133,6 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
string fileExt = Path.GetExtension(formFile.FileName);
|
||||
string savePath = Path.Combine(hostEnvironment.WebRootPath, FileUtil.GetdirPath("uploads"));
|
||||
|
||||
Console.WriteLine(savePath);
|
||||
if (!Directory.Exists(savePath)) { Directory.CreateDirectory(savePath); }
|
||||
|
||||
string fileName = FileUtil.HashFileName() + fileExt;
|
||||
@@ -146,7 +145,6 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
string accessUrl = $"{OptionsSetting.Upload.UploadUrl}/{FileUtil.GetdirPath("uploads")}{fileName}";
|
||||
|
||||
UserService.UpdatePhoto(new SysUser() { Avatar = accessUrl, UserId = loginUser.UserId });
|
||||
logger.Info("修改头像:" + accessUrl);
|
||||
return SUCCESS(new { imgUrl = accessUrl });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
public IActionResult Remove(int userid = 0)
|
||||
{
|
||||
if (userid <= 0) { return ToResponse(ApiResult.Error(101, "请求参数错误")); }
|
||||
|
||||
if (userid == 1) return ToResponse(Infrastructure.ResultCode.FAIL, "不能删除管理员账号");
|
||||
int result = UserService.DeleteUser(userid);
|
||||
|
||||
return ToResponse(ToJson(result));
|
||||
|
||||
@@ -38,11 +38,11 @@ namespace ZR.Admin.WebApi.Controllers.monitor
|
||||
[HttpGet("list")]
|
||||
public IActionResult OperList([FromQuery] SysOperLogDto sysOperLog)
|
||||
{
|
||||
PagerInfo pagerInfo = new PagerInfo(sysOperLog.pageNum);
|
||||
PagerInfo pagerInfo = new(sysOperLog.pageNum, sysOperLog.PageSize);
|
||||
|
||||
var list = sysOperLogService.SelectOperLogList(sysOperLog, pagerInfo);
|
||||
|
||||
return ToResponse(ToJson(list.TotalNum, list), TIME_FORMAT_FULL_2);
|
||||
return SUCCESS(list, "MM/dd HH:mm");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -37,12 +37,12 @@ namespace ZR.Admin.WebApi.Extensions
|
||||
ConfigId = "0",
|
||||
ConnectionString = connStr,
|
||||
DbType = (IocDbType)dbType,
|
||||
IsAutoCloseConnection = true//自动释放
|
||||
IsAutoCloseConnection = true
|
||||
}, new IocConfig() {
|
||||
ConfigId = "1",
|
||||
ConnectionString = connStrBus,
|
||||
DbType = (IocDbType)dbType_bus,
|
||||
IsAutoCloseConnection = true//自动释放
|
||||
IsAutoCloseConnection = true
|
||||
}
|
||||
});
|
||||
//每次Sql执行前事件
|
||||
|
||||
@@ -34,21 +34,11 @@ namespace ZR.Admin.WebApi.Extensions
|
||||
if (types.GetProperty("Create_by") != null && context != null)
|
||||
{
|
||||
types.GetProperty("Create_by").SetValue(source, context.GetName(), null);
|
||||
|
||||
// types.GetProperty("CreateName").SetValue(source, userSession.UserName, null);
|
||||
}
|
||||
if (types.GetProperty("UserId") != null && context != null)
|
||||
{
|
||||
types.GetProperty("UserId").SetValue(source, context.GetUId(), null);
|
||||
}
|
||||
//if (types.GetProperty("UpdateID") != null)
|
||||
//{
|
||||
// types.GetProperty("UpdateID").SetValue(source, userSession.UserID, null);
|
||||
|
||||
// types.GetProperty("UpdateName").SetValue(source, userSession.UserName, null);
|
||||
//}
|
||||
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,8 +6,10 @@ using Microsoft.AspNetCore.Http;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using UAParser;
|
||||
@@ -161,6 +163,32 @@ namespace ZR.Admin.WebApi.Extensions
|
||||
});
|
||||
}).Wait();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 设置请求参数
|
||||
/// </summary>
|
||||
/// <param name="operLog"></param>
|
||||
/// <param name="context"></param>
|
||||
public static void GetRequestValue(this HttpContext context, SysOperLog operLog)
|
||||
{
|
||||
string reqMethod = operLog.requestMethod;
|
||||
string param;
|
||||
|
||||
if (HttpMethods.IsPost(reqMethod) || HttpMethods.IsPut(reqMethod))
|
||||
{
|
||||
context.Request.Body.Seek(0, SeekOrigin.Begin);
|
||||
using var reader = new StreamReader(context.Request.Body, Encoding.UTF8);
|
||||
//需要使用异步方式才能获取
|
||||
param = reader.ReadToEndAsync().Result;
|
||||
}
|
||||
else
|
||||
{
|
||||
param = context.Request.QueryString.Value.ToString();
|
||||
}
|
||||
operLog.operParam = param;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -34,8 +34,6 @@ namespace ZR.Admin.WebApi.Extensions
|
||||
{
|
||||
var _tasksQzService = (ISysTasksQzService)App.GetRequiredService(typeof(ISysTasksQzService));
|
||||
|
||||
//此写法不通过有待研究
|
||||
//var _tasksQzService2 = (ISysTasksQzService)services.GetRequiredService(typeof(SysTasksQzService));
|
||||
ITaskSchedulerServer _schedulerServer = App.GetRequiredService<ITaskSchedulerServer>();
|
||||
|
||||
var tasks = _tasksQzService.GetList(m => m.IsStart);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Infrastructure;
|
||||
using Infrastructure.Model;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using System.Collections.Generic;
|
||||
@@ -57,8 +58,8 @@ namespace ZR.Admin.WebApi.Filters
|
||||
HasPermi = perms.Exists(f => f.ToLower() == Permission.ToLower());
|
||||
}
|
||||
|
||||
bool isDemoMode = ConfigUtils.Instance.GetAppConfig("DemoMode", false);
|
||||
|
||||
bool isDemoMode = AppSettings.GetAppConfig("DemoMode", false);
|
||||
var url = context.HttpContext.Request.Path;
|
||||
//演示公开环境屏蔽权限
|
||||
string[] denyPerms = new string[] { "update", "add", "remove", "add", "edit", "delete", "import", "run", "start", "stop", "clear", "send", "export", "upload", "common" };
|
||||
if (isDemoMode && denyPerms.Any(f => Permission.ToLower().Contains(f)))
|
||||
@@ -67,8 +68,17 @@ namespace ZR.Admin.WebApi.Filters
|
||||
}
|
||||
if (!HasPermi && !Permission.Equals("common"))
|
||||
{
|
||||
logger.Info($"用户{info.UserName}没有权限访问{context.HttpContext.Request.Path},当前权限[{Permission}]");
|
||||
context.Result = new JsonResult(new { code = ResultCode.FORBIDDEN, msg = "你没有权限访问" });
|
||||
logger.Info($"用户{info.UserName}没有权限访问{url},当前权限[{Permission}]");
|
||||
JsonResult result = new(new ApiResult()
|
||||
{
|
||||
Code = (int)ResultCode.FORBIDDEN,
|
||||
Msg = $"你当前没有权限[{Permission}]访问,请联系管理员",
|
||||
Data = url
|
||||
})
|
||||
{
|
||||
ContentType = "application/json",
|
||||
};
|
||||
context.Result = result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,27 +1,43 @@
|
||||
using Infrastructure;
|
||||
using Infrastructure.Attribute;
|
||||
using Infrastructure.Model;
|
||||
using IPTools.Core;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using NLog;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using ZR.Admin.WebApi.Extensions;
|
||||
using ZR.Model.System;
|
||||
using ZR.Service.System.IService;
|
||||
|
||||
namespace ZR.Admin.WebApi.Filters
|
||||
{
|
||||
public class GlobalActionMonitor : Attribute, IActionFilter
|
||||
public class GlobalActionMonitor : ActionFilterAttribute
|
||||
{
|
||||
static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||
private ISysOperLogService OperLogService;
|
||||
public GlobalActionMonitor(ISysOperLogService operLogService)
|
||||
{
|
||||
OperLogService = operLogService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// OnActionExecuting是在Action执行之前运行的方法。
|
||||
/// Action请求前
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
public void OnActionExecuting(ActionExecutingContext context)
|
||||
/// <param name="next"></param>
|
||||
/// <returns></returns>
|
||||
public override Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
|
||||
{
|
||||
if (context.ModelState.IsValid) return;
|
||||
ApiResult response = new ApiResult();
|
||||
ApiResult response = new();
|
||||
response.Code = (int)ResultCode.PARAM_ERROR;
|
||||
|
||||
//var keys = context.ModelState.Keys;
|
||||
var values = context.ModelState.Values;
|
||||
foreach (var item in values)
|
||||
{
|
||||
@@ -29,7 +45,7 @@ namespace ZR.Admin.WebApi.Filters
|
||||
{
|
||||
if (err.ErrorMessage.Contains("JSON"))
|
||||
{
|
||||
return;
|
||||
return next();
|
||||
}
|
||||
if (!string.IsNullOrEmpty(response.Msg))
|
||||
{
|
||||
@@ -39,16 +55,94 @@ namespace ZR.Admin.WebApi.Filters
|
||||
response.Msg += err.ErrorMessage;
|
||||
}
|
||||
}
|
||||
logger.Info($"请求参数错误,{response.Msg}");
|
||||
context.Result = new JsonResult(response);
|
||||
if (!string.IsNullOrEmpty(response.Msg))
|
||||
{
|
||||
logger.Info($"请求参数错误,{response.Msg}");
|
||||
context.Result = new JsonResult(response);
|
||||
}
|
||||
return base.OnActionExecutionAsync(context, next);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// OnActionExecuted是在Action中的代码执行之后运行的方法。
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
public void OnActionExecuted(ActionExecutedContext context)
|
||||
public override void OnResultExecuted(ResultExecutedContext context)
|
||||
{
|
||||
if (context.ActionDescriptor is not ControllerActionDescriptor controllerActionDescriptor) return;
|
||||
|
||||
//获得注解信息
|
||||
LogAttribute logAttribute = GetLogAttribute(controllerActionDescriptor);
|
||||
if (logAttribute == null) return;
|
||||
|
||||
try
|
||||
{
|
||||
string method = context.HttpContext.Request.Method.ToUpper();
|
||||
// 获取当前的用户
|
||||
string userName = context.HttpContext.GetName();
|
||||
string jsonResult = string.Empty;
|
||||
if (context.Result is ContentResult result && result.ContentType == "application/json")
|
||||
{
|
||||
jsonResult = result.Content.Replace("\r\n", "").Trim();
|
||||
}
|
||||
if (context.Result is JsonResult result2)
|
||||
{
|
||||
jsonResult = result2.Value?.ToString();
|
||||
}
|
||||
//获取当前执行方法的类名
|
||||
//string className = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name;
|
||||
//获取当前成员的名称
|
||||
//string methodName = System.Reflection.MethodBase.GetCurrentMethod().Name;
|
||||
string controller = context.RouteData.Values["Controller"].ToString();
|
||||
string action = context.RouteData.Values["Action"].ToString();
|
||||
|
||||
string ip = HttpContextExtension.GetClientUserIp(context.HttpContext);
|
||||
var ip_info = IpTool.Search(ip);
|
||||
|
||||
SysOperLog sysOperLog = new()
|
||||
{
|
||||
status = 0,
|
||||
operName = userName,
|
||||
operIp = ip,
|
||||
operUrl = HttpContextExtension.GetRequestUrl(context.HttpContext),
|
||||
requestMethod = method,
|
||||
jsonResult = jsonResult,
|
||||
operLocation = ip_info.Province + " " + ip_info.City,
|
||||
method = controller + "." + action + "()",
|
||||
//Elapsed = _stopwatch.ElapsedMilliseconds,
|
||||
operTime = DateTime.Now
|
||||
};
|
||||
HttpContextExtension.GetRequestValue(context.HttpContext, sysOperLog);
|
||||
|
||||
if (logAttribute != null)
|
||||
{
|
||||
sysOperLog.title = logAttribute?.Title;
|
||||
sysOperLog.businessType = (int)logAttribute?.BusinessType;
|
||||
sysOperLog.operParam = logAttribute.IsSaveRequestData ? sysOperLog.operParam : "";
|
||||
sysOperLog.jsonResult = logAttribute.IsSaveResponseData ? sysOperLog.jsonResult : "";
|
||||
}
|
||||
|
||||
LogEventInfo ei = new(LogLevel.Info, "GlobalActionMonitor", "");
|
||||
|
||||
ei.Properties["jsonResult"] = !HttpMethods.IsGet(method) ? jsonResult : "";
|
||||
ei.Properties["requestParam"] = sysOperLog.operParam;
|
||||
ei.Properties["user"] = userName;
|
||||
logger.Log(ei);
|
||||
|
||||
OperLogService.InsertOperlog(sysOperLog);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Error(ex, $"记录操作日志出错了#{ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private LogAttribute GetLogAttribute(ControllerActionDescriptor controllerActionDescriptor)
|
||||
{
|
||||
var attribute = controllerActionDescriptor.MethodInfo.GetCustomAttributes(inherit: true)
|
||||
.FirstOrDefault(a => a.GetType().Equals(typeof(LogAttribute)));
|
||||
|
||||
return (LogAttribute)attribute;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,133 +0,0 @@
|
||||
using Infrastructure;
|
||||
using Infrastructure.Attribute;
|
||||
using IPTools.Core;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using NLog;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using ZR.Admin.WebApi.Extensions;
|
||||
using ZR.Model.System;
|
||||
using ZR.Service.System.IService;
|
||||
|
||||
namespace ZR.Admin.WebApi.Filters
|
||||
{
|
||||
/// <summary>
|
||||
/// 记录请求,输出日志
|
||||
/// </summary>
|
||||
public class LogActionFilter : ActionFilterAttribute
|
||||
{
|
||||
static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
/// <summary>
|
||||
/// OnActionExecuted是在Action中的代码执行之后运行的方法。
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
public override void OnResultExecuted(ResultExecutedContext context)
|
||||
{
|
||||
if (context.ActionDescriptor is not ControllerActionDescriptor controllerActionDescriptor) return;
|
||||
|
||||
//获得注解信息
|
||||
LogAttribute logAttribute = GetLogAttribute(controllerActionDescriptor);
|
||||
if (logAttribute == null) return;
|
||||
|
||||
try
|
||||
{
|
||||
string method = context.HttpContext.Request.Method.ToUpper();
|
||||
// 获取当前的用户
|
||||
string userName = context.HttpContext.GetName();
|
||||
string jsonResult = string.Empty;
|
||||
|
||||
if (context.Result is ContentResult result && result.ContentType == "application/json")
|
||||
{
|
||||
jsonResult = result.Content.Replace("\r\n", "").Trim();
|
||||
}
|
||||
//获取当前执行方法的类名
|
||||
//string className = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name;
|
||||
//获取当前成员的名称
|
||||
//string methodName = System.Reflection.MethodBase.GetCurrentMethod().Name;
|
||||
string controller = context.RouteData.Values["Controller"].ToString();
|
||||
string action = context.RouteData.Values["Action"].ToString();
|
||||
|
||||
string ip = HttpContextExtension.GetClientUserIp(context.HttpContext);
|
||||
var ip_info = IpTool.Search(ip);
|
||||
|
||||
SysOperLog sysOperLog = new SysOperLog
|
||||
{
|
||||
status = 0,
|
||||
operName = userName,
|
||||
operIp = ip,
|
||||
operUrl = HttpContextExtension.GetRequestUrl(context.HttpContext),
|
||||
requestMethod = method,
|
||||
jsonResult = jsonResult,
|
||||
operLocation = ip_info.Province + " " + ip_info.City,
|
||||
method = controller + "." + action + "()",
|
||||
//Elapsed = _stopwatch.ElapsedMilliseconds,
|
||||
operTime = DateTime.Now
|
||||
};
|
||||
GetRequestValue(sysOperLog, context.HttpContext);
|
||||
|
||||
if (logAttribute != null)
|
||||
{
|
||||
sysOperLog.title = logAttribute?.Title;
|
||||
sysOperLog.businessType = (int)logAttribute?.BusinessType;
|
||||
sysOperLog.operParam = logAttribute.IsSaveRequestData ? sysOperLog.operParam : "";
|
||||
sysOperLog.jsonResult = logAttribute.IsSaveResponseData ? sysOperLog.jsonResult : "";
|
||||
}
|
||||
var sysOperLogService = (ISysOperLogService)App.GetRequiredService(typeof(ISysOperLogService));
|
||||
|
||||
sysOperLogService.InsertOperlog(sysOperLog);
|
||||
|
||||
LogEventInfo ei = new(LogLevel.Info, "GlobalExceptionMiddleware", "");
|
||||
|
||||
ei.Properties["status"] = 0;
|
||||
ei.Properties["jsonResult"] = !HttpMethods.IsGet(method) ? jsonResult : "";
|
||||
ei.Properties["requestParam"] = sysOperLog.operParam;
|
||||
ei.Properties["user"] = userName;
|
||||
|
||||
logger.Log(ei);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Error(ex, $"记录操作日志出错了#{ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private LogAttribute GetLogAttribute(ControllerActionDescriptor controllerActionDescriptor)
|
||||
{
|
||||
var attribute = controllerActionDescriptor.MethodInfo.GetCustomAttributes(inherit: true)
|
||||
.FirstOrDefault(a => a.GetType().Equals(typeof(LogAttribute)));
|
||||
|
||||
return (LogAttribute)attribute;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置请求参数
|
||||
/// </summary>
|
||||
/// <param name="operLog"></param>
|
||||
/// <param name="context"></param>
|
||||
public static void GetRequestValue(SysOperLog operLog, HttpContext context)
|
||||
{
|
||||
string reqMethod = operLog.requestMethod;
|
||||
string param;
|
||||
|
||||
if (HttpMethods.IsPost(reqMethod) || HttpMethods.IsPut(reqMethod))
|
||||
{
|
||||
context.Request.Body.Seek(0, SeekOrigin.Begin);
|
||||
using var reader = new StreamReader(context.Request.Body, Encoding.UTF8);
|
||||
//需要使用异步方式才能获取
|
||||
param = reader.ReadToEndAsync().Result;
|
||||
}
|
||||
else
|
||||
{
|
||||
param = context.Request.QueryString.Value.ToString();
|
||||
}
|
||||
operLog.operParam = param;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,6 @@
|
||||
using Infrastructure;
|
||||
using Infrastructure.Model;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
@@ -22,9 +20,6 @@ namespace ZR.Admin.WebApi.Filters
|
||||
public class VerifyAttribute : Attribute, IAuthorizationFilter
|
||||
{
|
||||
static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||
//IWebHostEnvironment webHostEnvironment = (IWebHostEnvironment)App.ServiceProvider.GetService(typeof(IWebHostEnvironment));
|
||||
|
||||
//public VerifyAttribute() { }
|
||||
|
||||
/// <summary>
|
||||
/// 只判断token是否正确,不判断权限
|
||||
@@ -45,20 +40,15 @@ namespace ZR.Admin.WebApi.Filters
|
||||
string ip = HttpContextExtension.GetClientUserIp(context.HttpContext);
|
||||
string url = context.HttpContext.Request.Path;
|
||||
var isAuthed = context.HttpContext.User.Identity.IsAuthenticated;
|
||||
var userName = context.HttpContext.User.Identity.Name;
|
||||
|
||||
//使用jwt token校验2020-11-21
|
||||
LoginUser info = JwtUtil.GetLoginUser(context.HttpContext);
|
||||
|
||||
if (info != null && info.UserId > 0)
|
||||
if (info == null || !isAuthed)
|
||||
{
|
||||
logger.Info($"[{info.UserId}-{userName}-{ip}]用户登录校验成功");
|
||||
}
|
||||
else
|
||||
{
|
||||
string msg = $"请求访问:{url}授权认证失败,无法访问系统资源";
|
||||
logger.Info($"用户{userName}{msg}");
|
||||
|
||||
string msg = $"请求访问[{url}]失败,无法访问系统资源";
|
||||
logger.Info($"{msg}");
|
||||
|
||||
context.Result = new JsonResult(new ApiResult((int)ResultCode.DENY, msg));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
using IPTools.Core;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using UAParser;
|
||||
using ZR.Admin.WebApi.Extensions;
|
||||
using ZR.Model.System;
|
||||
|
||||
namespace ZR.Admin.WebApi.Framework
|
||||
{
|
||||
public class AsyncFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// 记录用户登陆信息
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="status"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
public static SysLogininfor RecordLogInfo(HttpContext context, string status, string message)
|
||||
{
|
||||
ClientInfo clientInfo = context.GetClientInfo();
|
||||
SysLogininfor sysLogininfor = new SysLogininfor();
|
||||
sysLogininfor.browser = clientInfo.Device.Family;
|
||||
sysLogininfor.os = clientInfo.OS.ToString();
|
||||
sysLogininfor.ipaddr = context.GetClientUserIp();
|
||||
sysLogininfor.msg = message;
|
||||
sysLogininfor.userName = context.GetName();
|
||||
sysLogininfor.status = status;
|
||||
var ip_info = IpTool.Search(sysLogininfor.ipaddr);
|
||||
sysLogininfor.loginLocation = ip_info.Province + "-" + ip_info.City;
|
||||
|
||||
return sysLogininfor;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -71,8 +71,9 @@ namespace ZR.Admin.WebApi.Framework
|
||||
/// <returns></returns>
|
||||
public static TokenValidationParameters ValidParameters()
|
||||
{
|
||||
JwtSettings jwtSettings = new JwtSettings();
|
||||
ConfigUtils.Instance.Bind("JwtSettings", jwtSettings);
|
||||
JwtSettings jwtSettings = new();
|
||||
AppSettings.Bind("JwtSettings", jwtSettings);
|
||||
|
||||
if (jwtSettings == null || jwtSettings.SecretKey.IsEmpty())
|
||||
{
|
||||
throw new Exception("JwtSettings获取失败");
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Infrastructure.Constant;
|
||||
using Infrastructure.Model;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using ZR.Model;
|
||||
using ZR.Service.System.IService;
|
||||
|
||||
namespace ZR.Admin.WebApi.Hubs
|
||||
{
|
||||
public class MessageHub : Hub
|
||||
{
|
||||
//创建用户集合,用于存储所有链接的用户数据
|
||||
private static readonly List<OnlineUsers> clientUsers = new();
|
||||
private readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
private ISysNoticeService SysNoticeService;
|
||||
|
||||
public MessageHub(ISysNoticeService noticeService)
|
||||
{
|
||||
SysNoticeService = noticeService;
|
||||
}
|
||||
|
||||
private ApiResult SendNotice()
|
||||
{
|
||||
var result = SysNoticeService.GetSysNotices();
|
||||
|
||||
return new ApiResult(200, "success", result);
|
||||
}
|
||||
|
||||
#region 客户端连接
|
||||
|
||||
/// <summary>
|
||||
/// 客户端连接的时候调用
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override Task OnConnectedAsync()
|
||||
{
|
||||
var name = Context.User.Identity.Name;
|
||||
|
||||
var user = clientUsers.Any(u => u.ConnnectionId == Context.ConnectionId);
|
||||
//判断用户是否存在,否则添加集合
|
||||
if (!user && Context.User.Identity.IsAuthenticated)
|
||||
{
|
||||
clientUsers.Add(new OnlineUsers(Context.ConnectionId, name));
|
||||
Console.WriteLine($"{DateTime.Now}:{name},{Context.ConnectionId}连接服务端success,当前已连接{clientUsers.Count}个");
|
||||
//Clients.All.SendAsync("welcome", $"欢迎您:{name},当前时间:{DateTime.Now}");
|
||||
Clients.All.SendAsync(HubsConstant.MoreNotice, SendNotice());
|
||||
}
|
||||
|
||||
Clients.All.SendAsync(HubsConstant.OnlineNum, clientUsers.Count);
|
||||
return base.OnConnectedAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 连接终止时调用。
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override Task OnDisconnectedAsync(Exception exception)
|
||||
{
|
||||
var user = clientUsers.Where(p => p.ConnnectionId == Context.ConnectionId).FirstOrDefault();
|
||||
//判断用户是否存在,否则添加集合
|
||||
if (user != null)
|
||||
{
|
||||
Console.WriteLine($"用户{user?.Name}离开了,当前已连接{clientUsers.Count}个");
|
||||
clientUsers.Remove(user);
|
||||
Clients.All.SendAsync(HubsConstant.OnlineNum, clientUsers.Count);
|
||||
}
|
||||
return base.OnDisconnectedAsync(exception);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace ZR.Model
|
||||
{
|
||||
public class OnlineUsers
|
||||
{
|
||||
/// <summary>
|
||||
/// 客户端连接Id
|
||||
/// </summary>
|
||||
public string ConnnectionId { get; set; }
|
||||
/// <summary>
|
||||
/// 用户id
|
||||
/// </summary>
|
||||
public int Userid { get; set; }
|
||||
public string Name { get; set; }
|
||||
public DateTime LoginTime { get; set; }
|
||||
|
||||
public OnlineUsers(string clientid, string name)
|
||||
{
|
||||
ConnnectionId = clientid;
|
||||
Name = name;
|
||||
LoginTime = DateTime.Now;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -84,7 +84,7 @@ namespace ZR.Admin.WebApi.Middleware
|
||||
operLocation = ip_info.Province + " " + ip_info.City,
|
||||
operTime = DateTime.Now
|
||||
};
|
||||
LogActionFilter.GetRequestValue(sysOperLog, context);
|
||||
HttpContextExtension.GetRequestValue(context, sysOperLog);
|
||||
LogEventInfo ei = new(logLevel, "GlobalExceptionMiddleware", error);
|
||||
|
||||
ei.Exception = ex;
|
||||
|
||||
+17
-13
@@ -3,44 +3,48 @@
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
|
||||
autoReload="true"
|
||||
internalLogLevel="Info"
|
||||
internalLogLevel="Info"
|
||||
internalLogFile="nlog-internal.log">
|
||||
|
||||
|
||||
<!--Nlog 文档参考地址:https://github.com/NLog/NLog/wiki/Getting-started-with-ASP.NET-Core-2-->
|
||||
<!--internalLogLevel Nlog内部日志记录为Off关闭。除非纠错,不可以设为Trace否则速度很慢,起码Debug以上-->
|
||||
<!--自定义变量-->
|
||||
<variable name="logDir" value="${basedir}/nlogs/${date:format=yyyyMMdd}/${level}.log"/>
|
||||
|
||||
|
||||
<!-- Load the ASP.NET Core plugin,enable asp.net core layout renderers-->
|
||||
<extensions>
|
||||
<add assembly="NLog.Web.AspNetCore" />
|
||||
</extensions>
|
||||
|
||||
|
||||
<!--define various log targets-->
|
||||
<targets async="true">
|
||||
<!--写入文件-->
|
||||
<!--滚动日志文件上限数,滚动日志文件数达到上限新的文件内容会覆盖旧文件内容 -->
|
||||
<!--archiveAboveSize每个日志文件大小的最大值(单位:字节),主日志文件超过大小超过该值时会将文件内容写入滚动日志并清空主日志文件内容-->
|
||||
<!--${basedir}表示当前应用程序域所在的根目录-->
|
||||
<target name="allfile" xsi:type="File"
|
||||
fileName="${basedir}/adminlogs/all.log"
|
||||
<target name="allfile" xsi:type="File"
|
||||
fileName="${basedir}/adminlogs/all.txt"
|
||||
archiveFileName="${basedir}/adminlogs/all.{###}.txt"
|
||||
archiveAboveSize="20000000"
|
||||
archiveEvery="Day"
|
||||
archiveNumbering="DateAndSequence"
|
||||
archiveAboveSize="20000000"
|
||||
maxArchiveFiles="30"
|
||||
keepFileOpen="false"
|
||||
layout="${longdate} | ${event-properties:item=EventId_Id} | ${uppercase:${level}} | ${logger} | ${aspnet-request-iP} | ${event-properties:item=user} | ${aspnet-request-url} | ${message} | ${event-properties:item=requestParam} | ${event-properties:item=jsonResult} | ${onexception:${exception:format=tostring}"/>
|
||||
|
||||
keepFileOpen="true"
|
||||
layout="${longdate} | ${event-properties:item=EventId_Id} | ${uppercase:${level}} | ${logger} | ${aspnet-request-iP:CheckForwardedForHeader=true} | ${event-properties:item=user} | ${aspnet-request-url} | ${message} | ${event-properties:item=requestParam} | ${event-properties:item=jsonResult} | ${onexception:${exception:format=tostring}"/>
|
||||
|
||||
<!--SQL-->
|
||||
<target name="sqlfile" xsi:type="File"
|
||||
fileName="${basedir}/adminlogs/all-sql.log"
|
||||
fileName="${basedir}/adminlogs/all-sql.txt"
|
||||
archiveFileName="${basedir}/adminlogs/all.sql{###}.txt"
|
||||
archiveEvery="Day"
|
||||
archiveNumbering="DateAndSequence"
|
||||
archiveAboveSize="20000000"
|
||||
maxArchiveFiles="30"
|
||||
keepFileOpen="false"
|
||||
layout="===========================================${newline} ${longdate} - ${aspnet-request-iP} - ${aspnet-request-headers:HeaderNames=userid} - ${aspnet-request-url} ${newline} ${message}"/>
|
||||
|
||||
<!--写入控制台-->
|
||||
<target name="console" xsi:type="ColoredConsole"
|
||||
<target name="console" xsi:type="ColoredConsole"
|
||||
layout="${date:format=MM-dd HH\:mm\:ss} | ${uppercase:${level}} | ${logger} | ${aspnet-request-iP} | ${aspnet-request-url} | ${message}"/>
|
||||
|
||||
<!--写入黑洞-->
|
||||
@@ -57,7 +61,7 @@
|
||||
<logger name="Quartz*" minlevel="Trace" maxlevel="Info" final="true" />
|
||||
<logger name="*" minLevel="Debug" writeTo="console"/>
|
||||
<logger name="ZR.Admin.WebApi.Extensions.DbExtension" final="true" writeTo="sqlfile"/>
|
||||
|
||||
|
||||
<logger name="*" minLevel="Trace" writeTo="allfile" />
|
||||
<!--Skip non-critical Microsoft logs and so log only own logs-->
|
||||
<logger name="Microsoft.*,Quartz.Core.QuartzSchedulerThread" maxlevel="Info" final="true" />
|
||||
|
||||
+28
-11
@@ -15,8 +15,8 @@ using System.Threading.Tasks;
|
||||
using ZR.Admin.WebApi.Extensions;
|
||||
using ZR.Admin.WebApi.Filters;
|
||||
using ZR.Admin.WebApi.Framework;
|
||||
using ZR.Admin.WebApi.Hubs;
|
||||
using ZR.Admin.WebApi.Middleware;
|
||||
using ZR.Common.Cache;
|
||||
|
||||
namespace ZR.Admin.WebApi
|
||||
{
|
||||
@@ -30,7 +30,7 @@ namespace ZR.Admin.WebApi
|
||||
public IConfiguration Configuration { get; }
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
string corsUrls = Configuration["sysConfig:cors"];
|
||||
string corsUrls = Configuration["corsUrls"];
|
||||
|
||||
//配置跨域
|
||||
services.AddCors(c =>
|
||||
@@ -43,8 +43,17 @@ namespace ZR.Admin.WebApi
|
||||
.AllowAnyMethod();//允许任意方法
|
||||
});
|
||||
});
|
||||
//注入SignalR实时通讯,默认用json传输
|
||||
services.AddSignalR(options =>
|
||||
{
|
||||
//客户端发保持连接请求到服务端最长间隔,默认30秒,改成4分钟,网页需跟着设置connection.keepAliveIntervalInMilliseconds = 12e4;即2分钟
|
||||
//options.ClientTimeoutInterval = TimeSpan.FromMinutes(4);
|
||||
//服务端发保持连接请求到客户端间隔,默认15秒,改成2分钟,网页需跟着设置connection.serverTimeoutInMilliseconds = 24e4;即4分钟
|
||||
//options.KeepAliveInterval = TimeSpan.FromMinutes(2);
|
||||
});
|
||||
//消除Error unprotecting the session cookie警告
|
||||
services.AddDataProtection().PersistKeysToFileSystem(new DirectoryInfo(Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + "DataProtection"));
|
||||
services.AddDataProtection()
|
||||
.PersistKeysToFileSystem(new DirectoryInfo(Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + "DataProtection"));
|
||||
//普通验证码
|
||||
services.AddHeiCaptcha();
|
||||
services.AddSession();
|
||||
@@ -53,7 +62,7 @@ namespace ZR.Admin.WebApi
|
||||
//绑定整个对象到Model上
|
||||
services.Configure<OptionsSetting>(Configuration);
|
||||
|
||||
//Cookie 认证
|
||||
//jwt 认证
|
||||
services.AddAuthentication(options =>
|
||||
{
|
||||
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||
@@ -68,7 +77,7 @@ namespace ZR.Admin.WebApi
|
||||
|
||||
services.AddMvc(options =>
|
||||
{
|
||||
options.Filters.Add(typeof(GlobalActionMonitor));//全局注册异常
|
||||
options.Filters.Add(typeof(GlobalActionMonitor));//全局注册
|
||||
})
|
||||
.AddJsonOptions(options =>
|
||||
{
|
||||
@@ -91,11 +100,15 @@ namespace ZR.Admin.WebApi
|
||||
app.Use((context, next) =>
|
||||
{
|
||||
context.Request.EnableBuffering();
|
||||
if (context.Request.Query.TryGetValue("access_token", out var token))
|
||||
{
|
||||
context.Request.Headers.Add("Authorization", $"Bearer {token}");
|
||||
}
|
||||
return next();
|
||||
});
|
||||
//开启访问静态文件/wwwroot目录文件,要放在UseRouting前面
|
||||
app.UseStaticFiles();
|
||||
|
||||
//开启路由访问
|
||||
app.UseRouting();
|
||||
app.UseCors("Policy");//要放在app.UseEndpoints前。
|
||||
|
||||
@@ -106,16 +119,20 @@ namespace ZR.Admin.WebApi
|
||||
app.UseAuthentication();
|
||||
//2.再开启授权
|
||||
app.UseAuthorization();
|
||||
//开启session
|
||||
app.UseSession();
|
||||
//开启缓存
|
||||
app.UseResponseCaching();
|
||||
|
||||
// 恢复/启动任务
|
||||
//恢复/启动任务
|
||||
app.UseAddTaskSchedulers();
|
||||
|
||||
//使用全局异常中间件
|
||||
app.UseMiddleware<GlobalExceptionMiddleware>();
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
//设置socket连接
|
||||
endpoints.MapHub<MessageHub>("/msgHub");
|
||||
|
||||
endpoints.MapControllerRoute(
|
||||
name: "default",
|
||||
pattern: "{controller=Home}/{action=Index}/{id?}");
|
||||
@@ -130,12 +147,12 @@ namespace ZR.Admin.WebApi
|
||||
private void InjectServices(IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
services.AddAppService();
|
||||
|
||||
services.AddSingleton(new AppSettings(configuration));
|
||||
//开启计划任务
|
||||
services.AddTaskSchedulers();
|
||||
//初始化db
|
||||
DbExtension.AddDb(configuration);
|
||||
|
||||
|
||||
//注册REDIS 服务
|
||||
Task.Run(() =>
|
||||
{
|
||||
|
||||
@@ -22,20 +22,20 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="EPPlus" Version="5.8.3" />
|
||||
<PackageReference Include="EPPlus" Version="5.8.6" />
|
||||
<PackageReference Include="Hei.Captcha" Version="0.3.0" />
|
||||
<PackageReference Include="IPTools.China" Version="1.6.0" />
|
||||
<PackageReference Include="CSRedisCore" Version="3.6.5" />
|
||||
<PackageReference Include="Mapster" Version="7.0.1" />
|
||||
<PackageReference Include="CSRedisCore" Version="3.6.9" />
|
||||
<PackageReference Include="Mapster" Version="7.3.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="5.0.0" NoWarn="NU1605" />
|
||||
<PackageReference Include="NETCore.Encrypt" Version="2.0.9" />
|
||||
<PackageReference Include="NLog" Version="4.7.5" />
|
||||
<PackageReference Include="NLog.Web.AspNetCore" Version="4.9.3" />
|
||||
<PackageReference Include="NETCore.Encrypt" Version="2.1.0" />
|
||||
<PackageReference Include="NLog" Version="4.7.14" />
|
||||
<PackageReference Include="NLog.Web.AspNetCore" Version="4.14.0" />
|
||||
<PackageReference Include="Snowflake.Core" Version="2.0.0" />
|
||||
<PackageReference Include="SqlSugar.IOC" Version="1.7.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.1.4" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="7.0.2" />
|
||||
<PackageReference Include="UAParser" Version="3.1.46" />
|
||||
<PackageReference Include="UAParser" Version="3.1.47" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -13,10 +13,7 @@
|
||||
"conn_zrAdmin_type": 1, //MySql = 0, SqlServer = 1
|
||||
"conn_bus_type": 1,
|
||||
"urls": "http://localhost:8888", //项目启动url
|
||||
"sysConfig": {
|
||||
"DBCommandTimeout": 10,
|
||||
"cors": "http://localhost:8887" //跨域地址(前端启动项目,前后端分离单独部署需要设置),多个用","隔开
|
||||
},
|
||||
"corsUrls": "http://localhost:8887", //跨域地址(前端启动项目,前后端分离单独部署需要设置),多个用","隔开
|
||||
"JwtSettings": {
|
||||
"Issuer": "ZRAdmin.NET",
|
||||
"Audience": "ZRAdmin.NET",
|
||||
@@ -26,7 +23,6 @@
|
||||
"DemoMode": false, //是否演示模式
|
||||
"DbKey": "", //数据库加密key
|
||||
"Upload": {
|
||||
"UploadDirectory": "/",
|
||||
"UploadUrl": "http://localhost:8888"
|
||||
},
|
||||
//阿里云存储配置
|
||||
|
||||
@@ -21,7 +21,7 @@ $if(column.HtmlType == "customInput" && column.IsPk == false)
|
||||
</template>
|
||||
</el-table-column>
|
||||
$elseif(column.HtmlType == "imageUpload")
|
||||
<el-table-column prop="${columnName}" align="center" label="${labelName}">
|
||||
<el-table-column prop="${columnName}" label="${labelName}" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-image class="table-td-thumb" fit="contain" :src="scope.row.${columnName}" :preview-src-list="[scope.row.${columnName}]">
|
||||
<div slot="error"><i class="el-icon-document" /></div>
|
||||
@@ -29,7 +29,7 @@ $elseif(column.HtmlType == "imageUpload")
|
||||
</template>
|
||||
</el-table-column>
|
||||
$elseif(column.HtmlType == "checkbox" || column.HtmlType == "select" || column.HtmlType == "radio")
|
||||
<el-table-column label="${labelName}" align="center" prop="${columnName}">
|
||||
<el-table-column prop="${columnName}" label="${labelName}" align="center">
|
||||
<template slot-scope="scope">
|
||||
$if(column.HtmlType == "checkbox")
|
||||
<dict-tag :options="${columnName}Options" :value="scope.row.${columnName} ? scope.row.${columnName}.split(',') : []" />
|
||||
|
||||
@@ -95,9 +95,9 @@ $if(replaceDto.ShowBtnAdd)
|
||||
throw new CustomException("请求参数错误");
|
||||
}
|
||||
//从 Dto 映射到 实体
|
||||
var model = parm.Adapt<${replaceDto.ModelTypeName}>().ToCreate(HttpContext);
|
||||
var modal = parm.Adapt<${replaceDto.ModelTypeName}>().ToCreate(HttpContext);
|
||||
|
||||
var response = _${replaceDto.ModelTypeName}Service.Insert(model, it => new
|
||||
var response = _${replaceDto.ModelTypeName}Service.Insert(modal, it => new
|
||||
{
|
||||
$foreach(item in genTable.Columns)
|
||||
$if((item.IsInsert))
|
||||
@@ -124,14 +124,14 @@ $if(replaceDto.ShowBtnEdit)
|
||||
throw new CustomException("请求实体不能为空");
|
||||
}
|
||||
//从 Dto 映射到 实体
|
||||
var model = parm.Adapt<${replaceDto.ModelTypeName}>().ToUpdate(HttpContext);
|
||||
var modal = parm.Adapt<${replaceDto.ModelTypeName}>().ToUpdate(HttpContext);
|
||||
|
||||
var response = _${replaceDto.ModelTypeName}Service.Update(w => w.${replaceDto.PKName} == model.${replaceDto.PKName}, it => new ${replaceDto.ModelTypeName}()
|
||||
var response = _${replaceDto.ModelTypeName}Service.Update(w => w.${replaceDto.PKName} == modal.${replaceDto.PKName}, it => new ${replaceDto.ModelTypeName}()
|
||||
{
|
||||
//Update 字段映射
|
||||
$foreach(item in genTable.Columns)
|
||||
$if((item.IsEdit))
|
||||
$item.CsharpField = model.$item.CsharpField,
|
||||
$item.CsharpField = modal.$item.CsharpField,
|
||||
$end
|
||||
${end}
|
||||
});
|
||||
|
||||
@@ -11,15 +11,21 @@
|
||||
</el-form>
|
||||
<!-- 工具区域 -->
|
||||
<el-row :gutter="10" class="mb8">
|
||||
$if(replaceDto.ShowBtnAdd)
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" v-hasPermi="['${replaceDto.PermissionPrefix}:add']" plain icon="el-icon-plus" size="mini" @click="handleAdd">新增</el-button>
|
||||
</el-col>
|
||||
$end
|
||||
$if(replaceDto.ShowBtnEdit)
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" :disabled="single" v-hasPermi="['${replaceDto.PermissionPrefix}:edit']" plain icon="el-icon-edit" size="mini" @click="handleUpdate">修改</el-button>
|
||||
</el-col>
|
||||
$end
|
||||
$if(replaceDto.ShowBtnDelete)
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" :disabled="multiple" v-hasPermi="['${replaceDto.PermissionPrefix}:delete']" plain icon="el-icon-delete" size="mini" @click="handleDelete">删除</el-button>
|
||||
</el-col>
|
||||
$end
|
||||
$if(replaceDto.ShowBtnExport)
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" v-hasPermi="['${replaceDto.PermissionPrefix}:export']">导出</el-button>
|
||||
@@ -34,10 +40,14 @@ $end
|
||||
${VueViewListContent}
|
||||
<el-table-column label="操作" align="center" width="140">
|
||||
<template slot-scope="scope">
|
||||
$if(replaceDto.ShowBtnEdit)
|
||||
<el-button size="mini" v-hasPermi="['${replaceDto.PermissionPrefix}:edit']" type="success" icon="el-icon-edit" title="编辑"
|
||||
@click="handleUpdate(scope.row)"></el-button>
|
||||
$end
|
||||
$if(replaceDto.ShowBtnDelete)
|
||||
<el-button size="mini" v-hasPermi="['${replaceDto.PermissionPrefix}:delete']" type="danger" icon="el-icon-delete" title="删除"
|
||||
@click="handleDelete(scope.row)"></el-button>
|
||||
$end
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -118,7 +128,7 @@ $end
|
||||
],
|
||||
$foreach(item in genTable.Columns)
|
||||
$if((item.HtmlType == "radio" || item.HtmlType == "select" || item.HtmlType == "checkbox"))
|
||||
// ${item.ColumnComment}选项列表
|
||||
// ${item.ColumnComment}选项列表 格式 eg:{ dictLabel: '标签', dictValue: '0'}
|
||||
${item.CsharpFieldFl}Options: [],
|
||||
$elseif(item.HtmlType == "datetime" && item.IsQuery == true)
|
||||
//${item.ColumnComment}时间范围
|
||||
|
||||
@@ -11,9 +11,6 @@
|
||||
</el-form>
|
||||
<!-- 工具区域 -->
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" :disabled="multiple" v-hasPermi="['${replaceDto.PermissionPrefix}:delete']" plain icon="el-icon-delete" size="mini" @click="handleDelete">删除</el-button>
|
||||
</el-col>
|
||||
$if(replaceDto.ShowBtnExport)
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" v-hasPermi="['${replaceDto.PermissionPrefix}:export']">导出</el-button>
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace ZR.CodeGenerator
|
||||
InitJntTemplate(dto, replaceDto);
|
||||
replaceDto.VueViewListHtml = GenerateVueTableList();
|
||||
replaceDto.VueQueryFormHtml = GenerateVueQueryForm();
|
||||
|
||||
|
||||
GenerateModels(replaceDto, dto);
|
||||
GenerateInputDto(replaceDto, dto);
|
||||
GenerateRepository(replaceDto, dto);
|
||||
@@ -277,8 +277,8 @@ namespace ZR.CodeGenerator
|
||||
/// <returns></returns>
|
||||
public static string GetClassName(string tableName)
|
||||
{
|
||||
bool autoRemovePre = ConfigUtils.Instance.GetAppConfig(GenConstants.Gen_autoPre, false);
|
||||
string tablePrefix = ConfigUtils.Instance.GetAppConfig<string>(GenConstants.Gen_tablePrefix);
|
||||
bool autoRemovePre = AppSettings.GetAppConfig(GenConstants.Gen_autoPre, false);
|
||||
string tablePrefix = AppSettings.GetAppConfig<string>(GenConstants.Gen_tablePrefix);
|
||||
|
||||
if (!string.IsNullOrEmpty(tablePrefix) && autoRemovePre)
|
||||
{
|
||||
@@ -364,7 +364,7 @@ namespace ZR.CodeGenerator
|
||||
ModuleName = "business",//导入默认模块名
|
||||
ClassName = GetClassName(tableName).FirstUpperCase(),
|
||||
BusinessName = tableName.UnderScoreToCamelCase().FirstUpperCase(),
|
||||
FunctionAuthor = ConfigUtils.Instance.GetConfig(GenConstants.Gen_author),
|
||||
FunctionAuthor = AppSettings.GetConfig(GenConstants.Gen_author),
|
||||
TableName = tableName,
|
||||
TableComment = desc,
|
||||
FunctionName = desc,
|
||||
|
||||
@@ -23,8 +23,8 @@ namespace ZR.CodeGenerator
|
||||
/// <returns></returns>
|
||||
public SqlSugarClient GetSugarDbContext(string dbName = "")
|
||||
{
|
||||
string connStr = ConfigUtils.Instance.GetConfig(GenConstants.Gen_conn);
|
||||
int dbType = ConfigUtils.Instance.GetAppConfig(GenConstants.Gen_conn_dbType, 0);
|
||||
string connStr = AppSettings.GetConfig(GenConstants.Gen_conn);
|
||||
int dbType = AppSettings.GetAppConfig(GenConstants.Gen_conn_dbType, 0);
|
||||
|
||||
if (!string.IsNullOrEmpty(dbName))
|
||||
{
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="JinianNet.JNTemplate" Version="2.2.4" />
|
||||
<PackageReference Include="JinianNet.JNTemplate" Version="2.2.5" />
|
||||
<PackageReference Include="SqlSugarCoreNoDrive" Version="5.0.5.4" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -8,10 +8,10 @@ namespace ZR.Common
|
||||
{
|
||||
public class AliyunOssHelper
|
||||
{
|
||||
static string accessKeyId = ConfigUtils.Instance.GetConfig("ALIYUN_OSS:KEY");
|
||||
static string accessKeySecret = ConfigUtils.Instance.GetConfig("ALIYUN_OSS:SECRET");
|
||||
static string endpoint = ConfigUtils.Instance.GetConfig("ALIYUN_OSS:REGIONID");
|
||||
static string bucketName1 = ConfigUtils.Instance.GetConfig("ALIYUN_OSS:bucketName");
|
||||
static string accessKeyId = AppSettings.GetConfig("ALIYUN_OSS:KEY");
|
||||
static string accessKeySecret = AppSettings.GetConfig("ALIYUN_OSS:SECRET");
|
||||
static string endpoint = AppSettings.GetConfig("ALIYUN_OSS:REGIONID");
|
||||
static string bucketName1 = AppSettings.GetConfig("ALIYUN_OSS:bucketName");
|
||||
|
||||
/// <summary>
|
||||
/// 上传到阿里云
|
||||
@@ -21,7 +21,7 @@ namespace ZR.Common
|
||||
/// <param name="bucketName">存储桶 如果为空默认取配置文件</param>
|
||||
public static System.Net.HttpStatusCode PutObjectFromFile(Stream filestreams, string dirPath, string bucketName = "")
|
||||
{
|
||||
OssClient client = new OssClient(endpoint, accessKeyId, accessKeySecret);
|
||||
OssClient client = new(endpoint, accessKeyId, accessKeySecret);
|
||||
if (string.IsNullOrEmpty(bucketName)) { bucketName = bucketName1; }
|
||||
try
|
||||
{
|
||||
|
||||
@@ -10,8 +10,8 @@ namespace ZR.Common.Cache
|
||||
|
||||
public static void Initalize()
|
||||
{
|
||||
Cache = new CSRedisClient(ConfigUtils.Instance.GetConfig("RedisServer:Cache"));
|
||||
Session = new CSRedisClient(ConfigUtils.Instance.GetConfig("RedisServer:Session"));
|
||||
Cache = new CSRedisClient(AppSettings.GetConfig("RedisServer:Cache"));
|
||||
Session = new CSRedisClient(AppSettings.GetConfig("RedisServer:Session"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace ZR.Common
|
||||
|
||||
public MailHelper()
|
||||
{
|
||||
ConfigUtils.Instance.Bind("MailOptions", mailOptions);
|
||||
AppSettings.Bind("MailOptions", mailOptions);
|
||||
FromEmail = mailOptions.From;
|
||||
Smtp = mailOptions.Smtp;
|
||||
FromPwd = mailOptions.Password;
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.13.0" />
|
||||
<PackageReference Include="CSRedisCore" Version="3.6.5" />
|
||||
<PackageReference Include="EPPlus" Version="5.8.3" />
|
||||
<PackageReference Include="MailKit" Version="3.0.0" />
|
||||
<PackageReference Include="CSRedisCore" Version="3.6.9" />
|
||||
<PackageReference Include="EPPlus" Version="5.8.6" />
|
||||
<PackageReference Include="MailKit" Version="3.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace ZR.Model.System.Dto
|
||||
/// </summary>
|
||||
public class SysFileDto
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public long Id { get; set; }
|
||||
public string FileName { get; set; }
|
||||
public string FileUrl { get; set; }
|
||||
public string StorePath { get; set; }
|
||||
@@ -25,6 +25,6 @@ namespace ZR.Model.System.Dto
|
||||
public DateTime? BeginCreate_time { get; set; }
|
||||
public DateTime? EndCreate_time { get; set; }
|
||||
public int? StoreType { get; set; }
|
||||
public int? FileId { get; set; }
|
||||
public long? FileId { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,5 +28,6 @@ namespace ZR.Model.Dto
|
||||
public string NoticeTitle { get; set; }
|
||||
public string NoticeType { get; set; }
|
||||
public string CreateBy { get; set; }
|
||||
public string Status { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace ZR.Model.System.Dto
|
||||
/// 页码
|
||||
/// </summary>
|
||||
public int pageNum { get; set; }
|
||||
public int PageSize { get; set; }
|
||||
/// <summary>
|
||||
/// 操作人员
|
||||
/// </summary>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using SqlSugar;
|
||||
using Newtonsoft.Json;
|
||||
using SqlSugar;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
@@ -13,7 +14,8 @@ namespace ZR.Model.System
|
||||
/// 描述 : 自增id
|
||||
/// 空值 : false
|
||||
/// </summary>
|
||||
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
|
||||
[JsonConverter(typeof(ValueToStringConverter))]
|
||||
[SugarColumn(IsPrimaryKey = true)]
|
||||
public long Id { get; set; }
|
||||
/// <summary>
|
||||
/// 文件真实名
|
||||
|
||||
@@ -69,16 +69,16 @@ namespace ZR.Model.System
|
||||
//@Excel(name = "状态", readConverterExp = "0=正常,1=异常")
|
||||
public int status { get; set; }
|
||||
|
||||
/** 错误消息 */
|
||||
//@Excel(name = "错误消息")
|
||||
/// <summary>
|
||||
/// 错误消息
|
||||
/// </summary>
|
||||
[EpplusTableColumn(Header = "错误消息")]
|
||||
public string errorMsg { get; set; }
|
||||
|
||||
/** 操作时间 */
|
||||
//@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
//@Excel(name = "操作时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
|
||||
//[DataType]
|
||||
[JsonConverter(typeof(JsonDateConverter))]
|
||||
[EpplusTableColumn(NumberFormat = "yyyy-MM-dd HH:mm:ss")]
|
||||
/// <summary>
|
||||
/// 操作时间
|
||||
/// </summary>
|
||||
[EpplusTableColumn(Header = "操作时间", NumberFormat = "yyyy-MM-dd HH:mm:ss")]
|
||||
public DateTime? operTime { get; set; }
|
||||
/// <summary>
|
||||
/// 操作用时
|
||||
|
||||
@@ -21,9 +21,7 @@ namespace ZR.Model.System
|
||||
public long UserId { get; set; }
|
||||
//[Duplication]//校验模板类该列数据是否重复
|
||||
public string UserName { get; set; }
|
||||
|
||||
public string NickName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// '用户类型(00系统用户)',
|
||||
/// </summary>
|
||||
@@ -32,16 +30,15 @@ namespace ZR.Model.System
|
||||
[SugarColumn(IsOnlyIgnoreInsert = true)]
|
||||
[EpplusIgnore]
|
||||
public string Avatar { get; set; }
|
||||
|
||||
public string Email { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
[EpplusIgnore]
|
||||
public string Password { get; set; }
|
||||
|
||||
//[ColName("手机号")]
|
||||
/// <summary>
|
||||
/// 手机号
|
||||
/// </summary>
|
||||
public string Phonenumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户性别(0男 1女 2未知)
|
||||
/// </summary>
|
||||
@@ -76,7 +73,7 @@ namespace ZR.Model.System
|
||||
/// 部门Id
|
||||
/// </summary>
|
||||
public long DeptId { get; set; }
|
||||
|
||||
|
||||
#region 表额外字段
|
||||
public bool IsAdmin()
|
||||
{
|
||||
@@ -110,6 +107,37 @@ namespace ZR.Model.System
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
[EpplusIgnore]
|
||||
public List<SysRole> Roles { get; set; }
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public string WelcomeMessage
|
||||
{
|
||||
get
|
||||
{
|
||||
int now = DateTime.Now.Hour;
|
||||
|
||||
if (now > 0 && now <= 6)
|
||||
{
|
||||
return "午夜好";
|
||||
}
|
||||
else if (now > 6 && now <= 11)
|
||||
{
|
||||
return "早上好";
|
||||
}
|
||||
else if (now > 11 && now <= 14)
|
||||
{
|
||||
return "中午好";
|
||||
}
|
||||
else if (now > 14 && now <= 18)
|
||||
{
|
||||
return "下午好";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "晚上好";
|
||||
}
|
||||
}
|
||||
}
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public string WelcomeContent { get; set; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="EPPlus" Version="5.8.3" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
<PackageReference Include="EPPlus" Version="5.8.6" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="SqlSugarCoreNoDrive" Version="5.0.5.4" />
|
||||
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -107,12 +107,13 @@ namespace ZR.Repository.System
|
||||
public List<SysMenu> SelectMenuTreeByRoleIds(List<long> roleIds)
|
||||
{
|
||||
var menuTypes = new string[] { "M", "C" };
|
||||
return Context.Queryable<SysMenu, SysRoleMenu>((menu, roleMenu) => new JoinQueryInfos(
|
||||
JoinType.Left, menu.menuId == roleMenu.Menu_id
|
||||
))
|
||||
.Where((menu, roleMenu) => roleIds.Contains(roleMenu.Role_id) && menuTypes.Contains(menu.menuType) && menu.status == "0")
|
||||
.OrderBy((menu, roleMenu) => new { menu.parentId, menu.orderNum })
|
||||
.Select((menu, roleMenu) => menu).ToList();
|
||||
return Context.Queryable<SysMenu>()
|
||||
.Where((menu) =>
|
||||
menuTypes.Contains(menu.menuType)
|
||||
&& menu.status == "0"
|
||||
&& SqlFunc.Subqueryable<SysRoleMenu>().Where( s => roleIds.Contains(s.Role_id) && s.Menu_id == menu.menuId).Any())
|
||||
.OrderBy((menu) => new { menu.parentId, menu.orderNum })
|
||||
.Select((menu) => menu).ToList();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -111,7 +111,7 @@ namespace ZR.Repository.System
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除用户
|
||||
/// 删除用户(软删除)
|
||||
/// </summary>
|
||||
/// <param name="userid">用户id</param>
|
||||
/// <returns></returns>
|
||||
@@ -125,26 +125,25 @@ namespace ZR.Repository.System
|
||||
/// <summary>
|
||||
/// 修改用户信息
|
||||
/// </summary>
|
||||
/// <param name="sysUser"></param>
|
||||
/// <param name="user"></param>
|
||||
/// <returns></returns>
|
||||
public int UpdateUser(SysUser user)
|
||||
{
|
||||
return Context.Updateable(user)
|
||||
//.SetColumns(t => new SysUser()
|
||||
//{
|
||||
// UserName = user.UserName,
|
||||
// Status = user.Status,
|
||||
// NickName = user.NickName,
|
||||
// Remark = user.Remark,
|
||||
// Email = user.Email,
|
||||
// Update_by = user.Update_by,
|
||||
// Phonenumber = user.Phonenumber,
|
||||
// Update_time = DateTime.Now,
|
||||
// Sex = user.Sex,
|
||||
// DeptId = user.DeptId
|
||||
//})
|
||||
.UpdateColumns(t => new
|
||||
{
|
||||
t.NickName,
|
||||
t.Email,
|
||||
t.Phonenumber,
|
||||
t.DeptId,
|
||||
t.Status,
|
||||
t.Sex,
|
||||
t.PostIds,
|
||||
t.Remark,
|
||||
t.Update_by,
|
||||
t.Update_time
|
||||
})
|
||||
.IgnoreColumns(ignoreAllNullColumns: true)//忽略所有为null
|
||||
.IgnoreColumns(it => new { it.Password, it.Avatar })
|
||||
.Where(f => f.UserId == user.UserId).ExecuteCommand();
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Options" Version="5.0.0" />
|
||||
<PackageReference Include="MySql.Data" Version="8.0.25" />
|
||||
<PackageReference Include="NETCore.Encrypt" Version="2.0.9" />
|
||||
<PackageReference Include="NETCore.Encrypt" Version="2.1.0" />
|
||||
<PackageReference Include="SqlSugar.IOC" Version="1.7.0" />
|
||||
<PackageReference Include="SqlSugarCoreNoDrive" Version="5.0.5.4" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace ZR.Service.System.IService
|
||||
/// <param name="formFile"></param>
|
||||
/// <returns>结果、地址、文件名</returns>
|
||||
(bool, string, string) SaveFile(string picdir, IFormFile formFile);
|
||||
(bool, string, string) SaveFile(string picdir, IFormFile formFile, string customFileName);
|
||||
(bool, string, string) SaveFile(string picdir, IFormFile formFile, string customFileName, string bucketName);
|
||||
/// <summary>
|
||||
/// 按时间来创建文件夹
|
||||
/// </summary>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using ZR.Model.Models;
|
||||
|
||||
namespace ZR.Service.System.IService
|
||||
@@ -11,5 +12,6 @@ namespace ZR.Service.System.IService
|
||||
/// </summary>
|
||||
public interface ISysNoticeService: IBaseService<SysNotice>
|
||||
{
|
||||
List<SysNotice> GetSysNotices();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace ZR.Service.System
|
||||
foreach (var dictId in dictIds)
|
||||
{
|
||||
SysDictType dictType = DictRepository.GetFirst(x => x.DictId == dictId);
|
||||
if (DictRepository.Count(f => f.DictType == dictType.DictType) > 0)
|
||||
if (DictDataRepository.Count(f => f.DictType == dictType.DictType) > 0)
|
||||
{
|
||||
throw new CustomException($"{dictType.DictName}已分配,不能删除");
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ using System.Net;
|
||||
using ZR.Model.System;
|
||||
using ZR.Repository.System;
|
||||
using Infrastructure.Extensions;
|
||||
using SqlSugar.DistributedSystem.Snowflake;
|
||||
|
||||
namespace ZR.Service.System
|
||||
{
|
||||
@@ -20,7 +21,7 @@ namespace ZR.Service.System
|
||||
[AppService(ServiceType = typeof(ISysFileService), ServiceLifetime = LifeTime.Transient)]
|
||||
public class SysFileService : BaseService<SysFile>, ISysFileService
|
||||
{
|
||||
private string domainUrl = ConfigUtils.Instance.GetConfig("ALIYUN_OSS:domainUrl");
|
||||
private string domainUrl = AppSettings.GetConfig("ALIYUN_OSS:domainUrl");
|
||||
private readonly SysFileRepository SysFileRepository;
|
||||
|
||||
public SysFileService(SysFileRepository repository) : base(repository)
|
||||
@@ -36,18 +37,28 @@ namespace ZR.Service.System
|
||||
/// <returns></returns>
|
||||
public (bool, string, string) SaveFile(string picdir, IFormFile formFile)
|
||||
{
|
||||
return SaveFile(picdir, formFile, "");
|
||||
return SaveFile(picdir, formFile, "", "");
|
||||
}
|
||||
public (bool, string, string) SaveFile(string picdir, IFormFile formFile, string customFileName)
|
||||
|
||||
/// <summary>
|
||||
/// 存储文件
|
||||
/// </summary>
|
||||
/// <param name="picdir">文件夹</param>
|
||||
/// <param name="formFile"></param>
|
||||
/// <param name="customFileName">自定义文件名</param>
|
||||
/// <param name="bucketName">存储桶</param>
|
||||
/// <returns></returns>
|
||||
public (bool, string, string) SaveFile(string picdir, IFormFile formFile, string customFileName, string bucketName)
|
||||
{
|
||||
// eg: uploads/2020/08/18
|
||||
string dir = GetdirPath(picdir.ToString());
|
||||
//string dir = GetdirPath(picdir.ToString());
|
||||
|
||||
string tempName = customFileName.IsEmpty() ? HashFileName() : customFileName;
|
||||
string fileExt = Path.GetExtension(formFile.FileName);
|
||||
string fileName = $"{tempName}{fileExt}";
|
||||
string webUrl = $"{domainUrl}/{dir}/{fileName}";
|
||||
string fileName = tempName + fileExt;
|
||||
string webUrl = string.Concat(domainUrl, "/", picdir, "/", fileName);
|
||||
|
||||
HttpStatusCode statusCode = AliyunOssHelper.PutObjectFromFile(formFile.OpenReadStream(), Path.Combine(dir, fileName));
|
||||
HttpStatusCode statusCode = AliyunOssHelper.PutObjectFromFile(formFile.OpenReadStream(), Path.Combine(picdir, fileName), bucketName);
|
||||
|
||||
return (statusCode == HttpStatusCode.OK, webUrl, fileName);
|
||||
}
|
||||
@@ -81,13 +92,13 @@ namespace ZR.Service.System
|
||||
{
|
||||
try
|
||||
{
|
||||
return InsertReturnBigIdentity(file);
|
||||
return Insertable(file).ExecuteReturnSnowflakeId();//单条插入返回雪花ID;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("存储图片失败" + ex.Message);
|
||||
throw new Exception(ex.Message);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using Infrastructure;
|
||||
using Infrastructure.Attribute;
|
||||
using SqlSugar;
|
||||
using System.Collections.Generic;
|
||||
using ZR.Model.Models;
|
||||
using ZR.Repository;
|
||||
using ZR.Repository.System;
|
||||
@@ -24,6 +26,20 @@ namespace ZR.Service.System
|
||||
|
||||
#region 业务逻辑代码
|
||||
|
||||
/// <summary>
|
||||
/// 查询系统通知
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<SysNotice> GetSysNotices()
|
||||
{
|
||||
//开始拼装查询条件
|
||||
var predicate = Expressionable.Create<SysNotice>();
|
||||
|
||||
//搜索条件查询语法参考Sqlsugar
|
||||
predicate = predicate.And(m => m.Status == "0");
|
||||
return _SysNoticerepository.GetList(predicate.ToExpression());
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -43,6 +43,11 @@ namespace ZR.Service.System
|
||||
operLog.BeginTime = DateTimeHelper.GetBeginTime(operLog.BeginTime, -1);
|
||||
operLog.EndTime = DateTimeHelper.GetBeginTime(operLog.EndTime, 1);
|
||||
|
||||
bool isDemoMode = AppSettings.GetAppConfig("DemoMode", false);
|
||||
if (isDemoMode)
|
||||
{
|
||||
return new PagedInfo<SysOperLog>();
|
||||
}
|
||||
var list = sysOperLogRepository.GetSysOperLog(operLog, pager);
|
||||
|
||||
return list;
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
using Quartz;
|
||||
using Quartz.Spi;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace ZR.Tasks
|
||||
{
|
||||
public class JobFactory : IJobFactory
|
||||
{
|
||||
private NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
||||
/// <summary>
|
||||
/// 注入反射获取依赖对象
|
||||
/// </summary>
|
||||
@@ -32,8 +32,10 @@ namespace ZR.Tasks
|
||||
return job;
|
||||
|
||||
}
|
||||
catch (Exception)
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
logger.Error(ex, ex.Message);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NLog" Version="4.7.5" />
|
||||
<PackageReference Include="Quartz" Version="3.3.2" />
|
||||
<PackageReference Include="Quartz.Serialization.Json" Version="3.3.2" />
|
||||
<PackageReference Include="NLog" Version="4.7.14" />
|
||||
<PackageReference Include="Quartz" Version="3.3.3" />
|
||||
<PackageReference Include="Quartz.Serialization.Json" Version="3.3.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -7,6 +7,9 @@ VUE_APP_TITLE = 'ZrAdmin.NET后台管理'
|
||||
# 开发环境
|
||||
VUE_APP_BASE_API = '/dev-api'
|
||||
|
||||
#socket API
|
||||
VUE_APP_SOCKET_API = '/msgHub'
|
||||
|
||||
# 路由前缀
|
||||
VUE_APP_ROUTER_PREFIX = '/'
|
||||
|
||||
|
||||
@@ -7,8 +7,11 @@ VUE_APP_TITLE = 'ZrAdmin.NET后台管理'
|
||||
# 生产环境
|
||||
VUE_APP_BASE_API = '/prod-api'
|
||||
|
||||
#socket API
|
||||
VUE_APP_SOCKET_API = '/msgHub'
|
||||
|
||||
# 路由前缀
|
||||
VUE_APP_ROUTER_PREFIX = '/'
|
||||
|
||||
# 默认上传地址
|
||||
VUE_APP_UPLOAD_URL = '/Common/UploadFile'
|
||||
VUE_APP_UPLOAD_URL = '/Common/UploadFile'
|
||||
@@ -7,6 +7,9 @@ VUE_APP_TITLE = 'ZrAdmin.NET后台管理'
|
||||
# 测试环境
|
||||
VUE_APP_BASE_API = '/stage-api'
|
||||
|
||||
#socket API
|
||||
VUE_APP_SOCKET_API = '/msgHub'
|
||||
|
||||
# 路由前缀
|
||||
VUE_APP_ROUTER_PREFIX = '/'
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@microsoft/signalr": "^6.0.2",
|
||||
"@riophae/vue-treeselect": "0.4.0",
|
||||
"axios": "^0.21.4",
|
||||
"clipboard": "2.0.8",
|
||||
@@ -45,6 +46,7 @@
|
||||
"vue-count-to": "1.0.13",
|
||||
"vue-cropper": "0.4.9",
|
||||
"vue-router": "3.4.9",
|
||||
"vue-seamless-scroll": "^1.1.23",
|
||||
"vuedraggable": "2.20.0",
|
||||
"vuex": "3.6.0"
|
||||
},
|
||||
|
||||
@@ -5,7 +5,23 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from "vuex";
|
||||
|
||||
export default {
|
||||
name: "App",
|
||||
computed: {
|
||||
...mapGetters(["token"]),
|
||||
},
|
||||
watch: {
|
||||
token: {
|
||||
handler: function (val) {
|
||||
if (val) {
|
||||
this.signalr.start();
|
||||
}
|
||||
},
|
||||
deep: true,
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -8,6 +8,14 @@ export function listArticle(query) {
|
||||
params: query
|
||||
})
|
||||
}
|
||||
// 查询最新列表
|
||||
export function listNewArticle(query) {
|
||||
return request({
|
||||
url: '/Article/newList',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询详细
|
||||
export function getArticle(Id) {
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 导航栏查询公告列表
|
||||
export function queryNotice(query) {
|
||||
return request({
|
||||
url: '/system/notice/queryNotice',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询公告列表
|
||||
export function listNotice(query) {
|
||||
return request({
|
||||
@@ -41,4 +50,12 @@ export function delNotice(noticeId) {
|
||||
url: '/system/notice/' + noticeId,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 发送通知公告
|
||||
export function sendNotice(noticeId) {
|
||||
return request({
|
||||
url: '/system/notice/send/' + noticeId,
|
||||
method: 'PUT'
|
||||
})
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
.head-container {
|
||||
padding-bottom: 10px;
|
||||
.filter-item {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
margin: 0 3px 10px 0;
|
||||
input {
|
||||
height: 30.5px;
|
||||
line-height: 30.5px;
|
||||
}
|
||||
}
|
||||
.el-button+.el-button {
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
.el-select__caret.el-input__icon.el-icon-arrow-up{
|
||||
line-height: 30.5px;
|
||||
}
|
||||
.date-item {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
margin-bottom: 10px;
|
||||
height: 30.5px !important;
|
||||
width: 230px !important;
|
||||
}
|
||||
}
|
||||
.el-avatar {
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
background: #ccc;
|
||||
color: #fff;
|
||||
white-space: nowrap;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
vertical-align: middle;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border-radius: 16px;
|
||||
}
|
||||
|
||||
.logo-con{
|
||||
height: 60px;
|
||||
padding: 13px 0 0;
|
||||
img{
|
||||
height: 32px;
|
||||
width: 135px;
|
||||
display: block;
|
||||
//margin: 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
#el-login-footer {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
font-family: Arial, serif;
|
||||
font-size: 12px;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
#el-main-footer {
|
||||
background: none repeat scroll 0 0 white;
|
||||
border-top: 1px solid #e7eaec;
|
||||
overflow: hidden;
|
||||
padding: 10px 6px 0 6px;
|
||||
height: 33px;
|
||||
font-size: 0.7rem !important;
|
||||
color: #7a8b9a;
|
||||
letter-spacing: 0.8px;
|
||||
font-family: Arial, sans-serif !important;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
z-index: 99;
|
||||
width: 100%;
|
||||
}
|
||||
.eladmin-upload {
|
||||
border: 1px dashed #c0ccda;
|
||||
border-radius: 5px;
|
||||
height: 45px;
|
||||
line-height: 45px;
|
||||
width: 368px;
|
||||
}
|
||||
.my-blockquote{
|
||||
margin: 0 0 10px;
|
||||
padding: 15px;
|
||||
line-height: 22px;
|
||||
border-left: 5px solid #00437B;
|
||||
border-radius: 0 2px 2px 0;
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
.my-code{
|
||||
position: relative;
|
||||
padding: 15px;
|
||||
line-height: 20px;
|
||||
border-left: 5px solid #ddd;
|
||||
color: #333;
|
||||
font-family: Courier New, serif;
|
||||
font-size: 12px
|
||||
}
|
||||
|
||||
.el-tabs{
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
@@ -82,3 +82,71 @@
|
||||
.el-range-separator {
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
|
||||
/* 解决element-ui的table表格控件表头与内容列不对齐问题 */
|
||||
|
||||
.el-table th.gutter {
|
||||
display: table-cell !important;
|
||||
}
|
||||
|
||||
.el-checkbox.mini .el-checkbox__label {
|
||||
font-size: 12px !important;
|
||||
}
|
||||
|
||||
.el-checkbox.small .el-checkbox__label {
|
||||
font-size: 12px !important;
|
||||
}
|
||||
|
||||
.el-checkbox.medium .el-checkbox__label {
|
||||
font-size: 14px !important;
|
||||
}
|
||||
|
||||
.el-table .fixed-width .el-button--mini {
|
||||
color: #409EFF;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
width: inherit;
|
||||
}
|
||||
|
||||
.el-tree-node__content>.el-checkbox {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
// element ui 移动端组件适配
|
||||
@media screen and (max-width: 500px) {
|
||||
.el-message {
|
||||
min-width: 300px !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 500px) {
|
||||
.el-message-box {
|
||||
width: 300px !important;
|
||||
}
|
||||
.el-pagination__jump{
|
||||
display: none !important;
|
||||
}
|
||||
.el-pagination__sizes{
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
// dialog
|
||||
@media screen and (max-width: 500px) {
|
||||
.el-dialog__wrapper .el-dialog {
|
||||
width: 95% !important;
|
||||
}
|
||||
}
|
||||
|
||||
/** 表格更多操作下拉样式 */
|
||||
.el-table .el-dropdown-link {
|
||||
cursor: pointer;
|
||||
color: #409EFF;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.el-table .el-dropdown, .el-icon-arrow-down {
|
||||
font-size: 12px;
|
||||
}
|
||||
//适配完毕
|
||||
@@ -4,7 +4,6 @@
|
||||
@import 'element-ui';
|
||||
@import 'sidebar';
|
||||
@import 'btn';
|
||||
@import 'eladmin';
|
||||
|
||||
body {
|
||||
height: 100%;
|
||||
@@ -342,24 +341,6 @@ aside {
|
||||
height: 120px;
|
||||
}
|
||||
|
||||
/* 解决element-ui的table表格控件表头与内容列不对齐问题 */
|
||||
|
||||
.el-table th.gutter {
|
||||
display: table-cell !important;
|
||||
}
|
||||
|
||||
.el-checkbox.mini .el-checkbox__label {
|
||||
font-size: 12px !important;
|
||||
}
|
||||
|
||||
.el-checkbox.small .el-checkbox__label {
|
||||
font-size: 12px !important;
|
||||
}
|
||||
|
||||
.el-checkbox.medium .el-checkbox__label {
|
||||
font-size: 14px !important;
|
||||
}
|
||||
|
||||
.vue-treeselect.mini {
|
||||
font-size: 12px !important;
|
||||
}
|
||||
@@ -397,17 +378,6 @@ aside {
|
||||
}
|
||||
|
||||
|
||||
.el-table .fixed-width .el-button--mini {
|
||||
color: #409EFF;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
width: inherit;
|
||||
}
|
||||
|
||||
.el-tree-node__content>.el-checkbox {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.list-group-striped>.list-group-item {
|
||||
border-left: 0;
|
||||
border-right: 0;
|
||||
@@ -475,6 +445,7 @@ aside {
|
||||
height: 120px;
|
||||
}
|
||||
|
||||
// 导航栏头像
|
||||
.avatar-upload-preview {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
@@ -505,40 +476,3 @@ aside {
|
||||
.table-td-thumb {
|
||||
width: 56px;
|
||||
}
|
||||
|
||||
// 移动端组件适配
|
||||
@media screen and (max-width: 500px) {
|
||||
.el-message {
|
||||
min-width: 300px !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 500px) {
|
||||
.el-message-box {
|
||||
width: 300px !important;
|
||||
}
|
||||
.el-pagination__jump{
|
||||
display: none !important;
|
||||
}
|
||||
.el-pagination__sizes{
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
// dialog
|
||||
@media screen and (max-width: 500px) {
|
||||
.el-dialog__wrapper .el-dialog {
|
||||
width: 95% !important;
|
||||
}
|
||||
}
|
||||
|
||||
/** 表格更多操作下拉样式 */
|
||||
.el-table .el-dropdown-link {
|
||||
cursor: pointer;
|
||||
color: #409EFF;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.el-table .el-dropdown, .el-icon-arrow-down {
|
||||
font-size: 12px;
|
||||
}
|
||||
@@ -1,9 +1,12 @@
|
||||
<template>
|
||||
<div class="upload-file">
|
||||
<el-upload :action="uploadFileUrl" :before-upload="handleBeforeUpload" :file-list="fileList" :limit="limit" :on-error="handleUploadError"
|
||||
:on-exceed="handleExceed" :on-success="handleUploadSuccess" :on-progress="uploadProcess" :show-file-list="false" :data="data" :headers="headers" ref="upload">
|
||||
:on-exceed="handleExceed" :on-success="handleUploadSuccess" :on-progress="uploadProcess" :show-file-list="true" :data="data" :headers="headers"
|
||||
:drag="drag" ref="upload">
|
||||
<i class="el-icon-upload" v-if="drag"></i>
|
||||
<div class="el-upload__text" v-if="drag">将文件拖到此处,或<em>点击上传</em></div>
|
||||
<!-- 上传按钮 -->
|
||||
<el-button size="mini" type="primary" icon="el-icon-upload">选取文件</el-button>
|
||||
<el-button size="mini" icon="el-icon-upload" v-if="!drag">选取文件</el-button>
|
||||
<!-- 上传提示 -->
|
||||
<div class="el-upload__tip" slot="tip" v-if="showTip">
|
||||
请上传
|
||||
@@ -28,141 +31,155 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getToken } from "@/utils/auth";
|
||||
import { getToken } from '@/utils/auth'
|
||||
|
||||
export default {
|
||||
name: "FileUpload",
|
||||
name: 'FileUpload',
|
||||
props: {
|
||||
// 值
|
||||
value: [String, Object, Array],
|
||||
// 数量限制
|
||||
limit: {
|
||||
type: Number,
|
||||
default: 1,
|
||||
default: 1
|
||||
},
|
||||
// 大小限制(MB)
|
||||
fileSize: {
|
||||
type: Number,
|
||||
default: 5,
|
||||
default: 5
|
||||
},
|
||||
// 文件类型, 例如['png', 'jpg', 'jpeg']
|
||||
fileType: {
|
||||
type: Array,
|
||||
default: () => ["doc", "xls", "ppt", "txt", "pdf", "svga", "json"],
|
||||
default: () => ['doc', 'xls', 'ppt', 'txt', 'pdf', 'svga', 'json']
|
||||
},
|
||||
// 是否显示提示
|
||||
isShowTip: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
default: true
|
||||
},
|
||||
// 上传地址
|
||||
uploadUrl: {
|
||||
type: String,
|
||||
default: process.env.VUE_APP_UPLOAD_URL,
|
||||
default: process.env.VUE_APP_UPLOAD_URL
|
||||
},
|
||||
// form 列名
|
||||
column: [String],
|
||||
// 上传携带的参数
|
||||
data: {
|
||||
type: Object,
|
||||
type: Object
|
||||
},
|
||||
// 是否拖拽
|
||||
drag: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
baseUrl: process.env.VUE_APP_BASE_API,
|
||||
uploadFileUrl: process.env.VUE_APP_BASE_API + this.uploadUrl, // 上传的图片服务器地址
|
||||
headers: {
|
||||
Authorization: "Bearer " + getToken(),
|
||||
Authorization: 'Bearer ' + getToken()
|
||||
},
|
||||
fileList: [],
|
||||
};
|
||||
fileList: []
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value: {
|
||||
handler(val) {
|
||||
if (val) {
|
||||
let temp = 1;
|
||||
let temp = 1
|
||||
// 首先将值转为数组
|
||||
const list = Array.isArray(val) ? val : this.value.split(",");
|
||||
const list = Array.isArray(val) ? val : this.value.split(',')
|
||||
// 然后将数组转为对象数组
|
||||
this.fileList = list.map((item) => {
|
||||
if (typeof item === "string") {
|
||||
item = { name: item, url: item };
|
||||
if (typeof item === 'string') {
|
||||
item = { name: item, url: item }
|
||||
}
|
||||
item.uid = item.uid || new Date().getTime() + temp++;
|
||||
return item;
|
||||
});
|
||||
item.uid = item.uid || new Date().getTime() + temp++
|
||||
return item
|
||||
})
|
||||
} else {
|
||||
this.fileList = [];
|
||||
return [];
|
||||
this.fileList = []
|
||||
return []
|
||||
}
|
||||
},
|
||||
deep: true,
|
||||
immediate: true,
|
||||
immediate: true
|
||||
},
|
||||
uploadUrl: {
|
||||
handler(val){
|
||||
this.uploadFileUrl = process.env.VUE_APP_BASE_API + val;
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
uploadUrl: {
|
||||
handler(val) {
|
||||
this.uploadFileUrl = process.env.VUE_APP_BASE_API + val
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 是否显示提示
|
||||
showTip() {
|
||||
return this.isShowTip && (this.fileType || this.fileSize);
|
||||
},
|
||||
return this.isShowTip && (this.fileType || this.fileSize)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 上传前校检格式和大小
|
||||
handleBeforeUpload(file) {
|
||||
// 校检文件类型
|
||||
if (this.fileType && this.fileType.length > 0) {
|
||||
let fileExtension = "";
|
||||
if (file.name.lastIndexOf(".") > -1) {
|
||||
fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);
|
||||
let fileExtension = ''
|
||||
if (file.name.lastIndexOf('.') > -1) {
|
||||
fileExtension = file.name.slice(file.name.lastIndexOf('.') + 1)
|
||||
}
|
||||
const isTypeOk = this.fileType.some((type) => {
|
||||
if (file.type.indexOf(type) > -1) return true;
|
||||
if (fileExtension && fileExtension.indexOf(type) > -1) return true;
|
||||
return false;
|
||||
});
|
||||
if (file.type.indexOf(type) > -1) return true
|
||||
if (fileExtension && fileExtension.indexOf(type) > -1) return true
|
||||
return false
|
||||
})
|
||||
if (!isTypeOk) {
|
||||
this.msgError(
|
||||
`文件格式不正确, 请上传${this.fileType.join("/")}格式文件!`
|
||||
);
|
||||
return false;
|
||||
`文件格式不正确, 请上传${this.fileType.join('/')}格式文件!`
|
||||
)
|
||||
return false
|
||||
}
|
||||
}
|
||||
// 校检文件大小
|
||||
if (this.fileSize) {
|
||||
const isLt = file.size / 1024 / 1024 < this.fileSize;
|
||||
const isLt = file.size / 1024 / 1024 < this.fileSize
|
||||
if (!isLt) {
|
||||
this.msgError(`上传文件大小不能超过 ${this.fileSize} MB!`);
|
||||
return false;
|
||||
this.msgError(`上传文件大小不能超过 ${this.fileSize} MB!`)
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return true
|
||||
},
|
||||
// 文件个数超出
|
||||
handleExceed() {
|
||||
this.msgError(`上传文件数量不能超过 ${this.limit} 个!`);
|
||||
this.msgError(`上传文件数量不能超过 ${this.limit} 个!`)
|
||||
},
|
||||
// 上传失败
|
||||
handleUploadError(err) {
|
||||
this.msgError("上传失败, 请重试");
|
||||
this.fileList = [];
|
||||
this.msgError('上传失败, 请重试')
|
||||
this.fileList = []
|
||||
},
|
||||
// 上传成功回调
|
||||
handleUploadSuccess(res, file) {
|
||||
if (res.code != 200) {
|
||||
this.fileList = [];
|
||||
this.msgError(`上传失败,原因:${res.msg}!`);
|
||||
return;
|
||||
this.fileList = []
|
||||
this.msgError(`上传失败,原因:${res.msg}!`)
|
||||
return
|
||||
}
|
||||
this.msgSuccess("上传成功");
|
||||
this.fileList.push({ name: res.data.fileName, url: res.data.url, path: res.data.path });
|
||||
this.$emit("input", this.column, this.listToString(this.fileList), res.data);
|
||||
this.msgSuccess('上传成功')
|
||||
this.fileList.push({
|
||||
name: res.data.fileName,
|
||||
url: res.data.url,
|
||||
path: res.data.path
|
||||
})
|
||||
this.$emit(
|
||||
'input',
|
||||
this.column,
|
||||
this.listToString(this.fileList),
|
||||
res.data
|
||||
)
|
||||
},
|
||||
// 上传进度
|
||||
uploadProcess(event, file, fileList) {
|
||||
@@ -170,28 +187,28 @@ export default {
|
||||
},
|
||||
// 删除文件
|
||||
handleDelete(index) {
|
||||
this.fileList.splice(index, 1);
|
||||
this.$emit("input", this.column, this.listToString(this.fileList));
|
||||
this.fileList.splice(index, 1)
|
||||
this.$emit('input', this.column, this.listToString(this.fileList))
|
||||
},
|
||||
// 获取文件名称
|
||||
getFileName(name) {
|
||||
if (name.lastIndexOf("/") > -1) {
|
||||
return name.slice(name.lastIndexOf("/") + 1).toLowerCase();
|
||||
if (name.lastIndexOf('/') > -1) {
|
||||
return name.slice(name.lastIndexOf('/') + 1).toLowerCase()
|
||||
} else {
|
||||
return name;
|
||||
return name
|
||||
}
|
||||
},
|
||||
// 对象转成指定字符串分隔
|
||||
listToString(list, separator) {
|
||||
let strs = "";
|
||||
separator = separator || ",";
|
||||
for (let i in list) {
|
||||
strs += list[i].url + separator;
|
||||
let strs = ''
|
||||
separator = separator || ','
|
||||
for (const i in list) {
|
||||
strs += list[i].url + separator
|
||||
}
|
||||
return strs != "" ? strs.substr(0, strs.length - 1) : "";
|
||||
},
|
||||
},
|
||||
};
|
||||
return strs != '' ? strs.substr(0, strs.length - 1) : ''
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@@ -210,4 +227,8 @@ export default {
|
||||
.ele-upload-list__item-content-action .el-link {
|
||||
margin-right: 10px;
|
||||
}
|
||||
::v-deep .el-upload-dragger {
|
||||
width: 270px;
|
||||
height: 150px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,123 @@
|
||||
<template>
|
||||
<div class="layout-navbars-breadcrumb-user-news">
|
||||
<div class="head-box">
|
||||
<div class="head-box-title">通知</div>
|
||||
<!-- <div class="head-box-btn" v-if="noticeList.length > 0" @click="onAllReadClick">全部已读</div> -->
|
||||
</div>
|
||||
<div class="content-box">
|
||||
<template v-if="noticeList.length > 0">
|
||||
<div class="content-box-item" v-for="(v, k) in noticeList" :key="k">
|
||||
<div>{{ v.noticeTitle }}</div>
|
||||
<div class="content-box-msg" v-html="v.noticeContent"></div>
|
||||
<div class="content-box-time">{{ v.updateTime }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<div class="content-box-empty" v-else>
|
||||
<div class="content-box-empty-margin">
|
||||
<i class="el-icon-s-promotion"></i>
|
||||
<div class="mt15">全部已读</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="foot-box" @click="onGoToGiteeClick" v-if="noticeList.length > 0">前往通知中心</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from "vuex";
|
||||
export default {
|
||||
name: "noticeIndex",
|
||||
data() {
|
||||
return {
|
||||
dataList: [],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['noticeList'])
|
||||
},
|
||||
mounted() {
|
||||
},
|
||||
methods: {
|
||||
// 全部已读点击
|
||||
onAllReadClick() {
|
||||
|
||||
},
|
||||
// 前往通知中心点击
|
||||
onGoToGiteeClick() {
|
||||
window.open("https://gitee.com/izory/ZrAdminNetCore");
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.layout-navbars-breadcrumb-user-news {
|
||||
.head-box {
|
||||
display: flex;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
box-sizing: border-box;
|
||||
color: #333333;
|
||||
justify-content: space-between;
|
||||
height: 35px;
|
||||
align-items: center;
|
||||
.head-box-btn {
|
||||
color: #1890ff;
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
opacity: 0.8;
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
.content-box {
|
||||
font-size: 13px;
|
||||
.content-box-item {
|
||||
padding-top: 12px;
|
||||
&:last-of-type {
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
.content-box-msg {
|
||||
color: #999999;
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.content-box-time {
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
.content-box-empty {
|
||||
height: 260px;
|
||||
display: flex;
|
||||
.content-box-empty-margin {
|
||||
margin: auto;
|
||||
text-align: center;
|
||||
i {
|
||||
font-size: 60px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.foot-box {
|
||||
height: 35px;
|
||||
color: #1890ff;
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
opacity: 0.8;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-top: 1px solid #ebeef5;
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
::v-deep(.el-empty__description p) {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
::v-deep .el-badge__content .is-fixed {
|
||||
top: 12px !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -5,54 +5,54 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import screenfull from 'screenfull'
|
||||
import screenfull from "screenfull";
|
||||
|
||||
export default {
|
||||
name: 'Screenfull',
|
||||
name: "Screenfull",
|
||||
data() {
|
||||
return {
|
||||
isFullscreen: false
|
||||
}
|
||||
isFullscreen: false,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.init()
|
||||
this.init();
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.destroy()
|
||||
this.destroy();
|
||||
},
|
||||
methods: {
|
||||
click() {
|
||||
if (!screenfull.enabled) {
|
||||
this.$message({
|
||||
message: 'you browser can not work',
|
||||
type: 'warning'
|
||||
})
|
||||
return false
|
||||
message: "you browser can not work",
|
||||
type: "warning",
|
||||
});
|
||||
return false;
|
||||
}
|
||||
screenfull.toggle()
|
||||
screenfull.toggle();
|
||||
},
|
||||
change() {
|
||||
this.isFullscreen = screenfull.isFullscreen
|
||||
this.isFullscreen = screenfull.isFullscreen;
|
||||
},
|
||||
init() {
|
||||
if (screenfull.enabled) {
|
||||
screenfull.on('change', this.change)
|
||||
screenfull.on("change", this.change);
|
||||
}
|
||||
},
|
||||
destroy() {
|
||||
if (screenfull.enabled) {
|
||||
screenfull.off('change', this.change)
|
||||
screenfull.off("change", this.change);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.screenfull-svg {
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
fill: #5a5e66;;
|
||||
fill: #5a5e66;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
vertical-align: 10px;
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
<hamburger id="hamburger-container" class="hamburger-container" :is-active="sidebar.opened" @toggleClick="toggleSideBar" />
|
||||
|
||||
<!-- 面包屑导航 -->
|
||||
<breadcrumb id="breadcrumb-container" class="breadcrumb-container" v-if="!topNav"/>
|
||||
<top-nav id="topmenu-container" class="topmenu-container" v-if="topNav"/>
|
||||
<breadcrumb id="breadcrumb-container" class="breadcrumb-container" v-if="!topNav" />
|
||||
<top-nav id="topmenu-container" class="topmenu-container" v-if="topNav" />
|
||||
|
||||
<div class="right-menu">
|
||||
<template v-if="device!=='mobile'">
|
||||
@@ -15,12 +15,21 @@
|
||||
<size-select id="size-select" class="right-menu-item hover-effect" />
|
||||
<!-- </el-tooltip> -->
|
||||
<el-tooltip content="源码地址" effect="dark" placement="bottom">
|
||||
<zr-git id="zr-git" class="right-menu-item hover-effect" />
|
||||
<zr-git class="right-menu-item hover-effect" />
|
||||
</el-tooltip>
|
||||
<el-tooltip content="文档地址" effect="dark" placement="bottom">
|
||||
<zr-doc id="zr-doc" class="right-menu-item hover-effect" />
|
||||
<zr-doc class="right-menu-item hover-effect" />
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<!-- 通知 -->
|
||||
<div class="right-menu-item">
|
||||
<el-popover placement="bottom" trigger="click" v-model="isShowUserNewsPopover" width="300" popper-class="el-popover-pupop-user-news">
|
||||
<el-badge @click.stop="isShowUserNewsPopover = !isShowUserNewsPopover" :is-dot="true" slot="reference">
|
||||
<i class="el-icon-bell" title="通知"></i>
|
||||
</el-badge>
|
||||
<Notice v-show="isShowUserNewsPopover" />
|
||||
</el-popover>
|
||||
</div>
|
||||
|
||||
<el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click">
|
||||
<div class="avatar-wrapper">
|
||||
@@ -46,13 +55,14 @@
|
||||
<script>
|
||||
import { mapGetters } from "vuex";
|
||||
import Breadcrumb from "@/components/Breadcrumb";
|
||||
import TopNav from '@/components/TopNav'
|
||||
import TopNav from "@/components/TopNav";
|
||||
import Hamburger from "@/components/Hamburger";
|
||||
import Screenfull from "@/components/Screenfull";
|
||||
import SizeSelect from "@/components/SizeSelect";
|
||||
import Search from "@/components/HeaderSearch";
|
||||
import ZrGit from "@/components/Zr/Git";
|
||||
import ZrDoc from '@/components/Zr/Doc'
|
||||
import ZrDoc from "@/components/Zr/Doc";
|
||||
import Notice from "@/components/Notice/Index.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@@ -63,7 +73,13 @@ export default {
|
||||
SizeSelect,
|
||||
Search,
|
||||
ZrGit,
|
||||
ZrDoc
|
||||
ZrDoc,
|
||||
Notice,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isShowUserNewsPopover: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(["sidebar", "avatar", "device"]),
|
||||
@@ -80,9 +96,9 @@ export default {
|
||||
},
|
||||
topNav: {
|
||||
get() {
|
||||
return this.$store.state.settings.topNav
|
||||
}
|
||||
}
|
||||
return this.$store.state.settings.topNav;
|
||||
},
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
toggleSideBar() {
|
||||
@@ -135,7 +151,7 @@ export default {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.topmenu-container {
|
||||
.topmenu-container {
|
||||
position: absolute;
|
||||
left: 50px;
|
||||
}
|
||||
@@ -146,9 +162,9 @@ export default {
|
||||
}
|
||||
|
||||
.right-menu {
|
||||
float: right;
|
||||
height: 100%;
|
||||
line-height: 50px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
|
||||
@@ -17,11 +17,19 @@ export default {
|
||||
const vnodes = []
|
||||
|
||||
if (icon) {
|
||||
vnodes.push(<svg-icon icon-class={icon}/>)
|
||||
vnodes.push(<svg-icon icon-class={icon} />)
|
||||
}
|
||||
|
||||
if (title) {
|
||||
vnodes.push(<span slot='title'>{(title)}</span>)
|
||||
if (title.length > 5) {
|
||||
vnodes.push(
|
||||
<span slot='title' title={title}>
|
||||
{title}
|
||||
</span>
|
||||
)
|
||||
} else {
|
||||
vnodes.push(<span slot='title'>{title}</span>)
|
||||
}
|
||||
}
|
||||
return vnodes
|
||||
}
|
||||
|
||||
+7
-3
@@ -12,12 +12,13 @@ import store from './store'
|
||||
import router from './router'
|
||||
import permission from './directive/permission'
|
||||
import plugins from './plugins' // plugins
|
||||
import signalR from '@/utils/signalR'
|
||||
|
||||
import './assets/icons' // icon
|
||||
import './permission' // permission control
|
||||
import { getDicts} from "@/api/system/dict/data";
|
||||
import { getDicts } from "@/api/system/dict/data";
|
||||
import { getConfigKey } from "@/api/system/config";
|
||||
import { parseTime, resetForm, addDateRange, addDateRange2, selectDictLabel, selectDictLabels, download, handleTree } from "@/utils/ruoyi";
|
||||
import { parseTime, resetForm, addDateRange, selectDictLabel, selectDictLabels, download, handleTree, handleDict } from "@/utils/ruoyi";
|
||||
//分页组件
|
||||
import Pagination from "@/components/Pagination";
|
||||
//自定义表格工具扩展
|
||||
@@ -37,11 +38,11 @@ Vue.prototype.getConfigKey = getConfigKey
|
||||
Vue.prototype.parseTime = parseTime
|
||||
Vue.prototype.resetForm = resetForm
|
||||
Vue.prototype.addDateRange = addDateRange
|
||||
Vue.prototype.addDateRange2 = addDateRange2
|
||||
Vue.prototype.selectDictLabel = selectDictLabel
|
||||
Vue.prototype.selectDictLabels = selectDictLabels
|
||||
Vue.prototype.download = download
|
||||
Vue.prototype.handleTree = handleTree
|
||||
Vue.prototype.handleDict = handleDict
|
||||
|
||||
Vue.prototype.msgSuccess = function (msg) {
|
||||
this.$message({ showClose: true, message: msg, type: "success" });
|
||||
@@ -71,6 +72,9 @@ Vue.use(Element, {
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
signalR.init(process.env.VUE_APP_SOCKET_API);
|
||||
Vue.prototype.signalr = signalR
|
||||
|
||||
new Vue({
|
||||
el: '#app',
|
||||
router,
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
const sessionCache = {
|
||||
set(key, value) {
|
||||
if (!sessionStorage) {
|
||||
return
|
||||
}
|
||||
if (key != null && value != null) {
|
||||
sessionStorage.setItem(key, value)
|
||||
}
|
||||
},
|
||||
get(key) {
|
||||
if (!sessionStorage) {
|
||||
return null
|
||||
}
|
||||
if (key == null) {
|
||||
return null
|
||||
}
|
||||
return sessionStorage.getItem(key)
|
||||
},
|
||||
setJSON(key, jsonValue) {
|
||||
if (jsonValue != null) {
|
||||
this.set(key, JSON.stringify(jsonValue))
|
||||
}
|
||||
},
|
||||
getJSON(key) {
|
||||
const value = this.get(key)
|
||||
if (value != null) {
|
||||
return JSON.parse(value)
|
||||
}
|
||||
},
|
||||
remove(key) {
|
||||
sessionStorage.removeItem(key);
|
||||
}
|
||||
}
|
||||
const localCache = {
|
||||
set(key, value) {
|
||||
if (!localStorage) {
|
||||
return
|
||||
}
|
||||
if (key != null && value != null) {
|
||||
localStorage.setItem(key, value)
|
||||
}
|
||||
},
|
||||
get(key) {
|
||||
if (!localStorage) {
|
||||
return null
|
||||
}
|
||||
if (key == null) {
|
||||
return null
|
||||
}
|
||||
return localStorage.getItem(key)
|
||||
},
|
||||
setJSON(key, jsonValue) {
|
||||
if (jsonValue != null) {
|
||||
this.set(key, JSON.stringify(jsonValue))
|
||||
}
|
||||
},
|
||||
getJSON(key) {
|
||||
const value = this.get(key)
|
||||
if (value != null) {
|
||||
return JSON.parse(value)
|
||||
}
|
||||
},
|
||||
remove(key) {
|
||||
localStorage.removeItem(key);
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
/**
|
||||
* 会话级缓存
|
||||
*/
|
||||
session: sessionCache,
|
||||
/**
|
||||
* 本地缓存
|
||||
*/
|
||||
local: localCache
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import tab from './tab'
|
||||
// import auth from './auth'
|
||||
// import cache from './cache'
|
||||
// import modal from './modal'
|
||||
import cache from './cache'
|
||||
import modal from './modal'
|
||||
// import download from './download'
|
||||
|
||||
export default {
|
||||
@@ -11,9 +11,9 @@ export default {
|
||||
// 认证对象
|
||||
// Vue.prototype.$auth = auth
|
||||
// 缓存对象
|
||||
// Vue.prototype.$cache = cache
|
||||
Vue.prototype.$cache = cache
|
||||
// 模态框对象
|
||||
// Vue.prototype.$modal = modal
|
||||
Vue.prototype.$modal = modal
|
||||
// 下载文件
|
||||
// Vue.prototype.$download = download
|
||||
}
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
import { Message, MessageBox, Notification, Loading } from 'element-ui'
|
||||
|
||||
let loadingInstance;
|
||||
|
||||
export default {
|
||||
// 消息提示
|
||||
msg(content) {
|
||||
Message.info(content)
|
||||
},
|
||||
// 错误消息
|
||||
msgError(content) {
|
||||
Message.error(content)
|
||||
},
|
||||
// 成功消息
|
||||
msgSuccess(content) {
|
||||
Message.success(content)
|
||||
},
|
||||
// 警告消息
|
||||
msgWarning(content) {
|
||||
Message.warning(content)
|
||||
},
|
||||
// 弹出提示
|
||||
alert(content) {
|
||||
MessageBox.alert(content, "系统提示")
|
||||
},
|
||||
// 错误提示
|
||||
alertError(content) {
|
||||
MessageBox.alert(content, "系统提示", { type: 'error' })
|
||||
},
|
||||
// 成功提示
|
||||
alertSuccess(content) {
|
||||
MessageBox.alert(content, "系统提示", { type: 'success' })
|
||||
},
|
||||
// 警告提示
|
||||
alertWarning(content) {
|
||||
MessageBox.alert(content, "系统提示", { type: 'warning' })
|
||||
},
|
||||
// 通知提示
|
||||
notify(content) {
|
||||
Notification.info(content)
|
||||
},
|
||||
// 错误通知
|
||||
notifyError(content) {
|
||||
Notification.error(content);
|
||||
},
|
||||
// 成功通知
|
||||
notifySuccess(content) {
|
||||
Notification.success(content)
|
||||
},
|
||||
// 警告通知
|
||||
notifyWarning(content) {
|
||||
Notification.warning(content)
|
||||
},
|
||||
// 确认窗体
|
||||
confirm(content) {
|
||||
return MessageBox.confirm(content, "系统提示", {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: "warning",
|
||||
})
|
||||
},
|
||||
// 提交内容
|
||||
prompt(content) {
|
||||
return MessageBox.prompt(content, "系统提示", {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: "warning",
|
||||
})
|
||||
},
|
||||
// 打开遮罩层
|
||||
loading(content) {
|
||||
loadingInstance = Loading.service({
|
||||
lock: true,
|
||||
text: content,
|
||||
spinner: "el-icon-loading",
|
||||
background: "rgba(0, 0, 0, 0.7)",
|
||||
})
|
||||
},
|
||||
// 关闭遮罩层
|
||||
closeLoading() {
|
||||
loadingInstance.close();
|
||||
}
|
||||
}
|
||||
@@ -4,20 +4,21 @@ import router from '@/router';
|
||||
export default {
|
||||
// 刷新当前tab页签
|
||||
refreshPage(obj) {
|
||||
const { path, matched } = router.currentRoute;
|
||||
const { path, query, matched } = router.currentRoute;
|
||||
if (obj === undefined) {
|
||||
matched.forEach((m) => {
|
||||
if (m.components && m.components.default && m.components.default.name) {
|
||||
if (!['Layout', 'ParentView'].includes(m.components.default.name)) {
|
||||
obj = { name: m.components.default.name, path: path };
|
||||
obj = { name: m.components.default.name, path: path, query: query };
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return store.dispatch('tagsView/delCachedView', obj).then(() => {
|
||||
const { path } = obj
|
||||
const { path, query } = obj
|
||||
router.replace({
|
||||
path: '/redirect' + path
|
||||
path: '/redirect' + path,
|
||||
query: query
|
||||
})
|
||||
})
|
||||
},
|
||||
@@ -63,4 +64,4 @@ export default {
|
||||
updatePage(obj) {
|
||||
return store.dispatch('tagsView/updateVisitedView', obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@ module.exports = {
|
||||
/**
|
||||
* 框架版本号
|
||||
*/
|
||||
version: '3.7.7',
|
||||
version: '3.7.8',
|
||||
title: 'ZrAdmin.NET-后台管理',
|
||||
/**
|
||||
* 主题颜色
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user