初始化版本

This commit is contained in:
zmrid 2023-02-04 13:37:26 +08:00
parent 8ecba8153a
commit 9b2cbaccaf
1440 changed files with 195717 additions and 65 deletions

18
.gitignore vendored Normal file
View File

@ -0,0 +1,18 @@
# Build and Release Folders
bin-debug/
bin-release/
[Oo]bj/
[Bb]in/
# Other files and folders
.settings/
# Executables
*.swf
*.air
*.ipa
*.apk
# Project files, i.e. `.project`, `.actionScriptProperties` and `.flexProperties`
# should NOT be excluded as they contain compiler settings and other important
# information for Eclipse / Flash Builder.

BIN
DB/iMES_Open.sql Normal file

Binary file not shown.

BIN
Image/1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

BIN
Image/2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

BIN
Image/3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

BIN
Image/4.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

BIN
Image/5.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

BIN
Image/6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

BIN
Image/7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 KiB

BIN
Image/8.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

BIN
Image/9.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 KiB

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 zm-rid
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,36 +0,0 @@
# iMES工厂管家
#### Description
iMES工厂管家——您的新一代工厂管理助手
#### Software Architecture
Software architecture description
#### Installation
1. xxxx
2. xxxx
3. xxxx
#### Instructions
1. xxxx
2. xxxx
3. xxxx
#### Contribution
1. Fork the repository
2. Create Feat_xxx branch
3. Commit your code
4. Create Pull Request
#### Gitee Feature
1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
2. Gitee blog [blog.gitee.com](https://blog.gitee.com)
3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
4. The most valuable open source project [GVP](https://gitee.com/gvp)
5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)

101
README.md
View File

@ -1,37 +1,80 @@
# iMES工厂管家
## iMES工厂管家——您的新一代工厂助手
#### 介绍
iMES工厂管家——您的新一代工厂管理助手
## 功能模块
- 基础数据【工艺路线,绩效工资配置,产品定义,物料清单,单位管理,不良品项,工序,通知管理,车间设置】
- 自定义配置【自定义编号规则】
- 库存管理【出库单,入库单,库存收发明细,库存余额】
- 生产管理【销售订单,生产计划,装配工单,工单,任务,报工】
- 系统管理【用户管理部门管理消息推送权限管理角色管理菜单设置数据字典系统日志角色管理tree版本发布记录用户管理tree
- 报表管理【员工绩效,工资报表,不良品项分部,不良品项汇总,生产报表,产量统计】
- 定时任务【任务配置,执行记录】
- 流程管理【审批流程,我的任务】
- 开发管理【表单设计,表单配置,数据采集,代码生成】
- 质量管理【常见缺陷,检测项管理,检测模版,来料检验单,过程检验单,出货检验单】
- 排班管理【班组管理,排班计划,节假日设置,排班日历】
- 工具管理【工具领用,工具归还,工装夹具类型,工装夹具台账】
- 设备管理【设备类型设置,设备台账,点检保养项目,点检保养计划,维修单,点检保养工单】
- 看板管理【车间生产管控看板,工单执行进度看板】
#### 软件架构
软件架构说明
## 框架预览
- 框架内置了大量的通用组件可直接使用,并内置了基于本框架定制开发的代码生成器,尽量避免重复性代码编写。
- 框架不仅仅是快速开发,更多的是倾向于业务代码扩展的编写与代码规范。
- 如果有什么问题或建议提issue或加QQ514224717
- QQ群724346134
- 商业版演示地址http://imes.625sc.com
- 开源版演示地址http://imesopen.625sc.com
- 帐号admin密码123456
- gitee码云https://gitee.com/ZM-Rid/i-mes-factory-housekeeper
## 框架核心
- iMES工厂管家产品基于优秀的[Vue.NetCore](https://gitee.com/x_discoverer/Vue.NetCore)开发
- 快速开发(基础功能全部由代码生成器生成)
- 支持前端、后台自定义业务代码扩展,后台提供了大量常用扩展与通用类
- 前端、后台提供了近300个扩展方法与属性,开发人员可在此功能上编写扩展自定义业务代码
- 代码生成(代码生成器可直接生成主/从表前后端业务代码,有30多种属性可在线配置生成的代码)
- 前端table自动转换key/value
- 前端表单select/checkbox自动绑定数据源,不需要写任何代码
- 支持(主从表)一对一前后端代码全自动生成、并支持数据源自动绑定与业务代码扩展,不需要写任何代码
- 支持一对多从表自定义扩展(不限从表类型与从表数量) , 一对多从表使用扩展可轻松实现
- 如果能上手框架可以体会到不用996,更不用掉头发的感觉^_^
## 框架适用范围
- 前后端分离项目
- 编写各种后台restful api接口。后台基础代码由代码生成器完成,在生成的代码上继续编写业务即可
- 前端表单开发(直接上手看demo即可)
- 配合app做H5或全h5开发
- 移动端开发、app、微信小程序(uniapp),见下面介绍
- 在现有的代码生成器功能上,继续定制开发代码生成器功能,解决重复性工作
## 框架开发依赖环境
- 后台VS2019、vs2022 、.NetCore3.1 、EFCore3.1、JWT、Dapper、SignalR、Quartz.Net、Autofac、SqlServer2016、Redis
- 前端VsCode、vue3需要安装nodejs)、vuex、axios、promise、element ui、element plus
## 开源版和商业版区别
- 商业版支持自定义实体扩展
- 商业版支持打印模版设计
- 商业版支持模版打印
- 商业版支持Excel模版导出
- 商业版拥有移动端可以一套代码导出H5,Android,iOS端。并且提供桌面端
- 商业版提供可视化看板设计功能
- 商业版提供技术支持开源版只有开源交流QQ群
## 图片预览
#### 安装教程
1. xxxx
2. xxxx
3. xxxx
#### 使用说明
1. xxxx
2. xxxx
3. xxxx
#### 参与贡献
1. Fork 本仓库
2. 新建 Feat_xxx 分支
3. 提交代码
4. 新建 Pull Request
## 项目启动与上手
- 运行前先看后台appsettings.json配置属性说明(注意修改DbType属性修改为自己使用的数据库,数据库脚本在DB文件夹下)
- 1、启动后台项目后端项目路径 ../iMES.WebApi找到dev_run.bat命令点击启动。后台启动 默认端口是9991。
(dev_run.bat如果闪退请使用cmd切换至 ../iMES.WebApi目录下执行dotnet run看异常信息)
如从没执行过npm install命令使用cmd命令切换至前端Vue项目../iMES.Vue路径下,执行npm install命令
- 2、启动前端项目前端Vue项目路径 ../iMES.Vue 找到 run.bat命令点击启动 。
- 1(run.bat如果闪退,说明环境没配置好请使用cmd切换至 ../iMES.Vue目录下执行npm run dev看异常信息)
- 2使用cmd命令切换到../iMES.Vue目录下执行npm cache clear --force或者安装node.js版本14.15.1
- 3输入http://localhost:8080访问本地超级管理员帐号admin 密码:123456
- 详细文档查看http://v2.volcore.xyz/document/guide
#### 特技
1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com)
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目
4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)

25
iMES.Net/.dockerignore Normal file
View File

@ -0,0 +1,25 @@
**/.classpath
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/azds.yaml
**/bin
**/charts
**/docker-compose*
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
LICENSE
README.md

Binary file not shown.

BIN
iMES.Net/.vs/iMES/v16/.suo Normal file

Binary file not shown.

View File

@ -0,0 +1,8 @@
using System;
namespace iMES.Builder
{
public class Class1
{
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using iMES.Core.BaseProvider;
using iMES.Entity.DomainModels;
using iMES.Core.Extensions.AutofacManager;
namespace iMES.Builder.IRepositories
{
public partial interface ISys_TableInfoRepository : IDependency,IRepository<Sys_TableInfo>
{
}
}

View File

@ -0,0 +1,10 @@
using iMES.Core.BaseProvider;
using iMES.Entity.DomainModels;
namespace iMES.Builder.IServices
{
public partial interface ISys_TableInfoService : IService<Sys_TableInfo>
{
}
}

View File

@ -0,0 +1,26 @@
using iMES.Core.BaseProvider;
using iMES.Entity.DomainModels;
using System.Collections.Generic;
using System.Threading.Tasks;
using iMES.Core.Utilities;
namespace iMES.Builder.IServices
{
public partial interface ISys_TableInfoService
{
Task<(string, string)> GetTableTree();
string CreateEntityModel(Sys_TableInfo tableInfo);
WebResponseContent SaveEidt(Sys_TableInfo sysTableInfo);
string CreateServices(string tableName, string nameSpace, string foldername, bool webController, bool apiController);
string CreateVuePage(Sys_TableInfo sysTableInfo, string vuePath);
object LoadTable(int parentId, string tableName, string columnCNName, string nameSpace, string foldername, int table_Id, bool isTreeLoad,string dbServer);
Task<WebResponseContent> SyncTable(string tableName);
Task<WebResponseContent> DelTree(int table_Id);
}
}

View File

@ -0,0 +1,27 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:34188/",
"sslPort": 44309
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"iMES.Builder": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:5001;http://localhost:5000"
}
}
}

View File

@ -0,0 +1,22 @@
using iMES.Builder.IRepositories;
using iMES.Core.BaseProvider;
using iMES.Core.EFDbContext;
using iMES.Core.Extensions.AutofacManager;
using iMES.Entity.DomainModels;
namespace iMES.Builder.Repositories
{
public partial class Sys_TableInfoRepository : RepositoryBase<Sys_TableInfo>, ISys_TableInfoRepository
{
public Sys_TableInfoRepository(SysDbContext dbContext)
: base(dbContext)
{
}
public static ISys_TableInfoRepository GetService
{
get { return AutofacContainerModule.GetService<ISys_TableInfoRepository>(); }
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,22 @@
using iMES.Builder.IRepositories;
using iMES.Builder.IServices;
using iMES.Core.BaseProvider;
using iMES.Core.Extensions.AutofacManager;
using iMES.Entity.DomainModels;
namespace iMES.Builder.Services
{
public partial class Sys_TableInfoService : ServiceBase<Sys_TableInfo, ISys_TableInfoRepository>, ISys_TableInfoService, IDependency
{
public Sys_TableInfoService(ISys_TableInfoRepository repository)
: base(repository)
{
Init(repository);
}
public static ISys_TableInfoService Instance
{
get { return AutofacContainerModule.GetService<ISys_TableInfoService>(); }
}
}
}

View File

@ -0,0 +1,93 @@
using System.IO;
using System.Linq;
using iMES.Core.Extensions;
namespace iMES.Builder.Utility
{
public class ProjectPath
{
// private int findCount = 1;
/// <summary>
/// 获取web父目录所在位置
/// </summary>
/// <returns></returns>
public static DirectoryInfo GetProjectDirectoryInfo()
{
return GetProjectDirectoryInfo(new DirectoryInfo("".MapPath()), 1);
}
public static string GetProjectFileName(string startsWith)
{
string fileNames = GetProjectDirectoryInfo()?.GetDirectories()
.Where(
c =>
//c.Name.StartsWith(startsWith)&&
c.Name != startsWith + ".Core"
&& c.Name != startsWith + ".Entity"
&& !c.Name.ToLower().EndsWith(".web")
&& !c.Name.ToLower().EndsWith(".webapi")
&& !c.Name.ToLower().EndsWith(".builder")
&& c.Name.ToLower()!=".vs"
).Select(x => x.Name).ToList().Serialize();
if (string.IsNullOrEmpty(fileNames))
{
fileNames = new DirectoryInfo("".MapPath()).GetFiles().Where(x => x.Name.EndsWith(".dll")
//&& x.Name.StartsWith(startsWith)
&& !x.Name.EndsWith(".Core.dll")
&& !x.Name.EndsWith(".Entity.dll")
&& !x.Name.EndsWith(".Builder.dll")
&& !x.Name.ToLower().EndsWith(".web")
&& !x.Name.ToLower().EndsWith(".webapi")
&& !x.Name.ToLower().EndsWith(".builder")
).Select(x => x.Name.Replace(".dll", "")).ToList().Serialize();
}
return fileNames ?? "''";
}
/// <summary>
/// 获取指定结尾的项目名称
/// </summary>
/// <param name="lastIndexOfName"></param>
/// <returns></returns>
public static string GetLastIndexOfDirectoryName(string lastIndexOfName)
{
string projectName = GetProjectDirectoryInfo()?.GetDirectories()
.Where(c => c.Name.LastIndexOf(lastIndexOfName) != -1).Select(x => x.Name).FirstOrDefault();
if (string.IsNullOrEmpty(projectName))
{
projectName = new DirectoryInfo("".MapPath()).GetFiles().Where(x => x.Name.LastIndexOf(lastIndexOfName + ".dll") != -1).FirstOrDefault().Name;
if (!string.IsNullOrEmpty(projectName))
{
projectName = projectName.Replace(".dll", "");
}
}
return projectName;
}
/// <summary>
/// 获取项目所在路径
/// </summary>
/// <param name="directoryInfo"></param>
/// <returns></returns>
private static DirectoryInfo GetProjectDirectoryInfo(DirectoryInfo directoryInfo, int findCount)
{
if (directoryInfo == null)
{
return null;
}
if (directoryInfo.Exists
&& directoryInfo.GetDirectories().Where(x => x.Name.LastIndexOf(".Web") != -1).FirstOrDefault() != null)
{
return directoryInfo;
}
if (findCount < 7)
{
findCount++;
DirectoryInfo dir = GetProjectDirectoryInfo(directoryInfo.Parent, findCount);
if (dir != null)
{
return dir;
}
}
return null;
}
}
}

View File

@ -0,0 +1,32 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup Label="Globals">
<SccProjectName></SccProjectName>
<SccProvider></SccProvider>
<SccAuxPath></SccAuxPath>
<SccLocalPath></SccLocalPath>
</PropertyGroup>
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<ApplicationIcon />
<OutputType>Library</OutputType>
<StartupObject />
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="6.2.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.0" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="3.1.0" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="3.1.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\iMES.Core\iMES.Core.csproj" />
<ProjectReference Include="..\iMES.Entity\iMES.Entity.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ShowAllFiles>true</ShowAllFiles>
<ActiveDebugProfile>IIS Express</ActiveDebugProfile>
</PropertyGroup>
</Project>

View File

@ -0,0 +1,18 @@
/*
*,
*Repository提供数据库操作Partial文件夹ICal_HolidayRepository编写接口
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using iMES.Core.BaseProvider;
using iMES.Entity.DomainModels;
using iMES.Core.Extensions.AutofacManager;
namespace iMES.Calendar.IRepositories
{
public partial interface ICal_HolidayRepository : IDependency,IRepository<Cal_Holiday>
{
}
}

View File

@ -0,0 +1,18 @@
/*
*,
*Repository提供数据库操作Partial文件夹ICal_PlanRepository编写接口
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using iMES.Core.BaseProvider;
using iMES.Entity.DomainModels;
using iMES.Core.Extensions.AutofacManager;
namespace iMES.Calendar.IRepositories
{
public partial interface ICal_PlanRepository : IDependency,IRepository<Cal_Plan>
{
}
}

View File

@ -0,0 +1,18 @@
/*
*,
*Repository提供数据库操作Partial文件夹ICal_PlanShiftRepository编写接口
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using iMES.Core.BaseProvider;
using iMES.Entity.DomainModels;
using iMES.Core.Extensions.AutofacManager;
namespace iMES.Calendar.IRepositories
{
public partial interface ICal_PlanShiftRepository : IDependency,IRepository<Cal_PlanShift>
{
}
}

View File

@ -0,0 +1,18 @@
/*
*,
*Repository提供数据库操作Partial文件夹ICal_PlanTeamRepository编写接口
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using iMES.Core.BaseProvider;
using iMES.Entity.DomainModels;
using iMES.Core.Extensions.AutofacManager;
namespace iMES.Calendar.IRepositories
{
public partial interface ICal_PlanTeamRepository : IDependency,IRepository<Cal_PlanTeam>
{
}
}

View File

@ -0,0 +1,18 @@
/*
*,
*Repository提供数据库操作Partial文件夹ICal_TeamMemberRepository编写接口
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using iMES.Core.BaseProvider;
using iMES.Entity.DomainModels;
using iMES.Core.Extensions.AutofacManager;
namespace iMES.Calendar.IRepositories
{
public partial interface ICal_TeamMemberRepository : IDependency,IRepository<Cal_TeamMember>
{
}
}

View File

@ -0,0 +1,18 @@
/*
*,
*Repository提供数据库操作Partial文件夹ICal_TeamRepository编写接口
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using iMES.Core.BaseProvider;
using iMES.Entity.DomainModels;
using iMES.Core.Extensions.AutofacManager;
namespace iMES.Calendar.IRepositories
{
public partial interface ICal_TeamRepository : IDependency,IRepository<Cal_Team>
{
}
}

View File

@ -0,0 +1,18 @@
/*
*,
*Repository提供数据库操作Partial文件夹ICal_TeamShiftRepository编写接口
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using iMES.Core.BaseProvider;
using iMES.Entity.DomainModels;
using iMES.Core.Extensions.AutofacManager;
namespace iMES.Calendar.IRepositories
{
public partial interface ICal_TeamShiftRepository : IDependency,IRepository<Cal_TeamShift>
{
}
}

View File

@ -0,0 +1,12 @@
/*
*,
*/
using iMES.Core.BaseProvider;
using iMES.Entity.DomainModels;
namespace iMES.Calendar.IServices
{
public partial interface ICal_HolidayService : IService<Cal_Holiday>
{
}
}

View File

@ -0,0 +1,12 @@
/*
*,
*/
using iMES.Core.BaseProvider;
using iMES.Entity.DomainModels;
namespace iMES.Calendar.IServices
{
public partial interface ICal_PlanService : IService<Cal_Plan>
{
}
}

View File

@ -0,0 +1,12 @@
/*
*,
*/
using iMES.Core.BaseProvider;
using iMES.Entity.DomainModels;
namespace iMES.Calendar.IServices
{
public partial interface ICal_PlanShiftService : IService<Cal_PlanShift>
{
}
}

View File

@ -0,0 +1,12 @@
/*
*,
*/
using iMES.Core.BaseProvider;
using iMES.Entity.DomainModels;
namespace iMES.Calendar.IServices
{
public partial interface ICal_PlanTeamService : IService<Cal_PlanTeam>
{
}
}

View File

@ -0,0 +1,12 @@
/*
*,
*/
using iMES.Core.BaseProvider;
using iMES.Entity.DomainModels;
namespace iMES.Calendar.IServices
{
public partial interface ICal_TeamMemberService : IService<Cal_TeamMember>
{
}
}

View File

@ -0,0 +1,12 @@
/*
*,
*/
using iMES.Core.BaseProvider;
using iMES.Entity.DomainModels;
namespace iMES.Calendar.IServices
{
public partial interface ICal_TeamService : IService<Cal_Team>
{
}
}

View File

@ -0,0 +1,12 @@
/*
*,
*/
using iMES.Core.BaseProvider;
using iMES.Entity.DomainModels;
namespace iMES.Calendar.IServices
{
public partial interface ICal_TeamShiftService : IService<Cal_TeamShift>
{
}
}

View File

@ -0,0 +1,13 @@
/*
*Cal_Holiday类的业务代码接口应在此处编写
*/
using iMES.Core.BaseProvider;
using iMES.Entity.DomainModels;
using iMES.Core.Utilities;
using System.Linq.Expressions;
namespace iMES.Calendar.IServices
{
public partial interface ICal_HolidayService
{
}
}

View File

@ -0,0 +1,27 @@
/*
*Cal_Plan类的业务代码接口应在此处编写
*/
using iMES.Core.BaseProvider;
using iMES.Entity.DomainModels;
using iMES.Core.Utilities;
using System.Linq.Expressions;
using System.Threading.Tasks;
namespace iMES.Calendar.IServices
{
public partial interface ICal_PlanService
{
/// 获取table1的数据
/// </summary>
/// <param name="loadData"></param>
/// <returns></returns>
Task<object> GetTable1Data(PageDataOptions loadData);
/// <summary>
/// 获取table2的数据
/// </summary>
/// <param name="loadData"></param>
/// <returns></returns>
Task<object> GetTable2Data(PageDataOptions loadData);
}
}

View File

@ -0,0 +1,13 @@
/*
*Cal_PlanShift类的业务代码接口应在此处编写
*/
using iMES.Core.BaseProvider;
using iMES.Entity.DomainModels;
using iMES.Core.Utilities;
using System.Linq.Expressions;
namespace iMES.Calendar.IServices
{
public partial interface ICal_PlanShiftService
{
}
}

View File

@ -0,0 +1,13 @@
/*
*Cal_PlanTeam类的业务代码接口应在此处编写
*/
using iMES.Core.BaseProvider;
using iMES.Entity.DomainModels;
using iMES.Core.Utilities;
using System.Linq.Expressions;
namespace iMES.Calendar.IServices
{
public partial interface ICal_PlanTeamService
{
}
}

View File

@ -0,0 +1,13 @@
/*
*Cal_TeamMember类的业务代码接口应在此处编写
*/
using iMES.Core.BaseProvider;
using iMES.Entity.DomainModels;
using iMES.Core.Utilities;
using System.Linq.Expressions;
namespace iMES.Calendar.IServices
{
public partial interface ICal_TeamMemberService
{
}
}

View File

@ -0,0 +1,13 @@
/*
*Cal_Team类的业务代码接口应在此处编写
*/
using iMES.Core.BaseProvider;
using iMES.Entity.DomainModels;
using iMES.Core.Utilities;
using System.Linq.Expressions;
namespace iMES.Calendar.IServices
{
public partial interface ICal_TeamService
{
}
}

View File

@ -0,0 +1,13 @@
/*
*Cal_TeamShift类的业务代码接口应在此处编写
*/
using iMES.Core.BaseProvider;
using iMES.Entity.DomainModels;
using iMES.Core.Utilities;
using System.Linq.Expressions;
namespace iMES.Calendar.IServices
{
public partial interface ICal_TeamShiftService
{
}
}

View File

@ -0,0 +1,24 @@
/*
*,
*Repository提供数据库操作Partial文件夹Cal_HolidayRepository编写代码
*/
using iMES.Calendar.IRepositories;
using iMES.Core.BaseProvider;
using iMES.Core.EFDbContext;
using iMES.Core.Extensions.AutofacManager;
using iMES.Entity.DomainModels;
namespace iMES.Calendar.Repositories
{
public partial class Cal_HolidayRepository : RepositoryBase<Cal_Holiday> , ICal_HolidayRepository
{
public Cal_HolidayRepository(SysDbContext dbContext)
: base(dbContext)
{
}
public static ICal_HolidayRepository Instance
{
get { return AutofacContainerModule.GetService<ICal_HolidayRepository>(); } }
}
}

View File

@ -0,0 +1,24 @@
/*
*,
*Repository提供数据库操作Partial文件夹Cal_PlanRepository编写代码
*/
using iMES.Calendar.IRepositories;
using iMES.Core.BaseProvider;
using iMES.Core.EFDbContext;
using iMES.Core.Extensions.AutofacManager;
using iMES.Entity.DomainModels;
namespace iMES.Calendar.Repositories
{
public partial class Cal_PlanRepository : RepositoryBase<Cal_Plan> , ICal_PlanRepository
{
public Cal_PlanRepository(SysDbContext dbContext)
: base(dbContext)
{
}
public static ICal_PlanRepository Instance
{
get { return AutofacContainerModule.GetService<ICal_PlanRepository>(); } }
}
}

View File

@ -0,0 +1,24 @@
/*
*,
*Repository提供数据库操作Partial文件夹Cal_PlanShiftRepository编写代码
*/
using iMES.Calendar.IRepositories;
using iMES.Core.BaseProvider;
using iMES.Core.EFDbContext;
using iMES.Core.Extensions.AutofacManager;
using iMES.Entity.DomainModels;
namespace iMES.Calendar.Repositories
{
public partial class Cal_PlanShiftRepository : RepositoryBase<Cal_PlanShift> , ICal_PlanShiftRepository
{
public Cal_PlanShiftRepository(SysDbContext dbContext)
: base(dbContext)
{
}
public static ICal_PlanShiftRepository Instance
{
get { return AutofacContainerModule.GetService<ICal_PlanShiftRepository>(); } }
}
}

View File

@ -0,0 +1,24 @@
/*
*,
*Repository提供数据库操作Partial文件夹Cal_PlanTeamRepository编写代码
*/
using iMES.Calendar.IRepositories;
using iMES.Core.BaseProvider;
using iMES.Core.EFDbContext;
using iMES.Core.Extensions.AutofacManager;
using iMES.Entity.DomainModels;
namespace iMES.Calendar.Repositories
{
public partial class Cal_PlanTeamRepository : RepositoryBase<Cal_PlanTeam> , ICal_PlanTeamRepository
{
public Cal_PlanTeamRepository(SysDbContext dbContext)
: base(dbContext)
{
}
public static ICal_PlanTeamRepository Instance
{
get { return AutofacContainerModule.GetService<ICal_PlanTeamRepository>(); } }
}
}

View File

@ -0,0 +1,24 @@
/*
*,
*Repository提供数据库操作Partial文件夹Cal_TeamMemberRepository编写代码
*/
using iMES.Calendar.IRepositories;
using iMES.Core.BaseProvider;
using iMES.Core.EFDbContext;
using iMES.Core.Extensions.AutofacManager;
using iMES.Entity.DomainModels;
namespace iMES.Calendar.Repositories
{
public partial class Cal_TeamMemberRepository : RepositoryBase<Cal_TeamMember> , ICal_TeamMemberRepository
{
public Cal_TeamMemberRepository(SysDbContext dbContext)
: base(dbContext)
{
}
public static ICal_TeamMemberRepository Instance
{
get { return AutofacContainerModule.GetService<ICal_TeamMemberRepository>(); } }
}
}

View File

@ -0,0 +1,24 @@
/*
*,
*Repository提供数据库操作Partial文件夹Cal_TeamRepository编写代码
*/
using iMES.Calendar.IRepositories;
using iMES.Core.BaseProvider;
using iMES.Core.EFDbContext;
using iMES.Core.Extensions.AutofacManager;
using iMES.Entity.DomainModels;
namespace iMES.Calendar.Repositories
{
public partial class Cal_TeamRepository : RepositoryBase<Cal_Team> , ICal_TeamRepository
{
public Cal_TeamRepository(SysDbContext dbContext)
: base(dbContext)
{
}
public static ICal_TeamRepository Instance
{
get { return AutofacContainerModule.GetService<ICal_TeamRepository>(); } }
}
}

View File

@ -0,0 +1,24 @@
/*
*,
*Repository提供数据库操作Partial文件夹Cal_TeamShiftRepository编写代码
*/
using iMES.Calendar.IRepositories;
using iMES.Core.BaseProvider;
using iMES.Core.EFDbContext;
using iMES.Core.Extensions.AutofacManager;
using iMES.Entity.DomainModels;
namespace iMES.Calendar.Repositories
{
public partial class Cal_TeamShiftRepository : RepositoryBase<Cal_TeamShift> , ICal_TeamShiftRepository
{
public Cal_TeamShiftRepository(SysDbContext dbContext)
: base(dbContext)
{
}
public static ICal_TeamShiftRepository Instance
{
get { return AutofacContainerModule.GetService<ICal_TeamShiftRepository>(); } }
}
}

View File

@ -0,0 +1,26 @@
/*
*AuthorCOCO
*,
*Partial文件夹下Cal_HolidayService与ICal_HolidayService中编写
*/
using iMES.Calendar.IRepositories;
using iMES.Calendar.IServices;
using iMES.Core.BaseProvider;
using iMES.Core.Extensions.AutofacManager;
using iMES.Entity.DomainModels;
namespace iMES.Calendar.Services
{
public partial class Cal_HolidayService : ServiceBase<Cal_Holiday, ICal_HolidayRepository>
, ICal_HolidayService, IDependency
{
public Cal_HolidayService(ICal_HolidayRepository repository)
: base(repository)
{
Init(repository);
}
public static ICal_HolidayService Instance
{
get { return AutofacContainerModule.GetService<ICal_HolidayService>(); } }
}
}

View File

@ -0,0 +1,26 @@
/*
*AuthorCOCO
*,
*Partial文件夹下Cal_PlanService与ICal_PlanService中编写
*/
using iMES.Calendar.IRepositories;
using iMES.Calendar.IServices;
using iMES.Core.BaseProvider;
using iMES.Core.Extensions.AutofacManager;
using iMES.Entity.DomainModels;
namespace iMES.Calendar.Services
{
public partial class Cal_PlanService : ServiceBase<Cal_Plan, ICal_PlanRepository>
, ICal_PlanService, IDependency
{
public Cal_PlanService(ICal_PlanRepository repository)
: base(repository)
{
Init(repository);
}
public static ICal_PlanService Instance
{
get { return AutofacContainerModule.GetService<ICal_PlanService>(); } }
}
}

View File

@ -0,0 +1,26 @@
/*
*AuthorCOCO
*,
*Partial文件夹下Cal_PlanShiftService与ICal_PlanShiftService中编写
*/
using iMES.Calendar.IRepositories;
using iMES.Calendar.IServices;
using iMES.Core.BaseProvider;
using iMES.Core.Extensions.AutofacManager;
using iMES.Entity.DomainModels;
namespace iMES.Calendar.Services
{
public partial class Cal_PlanShiftService : ServiceBase<Cal_PlanShift, ICal_PlanShiftRepository>
, ICal_PlanShiftService, IDependency
{
public Cal_PlanShiftService(ICal_PlanShiftRepository repository)
: base(repository)
{
Init(repository);
}
public static ICal_PlanShiftService Instance
{
get { return AutofacContainerModule.GetService<ICal_PlanShiftService>(); } }
}
}

View File

@ -0,0 +1,26 @@
/*
*AuthorCOCO
*,
*Partial文件夹下Cal_PlanTeamService与ICal_PlanTeamService中编写
*/
using iMES.Calendar.IRepositories;
using iMES.Calendar.IServices;
using iMES.Core.BaseProvider;
using iMES.Core.Extensions.AutofacManager;
using iMES.Entity.DomainModels;
namespace iMES.Calendar.Services
{
public partial class Cal_PlanTeamService : ServiceBase<Cal_PlanTeam, ICal_PlanTeamRepository>
, ICal_PlanTeamService, IDependency
{
public Cal_PlanTeamService(ICal_PlanTeamRepository repository)
: base(repository)
{
Init(repository);
}
public static ICal_PlanTeamService Instance
{
get { return AutofacContainerModule.GetService<ICal_PlanTeamService>(); } }
}
}

View File

@ -0,0 +1,26 @@
/*
*AuthorCOCO
*,
*Partial文件夹下Cal_TeamMemberService与ICal_TeamMemberService中编写
*/
using iMES.Calendar.IRepositories;
using iMES.Calendar.IServices;
using iMES.Core.BaseProvider;
using iMES.Core.Extensions.AutofacManager;
using iMES.Entity.DomainModels;
namespace iMES.Calendar.Services
{
public partial class Cal_TeamMemberService : ServiceBase<Cal_TeamMember, ICal_TeamMemberRepository>
, ICal_TeamMemberService, IDependency
{
public Cal_TeamMemberService(ICal_TeamMemberRepository repository)
: base(repository)
{
Init(repository);
}
public static ICal_TeamMemberService Instance
{
get { return AutofacContainerModule.GetService<ICal_TeamMemberService>(); } }
}
}

View File

@ -0,0 +1,26 @@
/*
*AuthorCOCO
*,
*Partial文件夹下Cal_TeamService与ICal_TeamService中编写
*/
using iMES.Calendar.IRepositories;
using iMES.Calendar.IServices;
using iMES.Core.BaseProvider;
using iMES.Core.Extensions.AutofacManager;
using iMES.Entity.DomainModels;
namespace iMES.Calendar.Services
{
public partial class Cal_TeamService : ServiceBase<Cal_Team, ICal_TeamRepository>
, ICal_TeamService, IDependency
{
public Cal_TeamService(ICal_TeamRepository repository)
: base(repository)
{
Init(repository);
}
public static ICal_TeamService Instance
{
get { return AutofacContainerModule.GetService<ICal_TeamService>(); } }
}
}

View File

@ -0,0 +1,26 @@
/*
*AuthorCOCO
*,
*Partial文件夹下Cal_TeamShiftService与ICal_TeamShiftService中编写
*/
using iMES.Calendar.IRepositories;
using iMES.Calendar.IServices;
using iMES.Core.BaseProvider;
using iMES.Core.Extensions.AutofacManager;
using iMES.Entity.DomainModels;
namespace iMES.Calendar.Services
{
public partial class Cal_TeamShiftService : ServiceBase<Cal_TeamShift, ICal_TeamShiftRepository>
, ICal_TeamShiftService, IDependency
{
public Cal_TeamShiftService(ICal_TeamShiftRepository repository)
: base(repository)
{
Init(repository);
}
public static ICal_TeamShiftService Instance
{
get { return AutofacContainerModule.GetService<ICal_TeamShiftService>(); } }
}
}

View File

@ -0,0 +1,65 @@
/*
*Cal_Holiday类的业务代码应在此处编写
*使repository.EF/Dapper等信息
*使repository.DbContextBeginTransaction
*使DBServerProvider.
*使UserContext.Current操作
*Cal_HolidayService对增ServiceFunFilter
*/
using iMES.Core.BaseProvider;
using iMES.Core.Extensions.AutofacManager;
using iMES.Entity.DomainModels;
using System.Linq;
using iMES.Core.Utilities;
using System.Linq.Expressions;
using iMES.Core.Extensions;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Http;
using iMES.Calendar.IRepositories;
namespace iMES.Calendar.Services
{
public partial class Cal_HolidayService
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly ICal_HolidayRepository _repository;//访问数据库
[ActivatorUtilitiesConstructor]
public Cal_HolidayService(
ICal_HolidayRepository dbRepository,
IHttpContextAccessor httpContextAccessor
)
: base(dbRepository)
{
_httpContextAccessor = httpContextAccessor;
_repository = dbRepository;
//多租户会用到这init代码其他情况可以不用
//base.Init(dbRepository);
}
WebResponseContent _webResponse = new WebResponseContent();
/// <summary>
/// 新建
/// </summary>
/// <param name="saveDataModel"></param>
/// <returns></returns>
public override WebResponseContent Add(SaveModel saveDataModel)
{
//此处saveModel是从前台提交的原生数据可对数据进修改过滤
AddOnExecuting = (Cal_Holiday ho, object list) =>
{
//如果返回false,后面代码不会再执行
if (repository.Exists(x => x.TheDay == ho.TheDay))
{
Cal_Holiday calho = repository.FindAsIQueryable(x => x.TheDay == ho.TheDay)
.OrderByDescending(x => x.CreateDate)
.FirstOrDefault();
calho.HolidayType = ho.HolidayType;
repository.Update(calho, x => new { x.HolidayType }, true);
}
return _webResponse.OK();
};
return base.Add(saveDataModel);
}
}
}

View File

@ -0,0 +1,803 @@
/*
*Cal_Plan类的业务代码应在此处编写
*使repository.EF/Dapper等信息
*使repository.DbContextBeginTransaction
*使DBServerProvider.
*使UserContext.Current操作
*Cal_PlanService对增ServiceFunFilter
*/
using iMES.Core.BaseProvider;
using iMES.Core.Extensions.AutofacManager;
using iMES.Entity.DomainModels;
using System.Linq;
using iMES.Core.Utilities;
using System.Linq.Expressions;
using iMES.Core.Extensions;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Http;
using iMES.Calendar.IRepositories;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System;
using iMES.Calendar.Repositories;
using iMES.Core.Enums;
using iMES.Custom.IRepositories;
namespace iMES.Calendar.Services
{
public partial class Cal_PlanService
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly ICal_PlanRepository _repository;//访问数据库
private readonly ICal_PlanShiftRepository _shiftRepository;//访问数据库
private readonly ICal_PlanTeamRepository _teamRepository;//访问数据库
private readonly IBase_NumberRuleRepository _numberRuleRepository;//自定义编码规则访问数据库
[ActivatorUtilitiesConstructor]
public Cal_PlanService(
ICal_PlanRepository dbRepository,
IHttpContextAccessor httpContextAccessor,
ICal_PlanShiftRepository shiftRepository,
ICal_PlanTeamRepository teamRepository,
IBase_NumberRuleRepository numberRuleRepository
)
: base(dbRepository)
{
_httpContextAccessor = httpContextAccessor;
_repository = dbRepository;
_shiftRepository = shiftRepository;
_teamRepository = teamRepository;
_numberRuleRepository = numberRuleRepository;
//多租户会用到这init代码其他情况可以不用
//base.Init(dbRepository);
}
/// <summary>
/// 获取table1的数据
/// </summary>
/// <param name="loadData"></param>
/// <returns></returns>
public async Task<object> GetTable1Data(PageDataOptions loadData)
{
//Equip_SpotMaintPlanModelBody.vue中loadTableBefore方法查询前给loadData.Value写入的值
List<where> list = loadData.Wheres.DeserializeObject<List<where>>();
//获取查询到的总和数
int total = await Cal_PlanShiftRepository.Instance.FindAsIQueryable(x => x.PlanId == new Guid(list[0].value)).CountAsync();
var data = await Cal_PlanShiftRepository.Instance
//这里可以自己查询条件,从 loadData.Value找前台自定义传的查询条件
.FindAsIQueryable(x => x.PlanId == new Guid(list[0].value))
//分页
.TakeOrderByPage(1, 10, x => new Dictionary<object, QueryOrderBy>() { { x.CreateDate, QueryOrderBy.Desc } })
.Select(s => new { s.PlanShiftId, s.PlanId, s.PlanShiftName,s.Sequence,s.StartTime,s.EndTime, s.CreateID, s.Creator, s.CreateDate, s.ModifyID, s.Modifier, s.ModifyDate })
.ToListAsync();
object gridData = new { rows = data, total };
return gridData;
}
/// <summary>
/// 获取table2的数据
/// </summary>
/// <param name="loadData"></param>
/// <returns></returns>
public async Task<object> GetTable2Data(PageDataOptions loadData)
{
//Equip_SpotMaintPlanModelBody.vue中loadTableBefore方法查询前给loadData.Value写入的值
//获取查询到的总和数
List<where> list = loadData.Wheres.DeserializeObject<List<where>>();
//获取查询到的总和数
int total = await repository.DbContext.Set<Cal_PlanTeam>().Where(x => x.PlanId == new Guid(list[0].value)).CountAsync();
//从 loadData.Value取查询条件分页等信息
//这里可以自己查询条件,从 loadData.Value找前台自定义传的查询条件
var data = await repository.DbContext.Set<Cal_PlanTeam>().Where(x => x.PlanId == new Guid(list[0].value))
//分页
.TakeOrderByPage(1, 10, x => new Dictionary<object, QueryOrderBy>() { { x.CreateDate, QueryOrderBy.Desc } })
.Select(s => new { s.PlanTeamId
,s.PlanId
,s.TeamId
,s.TeamCode
,s.TeamName
,s.Sequence, s.CreateID, s.Creator, s.CreateDate, s.ModifyID, s.Modifier, s.ModifyDate })
.ToListAsync();
object gridData = new { rows = data, total };
return gridData;
}
WebResponseContent _webResponse = new WebResponseContent();
/// <summary>
/// 自定义保存从表数据逻辑
/// </summary>
/// <param name="saveDataModel"></param>
/// <returns></returns>
public override WebResponseContent Add(SaveModel saveDataModel)
{
//取出校验完成后的从表1.2的数据
TableExtra tableExtra = saveDataModel.Extra.ToString().DeserializeObject<TableExtra>();
//保存到数据库前
AddOnExecuting = (Cal_Plan plan, object obj) =>
{
if (string.IsNullOrWhiteSpace(plan.PlanCode))
plan.PlanCode = GetPlanCode();
//如果返回false,后面代码不会再执行
if (repository.Exists(x => x.PlanCode == plan.PlanCode))
{
return _webResponse.Error("计划编号已存在");
}
return WebResponseContent.Instance.OK();
};
//Equip_SpotMaintPlan 此处已经提交了数据库,处于事务中
AddOnExecuted = (Cal_Plan plan, object obj) =>
{
int i = 0;
//在此操作tableExtra从表信息
List<Cal_PlanShift> newsList = tableExtra.Table1List.Select(s => new Cal_PlanShift
{
PlanShiftId = s.PlanShiftId,
PlanId = plan.PlanId,
PlanShiftName = s.PlanShiftName,
StartTime = s.StartTime,
EndTime = s.EndTime,
Sequence = i++
}).ToList();
//id=0的默认为新增的数据
List<Cal_PlanShift> addList = newsList.Where(x => x.PlanShiftId == new Guid("00000000-0000-0000-0000-000000000000")).ToList();
//设置默认创建人信息
addList.ForEach(x => { x.SetCreateDefaultVal(); });
//新增
repository.AddRange(addList);
int j = 0;
//点检保养项目
List<Cal_PlanTeam> newsList2 = tableExtra.Table2List.Select(s => new Cal_PlanTeam
{
PlanTeamId = s.PlanTeamId,
PlanId = plan.PlanId,
TeamId = s.TeamId,
TeamCode = s.TeamCode,
TeamName = s.TeamName,
Sequence = j++
}).ToList();
//id=0的默认为新增的数据
List<Cal_PlanTeam> addList2 = newsList2.Where(x => x.PlanTeamId == new Guid("00000000-0000-0000-0000-000000000000")).ToList();
//设置默认创建人信息
addList2.ForEach(x => { x.SetCreateDefaultVal(); });
//新增
repository.AddRange(addList2);
//最终保存
repository.SaveChanges();
//生成班组排班
if (plan.Status == 2)
{
var teamShift = new List<Cal_TeamShift>();
for (var date = Convert.ToDateTime(plan.StartDate); date <= Convert.ToDateTime(plan.EndDate); date = date.AddDays(2))
{
if (newsList.Count >= 1)
{
teamShift.Add(new Cal_TeamShift
{
TeamShiftId = new Guid(),
TheDate = date,
TeamId = newsList2[0].TeamId.ToString(),
TeamName = newsList2[0].TeamName,
ShiftId = newsList[0].PlanShiftId,
ShiftName = newsList[0].PlanShiftName,
Sequence = newsList[0].Sequence,
PlanId = plan.PlanId
});
}
if (newsList.Count >= 2)
{
teamShift.Add(new Cal_TeamShift
{
TeamShiftId = new Guid(),
TheDate = date,
TeamId = newsList2[1].TeamId.ToString(),
TeamName = newsList2[1].TeamName,
ShiftId = newsList[1].PlanShiftId,
ShiftName = newsList[1].PlanShiftName,
Sequence = newsList[1].Sequence,
PlanId = plan.PlanId
});
}
if (newsList.Count >= 3)
{
teamShift.Add(new Cal_TeamShift
{
TeamShiftId = new Guid(),
TheDate = date,
TeamId = newsList2[2].TeamId.ToString(),
TeamName = newsList2[2].TeamName,
ShiftId = newsList[2].PlanShiftId,
ShiftName = newsList[2].PlanShiftName,
Sequence = newsList[2].Sequence,
PlanId = plan.PlanId
});
}
};
for (var date = Convert.ToDateTime(plan.StartDate).AddDays(1); date <= Convert.ToDateTime(plan.EndDate); date = date.AddDays(2))
{
if (newsList.Count == 1 && newsList2.Count == 1)
{
teamShift.Add(new Cal_TeamShift
{
TeamShiftId = new Guid(),
TheDate = date,
TeamId = newsList2[0].TeamId.ToString(),
TeamName = newsList2[0].TeamName,
ShiftId = newsList[0].PlanShiftId,
ShiftName = newsList[0].PlanShiftName,
Sequence = newsList[0].Sequence,
PlanId = plan.PlanId
});
}
if (newsList.Count == 2 && newsList2.Count == 2)
{
teamShift.Add(new Cal_TeamShift
{
TeamShiftId = new Guid(),
TheDate = date,
TeamId = newsList2[0].TeamId.ToString(),
TeamName = newsList2[0].TeamName,
ShiftId = newsList[1].PlanShiftId,
ShiftName = newsList[1].PlanShiftName,
Sequence = newsList[1].Sequence,
PlanId = plan.PlanId
});
teamShift.Add(new Cal_TeamShift
{
TeamShiftId = new Guid(),
TheDate = date,
TeamId = newsList2[1].TeamId.ToString(),
TeamName = newsList2[1].TeamName,
ShiftId = newsList[0].PlanShiftId,
ShiftName = newsList[0].PlanShiftName,
Sequence = newsList[0].Sequence,
PlanId = plan.PlanId
});
}
if (newsList.Count == 3 && newsList2.Count == 3)
{
teamShift.Add(new Cal_TeamShift
{
TeamShiftId = new Guid(),
TheDate = date,
TeamId = newsList2[2].TeamId.ToString(),
TeamName = newsList2[2].TeamName,
ShiftId = newsList[0].PlanShiftId,
ShiftName = newsList[0].PlanShiftName,
Sequence = newsList[0].Sequence,
PlanId = plan.PlanId
});
teamShift.Add(new Cal_TeamShift
{
TeamShiftId = new Guid(),
TheDate = date,
TeamId = newsList2[1].TeamId.ToString(),
TeamName = newsList2[1].TeamName,
ShiftId = newsList[1].PlanShiftId,
ShiftName = newsList[1].PlanShiftName,
Sequence = newsList[1].Sequence,
PlanId = plan.PlanId
});
teamShift.Add(new Cal_TeamShift
{
TeamShiftId = new Guid(),
TheDate = date,
TeamId = newsList2[0].TeamId.ToString(),
TeamName = newsList2[0].TeamName,
ShiftId = newsList[2].PlanShiftId,
ShiftName = newsList[2].PlanShiftName,
Sequence = newsList[2].Sequence,
PlanId = plan.PlanId
});
}
};
//新增
repository.AddRange(teamShift);
//最终保存
repository.SaveChanges();
}
return WebResponseContent.Instance.OK();
};
return base.Add(saveDataModel);
}
/// <summary>
/// 自定义更新从表操作
/// </summary>
/// <param name="saveModel"></param>
/// <returns></returns>
public override WebResponseContent Update(SaveModel saveModel)
{
//取出校验完成后的从表1.2的数据
TableExtra tableExtra = saveModel.Extra.ToString().DeserializeObject<TableExtra>();
//保存到数据库前
UpdateOnExecuting = (Cal_Plan plan, object obj, object obj2, List<object> list) =>
{
return WebResponseContent.Instance.OK();
};
//App_ReportPrice 此处已经提交了数据库,处于事务中
UpdateOnExecuted = (Cal_Plan plan, object obj, object obj2, List<object> list) =>
{
//在此操作tableExtra从表信息
List<Cal_PlanShift> newsList = tableExtra.Table1List.Select(s => new Cal_PlanShift
{
PlanShiftId = s.PlanShiftId,
PlanId = plan.PlanId,
PlanShiftName = s.PlanShiftName,
StartTime = s.StartTime,
EndTime = s.EndTime
}).ToList();
//id=0的默认为新增的数据
List<Cal_PlanShift> addList = newsList.Where(x => x.PlanShiftId == new Guid("00000000-0000-0000-0000-000000000000")).ToList();
//设置默认创建人信息
addList.ForEach(x => { x.SetCreateDefaultVal(); });
//获取所有编辑行
List<Guid> editIds = newsList.Where(x => x.PlanShiftId != new Guid("00000000-0000-0000-0000-000000000000")).Select(s => s.PlanShiftId).ToList();
addList.ForEach(x => { x.SetModifyDefaultVal(); });
//从数据库查询编辑的行是否存在,如果数据库不存在,执行修改操作会异常
List<Guid> existsIds = Cal_PlanShiftRepository.Instance.FindAsIQueryable(x => editIds.Contains(x.PlanShiftId)).Select(s => s.PlanShiftId).ToList();
//获取实际可以修改的数据
List<Cal_PlanShift> updateList = newsList.Where(x => existsIds.Contains(x.PlanShiftId)).ToList();
//设置默认修改人信息
updateList.ForEach(x => { x.SetModifyDefaultVal(); });
//新增
repository.AddRange(addList);
//修改(第二个参数指定要修改的字段,第三个参数执行保存)
repository.UpdateRange(updateList, x => new { x.PlanShiftName, x.StartTime, x.EndTime, x.Modifier, x.ModifyDate, x.ModifyID });
//点检保养项目
List<Cal_PlanTeam> newsList2 = tableExtra.Table2List.Select(s => new Cal_PlanTeam
{
PlanTeamId = s.PlanTeamId,
PlanId = plan.PlanId,
TeamId = s.TeamId,
TeamCode = s.TeamCode,
TeamName = s.TeamName,
}).ToList();
//id=0的默认为新增的数据
List<Cal_PlanTeam> addList2 = newsList2.Where(x => x.PlanTeamId == new Guid("00000000-0000-0000-0000-000000000000")).ToList();
//设置默认创建人信息
addList2.ForEach(x => { x.SetCreateDefaultVal(); });
//获取所有编辑行
List<Guid> editIds2 = newsList2.Where(x => x.PlanTeamId != new Guid("00000000-0000-0000-0000-000000000000")).Select(s => s.PlanTeamId).ToList();
addList2.ForEach(x => { x.SetModifyDefaultVal(); });
//从数据库查询编辑的行是否存在,如果数据库不存在,执行修改操作会异常
List<Guid> existsIds2 = Cal_PlanTeamRepository.Instance.FindAsIQueryable(x => editIds.Contains(x.PlanTeamId)).Select(s => s.PlanTeamId).ToList();
//获取实际可以修改的数据
List<Cal_PlanTeam> updateList2 = newsList2.Where(x => existsIds2.Contains(x.PlanTeamId)).ToList();
//设置默认修改人信息
updateList2.ForEach(x => { x.SetModifyDefaultVal(); });
//新增
repository.AddRange(addList2);
//修改(第二个参数指定要修改的字段,第三个参数执行保存)
repository.UpdateRange(updateList2, x => new { x.TeamId, x.TeamCode, x.TeamName, x.Modifier, x.ModifyDate, x.ModifyID });
//最终保存
repository.SaveChanges();
//生成班组排班
if (plan.Status == 2)
{
var teamShift = new List<Cal_TeamShift>();
for (var date = Convert.ToDateTime(plan.StartDate); date <= Convert.ToDateTime(plan.EndDate); date = date.AddDays(2))
{
if (newsList.Count >= 1)
{
teamShift.Add(new Cal_TeamShift
{
TeamShiftId = new Guid(),
TheDate = date,
TeamId = newsList2[0].TeamId.ToString(),
TeamName = newsList2[0].TeamName,
ShiftId = newsList[0].PlanShiftId,
ShiftName = newsList[0].PlanShiftName,
Sequence = newsList[0].Sequence,
PlanId = plan.PlanId
});
}
if (newsList.Count >= 2)
{
teamShift.Add(new Cal_TeamShift
{
TeamShiftId = new Guid(),
TheDate = date,
TeamId = newsList2[1].TeamId.ToString(),
TeamName = newsList2[1].TeamName,
ShiftId = newsList[1].PlanShiftId,
ShiftName = newsList[1].PlanShiftName,
Sequence = newsList[1].Sequence,
PlanId = plan.PlanId
});
}
if (newsList.Count >= 3)
{
teamShift.Add(new Cal_TeamShift
{
TeamShiftId = new Guid(),
TheDate = date,
TeamId = newsList2[2].TeamId.ToString(),
TeamName = newsList2[2].TeamName,
ShiftId = newsList[2].PlanShiftId,
ShiftName = newsList[2].PlanShiftName,
Sequence = newsList[2].Sequence,
PlanId = plan.PlanId
});
}
};
for (var date = Convert.ToDateTime(plan.StartDate).AddDays(1); date <= Convert.ToDateTime(plan.EndDate); date = date.AddDays(2))
{
if (newsList.Count == 1 && newsList2.Count == 1)
{
teamShift.Add(new Cal_TeamShift
{
TeamShiftId = new Guid(),
TheDate = date,
TeamId = newsList2[0].TeamId.ToString(),
TeamName = newsList2[0].TeamName,
ShiftId = newsList[0].PlanShiftId,
ShiftName = newsList[0].PlanShiftName,
Sequence = newsList[0].Sequence,
PlanId = plan.PlanId
});
}
if (newsList.Count == 2 && newsList2.Count == 2)
{
teamShift.Add(new Cal_TeamShift
{
TeamShiftId = new Guid(),
TheDate = date,
TeamId = newsList2[0].TeamId.ToString(),
TeamName = newsList2[0].TeamName,
ShiftId = newsList[1].PlanShiftId,
ShiftName = newsList[1].PlanShiftName,
Sequence = newsList[1].Sequence,
PlanId = plan.PlanId
});
teamShift.Add(new Cal_TeamShift
{
TeamShiftId = new Guid(),
TheDate = date,
TeamId = newsList2[1].TeamId.ToString(),
TeamName = newsList2[1].TeamName,
ShiftId = newsList[0].PlanShiftId,
ShiftName = newsList[0].PlanShiftName,
Sequence = newsList[0].Sequence,
PlanId = plan.PlanId
});
}
if (newsList.Count == 3 && newsList2.Count == 3)
{
teamShift.Add(new Cal_TeamShift
{
TeamShiftId = new Guid(),
TheDate = date,
TeamId = newsList2[2].TeamId.ToString(),
TeamName = newsList2[2].TeamName,
ShiftId = newsList[0].PlanShiftId,
ShiftName = newsList[0].PlanShiftName,
Sequence = newsList[0].Sequence,
PlanId = plan.PlanId
});
teamShift.Add(new Cal_TeamShift
{
TeamShiftId = new Guid(),
TheDate = date,
TeamId = newsList2[1].TeamId.ToString(),
TeamName = newsList2[1].TeamName,
ShiftId = newsList[1].PlanShiftId,
ShiftName = newsList[1].PlanShiftName,
Sequence = newsList[1].Sequence,
PlanId = plan.PlanId
});
teamShift.Add(new Cal_TeamShift
{
TeamShiftId = new Guid(),
TheDate = date,
TeamId = newsList2[0].TeamId.ToString(),
TeamName = newsList2[0].TeamName,
ShiftId = newsList[2].PlanShiftId,
ShiftName = newsList[2].PlanShiftName,
Sequence = newsList[2].Sequence,
PlanId = plan.PlanId
});
}
};
//新增
repository.AddRange(teamShift);
//最终保存
repository.SaveChanges();
}
return WebResponseContent.Instance.OK();
};
return base.Update(saveModel);
}
/// <summary>
/// 删除
/// </summary>
/// <param name="keys"></param>
/// <param name="delList"></param>
/// <returns></returns>
public override WebResponseContent Del(object[] keys, bool delList = true)
{
for (int i = 0; i < keys.Length; i++)
{
List<object> idsDevice = Cal_PlanShiftRepository.Instance.FindAsIQueryable(x => x.PlanId == new Guid(keys[i].ToString())).Select(s => (object)s.PlanShiftId).ToList();
List<object> idsProject = Cal_PlanTeamRepository.Instance.FindAsIQueryable(x => x.PlanId == new Guid(keys[i].ToString())).Select(s => (object)s.PlanTeamId).ToList();
object[] arrayDevice = idsDevice.ToArray();
object[] arrayProject = idsProject.ToArray();
_shiftRepository.DeleteWithKeys(arrayDevice, true);
_teamRepository.DeleteWithKeys(arrayProject, true);
}
//最终保存
repository.SaveChanges();
return base.Del(keys, true);
}
/// <summary>
/// 自动生成设备编号
/// </summary>
/// <returns></returns>
public string GetPlanCode()
{
DateTime dateNow = (DateTime)DateTime.Now.ToString("yyyy-MM-dd").GetDateTime();
//查询当天最新的订单号
string defectItemCode = repository.FindAsIQueryable(x => x.CreateDate > dateNow && x.PlanCode.Length > 8)
.OrderByDescending(x => x.PlanCode)
.Select(s => s.PlanCode)
.FirstOrDefault();
Base_NumberRule numberRule = _numberRuleRepository.FindAsIQueryable(x => x.FormCode == "CalPlan")
.OrderByDescending(x => x.CreateDate)
.FirstOrDefault();
if (numberRule != null)
{
string rule = numberRule.Prefix + DateTime.Now.ToString(numberRule.SubmitTime.Replace("hh", "HH"));
if (string.IsNullOrEmpty(defectItemCode))
{
rule += "1".PadLeft(numberRule.SerialNumber, '0');
}
else
{
rule += (defectItemCode.Substring(defectItemCode.Length - numberRule.SerialNumber).GetInt() + 1).ToString("0".PadLeft(numberRule.SerialNumber, '0'));
}
return rule;
}
else //如果自定义序号配置项不存在,则使用日期生成
{
return DateTime.Now.ToString("yyyyMMddHHmmssffff");
}
}
}
public class Table1
{
/// <summary>
///计划班次主键
/// </summary>
[Key]
[Display(Name = "计划班次主键")]
[Column(TypeName = "uniqueidentifier")]
[Editable(true)]
public Guid PlanShiftId { get; set; }
/// <summary>
///计划主键
/// </summary>
[Display(Name = "计划主键")]
[Column(TypeName = "uniqueidentifier")]
[Editable(true)]
public Guid PlanId { get; set; }
/// <summary>
///显示顺序
/// </summary>
[Display(Name = "显示顺序")]
[Column(TypeName = "int")]
[Editable(true)]
public int? Sequence { get; set; }
/// <summary>
///班次名称
/// </summary>
[Display(Name = "班次名称")]
[MaxLength(100)]
[Column(TypeName = "nvarchar(100)")]
[Editable(true)]
public string PlanShiftName { get; set; }
/// <summary>
///开始时间
/// </summary>
[Display(Name = "开始时间")]
[MaxLength(20)]
[Column(TypeName = "nvarchar(20)")]
[Editable(true)]
public string StartTime { get; set; }
/// <summary>
///结束时间
/// </summary>
[Display(Name = "结束时间")]
[MaxLength(20)]
[Column(TypeName = "nvarchar(20)")]
[Editable(true)]
public string EndTime { get; set; }
/// <summary>
///创建人编号
/// </summary>
[Display(Name = "创建人编号")]
[Column(TypeName = "int")]
[Editable(true)]
public int? CreateID { get; set; }
/// <summary>
///创建人
/// </summary>
[Display(Name = "创建人")]
[MaxLength(30)]
[Column(TypeName = "nvarchar(30)")]
[Editable(true)]
public string Creator { get; set; }
/// <summary>
///创建时间
/// </summary>
[Display(Name = "创建时间")]
[Column(TypeName = "datetime")]
[Editable(true)]
public DateTime? CreateDate { get; set; }
/// <summary>
///修改人编号
/// </summary>
[Display(Name = "修改人编号")]
[Column(TypeName = "int")]
[Editable(true)]
public int? ModifyID { get; set; }
/// <summary>
///修改人
/// </summary>
[Display(Name = "修改人")]
[MaxLength(30)]
[Column(TypeName = "nvarchar(30)")]
[Editable(true)]
public string Modifier { get; set; }
/// <summary>
///修改时间
/// </summary>
[Display(Name = "修改时间")]
[Column(TypeName = "datetime")]
[Editable(true)]
public DateTime? ModifyDate { get; set; }
}
public class Table2
{
/// <summary>
///计划班组主键
/// </summary>
[Key]
[Display(Name = "计划班组主键")]
[Column(TypeName = "uniqueidentifier")]
[Editable(true)]
public Guid PlanTeamId { get; set; }
/// <summary>
///计划主键
/// </summary>
[Display(Name = "计划主键")]
[Column(TypeName = "uniqueidentifier")]
[Editable(true)]
public Guid PlanId { get; set; }
/// <summary>
///班组主键
/// </summary>
[Display(Name = "班组主键")]
[Column(TypeName = "uniqueidentifier")]
[Editable(true)]
public Guid TeamId { get; set; }
/// <summary>
///班组编码
/// </summary>
[Display(Name = "班组编码")]
[MaxLength(100)]
[Column(TypeName = "nvarchar(100)")]
[Editable(true)]
public string TeamCode { get; set; }
/// <summary>
///班组名称
/// </summary>
[Display(Name = "班组名称")]
[MaxLength(100)]
[Column(TypeName = "nvarchar(100)")]
[Editable(true)]
public string TeamName { get; set; }
/// <summary>
///显示顺序
/// </summary>
[Display(Name = "显示顺序")]
[Column(TypeName = "int")]
[Editable(true)]
public int? Sequence { get; set; }
/// <summary>
///创建人编号
/// </summary>
[Display(Name = "创建人编号")]
[Column(TypeName = "int")]
[Editable(true)]
public int? CreateID { get; set; }
/// <summary>
///创建人
/// </summary>
[Display(Name = "创建人")]
[MaxLength(30)]
[Column(TypeName = "nvarchar(30)")]
[Editable(true)]
public string Creator { get; set; }
/// <summary>
///创建时间
/// </summary>
[Display(Name = "创建时间")]
[Column(TypeName = "datetime")]
[Editable(true)]
public DateTime? CreateDate { get; set; }
/// <summary>
///修改人编号
/// </summary>
[Display(Name = "修改人编号")]
[Column(TypeName = "int")]
[Editable(true)]
public int? ModifyID { get; set; }
/// <summary>
///修改人
/// </summary>
[Display(Name = "修改人")]
[MaxLength(30)]
[Column(TypeName = "nvarchar(30)")]
[Editable(true)]
public string Modifier { get; set; }
/// <summary>
///修改时间
/// </summary>
[Display(Name = "修改时间")]
[Column(TypeName = "datetime")]
[Editable(true)]
public DateTime? ModifyDate { get; set; }
}
public class TableExtra
{
/// <summary>
/// 从表1
/// </summary>
public List<Table1> Table1List { get; set; }
/// <summary>
/// 从表2
/// </summary>
public List<Table2> Table2List { get; set; }
}
public class where
{
public string name { get; set; }
public string value { get; set; }
}
}

View File

@ -0,0 +1,41 @@
/*
*Cal_PlanShift类的业务代码应在此处编写
*使repository.EF/Dapper等信息
*使repository.DbContextBeginTransaction
*使DBServerProvider.
*使UserContext.Current操作
*Cal_PlanShiftService对增ServiceFunFilter
*/
using iMES.Core.BaseProvider;
using iMES.Core.Extensions.AutofacManager;
using iMES.Entity.DomainModels;
using System.Linq;
using iMES.Core.Utilities;
using System.Linq.Expressions;
using iMES.Core.Extensions;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Http;
using iMES.Calendar.IRepositories;
namespace iMES.Calendar.Services
{
public partial class Cal_PlanShiftService
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly ICal_PlanShiftRepository _repository;//访问数据库
[ActivatorUtilitiesConstructor]
public Cal_PlanShiftService(
ICal_PlanShiftRepository dbRepository,
IHttpContextAccessor httpContextAccessor
)
: base(dbRepository)
{
_httpContextAccessor = httpContextAccessor;
_repository = dbRepository;
//多租户会用到这init代码其他情况可以不用
//base.Init(dbRepository);
}
}
}

View File

@ -0,0 +1,41 @@
/*
*Cal_PlanTeam类的业务代码应在此处编写
*使repository.EF/Dapper等信息
*使repository.DbContextBeginTransaction
*使DBServerProvider.
*使UserContext.Current操作
*Cal_PlanTeamService对增ServiceFunFilter
*/
using iMES.Core.BaseProvider;
using iMES.Core.Extensions.AutofacManager;
using iMES.Entity.DomainModels;
using System.Linq;
using iMES.Core.Utilities;
using System.Linq.Expressions;
using iMES.Core.Extensions;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Http;
using iMES.Calendar.IRepositories;
namespace iMES.Calendar.Services
{
public partial class Cal_PlanTeamService
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly ICal_PlanTeamRepository _repository;//访问数据库
[ActivatorUtilitiesConstructor]
public Cal_PlanTeamService(
ICal_PlanTeamRepository dbRepository,
IHttpContextAccessor httpContextAccessor
)
: base(dbRepository)
{
_httpContextAccessor = httpContextAccessor;
_repository = dbRepository;
//多租户会用到这init代码其他情况可以不用
//base.Init(dbRepository);
}
}
}

View File

@ -0,0 +1,41 @@
/*
*Cal_TeamMember类的业务代码应在此处编写
*使repository.EF/Dapper等信息
*使repository.DbContextBeginTransaction
*使DBServerProvider.
*使UserContext.Current操作
*Cal_TeamMemberService对增ServiceFunFilter
*/
using iMES.Core.BaseProvider;
using iMES.Core.Extensions.AutofacManager;
using iMES.Entity.DomainModels;
using System.Linq;
using iMES.Core.Utilities;
using System.Linq.Expressions;
using iMES.Core.Extensions;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Http;
using iMES.Calendar.IRepositories;
namespace iMES.Calendar.Services
{
public partial class Cal_TeamMemberService
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly ICal_TeamMemberRepository _repository;//访问数据库
[ActivatorUtilitiesConstructor]
public Cal_TeamMemberService(
ICal_TeamMemberRepository dbRepository,
IHttpContextAccessor httpContextAccessor
)
: base(dbRepository)
{
_httpContextAccessor = httpContextAccessor;
_repository = dbRepository;
//多租户会用到这init代码其他情况可以不用
//base.Init(dbRepository);
}
}
}

View File

@ -0,0 +1,101 @@
/*
*Cal_Team类的业务代码应在此处编写
*使repository.EF/Dapper等信息
*使repository.DbContextBeginTransaction
*使DBServerProvider.
*使UserContext.Current操作
*Cal_TeamService对增ServiceFunFilter
*/
using iMES.Core.BaseProvider;
using iMES.Core.Extensions.AutofacManager;
using iMES.Entity.DomainModels;
using System.Linq;
using iMES.Core.Utilities;
using System.Linq.Expressions;
using iMES.Core.Extensions;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Http;
using iMES.Calendar.IRepositories;
using iMES.Custom.IRepositories;
using System;
namespace iMES.Calendar.Services
{
public partial class Cal_TeamService
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly ICal_TeamRepository _repository;//访问数据库
private readonly IBase_NumberRuleRepository _numberRuleRepository;//自定义编码规则访问数据库
[ActivatorUtilitiesConstructor]
public Cal_TeamService(
ICal_TeamRepository dbRepository,
IBase_NumberRuleRepository numberRuleRepository,
IHttpContextAccessor httpContextAccessor
)
: base(dbRepository)
{
_httpContextAccessor = httpContextAccessor;
_numberRuleRepository = numberRuleRepository;
_repository = dbRepository;
//多租户会用到这init代码其他情况可以不用
//base.Init(dbRepository);
}
WebResponseContent webResponse = new WebResponseContent();
/// <summary>
/// 新建
/// </summary>
/// <param name="saveDataModel"></param>
/// <returns></returns>
public override WebResponseContent Add(SaveModel saveDataModel)
{
//此处saveModel是从前台提交的原生数据可对数据进修改过滤
AddOnExecuting = (Cal_Team tm, object list) =>
{
if (string.IsNullOrWhiteSpace(tm.TeamCode))
tm.TeamCode = GetTeamCode();
//如果返回false,后面代码不会再执行
if (repository.Exists(x => x.TeamCode == tm.TeamCode))
{
return webResponse.Error("班组编码已存在");
}
return webResponse.OK();
};
return base.Add(saveDataModel);
}
/// <summary>
/// 自动生成设备编号
/// </summary>
/// <returns></returns>
public string GetTeamCode()
{
DateTime dateNow = (DateTime)DateTime.Now.ToString("yyyy-MM-dd").GetDateTime();
//查询当天最新的订单号
string defectItemCode = repository.FindAsIQueryable(x => x.CreateDate > dateNow && x.TeamCode.Length > 8)
.OrderByDescending(x => x.TeamCode)
.Select(s => s.TeamCode)
.FirstOrDefault();
Base_NumberRule numberRule = _numberRuleRepository.FindAsIQueryable(x => x.FormCode == "Team")
.OrderByDescending(x => x.CreateDate)
.FirstOrDefault();
if (numberRule != null)
{
string rule = numberRule.Prefix + DateTime.Now.ToString(numberRule.SubmitTime.Replace("hh", "HH"));
if (string.IsNullOrEmpty(defectItemCode))
{
rule += "1".PadLeft(numberRule.SerialNumber, '0');
}
else
{
rule += (defectItemCode.Substring(defectItemCode.Length - numberRule.SerialNumber).GetInt() + 1).ToString("0".PadLeft(numberRule.SerialNumber, '0'));
}
return rule;
}
else //如果自定义序号配置项不存在,则使用日期生成
{
return DateTime.Now.ToString("yyyyMMddHHmmssffff");
}
}
}
}

View File

@ -0,0 +1,41 @@
/*
*Cal_TeamShift类的业务代码应在此处编写
*使repository.EF/Dapper等信息
*使repository.DbContextBeginTransaction
*使DBServerProvider.
*使UserContext.Current操作
*Cal_TeamShiftService对增ServiceFunFilter
*/
using iMES.Core.BaseProvider;
using iMES.Core.Extensions.AutofacManager;
using iMES.Entity.DomainModels;
using System.Linq;
using iMES.Core.Utilities;
using System.Linq.Expressions;
using iMES.Core.Extensions;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Http;
using iMES.Calendar.IRepositories;
namespace iMES.Calendar.Services
{
public partial class Cal_TeamShiftService
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly ICal_TeamShiftRepository _repository;//访问数据库
[ActivatorUtilitiesConstructor]
public Cal_TeamShiftService(
ICal_TeamShiftRepository dbRepository,
IHttpContextAccessor httpContextAccessor
)
: base(dbRepository)
{
_httpContextAccessor = httpContextAccessor;
_repository = dbRepository;
//多租户会用到这init代码其他情况可以不用
//base.Init(dbRepository);
}
}
}

View File

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\iMES.Core\iMES.Core.csproj" />
<ProjectReference Include="..\iMES.Custom\iMES.Custom.csproj" />
<ProjectReference Include="..\iMES.Entity\iMES.Entity.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,10 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace iMES.Core.BaseInterface
{
public interface IServices
{
}
}

View File

@ -0,0 +1,60 @@
using iMES.Core.Dapper;
using iMES.Core.DBManager;
using iMES.Core.EFDbContext;
using iMES.Core.Extensions;
using iMES.Entity.DomainModels;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using System;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace iMES.Core.BaseProvider.DictionaryComponent
{
/// <summary>
/// 组件视图参照https://docs.microsoft.com/en-us/aspnet/core/mvc/views/view-components?view=aspnetcore-2.1
/// 与Controller命名一样必须以ViewComponent结尾
/// </summary>
public class DictionaryViewComponent : ViewComponent
{
public async Task<IViewComponentResult> InvokeAsync(string dropDownIds)
{
if (string.IsNullOrEmpty(dropDownIds))
return null;
string[] dicNos = dropDownIds.Split(',');
StringBuilder stringBuilder = new StringBuilder();
SysDbContext context = DBServerProvider.GetEFDbContext();
var dicData =await (from d in context.Set<Sys_Dictionary>()
join list in context.Set<Sys_DictionaryList>()
on d.Dic_ID equals list.Dic_ID
into t
from list in t.DefaultIfEmpty()
where dicNos.Contains(d.DicNo)
select new { list.DicValue, list.DicName, d.Config, d.DbSql, list.OrderNo, d.DicNo }).ToListAsync();
foreach (var item in dicData.GroupBy(x => x.DicNo))
{
stringBuilder.AppendLine($" var optionConfig{item.Key} = {item.Select(x => x.Config).FirstOrDefault()}");
string dbSql = item.Select(s => s.DbSql).FirstOrDefault();
stringBuilder.AppendLine($@" var dataSource{item.Key} = {
(!string.IsNullOrEmpty(dbSql)
? DBServerProvider.GetSqlDapper().QueryList<object>(dbSql, null).Serialize()
: item.OrderByDescending(o => o.OrderNo).
Select(s => new { s.DicName, s.DicValue }).ToList()
.Serialize())
}.convertToValueText(optionConfig{item.Key})");
stringBuilder.AppendLine($" optionConfig{item.Key}.data = dataSource{item.Key};");
}
ViewBag.Dic = stringBuilder.ToString();
return View("~/Views/Shared/Dictionary.cshtml");
}
}
}

View File

@ -0,0 +1,287 @@
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore.Query;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using iMES.Core.Dapper;
using iMES.Core.EFDbContext;
using iMES.Core.Enums;
using iMES.Core.Utilities;
using iMES.Entity.SystemModels;
namespace iMES.Core.BaseProvider
{
public interface IRepository<TEntity> where TEntity : BaseEntity
{
/// <summary>
/// EF DBContext
/// </summary>
BaseDbContext DbContext { get; }
ISqlDapper DapperContext { get; }
/// <summary>
/// 执行事务。将在执行的方法带入Action
/// </summary>
/// <param name="action"></param>
/// <returns></returns>
WebResponseContent DbContextBeginTransaction(Func<WebResponseContent> action);
/// <summary>
/// 通过条件查询数据
/// </summary>
/// <param name="where"></param>
/// <returns></returns>
List<TEntity> Find(Expression<Func<TEntity, bool>> where);
/// <summary>
///
/// </summary>
/// <param name="predicate"></param>
/// <param name="orderBySelector">排序字段,数据格式如:
/// orderBy = x => new Dictionary<object, bool>() {
/// { x.BalconyName,QueryOrderBy.Asc},
/// { x.TranCorpCode1,QueryOrderBy.Desc}
/// };
///
/// </param>
/// <returns></returns>
TEntity FindFirst(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, Dictionary<object, QueryOrderBy>>> orderBy = null);
/// <summary>
///
/// </summary>
/// <param name="predicate">where条件</param>
/// <param name="orderBy">排序字段,数据格式如:
/// orderBy = x => new Dictionary<object, bool>() {
/// { x.BalconyName,QueryOrderBy.Asc},
/// { x.TranCorpCode1,QueryOrderBy.Desc}
/// };
/// </param>
/// <returns></returns>
IQueryable<TEntity> FindAsIQueryable(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, Dictionary<object, QueryOrderBy>>> orderBy = null);
/// <summary>
/// 通过条件查询数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="predicate">查询条件</param>
/// <param name="selector">返回类型如:Find(x => x.UserName == loginInfo.userName, p => new { uname = p.UserName });</param>
/// <returns></returns>
List<T> Find<T>(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, T>> selector);
/// <summary>
/// 根据条件,返回查询的类
/// </summary>
/// <typeparam name="TFind"></typeparam>
/// <param name="predicate"></param>
/// <returns></returns>
List<TFind> Find<TFind>(Expression<Func<TFind, bool>> predicate) where TFind : class;
Task<TFind> FindAsyncFirst<TFind>(Expression<Func<TFind, bool>> predicate) where TFind : class;
Task<TEntity> FindAsyncFirst(Expression<Func<TEntity, bool>> predicate);
Task<List<TFind>> FindAsync<TFind>(Expression<Func<TFind, bool>> predicate) where TFind : class;
Task<TEntity> FindFirstAsync(Expression<Func<TEntity, bool>> predicate);
Task<List<TEntity>> FindAsync(Expression<Func<TEntity, bool>> predicate);
Task<List<T>> FindAsync<T>(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, T>> selector);
Task<T> FindFirstAsync<T>(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, T>> selector);
/// <summary>
/// 多条件查询
/// </summary>
/// <typeparam name="Source"></typeparam>
/// <param name="sources">要查询的多个条件的数据源</param>
/// <param name="predicate">生成的查询条件</param>
/// <returns></returns>
List<TEntity> Find<Source>(IEnumerable<Source> sources,
Func<Source, Expression<Func<TEntity, bool>>> predicate)
where Source : class;
/// <summary>
/// 多条件查询
/// </summary>
/// <typeparam name="Source"></typeparam>
/// <param name="sources">要查询的多个条件的数据源</param>
/// <param name="predicate">生成的查询条件</param>
/// <param name="selector">自定义返回结果</param>
/// <returns></returns>
List<TResult> Find<Source, TResult>(IEnumerable<Source> sources,
Func<Source, Expression<Func<TEntity, bool>>> predicate,
Expression<Func<TEntity, TResult>> selector)
where Source : class;
/// <summary>
/// 多条件查询
/// </summary>
/// <typeparam name="Source"></typeparam>
/// <param name="sources">要查询的多个条件的数据源</param>
/// <param name="predicate">生成的查询条件</param>
/// <returns></returns>
IQueryable<TEntity> FindAsIQueryable<Source>(IEnumerable<Source> sources,
Func<Source, Expression<Func<TEntity, bool>>> predicate)
where Source : class;
Task<bool> ExistsAsync(Expression<Func<TEntity, bool>> predicate);
bool Exists(Expression<Func<TEntity, bool>> predicate);
bool Exists<TExists>(Expression<Func<TExists, bool>> predicate) where TExists : class;
Task<bool> ExistsAsync<TExists>(Expression<Func<TExists, bool>> predicate) where TExists : class;
IIncludableQueryable<TEntity, TProperty> Include<TProperty>(Expression<Func<TEntity, TProperty>> incluedProperty);
/// <summary>
///
/// </summary>
/// <typeparam name="TResult"></typeparam>
/// <param name="pageIndex"></param>
/// <param name="pagesize"></param>
/// <param name="rowcount"></param>
/// <param name="predicate"></param>
/// <param name="orderBy">
/// 通过多个字段排序Expression<Func<TEntity, Dictionary<object, bool>>>
/// orderBy = x => new Dictionary<object, bool>() {
/// { x.BalconyName,QueryOrderBy.Asc},
/// { x.TranCorpCode1,QueryOrderBy.Desc}
/// };
/// <param name="selectorResult">查询返回的对象</param>
/// <returns></returns>
List<TResult> QueryByPage<TResult>(int pageIndex, int pagesize, out int rowcount, Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, Dictionary<object, QueryOrderBy>>> orderBySelector, Expression<Func<TEntity, TResult>> selectorResult, bool returnRowCount = true);
List<TResult> QueryByPage<TResult>(int pageIndex, int pagesize, Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, Dictionary<object, QueryOrderBy>>> orderBy, Expression<Func<TEntity, TResult>> selectorResult = null);
/// <summary>
///
/// </summary>
/// <param name="pageIndex"></param>
/// <param name="pagesize"></param>
/// <param name="rowcount"></param>
/// <param name="predicate"></param>
/// <param name="orderBy"></param>
/// /// 通过多个字段排序Expression<Func<TEntity, Dictionary<object, bool>>>
/// orderBy = x => new Dictionary<object, bool>() {
/// { x.BalconyName,QueryOrderBy.Asc},
/// { x.TranCorpCode1,QueryOrderBy.Desc}
/// };
/// <returns></returns>
List<TEntity> QueryByPage(int pageIndex, int pagesize, out int rowcount, Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, Dictionary<object, QueryOrderBy>>> orderBy, bool returnRowCount = true);
IQueryable<TFind> IQueryablePage<TFind>(int pageIndex, int pagesize, out int rowcount, Expression<Func<TFind, bool>> predicate, Expression<Func<TEntity, Dictionary<object, QueryOrderBy>>> orderBy, bool returnRowCount = true) where TFind : class;
IQueryable<TEntity> IQueryablePage(IQueryable<TEntity> queryable, int pageIndex, int pagesize, out int rowcount, Dictionary<string, QueryOrderBy> orderBy, bool returnRowCount = true);
/// <summary>
///
/// </summary>
/// <param name="entity"></param>
/// <param name="properties">指定更新字段:x=>new {x.Name,x.Enable}</param>
/// <param name="saveChanges">是否保存</param>
/// <returns></returns>
int Update(TEntity entity, Expression<Func<TEntity, object>> properties, bool saveChanges = false);
/// <summary>
///
/// </summary>
/// <param name="entity"></param>
/// <param name="properties">指定更新字段:x=>new {x.Name,x.Enable}</param>
/// <param name="saveChanges">是否保存</param>
/// <returns></returns>
int Update<TSource>(TSource entity, Expression<Func<TSource, object>> properties, bool saveChanges = false) where TSource : class;
int Update<TSource>(TSource entity, bool saveChanges = false) where TSource : class;
int Update<TSource>(TSource entity, string[] properties, bool saveChanges = false) where TSource : class;
int UpdateRange<TSource>(IEnumerable<TSource> entities, bool saveChanges = false) where TSource : class;
/// <summary>
///
/// </summary>
/// <param name="entity"></param>
/// <param name="properties">指定更新字段:x=>new {x.Name,x.Enable}</param>
/// <param name="saveChanges">是否保存</param>
/// <returns></returns>
int UpdateRange<TSource>(IEnumerable<TSource> models, Expression<Func<TSource, object>> properties, bool saveChanges = false) where TSource : class;
int UpdateRange<TSource>(IEnumerable<TSource> entities, string[] properties, bool saveChanges = false) where TSource : class;
/// <summary>
///修改时同时对明细的添加、删除、修改
/// </summary>
/// <param name="entity"></param>
/// <param name="updateDetail">是否修改明细</param>
/// <param name="delNotExist">是否删除明细不存在的数据</param>
/// <param name="updateMainFields">主表指定修改字段</param>
/// <param name="updateDetailFields">明细指定修改字段</param>
/// <param name="saveChange">是否保存</param>
/// <returns></returns>
WebResponseContent UpdateRange<Detail>(TEntity entity,
bool updateDetail = false,
bool delNotExist = false,
Expression<Func<TEntity, object>> updateMainFields = null,
Expression<Func<Detail, object>> updateDetailFields = null,
bool saveChange = false) where Detail : class;
void Delete(TEntity model, bool saveChanges=false);
/// <summary>
///
/// </summary>
/// <param name="keys"></param>
/// <param name="delList">是否将子表的数据也删除</param>
/// <returns></returns>
int DeleteWithKeys(object[] keys, bool delList = false);
void Add(TEntity entities, bool SaveChanges = false);
void AddRange(IEnumerable<TEntity> entities, bool SaveChanges = false);
Task AddAsync(TEntity entities);
Task AddRangeAsync(IEnumerable<TEntity> entities);
void AddRange<T>(IEnumerable<T> entities, bool saveChanges = false)
where T : class;
void BulkInsert(IEnumerable<TEntity> entities, bool setOutputIdentity = false);
int SaveChanges();
Task<int> SaveChangesAsync();
int ExecuteSqlCommand(string sql, params SqlParameter[] sqlParameters);
List<TEntity> FromSql(string sql, params SqlParameter[] sqlParameters);
/// <summary>
/// 执行sql
/// 使用方式 FormattableString sql=$"select * from xx where name ={xx} and pwd={xx1} "
/// FromSqlInterpolated内部处理sql注入的问题直接在{xx}写对应的值即可
/// 注意sql必须 select * 返回所有TEntity字段
/// </summary>
/// <param name="formattableString"></param>
/// <returns></returns>
IQueryable<TEntity> FromSqlInterpolated([System.Diagnostics.CodeAnalysis.NotNull] FormattableString sql);
/// <summary>
/// 取消上下文跟踪(2021.08.22)
/// 更新报错时请调用此方法The instance of entity type 'XXX' cannot be tracked because another instance with the same key value for {'XX'} is already being tracked.
/// </summary>
/// <param name="entity"></param>
void Detached(TEntity entity);
void DetachedRange(IEnumerable<TEntity> entities);
}
}

View File

@ -0,0 +1,138 @@

using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using iMES.Core.CacheManager;
using iMES.Core.Utilities;
using iMES.Entity.DomainModels;
using iMES.Entity.SystemModels;
namespace iMES.Core.BaseProvider
{
public interface IService<T> where T : BaseEntity
{
ICacheService CacheContext { get; }
Microsoft.AspNetCore.Http.HttpContext Context { get; }
/// <summary>
/// 查询
/// </summary>
/// <param name="pageData"></param>
/// <returns></returns>
PageGridData<T> GetPageData(PageDataOptions pageData);
object GetDetailPage(PageDataOptions pageData);
WebResponseContent Upload(List<IFormFile> files);
WebResponseContent DownLoadTemplate();
WebResponseContent Import(List<IFormFile> files);
/// <summary>
/// 导出
/// </summary>
/// <param name="pageData"></param>
/// <returns></returns>
WebResponseContent Export(PageDataOptions pageData);
/// <summary>
/// 新增
/// </summary>
/// <param name="saveDataModel">主表与子表的数据</param>
/// <returns></returns>
WebResponseContent Add(SaveModel saveDataModel);
/// <summary>
///
/// </summary>
/// <param name="entity">保存的实体</param>
/// <param name="validationEntity">是否对实体进行校验</param>
/// <returns></returns>
WebResponseContent AddEntity(T entity, bool validationEntity = true);
/// <summary>
///
/// </summary>
/// <typeparam name="TDetail"></typeparam>
/// <param name="entity">保存的实体</param>
/// <param name="list">保存的明细</param>
/// <param name="validationEntity">是否对实体进行校验</param>
/// <returns></returns>
WebResponseContent Add<TDetail>(T entity, List<TDetail> list = null, bool validationEntity = true) where TDetail : class;
/// <summary>
/// 编辑
/// </summary>
/// <param name="saveDataModel">主表与子表的数据</param>
/// <returns></returns>
WebResponseContent Update(SaveModel saveDataModel);
/// <summary>
/// 删除数据
/// </summary>
/// <param name="keys">删除的主键</param>
/// <param name="delList">是否删除对应明细(默认会删除明细)</param>
/// <returns></returns>
WebResponseContent Del(object[] keys, bool delList = true);
WebResponseContent Audit(object[] id, int? auditStatus, string auditReason);
(string, T, bool) ApiValidate(string bizContent, Expression<Func<T, object>> expression = null);
/// <summary>
///
/// </summary>
/// <typeparam name="TInput"></typeparam>
/// <param name="bizContent"></param>
/// <param name="expression">对指属性验证格式如x=>new { x.UserName,x.Value }</param>
/// <returns>(string,TInput, bool) string:返回验证消息,TInputbizContent序列化后的对象,bool:验证是否通过</returns>
(string, TInput, bool) ApiValidateInput<TInput>(string bizContent, Expression<Func<TInput, object>> expression);
/// <summary>
///
/// </summary>
/// <typeparam name="TInput"></typeparam>
/// <param name="bizContent"></param>
/// <param name="expression">对指属性验证格式如x=>new { x.UserName,x.Value }</param>
/// <param name="validateExpression">对指定的字段只做合法性判断比如长度是是否超长</param>
/// <returns>(string,TInput, bool) string:返回验证消息,TInputbizContent序列化后的对象,bool:验证是否通过</returns>
(string, TInput, bool) ApiValidateInput<TInput>(string bizContent, Expression<Func<TInput, object>> expression, Expression<Func<TInput, object>> validateExpression);
/// <summary>
/// 将数据源映射到新的数据中,List<TSource>映射到List<TResult>或TSource映射到TResult
/// 目前只支持Dictionary或实体类型
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <typeparam name="TResult"></typeparam>
/// <param name="source"></param>
/// <param name="resultExpression">只映射返回对象的指定字段</param>
/// <param name="sourceExpression">只映射数据源对象的指定字段</param>
/// 过滤条件表达式调用方式List表达式x => new { x[0].MenuName, x[0].Menu_Id}表示指定映射MenuName,Menu_Id字段
/// List<Sys_Menu> list = new List<Sys_Menu>();
/// list.MapToObject<List<Sys_Menu>, List<Sys_Menu>>(x => new { x[0].MenuName, x[0].Menu_Id}, null);
///
///过滤条件表达式调用方式实体表达式x => new { x.MenuName, x.Menu_Id}表示指定映射MenuName,Menu_Id字段
/// Sys_Menu sysMenu = new Sys_Menu();
/// sysMenu.MapToObject<Sys_Menu, Sys_Menu>(x => new { x.MenuName, x.Menu_Id}, null);
/// <returns></returns>
TResult MapToEntity<TSource, TResult>(TSource source, Expression<Func<TResult, object>> resultExpression,
Expression<Func<TSource, object>> sourceExpression = null) where TResult : class;
/// <summary>
/// 将一个实体的赋到另一个实体上,应用场景:
/// 两个实体a a1= new a();b b1= new b(); a1.P=b1.P; a1.Name=b1.Name;
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <typeparam name="TResult"></typeparam>
/// <param name="source"></param>
/// <param name="result"></param>
/// <param name="expression">指定对需要的字段赋值,格式x=>new {x.Name,x.P},返回的结果只会对Name与P赋值</param>
void MapValueToEntity<TSource, TResult>(TSource source, TResult result, Expression<Func<TResult, object>> expression = null) where TResult : class;
}
}

View File

@ -0,0 +1,630 @@
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.EntityFrameworkCore.Storage;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading.Tasks;
using iMES.Core.Dapper;
using iMES.Core.DBManager;
using iMES.Core.EFDbContext;
using iMES.Core.Enums;
using iMES.Core.Extensions;
using iMES.Core.Utilities;
using iMES.Entity;
using iMES.Entity.SystemModels;
namespace iMES.Core.BaseProvider
{
public abstract class RepositoryBase<TEntity> where TEntity : BaseEntity
{
public RepositoryBase()
{
}
public RepositoryBase(BaseDbContext dbContext)
{
this.DefaultDbContext = dbContext ?? throw new Exception("dbContext未实例化。");
}
private BaseDbContext DefaultDbContext { get; set; }
private BaseDbContext EFContext
{
get
{
//DBServerProvider.GetDbContextConnection<TEntity>(DefaultDbContext);
return DefaultDbContext;
}
}
public virtual BaseDbContext DbContext
{
get { return DefaultDbContext; }
}
private DbSet<TEntity> DBSet
{
get { return EFContext.Set<TEntity>(); }
}
public ISqlDapper DapperContext
{
get { return DBServerProvider.GetSqlDapper<TEntity>(); }
}
/// <summary>
/// 执行事务
/// </summary>
/// <param name="action">如果返回false则回滚事务(可自行定义规则)</param>
/// <returns></returns>
public virtual WebResponseContent DbContextBeginTransaction(Func<WebResponseContent> action)
{
WebResponseContent webResponse = new WebResponseContent();
using (IDbContextTransaction transaction = DefaultDbContext.Database.BeginTransaction())
{
try
{
webResponse = action();
if (webResponse.Status)
{
transaction.Commit();
}
else
{
transaction.Rollback();
}
return webResponse;
}
catch (Exception ex)
{
transaction.Rollback();
return new WebResponseContent().Error(ex.Message);
}
}
}
public virtual bool Exists<TExists>(Expression<Func<TExists, bool>> predicate) where TExists : class
{
return EFContext.Set<TExists>().Any(predicate);
}
public virtual Task<bool> ExistsAsync<TExists>(Expression<Func<TExists, bool>> predicate) where TExists : class
{
return EFContext.Set<TExists>().AnyAsync(predicate);
}
public virtual bool Exists(Expression<Func<TEntity, bool>> predicate)
{
return DBSet.Any(predicate);
}
public virtual Task<bool> ExistsAsync(Expression<Func<TEntity, bool>> predicate)
{
return DBSet.AnyAsync(predicate);
}
public virtual List<TFind> Find<TFind>(Expression<Func<TFind, bool>> predicate) where TFind : class
{
return EFContext.Set<TFind>().Where(predicate).ToList();
}
public virtual Task<TFind> FindAsyncFirst<TFind>(Expression<Func<TFind, bool>> predicate) where TFind : class
{
return FindAsIQueryable<TFind>(predicate).FirstOrDefaultAsync();
}
public virtual Task<TEntity> FindAsyncFirst(Expression<Func<TEntity, bool>> predicate)
{
return FindAsIQueryable<TEntity>(predicate).FirstOrDefaultAsync();
}
public virtual Task<List<TFind>> FindAsync<TFind>(Expression<Func<TFind, bool>> predicate) where TFind : class
{
return FindAsIQueryable<TFind>(predicate).ToListAsync();
}
public virtual Task<List<TEntity>> FindAsync(Expression<Func<TEntity, bool>> predicate)
{
return FindAsIQueryable(predicate).ToListAsync();
}
public virtual Task<TEntity> FindFirstAsync(Expression<Func<TEntity, bool>> predicate)
{
return FindAsIQueryable(predicate).FirstOrDefaultAsync();
}
public virtual Task<List<T>> FindAsync<T>(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, T>> selector)
{
return FindAsIQueryable(predicate).Select(selector).ToListAsync();
}
public virtual Task<T> FindFirstAsync<T>(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, T>> selector)
{
return FindAsIQueryable(predicate).Select(selector).FirstOrDefaultAsync();
}
public virtual IQueryable<TFind> FindAsIQueryable<TFind>(Expression<Func<TFind, bool>> predicate) where TFind : class
{
return EFContext.Set<TFind>().Where(predicate);
}
public virtual List<TEntity> Find<Source>(IEnumerable<Source> sources,
Func<Source, Expression<Func<TEntity, bool>>> predicate)
where Source : class
{
return FindAsIQueryable(sources, predicate).ToList();
}
public virtual List<TResult> Find<Source, TResult>(IEnumerable<Source> sources,
Func<Source, Expression<Func<TEntity, bool>>> predicate,
Expression<Func<TEntity, TResult>> selector)
where Source : class
{
return FindAsIQueryable(sources, predicate).Select(selector).ToList();
}
/// <summary>
/// 多条件查询
/// </summary>
/// <typeparam name="Source"></typeparam>
/// <param name="sources"></param>
/// <param name="predicate"></param>
/// <returns></returns>
public virtual IQueryable<TEntity> FindAsIQueryable<Source>(IEnumerable<Source> sources,
Func<Source, Expression<Func<TEntity, bool>>> predicate)
where Source : class
{
// EFContext.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.TrackAll;
Expression<Func<TEntity, bool>> resultPredicate = x => 1 == 2;
foreach (Source source in sources)
{
Expression<Func<TEntity, bool>> expression = predicate(source);
resultPredicate = (resultPredicate).Or<TEntity>((expression));
}
return EFContext.Set<TEntity>().Where(resultPredicate);
}
public virtual List<T> Find<T>(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, T>> selector)
{
return DBSet.Where(predicate).Select(selector).ToList();
}
/// <summary>
/// 单表查询
/// </summary>
/// <param name="predicate"></param>
/// <returns></returns>
public virtual List<TEntity> Find(Expression<Func<TEntity, bool>> predicate)
{
return FindAsIQueryable(predicate).ToList();
}
/// <summary>
///
/// </summary>
/// <param name="predicate"></param>
/// <param name=""></param>
/// <param name="orderBy">排序字段</param>
/// <returns></returns>
public virtual TEntity FindFirst(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, Dictionary<object, QueryOrderBy>>> orderBy = null)
{
return FindAsIQueryable(predicate, orderBy).FirstOrDefault();
}
public IQueryable<TEntity> FindAsIQueryable(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, Dictionary<object, QueryOrderBy>>> orderBy = null)
{
if (orderBy != null)
return DbContext.Set<TEntity>().Where(predicate).GetIQueryableOrderBy(orderBy.GetExpressionToDic());
return DbContext.Set<TEntity>().Where(predicate);
}
public IIncludableQueryable<TEntity, TProperty> Include<TProperty>(Expression<Func<TEntity, TProperty>> incluedProperty)
{
return DbContext.Set<TEntity>().Include(incluedProperty);
}
/// <summary>
/// 通过条件查询返回指定列的数据(将TEntity映射到匿名或实体T)
///var result = Sys_UserRepository.GetInstance.Find(x => x.UserName == loginInfo.userName, p => new { uname = p.UserName });
/// <summary>
///
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <param name="pageIndex"></param>
/// <param name="pagesize"></param>
/// <param name="rowcount"></param>
/// <param name="predicate">查询条件</param>
/// <param name="orderBySelector">多个排序字段key为字段value为升序/降序</param>
/// <returns></returns>
public virtual IQueryable<TFind> IQueryablePage<TFind>(int pageIndex, int pagesize, out int rowcount, Expression<Func<TFind, bool>> predicate, Expression<Func<TEntity, Dictionary<object, QueryOrderBy>>> orderBy, bool returnRowCount = true) where TFind : class
{
pageIndex = pageIndex <= 0 ? 1 : pageIndex;
pagesize = pagesize <= 0 ? 10 : pagesize;
if (predicate == null)
{
predicate = x => 1 == 1;
}
var _db = DbContext.Set<TFind>();
rowcount = returnRowCount ? _db.Count(predicate) : 0;
return DbContext.Set<TFind>().Where(predicate)
.GetIQueryableOrderBy(orderBy.GetExpressionToDic())
.Skip((pageIndex - 1) * pagesize)
.Take(pagesize);
}
/// <summary>
/// 分页排序
/// </summary>
/// <param name="queryable"></param>
/// <param name="pageIndex"></param>
/// <param name="pagesize"></param>
/// <param name="rowcount"></param>
/// <param name="orderBy"></param>
/// <returns></returns>
public virtual IQueryable<TEntity> IQueryablePage(IQueryable<TEntity> queryable, int pageIndex, int pagesize, out int rowcount, Dictionary<string, QueryOrderBy> orderBy, bool returnRowCount = true)
{
pageIndex = pageIndex <= 0 ? 1 : pageIndex;
pagesize = pagesize <= 0 ? 10 : pagesize;
rowcount = returnRowCount ? queryable.Count() : 0;
return queryable.GetIQueryableOrderBy<TEntity>(orderBy)
.Skip((pageIndex - 1) * pagesize)
.Take(pagesize);
}
public virtual List<TResult> QueryByPage<TResult>(int pageIndex, int pagesize, out int rowcount, Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, Dictionary<object, QueryOrderBy>>> orderBy, Expression<Func<TEntity, TResult>> selectorResult, bool returnRowCount = true)
{
return IQueryablePage<TEntity>(pageIndex, pagesize, out rowcount, predicate, orderBy, returnRowCount).Select(selectorResult).ToList();
}
public List<TEntity> QueryByPage(int pageIndex, int pagesize, out int rowcount, Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, Dictionary<object, QueryOrderBy>>> orderBy, bool returnRowCount = true)
{
return IQueryablePage<TEntity>(pageIndex, pagesize, out rowcount, predicate, orderBy).ToList();
}
public virtual List<TResult> QueryByPage<TResult>(int pageIndex, int pagesize, Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, Dictionary<object, QueryOrderBy>>> orderBy, Expression<Func<TEntity, TResult>> selectorResult = null)
{
return IQueryablePage<TEntity>(pageIndex, pagesize, out int rowcount, predicate, orderBy).Select(selectorResult).ToList();
}
/// <summary>
/// 更新表数据
/// </summary>
/// <param name="entity"></param>
/// <param name="saveChanges">是否保存</param>
/// <param name="properties">格式 Expression<Func<entityt, object>> expTree = x => new { x.字段1, x.字段2 };</param>
public virtual int Update(TEntity entity, Expression<Func<TEntity, object>> properties, bool saveChanges = false)
{
return Update<TEntity>(entity, properties, saveChanges);
}
public virtual int Update<TSource>(TSource entity, Expression<Func<TSource, object>> properties, bool saveChanges = false) where TSource : class
{
return UpdateRange(new List<TSource>
{
entity
}, properties, saveChanges);
}
public virtual int Update<TSource>(TSource entity, string[] properties, bool saveChanges = false) where TSource : class
{
return UpdateRange<TSource>(new List<TSource>() { entity }, properties, saveChanges);
}
public virtual int Update<TSource>(TSource entity, bool saveChanges = false) where TSource : class
{
return UpdateRange<TSource>(new List<TSource>() { entity }, new string[0], saveChanges);
}
public virtual int UpdateRange<TSource>(IEnumerable<TSource> entities, Expression<Func<TSource, object>> properties, bool saveChanges = false) where TSource : class
{
return UpdateRange<TSource>(entities, properties?.GetExpressionProperty(), saveChanges);
}
public virtual int UpdateRange<TSource>(IEnumerable<TSource> entities, bool saveChanges = false) where TSource : class
{
return UpdateRange<TSource>(entities, new string[0], saveChanges);
}
/// <summary>
/// 更新表数据
/// </summary>
/// <param name="models"></param>
/// <param name="properties">格式 Expression<Func<entityt, object>> expTree = x => new { x.字段1, x.字段2 };</param>
public int UpdateRange<TSource>(IEnumerable<TSource> entities, string[] properties, bool saveChanges = false) where TSource : class
{
if (properties != null && properties.Length > 0)
{
PropertyInfo[] entityProperty = typeof(TSource).GetProperties();
string keyName = entityProperty.GetKeyName();
if (properties.Contains(keyName))
{
properties = properties.Where(x => x != keyName).ToArray();
}
properties = properties.Where(x => entityProperty.Select(s => s.Name).Contains(x)).ToArray();
}
foreach (TSource item in entities)
{
if (properties == null || properties.Length == 0)
{
DbContext.Entry<TSource>(item).State = EntityState.Modified;
continue;
}
var entry = DbContext.Entry(item);
properties.ToList().ForEach(x =>
{
entry.Property(x).IsModified = true;
});
}
if (!saveChanges) return 0;
//2020.04.24增加更新时并行重试处理
try
{
// Attempt to save changes to the database
return DbContext.SaveChanges();
}
catch (DbUpdateConcurrencyException ex)
{
int affectedRows = 0;
foreach (var entry in ex.Entries)
{
var proposedValues = entry.CurrentValues;
var databaseValues = entry.GetDatabaseValues();
//databaseValues == null说明数据已被删除
if (databaseValues != null)
{
foreach (var property in properties == null
|| properties.Length == 0 ? proposedValues.Properties
: proposedValues.Properties.Where(x => properties.Contains(x.Name)))
{
var proposedValue = proposedValues[property];
var databaseValue = databaseValues[property];
}
affectedRows++;
entry.OriginalValues.SetValues(databaseValues);
}
}
if (affectedRows == 0) return 0;
return DbContext.SaveChanges();
}
}
/// <summary>
///
/// </summary>
/// <param name="entity"></param>
/// <param name="updateDetail">是否修改明细</param>
/// <param name="delNotExist">是否删除明细不存在的数据</param>
/// <param name="updateMainFields">主表指定修改字段</param>
/// <param name="updateDetailFields">明细指定修改字段</param>
/// <param name="saveChange">是否保存</param>
/// <returns></returns>
public virtual WebResponseContent UpdateRange<Detail>(TEntity entity,
bool updateDetail = false,
bool delNotExist = false,
Expression<Func<TEntity, object>> updateMainFields = null,
Expression<Func<Detail, object>> updateDetailFields = null,
bool saveChange = false) where Detail : class
{
WebResponseContent webResponse = new WebResponseContent();
Update(entity, updateMainFields);
string message = "";
if (updateDetail)
{
PropertyInfo[] properties = typeof(TEntity).GetProperties();
PropertyInfo detail = properties.Where(x => x.PropertyType.Name == "List`1").ToList().FirstOrDefault();
if (detail != null)
{
PropertyInfo key = properties.GetKeyProperty();
object obj = detail.GetValue(entity);
Type detailType = typeof(TEntity).GetCustomAttribute<EntityAttribute>().DetailTable[0];
message = UpdateDetail<Detail>(obj as List<Detail>, key.Name, key.GetValue(entity), updateDetailFields, delNotExist);
}
}
if (!saveChange) return webResponse.OK();
DbContext.SaveChanges();
return webResponse.OK("修改成功,明细" + message, entity);
}
private string UpdateDetail<TDetail>(List<TDetail> list,
string keyName,
object keyValue,
Expression<Func<TDetail, object>> updateDetailFields = null,
bool delNotExist = false) where TDetail : class
{
if (list == null) return "";
PropertyInfo property = typeof(TDetail).GetKeyProperty();
string detailKeyName = property.Name;
DbSet<TDetail> details = DbContext.Set<TDetail>();
Expression<Func<TDetail, object>> selectExpression = detailKeyName.GetExpression<TDetail, object>();
Expression<Func<TDetail, bool>> whereExpression = keyName.CreateExpression<TDetail>(keyValue, LinqExpressionType.Equal);
List<object> detailKeys = details.Where(whereExpression).Select(selectExpression).ToList();
//获取主键默认值
string keyDefaultVal = property.PropertyType
.Assembly
.CreateInstance(property.PropertyType.FullName).ToString();
int addCount = 0;
int editCount = 0;
int delCount = 0;
PropertyInfo mainKeyProperty = typeof(TDetail).GetProperty(keyName);
List<object> keys = new List<object>();
list.ForEach(x =>
{
var set = DbContext.Set<TDetail>();
object val = property.GetValue(x);
//主键是默认值的为新增的数据
if (val.ToString() == keyDefaultVal)
{
x.SetCreateDefaultVal();
//设置主表的值,也可以不设置
mainKeyProperty.SetValue(x, keyValue);
details.Add(x);
addCount++;
}
else//修改的数据
{
//获取所有修改的key,如果从数据库查来的key,不在修改中的key则为删除的数据
keys.Add(val);
x.SetModifyDefaultVal();
Update<TDetail>(x, updateDetailFields);
// repository.DbContext.Entry<TDetail>(x).State = EntityState.Modified;
editCount++;
}
});
//删除
if (delNotExist)
{
detailKeys.Where(x => !keys.Contains(x)).ToList().ForEach(d =>
{
delCount++;
TDetail detail = Activator.CreateInstance<TDetail>();
property.SetValue(detail, d);
DbContext.Entry<TDetail>(detail).State = EntityState.Deleted;
for (int i = 0; i < list.Count(); i++)
{
if (property.GetValue(list[i]) == d)
{
list.RemoveAt(i);
}
}
});
}
return $"修改[{editCount}]条,新增[{addCount}]条,删除[{delCount}]条";
}
public virtual void Delete(TEntity model, bool saveChanges)
{
DBSet.Remove(model);
if (saveChanges)
{
DbContext.SaveChanges();
}
}
/// <summary>
/// 通过主键批量删除
/// </summary>
/// <param name="keys">主键key</param>
/// <param name="delList">是否连明细一起删除</param>
/// <returns></returns>
public virtual int DeleteWithKeys(object[] keys, bool delList = false)
{
Type entityType = typeof(TEntity);
string tKey = entityType.GetKeyProperty().Name;
FieldType fieldType = entityType.GetFieldType();
string joinKeys = (fieldType == FieldType.Int || fieldType == FieldType.BigInt)
? string.Join(",", keys)
: $"'{string.Join("','", keys)}'";
string sql = $"DELETE FROM {entityType.GetEntityTableName() } where {tKey} in ({joinKeys});";
if (delList)
{
Type detailType = entityType.GetCustomAttribute<EntityAttribute>().DetailTable?[0];
if (detailType != null)
sql = sql + $"DELETE FROM {detailType.GetEntityTableName()} where {tKey} in ({joinKeys});";
}
return ExecuteSqlCommand(sql);
}
public virtual Task AddAsync(TEntity entities)
{
return DBSet.AddRangeAsync(entities);
}
public virtual Task AddRangeAsync(IEnumerable<TEntity> entities)
{
return DBSet.AddRangeAsync(entities);
}
public virtual void Add(TEntity entities, bool saveChanges = false)
{
AddRange(new List<TEntity>() { entities }, saveChanges);
}
public virtual void AddRange(IEnumerable<TEntity> entities, bool saveChanges = false)
{
DBSet.AddRange(entities);
if (saveChanges) DbContext.SaveChanges();
}
public virtual void AddRange<T>(IEnumerable<T> entities, bool saveChanges = false)
where T : class
{
DbContext.Set<T>().AddRange(entities);
if (saveChanges) DbContext.SaveChanges();
}
/// <summary>
/// 注意List生成的table的列顺序必须要和数据库表的列顺序一致
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entities"></param>
public virtual void BulkInsert(IEnumerable<TEntity> entities, bool setOutputIdentity = false)
{
// EFContext.Model.FindEntityType("").Relational()
//Pomelo.EntityFrameworkCore.MySql
try
{
// EFContext.BulkInsert(entities.ToList());
}
catch (DbUpdateException ex)
{
throw (ex.InnerException as Exception ?? ex);
}
// BulkInsert(entities.ToDataTable(), typeof(T).GetEntityTableName(), null);
}
public virtual int SaveChanges()
{
return EFContext.SaveChanges();
}
public virtual Task<int> SaveChangesAsync()
{
return EFContext.SaveChangesAsync();
}
public virtual int ExecuteSqlCommand(string sql, params SqlParameter[] sqlParameters)
{
return DbContext.Database.ExecuteSqlRaw(sql, sqlParameters);
}
public virtual List<TEntity> FromSql(string sql, params SqlParameter[] sqlParameters)
{
return DBSet.FromSqlRaw(sql, sqlParameters).ToList();
}
/// <summary>
/// 执行sql
/// 使用方式 FormattableString sql=$"select * from xx where name ={xx} and pwd={xx1} "
/// FromSqlInterpolated内部处理sql注入的问题直接在{xx}写对应的值即可
/// 注意sql必须 select * 返回所有TEntity字段
/// </summary>
/// <param name="formattableString"></param>
/// <returns></returns>
public virtual IQueryable<TEntity> FromSqlInterpolated([NotNull] FormattableString sql)
{
//DBSet.FromSqlInterpolated(sql).Select(x => new { x,xxx}).ToList();
return DBSet.FromSqlInterpolated(sql);
}
/// <summary>
/// 取消上下文跟踪
/// </summary>
/// <param name="entity"></param>
public virtual void Detached(TEntity entity)
{
DbContext.Entry(entity).State = EntityState.Detached;
}
public virtual void DetachedRange(IEnumerable<TEntity> entities)
{
foreach (var entity in entities)
{
DbContext.Entry(entity).State = EntityState.Detached;
}
}
}
}

View File

@ -0,0 +1,52 @@

using Microsoft.AspNetCore.Hosting;
using System.IO;
using iMES.Core.Extensions;
using iMES.Core.Extensions.AutofacManager;
namespace iMES.Core.BaseProvider.ServerMapPath
{
public interface IPathProvider : IDependency
{
string MapPath(string path);
string MapPath(string path, bool rootPath);
IWebHostEnvironment GetHostingEnvironment();
}
public class PathProvider : IPathProvider
{
private IWebHostEnvironment _hostingEnvironment;
public PathProvider(IWebHostEnvironment environment)
{
_hostingEnvironment = environment;
}
public IWebHostEnvironment GetHostingEnvironment()
{
return _hostingEnvironment;
}
public string MapPath(string path)
{
return MapPath(path, false);
}
/// <summary>
///
/// </summary>
/// <param name="path"></param>
/// <param name="rootPath">获取wwwroot路径</param>
/// <returns></returns>
public string MapPath(string path, bool rootPath)
{
if (rootPath)
{
if (_hostingEnvironment.WebRootPath == null)
{
_hostingEnvironment.WebRootPath = _hostingEnvironment.ContentRootPath + "/wwwroot".ReplacePath();
}
return Path.Combine(_hostingEnvironment.WebRootPath, path).ReplacePath();
}
return Path.Combine(_hostingEnvironment.ContentRootPath, path).ReplacePath();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,95 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace iMES.Core.CacheManager
{
public interface ICacheService : IDisposable
{
/// <summary>
/// 验证缓存项是否存在
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
bool Exists(string key);
/// <summary>
/// List写入head
/// </summary>
/// <param name="key"></param>
/// <param name="val"></param>
void LPush(string key, string val);
void RPush(string key, string val);
/// <summary>
/// List出队 lpop
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
object ListDequeue(string key);
/// <summary>
/// List出队 lpop
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
T ListDequeue<T>(string key) where T : class;
/// <summary>
/// 移除list中的数据keepIndex为保留的位置到最后一个元素如list 元素为1.2.3.....100
/// 需要移除前3个数keepindex应该为4
/// </summary>
/// <param name="key"></param>
/// <param name="keepIndex"></param>
void ListRemove(string key, int keepIndex);
/// <summary>
/// 添加缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <param name="value">缓存Value</param>
/// <param name="expiresIn">缓存时长</param>
/// <param name="isSliding">是否滑动过期(如果在过期时间内有操作,则以当前时间点延长过期时间) //new TimeSpan(0, 60, 0);</param>
/// <returns></returns>
bool AddObject(string key, object value, int expireSeconds = -1, bool isSliding = false);
bool Add(string key, string value, int expireSeconds = -1, bool isSliding = false);
/// <summary>
/// 删除缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
bool Remove(string key);
/// <summary>
/// 批量删除缓存
/// </summary>
/// <param name="key">缓存Key集合</param>
/// <returns></returns>
void RemoveAll(IEnumerable<string> keys);
/// <summary>
/// 获取缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
T Get<T>(string key) where T : class;
/// <summary>
/// 获取缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
string Get(string key);
}
}

View File

@ -0,0 +1,189 @@

using Microsoft.Extensions.Caching.Memory;
using System;
using System.Collections.Generic;
using System.Linq;
namespace iMES.Core.CacheManager
{
public class MemoryCacheService : ICacheService
{
protected IMemoryCache _cache;
public MemoryCacheService(IMemoryCache cache)
{
_cache = cache;
}
/// <summary>
/// 验证缓存项是否存在
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
public bool Exists(string key)
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
return _cache.Get(key) != null;
}
/// <summary>
/// 添加缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <param name="value">缓存Value</param>
/// <returns></returns>
public bool Add(string key, object value)
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
_cache.Set(key, value);
return Exists(key);
}
public bool AddObject(string key, object value, int expireSeconds = -1, bool isSliding = false)
{
if (expireSeconds != -1)
{
_cache.Set(key,
value,
new MemoryCacheEntryOptions()
.SetSlidingExpiration(new TimeSpan(0, 0, expireSeconds))
);
}
else
{
_cache.Set(key, value);
}
return true;
}
public bool Add(string key, string value, int expireSeconds = -1, bool isSliding = false)
{
return AddObject(key, value, expireSeconds, isSliding);
}
public void LPush(string key, string val)
{
}
public void RPush(string key, string val)
{
}
public T ListDequeue<T>(string key) where T : class
{
return null;
}
public object ListDequeue(string key)
{
return null;
}
public void ListRemove(string key, int keepIndex)
{
}
/// <summary>
/// 添加缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <param name="value">缓存Value</param>
/// <param name="expiresSliding">滑动过期时长(如果在过期时间内有操作,则以当前时间点延长过期时间)</param>
/// <param name="expiressAbsoulte">绝对过期时长</param>
/// <returns></returns>
public bool Add(string key, object value, TimeSpan expiresSliding, TimeSpan expiressAbsoulte)
{
_cache.Set(key, value,
new MemoryCacheEntryOptions()
.SetSlidingExpiration(expiresSliding)
.SetAbsoluteExpiration(expiressAbsoulte)
);
return Exists(key);
}
/// <summary>
/// 添加缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <param name="value">缓存Value</param>
/// <param name="expiresIn">缓存时长</param>
/// <param name="isSliding">是否滑动过期(如果在过期时间内有操作,则以当前时间点延长过期时间)</param>
/// <returns></returns>
public bool Add(string key, object value, TimeSpan expiresIn, bool isSliding = false)
{
if (isSliding)
_cache.Set(key, value,
new MemoryCacheEntryOptions()
.SetSlidingExpiration(expiresIn)
);
else
_cache.Set(key, value,
new MemoryCacheEntryOptions()
.SetAbsoluteExpiration(expiresIn)
);
return Exists(key);
}
/// <summary>
/// 删除缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
public bool Remove(string key)
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
_cache.Remove(key);
return !Exists(key);
}
/// <summary>
/// 批量删除缓存
/// </summary>
/// <param name="key">缓存Key集合</param>
/// <returns></returns>
public void RemoveAll(IEnumerable<string> keys)
{
if (keys == null)
{
throw new ArgumentNullException(nameof(keys));
}
keys.ToList().ForEach(item => _cache.Remove(item));
}
public string Get(string key)
{
return _cache.Get(key)?.ToString();
}
/// <summary>
/// 获取缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
public T Get<T>(string key) where T : class
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
return _cache.Get(key) as T;
}
public void Dispose()
{
if (_cache != null)
_cache.Dispose();
GC.SuppressFinalize(this);
}
}
}

View File

@ -0,0 +1,119 @@
using CSRedis;
using Newtonsoft.Json;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using iMES.Core.Configuration;
using iMES.Core.Const;
namespace iMES.Core.CacheManager
{
public class RedisCacheService : ICacheService
{
public RedisCacheService()
{
var csredis = new CSRedisClient(AppSetting.RedisConnectionString);
RedisHelper.Initialization(csredis);
}
/// <summary>
/// 验证缓存项是否存在
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
public bool Exists(string key)
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
return RedisHelper.Exists(key);
}
public void LPush(string key, string val)
{
RedisHelper.LPush(key, val);
}
public void RPush(string key, string val)
{
RedisHelper.RPush(key, val);
}
public T ListDequeue<T>(string key) where T : class
{
string value = RedisHelper.RPop(key);
if (string.IsNullOrEmpty(value))
return null;
return JsonConvert.DeserializeObject<T>(value);
}
public object ListDequeue(string key)
{
string value = RedisHelper.RPop(key);
if (string.IsNullOrEmpty(value))
return null;
return value;
}
/// <summary>
/// 移除list中的数据keepIndex为保留的位置到最后一个元素如list 元素为1.2.3.....100
/// 需要移除前3个数keepindex应该为4
/// </summary>
/// <param name="key"></param>
/// <param name="keepIndex"></param>
public void ListRemove(string key, int keepIndex)
{
RedisHelper.LTrim(key, keepIndex, -1);
}
public bool Add(string key, string value, int expireSeconds = -1, bool isSliding = false)
{
return RedisHelper.Set(key, value, expireSeconds);
}
public bool AddObject(string key, object value, int expireSeconds = -1, bool isSliding = false)
{
return RedisHelper.Set(key, value, expireSeconds);
}
/// <summary>
/// 删除缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
public bool Remove(string key)
{
RedisHelper.Del(key);
return true;
}
/// <summary>
/// 批量删除缓存
/// </summary>
/// <param name="key">缓存Key集合</param>
/// <returns></returns>
public void RemoveAll(IEnumerable<string> keys)
{
RedisHelper.Del(keys.ToArray());
}
/// <summary>
/// 获取缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
public T Get<T>(string key) where T : class
{
return RedisHelper.Get<T>(key);
}
/// <summary>
/// 获取缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
public string Get(string key)
{
return RedisHelper.Get(key);
}
public void Dispose()
{
}
}
}

View File

@ -0,0 +1,183 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using System.IO;
using iMES.Core.Const;
using iMES.Core.Extensions;
namespace iMES.Core.Configuration
{
public static class AppSetting
{
public static IConfiguration Configuration { get; private set; }
public static string DbConnectionString
{
get { return _connection.DbConnectionString; }
}
public static string RedisConnectionString
{
get { return _connection.RedisConnectionString; }
}
public static bool UseRedis
{
get { return _connection.UseRedis; }
}
public static bool UseSignalR
{
get { return _connection.UseSignalR; }
}
public static Secret Secret { get; private set; }
public static CreateMember CreateMember { get; private set; }
public static ModifyMember ModifyMember { get; private set; }
private static Connection _connection;
public static string TokenHeaderName = "Authorization";
/// <summary>
/// Actions权限过滤
/// </summary>
public static GlobalFilter GlobalFilter { get; set; }
/// <summary>
/// kafka配置
/// </summary>
public static Kafka Kafka { get; set; }
/// <summary>
/// JWT有效期(分钟=默认120)
/// </summary>
public static int ExpMinutes { get; private set; } = 120;
public static string CurrentPath { get; private set; } = null;
public static string DownLoadPath { get { return CurrentPath + "\\Download\\"; } }
public static void Init(IServiceCollection services, IConfiguration configuration)
{
Configuration = configuration;
services.Configure<Secret>(configuration.GetSection("Secret"));
services.Configure<Connection>(configuration.GetSection("Connection"));
services.Configure<CreateMember>(configuration.GetSection("CreateMember"));
services.Configure<ModifyMember>(configuration.GetSection("ModifyMember"));
services.Configure<GlobalFilter>(configuration.GetSection("GlobalFilter"));
services.Configure<Kafka>(configuration.GetSection("Kafka"));
var provider = services.BuildServiceProvider();
IWebHostEnvironment environment = provider.GetRequiredService<IWebHostEnvironment>();
CurrentPath = Path.Combine(environment.ContentRootPath, "").ReplacePath();
Secret = provider.GetRequiredService<IOptions<Secret>>().Value;
//设置修改或删除时需要设置为默认用户信息的字段
CreateMember = provider.GetRequiredService<IOptions<CreateMember>>().Value ?? new CreateMember();
ModifyMember = provider.GetRequiredService<IOptions<ModifyMember>>().Value ?? new ModifyMember();
GlobalFilter = provider.GetRequiredService<IOptions<GlobalFilter>>().Value ?? new GlobalFilter();
GlobalFilter.Actions = GlobalFilter.Actions ?? new string[0];
Kafka = provider.GetRequiredService<IOptions<Kafka>>().Value ?? new Kafka();
_connection = provider.GetRequiredService<IOptions<Connection>>().Value;
ExpMinutes = (configuration["ExpMinutes"] ?? "120").GetInt();
DBType.Name = _connection.DBType;
if (string.IsNullOrEmpty(_connection.DbConnectionString))
throw new System.Exception("未配置好数据库默认连接");
try
{
_connection.DbConnectionString = _connection.DbConnectionString.DecryptDES(Secret.DB);
}
catch { }
if (!string.IsNullOrEmpty(_connection.RedisConnectionString))
{
try
{
_connection.RedisConnectionString = _connection.RedisConnectionString.DecryptDES(Secret.Redis);
}
catch { }
}
}
// 多个节点name格式 ["key:key1"]
public static string GetSettingString(string key)
{
return Configuration[key];
}
// 多个节点,通过.GetSection("key")["key1"]获取
public static IConfigurationSection GetSection(string key)
{
return Configuration.GetSection(key);
}
}
public class Connection
{
public string DBType { get; set; }
public string DbConnectionString { get; set; }
public string RedisConnectionString { get; set; }
public bool UseRedis { get; set; }
public bool UseSignalR { get; set; }
}
public class CreateMember: TableDefaultColumns
{
}
public class ModifyMember: TableDefaultColumns
{
}
public abstract class TableDefaultColumns
{
public string UserIdField { get; set; }
public string UserNameField { get; set; }
public string DateField { get; set; }
}
public class GlobalFilter
{
public string Message { get; set; }
public bool Enable { get; set; }
public string[] Actions { get; set; }
}
public class Kafka
{
public bool UseProducer { get; set; }
public ProducerSettings ProducerSettings { get; set; }
public bool UseConsumer { get; set; }
public bool IsConsumerSubscribe { get; set; }
public ConsumerSettings ConsumerSettings { get; set; }
public Topics Topics { get; set; }
}
public class ProducerSettings
{
public string BootstrapServers { get; set; }
public string SaslMechanism { get; set; }
public string SecurityProtocol { get; set; }
public string SaslUsername { get; set; }
public string SaslPassword { get; set; }
}
public class ConsumerSettings
{
public string BootstrapServers { get; set; }
public string SaslMechanism { get; set; }
public string SecurityProtocol { get; set; }
public string SaslUsername { get; set; }
public string SaslPassword { get; set; }
public string GroupId { get; set; }
}
public class Topics
{
public string TestTopic { get; set; }
}
}

View File

@ -0,0 +1,11 @@
namespace iMES.Core.Const
{
public class ApplicationContentType
{
public const string FORM = "application/x-www-form-urlencoded; charset=utf-8";
public const string STREAM = "application/octet-stream; charset=utf-8";
public const string JSON = "application/json; charset=utf-8";
public const string XML = "application/xml; charset=utf-8";
public const string TEXT = "application/text; charset=utf-8";
}
}

View File

@ -0,0 +1,7 @@
namespace iMES.Core.Const
{
public static class DBType
{
public static string Name { get; set; }
}
}

View File

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace iMES.Core.Const
{
public struct HtmlElementType
{
public const string drop = "drop";
public const string droplist = "droplist";
public const string select = "select";
public const string selectlist = "selectlist";
public const string checkbox = "checkbox";
public const string textarea = "textarea";
public const string thanorequal = "thanorequal";
public const string lessorequal = "lessorequal";
public const string gt = "gt";
public const string lt = "lt";
public const string GT = ">";
public const string LT = "<";
public const string like = "like";
public const string ThanOrEqual = ">=";
public const string LessOrequal = "<=";
public const string Contains = "in";
public const string Equal = "=";
}
}

View File

@ -0,0 +1,36 @@
namespace iMES.Core.Const
{
/// <summary>
/// 加密对应密钥Key
/// </summary>
public class Secret
{
/// <summary>
/// 用户密码加密key
/// </summary>
public string User { get; set; }
/// <summary>
/// 数据库加密key
/// </summary>
public string DB { get; set; }
/// <summary>
/// redis加密key
/// </summary>
public string Redis { get; set; }
/// <summary>
/// jwt加密key
/// </summary>
public string JWT { get; set; }
public string Audience { get; set; }
public string Issuer { get; set; }
/// <summary>
/// 导出文件加密key
/// </summary>
public string ExportFile = "C5ABA9E202D94C13A3CB66002BF77FAF";
}
}

View File

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace iMES.Core.Const
{
public struct SqlDbTypeName
{
public const string NVarChar = "nvarchar";
public const string VarChar = "varchar";
public const string NChar = "nchar";
public const string Char = "char";
public const string Text = "text";
public const string Int = "int";
public const string BigInt = "bigint";
public const string DateTime = "datetime";
public const string Date = "date";
public const string SmallDateTime = "smalldatetime";
public const string SmallDate = "smalldate";
public const string Float = "float";
public const string Decimal = "decimal";
public const string Double = "double";
public const string Bit = "bit";
public const string Bool = "bool";
public const string UniqueIdentifier = "uniqueidentifier";
}
}

View File

@ -0,0 +1,247 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using iMES.Core.Configuration;
using iMES.Core.Extensions;
using iMES.Core.Filters;
using iMES.Core.Services;
using iMES.Core.Utilities;
using iMES.Entity.DomainModels;
namespace iMES.Core.Controllers.Basic
{
[JWTAuthorize, ApiController]
public class ApiBaseController<IServiceBase> : Controller
{
protected IServiceBase Service;
private WebResponseContent _baseWebResponseContent { get; set; }
public ApiBaseController()
{
}
public ApiBaseController(IServiceBase service)
{
Service = service;
}
public ApiBaseController(string projectName, string folder, string tablename, IServiceBase service)
{
Service = service;
}
/// <summary>
/// 2020.11.21增加json原格式返回数据(默认是驼峰格式)
/// </summary>
/// <param name="data"></param>
/// <param name="serializerSettings"></param>
/// <returns></returns>
protected JsonResult JsonNormal(object data, JsonSerializerSettings serializerSettings = null, bool formateDate = true)
{
serializerSettings = serializerSettings ?? new JsonSerializerSettings();
serializerSettings.ContractResolver = null;
if (formateDate)
{
serializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
}
return Json(data, serializerSettings);
}
[ApiActionPermission(Enums.ActionPermissionOptions.Search)]
[HttpPost, Route("GetPageData")]
public virtual ActionResult GetPageData([FromBody] PageDataOptions loadData)
{
return JsonNormal(InvokeService("GetPageData", new object[] { loadData }));
}
/// <summary>
/// 获取明细grid分页数据
/// </summary>
/// <param name="loadData"></param>
/// <returns></returns>
[ApiActionPermission(Enums.ActionPermissionOptions.Search)]
[HttpPost, Route("GetDetailPage")]
[ApiExplorerSettings(IgnoreApi = true)]
public virtual ActionResult GetDetailPage([FromBody] PageDataOptions loadData)
{
return Content(InvokeService("GetDetailPage", new object[] { loadData }).Serialize());
}
/// <summary>
/// 上传文件
/// </summary>
/// <param name="fileInput"></param>
/// <returns></returns>
[HttpPost, Route("Upload")]
[ApiActionPermission(Enums.ActionPermissionOptions.Upload)]
[ApiExplorerSettings(IgnoreApi = true)]
public virtual IActionResult Upload(IEnumerable<IFormFile> fileInput)
{
return Json(InvokeService("Upload", new object[] { fileInput }));
}
/// <summary>
/// 下载导入Excel模板
/// </summary>
/// <returns></returns>
[HttpGet, Route("DownLoadTemplate")]
[ApiActionPermission(Enums.ActionPermissionOptions.Import)]
[ApiExplorerSettings(IgnoreApi = true)]
public virtual ActionResult DownLoadTemplate()
{
_baseWebResponseContent = InvokeService("DownLoadTemplate", new object[] { }) as WebResponseContent;
if (!_baseWebResponseContent.Status) return Json(_baseWebResponseContent);
byte[] fileBytes = System.IO.File.ReadAllBytes(_baseWebResponseContent.Data.ToString());
return File(
fileBytes,
System.Net.Mime.MediaTypeNames.Application.Octet,
Path.GetFileName(_baseWebResponseContent.Data.ToString())
);
}
/// <summary>
/// 导入表数据Excel
/// </summary>
/// <param name="fileInput"></param>
/// <returns></returns>
[HttpPost, Route("Import")]
[ApiActionPermission(Enums.ActionPermissionOptions.Import)]
[ApiExplorerSettings(IgnoreApi = true)]
public virtual ActionResult Import(List<IFormFile> fileInput)
{
return Json(InvokeService("Import", new object[] { fileInput }));
}
/// <summary>
/// 导出文件,返回日期+文件名
/// </summary>
/// <param name="loadData"></param>
/// <returns></returns>
[ApiActionPermission(Enums.ActionPermissionOptions.Export)]
[ApiExplorerSettings(IgnoreApi = true)]
[HttpPost, Route("Export")]
public virtual ActionResult Export([FromBody] PageDataOptions loadData)
{
var result = InvokeService("Export", new object[] { loadData }) as WebResponseContent;
return File(
System.IO.File.ReadAllBytes(result.Data.ToString().MapPath()),
System.Net.Mime.MediaTypeNames.Application.Octet,
Path.GetFileName(result.Data.ToString())
);
}
/// <summary>
/// 2022.01.08移除原来的导出功能
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
[Obsolete]
[ApiActionPermission(Enums.ActionPermissionOptions.Export)]
[HttpGet, Route("DownLoadFile")]
[ApiExplorerSettings(IgnoreApi = true)]
public virtual IActionResult DownLoadFile()
{
throw new Exception("原导出方法已停用");
//string path = HttpContext.Request("path");
//if (string.IsNullOrEmpty(path)) return Content("未找到文件");
//try
//{
// path = path.IndexOf("/") == -1 && path.IndexOf("\\") == -1
// ?path.DecryptDES(AppSetting.Secret.ExportFile)
// : path.MapPath();
// return File(
// System.IO.File.ReadAllBytes(path),
// System.Net.Mime.MediaTypeNames.Application.Octet,
// Path.GetFileName(path)
// );
//}
//catch (Exception ex)
//{
// Logger.Error($"文件下载出错:{path}{ex.Message}");
//}
//return Content("");
}
/// <summary>
/// 通过key删除文件
/// </summary>
/// <param name="keys"></param>
/// <returns></returns>
[ApiActionPermission(Enums.ActionPermissionOptions.Delete)]
[HttpPost, Route("Del")]
[ApiExplorerSettings(IgnoreApi = true)]
public virtual ActionResult Del([FromBody] object[] keys)
{
_baseWebResponseContent = InvokeService("Del", new object[] { keys, true }) as WebResponseContent;
Logger.Info(Enums.LoggerType.Del, keys.Serialize(), _baseWebResponseContent.Status ? "Ok" : _baseWebResponseContent.Message);
return Json(_baseWebResponseContent);
}
/// <summary>
/// 审核
/// </summary>
/// <param name="keys"></param>
/// <returns></returns>
[ApiActionPermission(Enums.ActionPermissionOptions.Audit)]
[HttpPost, Route("Audit")]
[ApiExplorerSettings(IgnoreApi = true)]
public virtual ActionResult Audit([FromBody] object[] id, int? auditStatus, string auditReason)
{
_baseWebResponseContent = InvokeService("Audit", new object[] { id, auditStatus, auditReason }) as WebResponseContent;
Logger.Info(Enums.LoggerType.Del, id?.Serialize() + "," + (auditStatus ?? -1) + "," + auditReason, _baseWebResponseContent.Status ? "Ok" : _baseWebResponseContent.Message);
return Json(_baseWebResponseContent);
}
/// <summary>
/// 新增支持主子表
/// </summary>
/// <param name="saveDataModel"></param>
/// <returns></returns>
[ApiActionPermission(Enums.ActionPermissionOptions.Add)]
[HttpPost, Route("Add")]
[ApiExplorerSettings(IgnoreApi = true)]
public virtual ActionResult Add([FromBody] SaveModel saveModel)
{
_baseWebResponseContent = InvokeService("Add",
new Type[] { typeof(SaveModel) },
new object[] { saveModel }) as WebResponseContent;
Logger.Info(Enums.LoggerType.Add, saveModel.Serialize(), _baseWebResponseContent.Status ? "Ok" : _baseWebResponseContent.Message);
_baseWebResponseContent.Data = _baseWebResponseContent.Data?.Serialize();
return Json(_baseWebResponseContent);
}
/// <summary>
/// 编辑支持主子表
/// [ModelBinder(BinderType =(typeof(ModelBinder.BaseModelBinder)))]可指定绑定modelbinder
/// </summary>
/// <param name="saveDataModel"></param>
/// <returns></returns>
[ApiActionPermission(Enums.ActionPermissionOptions.Update)]
[HttpPost, Route("Update")]
[ApiExplorerSettings(IgnoreApi = true)]
public virtual ActionResult Update([FromBody] SaveModel saveModel)
{
_baseWebResponseContent = InvokeService("Update", new object[] { saveModel }) as WebResponseContent;
Logger.Info(Enums.LoggerType.Edit, saveModel.Serialize(), _baseWebResponseContent.Status ? "Ok" : _baseWebResponseContent.Message);
_baseWebResponseContent.Data = _baseWebResponseContent.Data?.Serialize();
return Json(_baseWebResponseContent);
}
/// <summary>
/// 调用service方法
/// </summary>
/// <param name="methodName"></param>
/// <param name="parameters"></param>
/// <returns></returns>
private object InvokeService(string methodName, object[] parameters)
{
return Service.GetType().GetMethod(methodName).Invoke(Service, parameters);
}
/// <summary>
/// 调用service方法
/// </summary>
/// <param name="methodName"></param>
/// <param name="types">为要调用重载的方法参数类型new Type[] { typeof(SaveDataModel)</param>
/// <param name="parameters"></param>
/// <returns></returns>
private object InvokeService(string methodName, Type[] types, object[] parameters)
{
return Service.GetType().GetMethod(methodName, types).Invoke(Service, parameters);
}
}
}

View File

@ -0,0 +1,186 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using iMES.Core.Configuration;
using iMES.Core.Extensions;
using iMES.Core.Services;
using iMES.Core.Utilities;
using iMES.Entity.DomainModels;
namespace iMES.Core.Controllers.Basic
{
public class BaseController<IServiceBase> : Controller
{
protected IServiceBase Service;
private WebResponseContent ResponseContent { get; set; }
/// <summary>
///
/// </summary>
public BaseController()
{
}
public BaseController(IServiceBase service)
{
Service = service;
}
public BaseController(string projectName, string folder, string tablename, IServiceBase service)
{
Service = service;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
[ApiExplorerSettings(IgnoreApi = true)]
public virtual ActionResult Manager()
{
return View();
//if (System.IO.File.Exists(($"Views\\PageExtension\\{projectName }\\{TableName}Extension.cshtml").MapPath()))
//{
// ViewBag.UrlExtension = $"~/Views/PageExtension/{projectName}/{TableName}Extension.cshtml";
//}
// return View("~/Views/" + projectName + "/" + folder + "/" + TableName + ".cshtml");
}
[ApiExplorerSettings(IgnoreApi = true)]
public virtual async Task<ActionResult> GetPageData(PageDataOptions loadData)
{
string pageData = await Task.FromResult(InvokeService("GetPageData", new object[] { loadData }).Serialize());
return Content(pageData);
}
[ApiExplorerSettings(IgnoreApi = true)]
public virtual async Task<ActionResult> GetDetailPage(PageDataOptions loadData)
{
string pageData = await Task.FromResult(InvokeService("GetDetailPage", new object[] { loadData }).Serialize());
return Content(pageData);
}
/// <summary>
/// 上传文件
/// </summary>
/// <param name="fileInput"></param>
/// <returns></returns>
[ApiExplorerSettings(IgnoreApi = true)]
public virtual async Task<ActionResult> Upload(List<IFormFile> fileInput)
{
object result = await Task.FromResult(InvokeService("Upload", new object[] { fileInput }));
return Json(result);
}
/// <summary>
/// 导入表数据Excel
/// </summary>
/// <param name="fileInput"></param>
/// <returns></returns>
[HttpPost]
public virtual async Task<ActionResult> Import(List<IFormFile> fileInput)
{
object result = await Task.FromResult(InvokeService("Import", new object[] { fileInput }));
return Json(result);
}
[ApiExplorerSettings(IgnoreApi = true)]
public virtual async Task<ActionResult> Export(PageDataOptions loadData)
{
return Json(await Task.FromResult(InvokeService("Export", new object[] { loadData })));
}
[ApiExplorerSettings(IgnoreApi = true)]
public virtual ActionResult DownLoadFile(string path)
{
if (string.IsNullOrEmpty(path)) return Content("未找到文件");
try
{
if (path.IndexOf("/") == -1 && path.IndexOf("\\") == -1)
{
path = path.DecryptDES(AppSetting.Secret.ExportFile);
}
else
{
path = path.MapPath();
}
string fileName = Path.GetFileName(path);
return File(System.IO.File.ReadAllBytes(path), System.Net.Mime.MediaTypeNames.Application.Octet, fileName);
}
catch (Exception ex)
{
Logger.Error($"文件下载出错:{path}{ex.Message}");
}
return Content("");
}
/// <summary>
/// 下载Excel导入的模板
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
[HttpGet]
[ApiExplorerSettings(IgnoreApi = true)]
public async virtual Task<ActionResult> DownLoadTemplate()
{
ResponseContent = await Task.FromResult(InvokeService("DownLoadTemplate", new object[] { })) as WebResponseContent;
if (!ResponseContent.Status)
{
return Json(ResponseContent);
}
byte[] fileBytes = System.IO.File.ReadAllBytes(ResponseContent.Data.ToString());
return File(fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, Path.GetFileName(ResponseContent.Data.ToString()));
}
[ApiExplorerSettings(IgnoreApi = true)]
public virtual async Task<ActionResult> Del(object[] keys)
{
ResponseContent = await Task.FromResult(InvokeService("Del", new object[] { keys, true })) as WebResponseContent;
Logger.Info(Enums.LoggerType.Del, keys.Serialize(), ResponseContent.Status ? "Ok" : ResponseContent.Message);
return Json(ResponseContent);
}
[ApiExplorerSettings(IgnoreApi = true)]
public virtual async Task<ActionResult> Audit(object[] id, int? auditStatus, string auditReason)
{
ResponseContent = await Task.FromResult(InvokeService("Audit", new object[] { id, auditStatus, auditReason })) as WebResponseContent;
Logger.Info(Enums.LoggerType.Del, id?.Serialize() + "," + (auditStatus ?? -1) + "," + auditReason, ResponseContent.Status ? "Ok" : ResponseContent.Message);
return Json(ResponseContent);
}
[ApiExplorerSettings(IgnoreApi = true)]
public virtual async Task<WebResponseContent> Add(SaveModel saveModel)
{
ResponseContent = await Task.FromResult(InvokeService("Add", new Type[] { typeof(SaveModel) }, new object[] { saveModel })) as WebResponseContent;
Logger.Info(Enums.LoggerType.Add, saveModel.Serialize(), ResponseContent.Status ? "Ok" : ResponseContent.Message);
return ResponseContent;
}
[ApiExplorerSettings(IgnoreApi = true)]
public virtual async Task<WebResponseContent> Update(SaveModel saveModel)
{
ResponseContent = await Task.FromResult(InvokeService("Update", new object[] { saveModel })) as WebResponseContent;
Logger.Info(Enums.LoggerType.Edit, saveModel.Serialize(), ResponseContent.Status ? "Ok" : ResponseContent.Message);
return ResponseContent;
}
/// <summary>
/// 反射调用service方法
/// </summary>
/// <param name="methodName"></param>
/// <param name="parameters"></param>
/// <returns></returns>
private object InvokeService(string methodName, object[] parameters)
{
return Service.GetType().GetMethod(methodName).Invoke(Service, parameters);
}
/// <summary>
/// 反射调用service方法
/// </summary>
/// <param name="methodName"></param>
/// <param name="types">为要调用重载的方法参数类型new Type[] { typeof(SaveDataModel)</param>
/// <param name="parameters"></param>
/// <returns></returns>
private object InvokeService(string methodName, Type[] types, object[] parameters)
{
return Service.GetType().GetMethod(methodName, types).Invoke(Service, parameters);
}
}
}

View File

@ -0,0 +1,112 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Threading.Tasks;
using iMES.Core.Filters;
using iMES.Entity.DomainModels;
namespace iMES.Core.Controllers.Basic
{
public class WebBaseController<IServiceBase> : BaseController<IServiceBase>
{
public WebBaseController(string projectName, string folder, string tablename, IServiceBase service)
: base(projectName, folder, tablename, service)
{
}
/// <summary>
/// 获取grid分页数据
/// </summary>
/// <param name="loadData"></param>
/// <returns></returns>
[ActionPermission(Enums.ActionPermissionOptions.Search)]
[HttpPost]
public override async Task<ActionResult> GetPageData(PageDataOptions loadData)
{
return await base.GetPageData(loadData);
}
[HttpPost]
[ActionPermission(Enums.ActionPermissionOptions.Upload)]
public override async Task<ActionResult> Upload(List<IFormFile> fileInput)
{
return await base.Upload(fileInput);
}
/// <summary>
/// 导出文件,返回日期+文件名
/// </summary>
/// <param name="loadData"></param>
/// <returns></returns>
[ActionPermission(Enums.ActionPermissionOptions.Export)]
[HttpPost]
public override async Task<ActionResult> Export(PageDataOptions loadData)
{
return await base.Export(loadData);
}
/// <summary>
/// 下载文件
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
[ActionPermission(Enums.ActionPermissionOptions.Export)]
[HttpGet]
public override ActionResult DownLoadFile(string fileName)
{
return base.DownLoadFile(fileName);
}
/// <summary>
/// 通过key删除文件
/// </summary>
/// <param name="keys"></param>
/// <returns></returns>
[ActionPermission(Enums.ActionPermissionOptions.Delete)]
[HttpPost]
public override async Task<ActionResult> Del(object[] keys)
{
return await base.Del(keys);
}
/// <summary>
/// 审核
/// </summary>
/// <param name="keys"></param>
/// <returns></returns>
[ActionPermission(Enums.ActionPermissionOptions.Audit)]
[HttpPost]
public override async Task<ActionResult> Audit(object[] id, int? auditStatus, string auditReason)
{
return await base.Audit(id, auditStatus, auditReason);
}
/// <summary>
/// 新增支持主子表
/// </summary>
/// <param name="saveDataModel"></param>
/// <returns></returns>
[ActionPermission(Enums.ActionPermissionOptions.Add)]
[HttpPost]
public async Task<ActionResult> Add([ModelBinder]Dictionary<string, object> mainData, [ModelBinder] List<Dictionary<string, object>> detailData)
{
SaveModel saveModel = new SaveModel() { MainData = mainData, DetailData = detailData };
return Json(await base.Add(saveModel));
}
/// <summary>
/// 编辑支持主子表
/// [ModelBinder(BinderType =(typeof(ModelBinder.BaseModelBinder)))]可指定绑定modelbinder
/// </summary>
/// <param name="saveDataModel"></param>
/// <returns></returns>
[ActionPermission(Enums.ActionPermissionOptions.Update)]
[HttpPost]
public async Task<ActionResult> Update([ModelBinder(BinderType = (typeof(ModelBinder.BaseModelBinder)))]Dictionary<string, object> mainData, [ModelBinder] List<Dictionary<string, object>> detailData, [ModelBinder] List<object> delKeys)
{
SaveModel saveModel = new SaveModel()
{
DelKeys = delKeys,
MainData = mainData,
DetailData = detailData
};
var data = await base.Update(saveModel);
return Json(data);
}
}
}

View File

@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace iMES.Core.DBManager
{
public class DBConnectionAttribute : Attribute
{
public string DBName { get; set; }
}
}

View File

@ -0,0 +1,297 @@
using Microsoft.EntityFrameworkCore;
using Npgsql;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using iMES.Core.Configuration;
using iMES.Core.Const;
using iMES.Core.Dapper;
using iMES.Core.EFDbContext;
using iMES.Core.Enums;
using iMES.Core.Extensions;
using iMES.Entity.SystemModels;
namespace iMES.Core.DBManager
{
public class DBServerProvider
{
private static readonly string _netcoredevserver = "netcoredevserver";
private static readonly string _report = "report";
private static Dictionary<string, string> ConnectionPool = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
{
//配置业务数据库连接
{_netcoredevserver, AppSetting.GetSettingString("ServiceConnectingString")},
//配置报表数据库连接
{_report, AppSetting.GetSettingString("ReportConnectingString")}
//系统库不用配置了已经在appsetting.json中配置过了
};
private static readonly string DefaultConnName = "default";
static DBServerProvider()
{
SetConnection(DefaultConnName, AppSetting.DbConnectionString);
}
public static void SetConnection(string key, string val)
{
ConnectionPool[key] = val;
}
/// <summary>
/// 设置默认数据库连接
/// </summary>
/// <param name="val"></param>
public static void SetDefaultConnection(string val)
{
SetConnection(DefaultConnName, val);
}
public static string GetConnectionString(string key)
{
key = key ?? DefaultConnName;
if (ConnectionPool.ContainsKey(key))
{
return ConnectionPool[key];
}
return key;
}
/// <summary>
/// 获取默认数据库连接
/// </summary>
/// <returns></returns>
public static string GetConnectionString()
{
return GetConnectionString(DefaultConnName);
}
public static IDbConnection GetDbConnection(string connString = null)
{
if (connString == null)
{
connString = ConnectionPool[DefaultConnName];
}
if (DBType.Name == DbCurrentType.MySql.ToString())
{
return new MySql.Data.MySqlClient.MySqlConnection(connString);
}
if (DBType.Name == DbCurrentType.PgSql.ToString())
{
return new NpgsqlConnection(connString);
}
return new SqlConnection(connString);
}
/// <summary>
/// 扩展dapper 获取MSSQL数据库DbConnection默认系统获取配置文件的DBType数据库类型
/// </summary>
/// <param name="connString">如果connString为null 执行重载GetDbConnection(string connString = null)</param>
/// <param name="dapperType">指定连接数据库的类型MySql/MsSql/PgSql</param>
/// <returns></returns>
public static IDbConnection GetDbConnection(string connString = null, DbCurrentType dbCurrentType = DbCurrentType.Default)
{
//默认获取DbConnection
if (connString.IsNullOrEmpty() || DbCurrentType.Default == dbCurrentType)
{
return GetDbConnection(connString);
}
if (dbCurrentType == DbCurrentType.MySql)
{
return new MySql.Data.MySqlClient.MySqlConnection(connString);
}
if (dbCurrentType == DbCurrentType.PgSql)
{
return new NpgsqlConnection(connString);
}
return new SqlConnection(connString);
}
/// <summary>
/// 获取系统库(2020.08.22)
/// </summary>
public static SysDbContext SysDbContext
{
get { return Utilities.HttpContext.Current.GetService<SysDbContext>(); ; }
}
/// <summary>
/// 获取系统库(2020.08.22)
/// </summary>
public static SysDbContext DbContext
{
get { return GetEFDbContext(); }
}
/// <summary>
/// 获取系统库(2020.08.22)
/// </summary>
public static SysDbContext GetEFDbContext()
{
return SysDbContext;
}
/// <summary>
/// 获取业务库(2020.08.22)
/// </summary>
public static ServiceDbContext ServiceDbContext
{
get { return Utilities.HttpContext.Current.GetService<ServiceDbContext>(); ; }
}
/// <summary>
/// 获取报表库(2020.08.22)
/// </summary>
public static ReportDbContext ReportDbContext
{
get { return Utilities.HttpContext.Current.GetService<ReportDbContext>(); ; }
}
/// <summary>
/// 获取调用系统库的Dapper(2020.08.22)
/// </summary>
public static ISqlDapper SqlDapper
{
get
{
return new SqlDapper(DefaultConnName);
}
}
/// <summary>
/// 获取连接报表库的dapper(2020.08.22)
/// </summary>
public static ISqlDapper SqlDapperReport
{
get
{
return new SqlDapper(ReportConnectingString);
}
}
/// <summary>
/// 获取连接业务库的dapper(2020.08.22)
/// </summary>
public static ISqlDapper SqlDapperService
{
get
{
return new SqlDapper(ServiceConnectingString);
}
}
/// <summary>
/// 获取当前用户所属的业务库,需要添加存储用户所属数据库的字段(2020.08.22)
/// </summary>
public static ISqlDapper SqlDapperUserCurrentService
{
get
{
return new SqlDapper(ServiceUserCurrnetConnectingString);
}
}
/// <summary>
/// 默认获取连接系统库的dapper(2020.08.22)
/// </summary>
public static ISqlDapper GetSqlDapper(string dbName = null)
{
return new SqlDapper(dbName ?? DefaultConnName);
}
//(2020.08.22)
public static ISqlDapper GetSqlDapper<TEntity>()
{
Type baseType = typeof(TEntity).BaseType;
string dbName = null;
if (baseType == typeof(SysEntity))
{
dbName = SysConnectingString;
}
else if (baseType == typeof(ServiceEntity))
{
dbName = ServiceConnectingString;
}
else if (baseType == typeof(ReportEntity))
{
dbName = ServiceConnectingString;
}
//获取实体真实的数据库连接池对象名,如果不存在则用默认数据连接池名
//string dbName = typeof(TEntity).GetTypeCustomValue<DBConnectionAttribute>(x => x.DBName) ?? DefaultConnName;
return GetSqlDapper(dbName);
}
/// <summary>
/// 获取报表数据库的字符串连接(2020.08.22)
/// </summary>
public static string ReportConnectingString
{
//netcoredevserver为ConnectionPool字典中的key如果字典中的key改变了这里也要改变
get { return GetDbConnectionString(_report); }
}
/// <summary>
/// 获取业务库的字符串连接(2020.08.22)
/// </summary>
public static string ServiceConnectingString
{
//netcoredevserver为ConnectionPool字典中的key如果字典中的key改变了这里也要改变
get { return GetDbConnectionString(_netcoredevserver); }
}
/// <summary>
/// 获取业务库的字符串连接(2020.08.22)
/// 获取当前用户所属的数据库连接,需要添加存储用户所属数据库的字段(2020.08.22)
/// </summary>
public static string ServiceUserCurrnetConnectingString
{
get
{
//UserContext.Current.DbName用户所属性数据库。需要自己添加字段
// return ConnectionPool[UserContext.Current.DbName];
return ServiceConnectingString;
}
}
/// <summary>
/// 获取系统库的字符串连接(2020.08.22)
/// </summary>
public static string SysConnectingString
{
get { return GetDbConnectionString(DefaultConnName); }
}
/// <summary>
/// key为ConnectionPool初始化的所有数据库连接(2020.08.22)
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static string GetDbConnectionString(string key)
{
if (ConnectionPool.TryGetValue(key, out string connString))
{
return connString;
}
throw new Exception($"未配置[{key}]的数据库连接");
}
public static string GetContextName(string DBServer)
{
// 业务库
if (DBServer == typeof(ServiceDbContext).Name)
{
return typeof(ServiceEntity).Name;
}//报表库
else if (DBServer == typeof(ReportDbContext).Name)
{
return typeof(ReportEntity).Name;
}
else//系统库
{
return typeof(SysEntity).Name;
}
}
}
}

View File

@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace iMES.Core.DBManage
{
public struct DbName
{
public static string Default = "default";
}
}

View File

@ -0,0 +1,29 @@
using Dapper;
using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
namespace iMES.Core.Dapper
{
public class DapperParseGuidTypeHandler : SqlMapper.TypeHandler<Guid?>
{
public override void SetValue(IDbDataParameter parameter, Guid? guid)
{
parameter.Value = guid.ToString();
}
public override Guid? Parse(object value)
{
if (value == null || value.ToString() == "")
{
return null;
}
if (value.GetType() == typeof(string))
{
return new Guid((string)value);
}
return (Guid)value;
}
}
}

View File

@ -0,0 +1,155 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Dapper;
namespace iMES.Core.Dapper
{
public interface ISqlDapper
{
/// <summary>
/// 超时时间(秒)2021.05.05
/// </summary>
/// <param name="timeout"></param>
/// <returns></returns>
ISqlDapper SetTimout(int timeout);
void BeginTransaction(Func<ISqlDapper, bool> action, Action<Exception> error);
List<T> QueryList<T>(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false);
Task<IEnumerable<T>> QueryListAsync<T>(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false);
T QueryFirst<T>(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false) where T : class;
Task<T> QueryFirstAsync<T>(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false) where T : class;
Task<dynamic> QueryDynamicFirstAsync(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false);
dynamic QueryDynamicFirst(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false);
Task<dynamic> QueryDynamicListAsync(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false);
List<dynamic> QueryDynamicList(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false);
object ExecuteScalar(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false);
Task<object> ExecuteScalarAsync(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false);
int ExcuteNonQuery(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false);
Task<int> ExcuteNonQueryAsync(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false);
IDataReader ExecuteReader(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false);
SqlMapper.GridReader QueryMultiple(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false);
Task<(IEnumerable<T1>, IEnumerable<T2>)> QueryMultipleAsync<T1, T2>(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false);
(List<T1>, List<T2>) QueryMultiple<T1, T2>(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false);
Task<(IEnumerable<T1>, IEnumerable<T2>, IEnumerable<T3>)> QueryMultipleAsync<T1, T2, T3>(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false);
(List<T1>, List<T2>, List<T3>) QueryMultiple<T1, T2, T3>(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false);
Task<(IEnumerable<dynamic>, IEnumerable<dynamic>)> QueryDynamicMultipleAsync(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false);
(List<dynamic>, List<dynamic>) QueryDynamicMultiple(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false);
Task<(IEnumerable<T1>, IEnumerable<T2>, IEnumerable<T3>, IEnumerable<T4>)> QueryMultipleAsync<T1, T2, T3, T4>(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false);
(List<T1>, List<T2>, List<T3>, List<T4>) QueryMultiple<T1, T2, T3, T4>(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false);
Task<(IEnumerable<T1>, IEnumerable<T2>, IEnumerable<T3>, IEnumerable<T4>, IEnumerable<T5>)> QueryMultipleAsync<T1, T2, T3, T4, T5>(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false);
(List<T1>, List<T2>, List<T3>, List<T4>, List<T5>) QueryMultiple<T1, T2, T3, T4, T5>(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false);
Task<(IEnumerable<dynamic>, IEnumerable<dynamic>)> QueryDynamicMultipleAsync2(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false);
(List<dynamic>, List<dynamic>) QueryDynamicMultiple2(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false);
Task<(IEnumerable<dynamic>, IEnumerable<dynamic>, IEnumerable<dynamic>)> QueryDynamicMultipleAsync3(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false);
(List<dynamic>, List<dynamic>, List<dynamic>) QueryDynamicMultiple3(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false);
Task<(IEnumerable<dynamic>, IEnumerable<dynamic>, IEnumerable<dynamic>, IEnumerable<dynamic>, IEnumerable<dynamic>)> QueryDynamicMultipleAsync5(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false);
(List<dynamic>, List<dynamic>, List<dynamic>, List<dynamic>, List<dynamic>) QueryDynamicMultiple5(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false);
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entities"></param>
/// <param name="updateFileds">指定插入的字段</param>
/// <param name="beginTransaction">是否开启事务</param>
/// <returns></returns>
int Add<T>(T entity, Expression<Func<T, object>> updateFileds = null, bool beginTransaction = false);
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entities"></param>
/// <param name="updateFileds">指定插入的字段</param>
/// <param name="beginTransaction">是否开启事务</param>
/// <returns></returns>
int AddRange<T>(IEnumerable<T> entities, Expression<Func<T, object>> updateFileds = null, bool beginTransaction = false);
/// <summary>
/// sqlserver使用的临时表参数化批量更新mysql批量更新待发开
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entity">实体必须带主键</param>
/// <param name="updateFileds">指定更新的字段x=new {x.a,x.b}</param>
/// <param name="beginTransaction">是否开启事务</param>
/// <returns></returns>
int Update<T>(T entity, Expression<Func<T, object>> updateFileds = null, bool beginTransaction = false);
/// <summary>
/// sqlserver使用的临时表参数化批量更新mysql批量更新待发开
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entity">实体必须带主键</param>
/// <param name="updateFileds">指定更新的字段x=new {x.a,x.b}</param>
/// <param name="beginTransaction">是否开启事务</param>
/// <returns></returns>
int UpdateRange<T>(IEnumerable<T> entities, Expression<Func<T, object>> updateFileds = null, bool beginTransaction = false);
int DelWithKey<T>(params object[] keys);
int DelWithKey<T>(bool beginTransaction = false, params object[] keys);
/// <summary>
/// sqlserver批量写入
/// 使用时DataTable table表字段顺序要和数据库字段顺序一致
/// <summary>
/// mysql批量写入
/// </summary>
/// <param name="table"></param>
/// <param name="tableName"></param>
/// <param name="tmpPath">默认当前下载路径</param>
/// <param name="fileName">默认$"{DateTime.Now.ToString("yyyyMMddHHmmss")}.csv"</param>
/// <returns></returns>
int BulkInsert(DataTable table, string tableName, SqlBulkCopyOptions? sqlBulkCopyOptions = null, string fileName = null, string tmpPath = null);
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entities"></param>
/// <param name="tableName"></param>
/// <param name="columns">所包含的列</param>
/// <param name="sqlBulkCopyOptions"></param>
/// <param name="fileName"></param>
/// <param name="tmpPath"></param>
/// <returns></returns>
int BulkInsert<T>(List<T> entities, string tableName = null,
Expression<Func<T, object>> columns = null,
SqlBulkCopyOptions? sqlBulkCopyOptions = null);
}
}

View File

@ -0,0 +1,885 @@

using Dapper;
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using iMES.Core.Const;
using iMES.Core.DBManager;
using iMES.Core.Enums;
using iMES.Core.Extensions;
using iMES.Core.Utilities;
namespace iMES.Core.Dapper
{
public class SqlDapper : ISqlDapper
{
private string _connectionString;
private int? commandTimeout = null;
private DbCurrentType _dbCurrentType;
public SqlDapper()
{
_connectionString = DBServerProvider.GetConnectionString();
}
public SqlDapper(string connKeyName, DbCurrentType dbCurrentType)
{
_dbCurrentType = dbCurrentType;
_connectionString = DBServerProvider.GetConnectionString(connKeyName);
}
public SqlDapper(string connKeyName)
{
_connectionString = DBServerProvider.GetConnectionString(connKeyName);
}
private bool _transaction { get; set; }
private IDbConnection _transactionConnection = null;
/// <summary>
/// 超时时间(秒)
/// </summary>
/// <param name="timeout"></param>
/// <returns></returns>
public ISqlDapper SetTimout(int timeout)
{
this.commandTimeout = timeout;
return this;
}
private T Execute<T>(Func<IDbConnection, IDbTransaction, T> func, bool beginTransaction = false)
{
if (_transaction)
{
return func(_transactionConnection, dbTransaction);
}
if (beginTransaction)
{
return ExecuteTransaction(func);
}
using (var connection = DBServerProvider.GetDbConnection(_connectionString, _dbCurrentType))
{
return func(connection, dbTransaction);
}
}
private T ExecuteTransaction<T>(Func<IDbConnection, IDbTransaction, T> func)
{
using (_transactionConnection = DBServerProvider.GetDbConnection(_connectionString, _dbCurrentType))
{
try
{
_transactionConnection.Open();
dbTransaction = _transactionConnection.BeginTransaction();
T reslutT = func(_transactionConnection, dbTransaction);
dbTransaction.Commit();
return reslutT;
}
catch (Exception ex)
{
dbTransaction?.Rollback();
throw ex;
}
finally
{
dbTransaction?.Dispose();
}
}
}
private async Task<T> ExecuteAsync<T>(Func<IDbConnection, IDbTransaction, Task<T>> funcAsync, bool beginTransaction = false)
{
if (_transaction)
{
return await funcAsync(_transactionConnection, dbTransaction);
}
if (beginTransaction)
{
return await ExecuteTransactionAsync(funcAsync);
}
using (var connection = DBServerProvider.GetDbConnection(_connectionString))
{
T reslutT = await funcAsync(connection, dbTransaction);
if (!_transaction && dbTransaction != null)
{
dbTransaction.Commit();
}
return reslutT;
}
}
private async Task<T> ExecuteTransactionAsync<T>(Func<IDbConnection, IDbTransaction, Task<T>> funcAsync)
{
using (var connection = DBServerProvider.GetDbConnection(_connectionString))
{
try
{
connection.Open();
dbTransaction = connection.BeginTransaction();
T reslutT = await funcAsync(connection, dbTransaction);
if (!_transaction && dbTransaction != null)
{
dbTransaction.Commit();
}
return reslutT;
}
catch (Exception ex)
{
dbTransaction?.Rollback();
throw ex;
}
}
}
/// <summary>
/// 2020.06.15增加Dapper事务处理
/// <param name="action"></param>
/// <param name="error"></param>
public void BeginTransaction(Func<ISqlDapper, bool> action, Action<Exception> error)
{
_transaction = true;
using (var connection = DBServerProvider.GetDbConnection(_connectionString, _dbCurrentType))
{
try
{
_transactionConnection = connection;
_transactionConnection.Open();
dbTransaction = _transactionConnection.BeginTransaction();
bool result = action(this);
if (result)
{
dbTransaction?.Commit();
}
else
{
dbTransaction?.Rollback();
}
}
catch (Exception ex)
{
dbTransaction?.Rollback();
error(ex);
}
finally
{
_transaction = false;
dbTransaction?.Dispose();
}
}
}
/// <summary>
/// var p = new object();
// p.Add("@a", 11);
//p.Add("@b", dbType: DbType.Int32, direction: ParameterDirection.Output);
//p.Add("@c", dbType: DbType.Int32, direction: ParameterDirection.ReturnValue);
// /// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="cmd"></param>
/// <param name="param"></param>
/// <param name="commandType"></param>
/// <returns></returns>
public List<T> QueryList<T>(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false)
{
return Execute((conn, dbTransaction) =>
{
return conn.Query<T>(cmd, param, dbTransaction, commandType: commandType ?? CommandType.Text, commandTimeout: commandTimeout).ToList();
}, beginTransaction);
}
public async Task<IEnumerable<T>> QueryListAsync<T>(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false)
{
return await ExecuteAsync(async (conn, dbTransaction) =>
{
return await conn.QueryAsync<T>(cmd, param, dbTransaction, commandType: commandType ?? CommandType.Text, commandTimeout: commandTimeout);
}, beginTransaction);
}
public async Task<T> QueryFirstAsync<T>(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false) where T : class
{
return await ExecuteAsync(async (conn, dbTransaction) =>
{
return await conn.QueryFirstOrDefaultAsync<T>(cmd, param, dbTransaction, commandType: commandType ?? CommandType.Text, commandTimeout: commandTimeout);
}, beginTransaction);
}
public T QueryFirst<T>(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false) where T : class
{
return Execute((conn, dbTransaction) =>
{
return conn.QueryFirstOrDefault<T>(cmd, param, dbTransaction, commandType: commandType ?? CommandType.Text, commandTimeout: commandTimeout);
}, beginTransaction);
}
public async Task<dynamic> QueryDynamicFirstAsync(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false)
{
return await ExecuteAsync(async (conn, dbTransaction) =>
{
return await conn.QueryFirstOrDefaultAsync(cmd, param, dbTransaction, commandType: commandType ?? CommandType.Text, commandTimeout: commandTimeout);
}, beginTransaction);
}
public dynamic QueryDynamicFirst(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false)
{
return Execute((conn, dbTransaction) =>
{
return conn.QueryFirstOrDefault(cmd, param, dbTransaction, commandType: commandType ?? CommandType.Text, commandTimeout: commandTimeout);
}, beginTransaction);
}
public async Task<dynamic> QueryDynamicListAsync(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false)
{
return await ExecuteAsync(async (conn, dbTransaction) =>
{
return await conn.QueryAsync(cmd, param, dbTransaction, commandType: commandType ?? CommandType.Text, commandTimeout: commandTimeout);
}, beginTransaction);
}
public List<dynamic> QueryDynamicList(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false)
{
return Execute((conn, dbTransaction) =>
{
return conn.Query(cmd, param, dbTransaction, commandType: commandType ?? CommandType.Text, commandTimeout: commandTimeout).ToList();
}, beginTransaction);
}
public async Task<object> ExecuteScalarAsync(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false)
{
return await ExecuteAsync(async (conn, dbTransaction) =>
{
return await conn.ExecuteScalarAsync(cmd, param, dbTransaction, commandType: commandType ?? CommandType.Text, commandTimeout: commandTimeout);
}, beginTransaction);
}
public object ExecuteScalar(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false)
{
return Execute((conn, dbTransaction) =>
{
return conn.ExecuteScalar(cmd, param, dbTransaction, commandType: commandType ?? CommandType.Text, commandTimeout: commandTimeout);
}, beginTransaction);
}
public async Task<int> ExcuteNonQueryAsync(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false)
{
return await ExecuteAsync(async (conn, dbTransaction) =>
{
return await conn.ExecuteAsync(cmd, param, dbTransaction, commandType: commandType ?? CommandType.Text, commandTimeout: commandTimeout);
}, beginTransaction);
}
public int ExcuteNonQuery(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false)
{
return Execute<int>((conn, dbTransaction) =>
{
return conn.Execute(cmd, param, dbTransaction, commandType: commandType ?? CommandType.Text, commandTimeout: commandTimeout);
}, beginTransaction);
}
public IDataReader ExecuteReader(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false)
{
return Execute<IDataReader>((conn, dbTransaction) =>
{
return conn.ExecuteReader(cmd, param, dbTransaction, commandType: commandType ?? CommandType.Text, commandTimeout: commandTimeout);
}, beginTransaction);
}
public SqlMapper.GridReader QueryMultiple(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false)
{
return Execute((conn, dbTransaction) =>
{
return conn.QueryMultiple(cmd, param, dbTransaction, commandType: commandType ?? CommandType.Text, commandTimeout: commandTimeout);
}, beginTransaction);
}
public async Task<(IEnumerable<T1>, IEnumerable<T2>)> QueryMultipleAsync<T1, T2>(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false)
{
return await ExecuteAsync(async (conn, dbTransaction) =>
{
using (SqlMapper.GridReader reader = await conn.QueryMultipleAsync(cmd, param, dbTransaction, commandType: commandType ?? CommandType.Text, commandTimeout: commandTimeout))
{
return (await reader.ReadAsync<T1>(), await reader.ReadAsync<T2>());
}
}, beginTransaction);
}
/// <summary>
/// 获取output值 param.Get<int>("@b");
/// </summary>
/// <typeparam name="T1"></typeparam>
/// <param name="cmd"></param>
/// <param name="param"></param>
/// <param name="commandType"></param>
/// <param name="dbTransaction"></param>
/// <returns></returns>
public (List<T1>, List<T2>) QueryMultiple<T1, T2>(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false)
{
return Execute((conn, dbTransaction) =>
{
using (SqlMapper.GridReader reader = conn.QueryMultiple(cmd, param, dbTransaction, commandType: commandType ?? CommandType.Text, commandTimeout: commandTimeout))
{
return (reader.Read<T1>().ToList(), reader.Read<T2>().ToList());
}
}, beginTransaction);
}
public async Task<(IEnumerable<dynamic>, IEnumerable<dynamic>)> QueryDynamicMultipleAsync(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false)
{
return await ExecuteAsync(async (conn, dbTransaction) =>
{
using (SqlMapper.GridReader reader = await conn.QueryMultipleAsync(cmd, param, dbTransaction, commandType: commandType ?? CommandType.Text, commandTimeout: commandTimeout))
{
return (await reader.ReadAsync(), await reader.ReadAsync());
}
}, beginTransaction);
}
public (List<dynamic>, List<dynamic>) QueryDynamicMultiple(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false)
{
return Execute((conn, dbTransaction) =>
{
using (SqlMapper.GridReader reader = conn.QueryMultiple(cmd, param, dbTransaction, commandType: commandType ?? CommandType.Text, commandTimeout: commandTimeout))
{
return (reader.Read().ToList(), reader.Read().ToList());
}
}, beginTransaction);
}
public async Task<(IEnumerable<T1>, IEnumerable<T2>, IEnumerable<T3>)> QueryMultipleAsync<T1, T2, T3>(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false)
{
return await ExecuteAsync(async (conn, dbTransaction) =>
{
using (SqlMapper.GridReader reader = await conn.QueryMultipleAsync(cmd, param, dbTransaction, commandType: commandType ?? CommandType.Text, commandTimeout: commandTimeout))
{
return (await reader.ReadAsync<T1>(), await reader.ReadAsync<T2>(), await reader.ReadAsync<T3>());
}
}, beginTransaction);
}
public (List<T1>, List<T2>, List<T3>) QueryMultiple<T1, T2, T3>(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false)
{
return Execute((conn, dbTransaction) =>
{
using (SqlMapper.GridReader reader = conn.QueryMultiple(cmd, param, dbTransaction, commandType: commandType ?? CommandType.Text, commandTimeout: commandTimeout))
{
return (reader.Read<T1>().ToList(), reader.Read<T2>().ToList(), reader.Read<T3>().ToList());
}
}, beginTransaction);
}
public async Task<(IEnumerable<dynamic>, IEnumerable<dynamic>)> QueryDynamicMultipleAsync2(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false)
{
return await ExecuteAsync(async (conn, dbTransaction) =>
{
using (SqlMapper.GridReader reader = await conn.QueryMultipleAsync(cmd, param, dbTransaction, commandType: commandType ?? CommandType.Text, commandTimeout: commandTimeout))
{
return (
await reader.ReadAsync<dynamic>(),
await reader.ReadAsync<dynamic>()
);
}
}, beginTransaction);
}
public (List<dynamic>, List<dynamic>) QueryDynamicMultiple2(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false)
{
return Execute((conn, dbTransaction) =>
{
using (SqlMapper.GridReader reader = conn.QueryMultiple(cmd, param, dbTransaction, commandType: commandType ?? CommandType.Text, commandTimeout: commandTimeout))
{
return (
reader.Read<dynamic>().ToList(),
reader.Read<dynamic>().ToList()
);
}
}, beginTransaction);
}
public async Task<(IEnumerable<dynamic>, IEnumerable<dynamic>, IEnumerable<dynamic>)> QueryDynamicMultipleAsync3(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false)
{
return await ExecuteAsync(async (conn, dbTransaction) =>
{
using (SqlMapper.GridReader reader = await conn.QueryMultipleAsync(cmd, param, dbTransaction, commandType: commandType ?? CommandType.Text, commandTimeout: commandTimeout))
{
return (
await reader.ReadAsync<dynamic>(),
await reader.ReadAsync<dynamic>(),
await reader.ReadAsync<dynamic>()
);
}
}, beginTransaction);
}
public (List<dynamic>, List<dynamic>, List<dynamic>) QueryDynamicMultiple3(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false)
{
return Execute((conn, dbTransaction) =>
{
using (SqlMapper.GridReader reader = conn.QueryMultiple(cmd, param, dbTransaction, commandType: commandType ?? CommandType.Text, commandTimeout: commandTimeout))
{
return (reader.Read<dynamic>().ToList(),
reader.Read<dynamic>().ToList(),
reader.Read<dynamic>().ToList()
);
}
}, beginTransaction);
}
public async Task<(IEnumerable<dynamic>, IEnumerable<dynamic>, IEnumerable<dynamic>, IEnumerable<dynamic>, IEnumerable<dynamic>)> QueryDynamicMultipleAsync5(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false)
{
return await ExecuteAsync(async (conn, dbTransaction) =>
{
using (SqlMapper.GridReader reader = await conn.QueryMultipleAsync(cmd, param, dbTransaction, commandType: commandType ?? CommandType.Text, commandTimeout: commandTimeout))
{
return (
await reader.ReadAsync<dynamic>(),
await reader.ReadAsync<dynamic>(),
await reader.ReadAsync<dynamic>(),
await reader.ReadAsync<dynamic>(),
await reader.ReadAsync<dynamic>()
);
}
}, beginTransaction);
}
public (List<dynamic>, List<dynamic>, List<dynamic>, List<dynamic>, List<dynamic>) QueryDynamicMultiple5(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false)
{
return Execute((conn, dbTransaction) =>
{
using (SqlMapper.GridReader reader = conn.QueryMultiple(cmd, param, dbTransaction, commandType: commandType ?? CommandType.Text, commandTimeout: commandTimeout))
{
return (reader.Read<dynamic>().ToList(),
reader.Read<dynamic>().ToList(),
reader.Read<dynamic>().ToList(),
reader.Read<dynamic>().ToList(),
reader.Read<dynamic>().ToList()
);
}
}, beginTransaction);
}
public async Task<(IEnumerable<T1>, IEnumerable<T2>, IEnumerable<T3>, IEnumerable<T4>)> QueryMultipleAsync<T1, T2, T3, T4>(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false)
{
return await ExecuteAsync(async (conn, dbTransaction) =>
{
using (SqlMapper.GridReader reader = await conn.QueryMultipleAsync(cmd, param, dbTransaction, commandType: commandType ?? CommandType.Text, commandTimeout: commandTimeout))
{
return (await reader.ReadAsync<T1>(),
await reader.ReadAsync<T2>(),
await reader.ReadAsync<T3>(),
await reader.ReadAsync<T4>()
);
}
}, beginTransaction);
}
public (List<T1>, List<T2>, List<T3>, List<T4>) QueryMultiple<T1, T2, T3, T4>(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false)
{
return Execute((conn, dbTransaction) =>
{
using (SqlMapper.GridReader reader = conn.QueryMultiple(cmd, param, dbTransaction, commandType: commandType ?? CommandType.Text, commandTimeout: commandTimeout))
{
return (reader.Read<T1>().ToList(),
reader.Read<T2>().ToList(),
reader.Read<T3>().ToList(),
reader.Read<T4>().ToList()
);
}
}, beginTransaction);
}
public async Task<(IEnumerable<T1>, IEnumerable<T2>, IEnumerable<T3>, IEnumerable<T4>, IEnumerable<T5>)> QueryMultipleAsync<T1, T2, T3, T4, T5>(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false)
{
return await ExecuteAsync(async (conn, dbTransaction) =>
{
using (SqlMapper.GridReader reader = await conn.QueryMultipleAsync(cmd, param, dbTransaction, commandType: commandType ?? CommandType.Text, commandTimeout: commandTimeout))
{
return (await reader.ReadAsync<T1>(),
await reader.ReadAsync<T2>(),
await reader.ReadAsync<T3>(),
await reader.ReadAsync<T4>(),
await reader.ReadAsync<T5>()
);
}
}, beginTransaction);
}
public (List<T1>, List<T2>, List<T3>, List<T4>, List<T5>) QueryMultiple<T1, T2, T3, T4, T5>(string cmd, object param, CommandType? commandType = null, bool beginTransaction = false)
{
return Execute((conn, dbTransaction) =>
{
using (SqlMapper.GridReader reader = conn.QueryMultiple(cmd, param, dbTransaction, commandType: commandType ?? CommandType.Text, commandTimeout: commandTimeout))
{
return (reader.Read<T1>().ToList(),
reader.Read<T2>().ToList(),
reader.Read<T3>().ToList(),
reader.Read<T4>().ToList(),
reader.Read<T5>().ToList()
);
}
}, beginTransaction);
}
IDbTransaction dbTransaction = null;
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entity"></param>
/// <param name="addFileds">指定插入的字段</param>
/// <param name="beginTransaction">是否开启事务</param>
/// <returns></returns>
public int Add<T>(T entity, Expression<Func<T, object>> addFileds = null, bool beginTransaction = false)
{
return AddRange<T>(new T[] { entity }, addFileds, beginTransaction);
}
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entities"></param>
/// <param name="addFileds">指定插入的字段</param>
/// <param name="beginTransaction">是否开启事务</param>
/// <returns></returns>
public int AddRange<T>(IEnumerable<T> entities, Expression<Func<T, object>> addFileds = null, bool beginTransaction = true)
{
Type entityType = typeof(T);
var key = entityType.GetKeyProperty();
if (key == null)
{
throw new Exception("实体必须包括主键才能批量更新");
}
string[] columns;
//指定插入的字段
if (addFileds != null)
{
columns = addFileds.GetExpressionToArray();
}
else
{
var properties = entityType.GetGenericProperties();
if (key.PropertyType != typeof(Guid))
{
properties = properties.Where(x => x.Name != key.Name).ToArray();
}
columns = properties.Select(x => x.Name).ToArray();
}
string sql = null;
if (DBType.Name == DbCurrentType.MySql.ToString())
{
//mysql批量写入待优化
sql = $"insert into {entityType.GetEntityTableName()}({string.Join(",", columns)})" +
$"values(@{string.Join(",@", columns)});";
}
else if (DBType.Name == DbCurrentType.PgSql.ToString())
{
//todo pgsql批量写入 待检查是否正确
sql = $"insert into {entityType.GetEntityTableName()}({"\"" + string.Join("\",\"", columns) + "\""})" +
$"values(@{string.Join(",@", columns)});";
}
else
{
//sqlserver通过临时表批量写入
sql = $"insert into {entityType.GetEntityTableName()}({string.Join(",", columns)})" +
$"select {string.Join(",", columns)} from {EntityToSqlTempName.TempInsert};";
//2020.11.21修复sqlserver批量写入主键类型判断错误
sql = entities.GetEntitySql(key.PropertyType == typeof(Guid), sql, null, addFileds, null);
}
return Execute<int>((conn, dbTransaction) =>
{
//todo pgsql待实现
return conn.Execute(sql, (DBType.Name == DbCurrentType.MySql.ToString() || DBType.Name == DbCurrentType.PgSql.ToString()) ? entities.ToList() : null, dbTransaction);
}, beginTransaction);
}
/// <summary>
/// sqlserver使用的临时表参数化批量更新mysql批量更新待发开
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entity">实体必须带主键</param>
/// <param name="updateFileds">指定更新的字段x=new {x.a,x.b}</param>
/// <param name="beginTransaction">是否开启事务</param>
/// <returns></returns>
public int Update<T>(T entity, Expression<Func<T, object>> updateFileds = null, bool beginTransaction = false)
{
return UpdateRange<T>(new T[] { entity }, updateFileds, beginTransaction);
}
/// <summary>
///(根据主键批量更新实体) sqlserver使用的临时表参数化批量更新mysql待优化
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entities">实体必须带主键</param>
/// <param name="updateFileds">批定更新字段</param>
/// <param name="beginTransaction"></param>
/// <returns></returns>
public int UpdateRange<T>(IEnumerable<T> entities, Expression<Func<T, object>> updateFileds = null, bool beginTransaction = false)
{
Type entityType = typeof(T);
var key = entityType.GetKeyProperty();
if (key == null)
{
throw new Exception("实体必须包括主键才能批量更新");
}
var properties = entityType.GetGenericProperties()
.Where(x => x.Name != key.Name);
if (updateFileds != null)
{
properties = properties.Where(x => updateFileds.GetExpressionToArray().Contains(x.Name));
}
if (DBType.Name == DbCurrentType.MySql.ToString())
{
List<string> paramsList = new List<string>();
foreach (var item in properties)
{
paramsList.Add(item.Name + "=@" + item.Name);
}
string sqltext = $@"UPDATE { entityType.GetEntityTableName()} SET {string.Join(",", paramsList)} WHERE {entityType.GetKeyName()} = @{entityType.GetKeyName()} ;";
return ExcuteNonQuery(sqltext, entities, CommandType.Text, beginTransaction);
// throw new Exception("mysql批量更新未实现");
}
string fileds = string.Join(",", properties.Select(x => $" a.{x.Name}=b.{x.Name}").ToArray());
string sql = $"update a set {fileds} from {entityType.GetEntityTableName()} as a inner join {EntityToSqlTempName.TempInsert.ToString()} as b on a.{key.Name}=b.{key.Name}";
sql = entities.ToList().GetEntitySql(true, sql, null, updateFileds, null);
return ExcuteNonQuery(sql, null, CommandType.Text, beginTransaction);
}
public int DelWithKey<T>(bool beginTransaction = false, params object[] keys)
{
Type entityType = typeof(T);
var keyProperty = entityType.GetKeyProperty();
if (keyProperty == null || keys == null || keys.Length == 0) return 0;
IEnumerable<(bool, string, object)> validation = keyProperty.ValidationValueForDbType(keys);
if (validation.Any(x => !x.Item1))
{
throw new Exception($"主键类型【{validation.Where(x => !x.Item1).Select(s => s.Item3).FirstOrDefault()}】不正确");
}
string tKey = entityType.GetKeyProperty().Name;
FieldType fieldType = entityType.GetFieldType();
string joinKeys = (fieldType == FieldType.Int || fieldType == FieldType.BigInt)
? string.Join(",", keys)
: $"'{string.Join("','", keys)}'";
string sql;
// 2020.08.06增加pgsql删除功能
if (DBType.Name == DbCurrentType.PgSql.ToString())
{
sql = $"DELETE FROM \"public\".\"{entityType.GetEntityTableName()}\" where \"{tKey}\" in ({joinKeys});";
}
else
{
sql = $"DELETE FROM {entityType.GetEntityTableName() } where {tKey} in ({joinKeys});";
}
return ExcuteNonQuery(sql, null);
}
/// <summary>
/// 使用key批量删除
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="keys"></param>
/// <returns></returns>
public int DelWithKey<T>(params object[] keys)
{
return DelWithKey<T>(false, keys);
}
/// <summary>
/// 通过Bulk批量插入
/// </summary>
/// <param name="table"></param>
/// <param name="tableName"></param>
/// <param name="sqlBulkCopyOptions"></param>
/// <param name="dbKeyName"></param>
/// <returns></returns>
private int MSSqlBulkInsert(DataTable table, string tableName, SqlBulkCopyOptions sqlBulkCopyOptions = SqlBulkCopyOptions.UseInternalTransaction, string dbKeyName = null)
{
using (var Connection = DBServerProvider.GetDbConnection(_connectionString, _dbCurrentType))
{
if (!string.IsNullOrEmpty(dbKeyName))
{
Connection.ConnectionString = DBServerProvider.GetConnectionString(dbKeyName);
}
using (SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(Connection.ConnectionString, sqlBulkCopyOptions))
{
sqlBulkCopy.DestinationTableName = tableName;
sqlBulkCopy.BatchSize = table.Rows.Count;
for (int i = 0; i < table.Columns.Count; i++)
{
sqlBulkCopy.ColumnMappings.Add(table.Columns[i].ColumnName, table.Columns[i].ColumnName);
}
sqlBulkCopy.WriteToServer(table);
return table.Rows.Count;
}
}
}
public int BulkInsert<T>(List<T> entities, string tableName = null,
Expression<Func<T, object>> columns = null,
SqlBulkCopyOptions? sqlBulkCopyOptions = null)
{
DataTable table = entities.ToDataTable(columns, false);
return BulkInsert(table, tableName ?? typeof(T).GetEntityTableName(), sqlBulkCopyOptions);
}
public int BulkInsert(DataTable table, string tableName, SqlBulkCopyOptions? sqlBulkCopyOptions = null, string fileName = null, string tmpPath = null)
{
if (!string.IsNullOrEmpty(tmpPath))
{
tmpPath = tmpPath.ReplacePath();
}
if (DBType.Name == "MySql")
{
return MySqlBulkInsert(table, tableName, fileName, tmpPath);
}
if (DBType.Name == "PgSql")
{
PGSqlBulkInsert(table, tableName);
return table.Rows.Count;
}
return MSSqlBulkInsert(table, tableName, sqlBulkCopyOptions ?? SqlBulkCopyOptions.KeepIdentity);
}
/// <summary>
///大批量数据插入,返回成功插入行数
////
/// </summary>
/// <param name="connectionString">数据库连接字符串</param>
/// <param name="table">数据表</param>
/// <returns>返回成功插入行数</returns>
private int MySqlBulkInsert(DataTable table, string tableName, string fileName = null, string tmpPath = null)
{
if (table.Rows.Count == 0) return 0;
tmpPath = tmpPath ?? FileHelper.GetCurrentDownLoadPath();
int insertCount = 0;
string csv = DataTableToCsv(table);
string text = $"当前行:{table.Rows.Count}";
MemoryStream stream = null;
try
{
using (var Connection = DBServerProvider.GetDbConnection(_connectionString, _dbCurrentType))
{
if (Connection.State == ConnectionState.Closed)
{
Connection.Open();
}
using (IDbTransaction tran = Connection.BeginTransaction())
{
MySqlBulkLoader bulk = new MySqlBulkLoader(Connection as MySqlConnection)
{
LineTerminator = "\n",
TableName = tableName,
CharacterSet = "UTF8"
};
if (csv.IndexOf("\n")>0)
{
csv = csv.Replace("\n", " ");
}
var array = Encoding.UTF8.GetBytes(csv);
using (stream = new MemoryStream(array))
{
stream = new MemoryStream(array);
bulk.SourceStream = stream; //File.OpenRead(fileName);
bulk.Columns.AddRange(table.Columns.Cast<DataColumn>().Select(colum => colum.ColumnName).ToList());
insertCount = bulk.Load();
tran.Commit();
}
}
}
}
catch (Exception ex)
{
throw ex;
}
return insertCount;
// File.Delete(path);
}
/// <summary>
///将DataTable转换为标准的CSV
/// </summary>
/// <param name="table">数据表</param>
/// <returns>返回标准的CSV</returns>
private string DataTableToCsv(DataTable table)
{
//以半角逗号(即,)作分隔符,列为空也要表达其存在。
//列内容如存在半角逗号(即,)则用半角引号(即"")将该字段值包含起来。
//列内容如存在半角引号(即")则应替换成半角双引号("")转义,并用半角引号(即"")将该字段值包含起来。
StringBuilder sb = new StringBuilder();
DataColumn colum;
Type typeString = typeof(string);
Type typeDate = typeof(DateTime);
foreach (DataRow row in table.Rows)
{
for (int i = 0; i < table.Columns.Count; i++)
{
colum = table.Columns[i];
if (i != 0) sb.Append("\t");
if (colum.DataType == typeString && row[colum].ToString().Contains(","))
{
sb.Append(row[colum].ToString());
}
else if (colum.DataType == typeDate)
{
//centos系统里把datatable里的日期转换成了10/18/18 3:26:15 PM格式
bool b = DateTime.TryParse(row[colum].ToString(), out DateTime dt);
sb.Append(b ? dt.ToString("yyyy-MM-dd HH:mm:ss") : "");
}
else sb.Append(row[colum].ToString());
}
sb.Append("\n");
}
return sb.ToString();
}
/// <summary>
/// 2020.08.07增加PGSQL批量写入
/// </summary>
/// <param name="table"></param>
/// <param name="tableName"></param>
private void PGSqlBulkInsert(DataTable table, string tableName)
{
List<string> columns = new List<string>();
for (int i = 0; i < table.Columns.Count; i++)
{
columns.Add("\"" + table.Columns[i].ColumnName + "\"");
}
string copySql = $"copy \"public\".\"{tableName}\"({string.Join(',', columns)}) FROM STDIN (FORMAT BINARY)";
using (var conn = new Npgsql.NpgsqlConnection(_connectionString))
{
conn.Open();
using (var writer = conn.BeginBinaryImport(copySql))
{
foreach (DataRow row in table.Rows)
{
writer.StartRow();
for (int i = 0; i < table.Columns.Count; i++)
{
writer.Write(row[i]);
}
}
writer.Complete();
}
}
}
}
}

View File

@ -0,0 +1,72 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;
using System.Text;
using iMES.Core.Extensions;
namespace iMES.Core.EFDbContext
{
public abstract class BaseDbContext : DbContext
{
protected abstract string ConnectionString { get; }
public bool QueryTracking
{
set
{
this.ChangeTracker.QueryTrackingBehavior = value ? QueryTrackingBehavior.TrackAll : QueryTrackingBehavior.NoTracking;
}
}
public BaseDbContext() : base() { }
public BaseDbContext(DbContextOptions<BaseDbContext> options) : base(options) { }
protected void UseDbType(DbContextOptionsBuilder optionsBuilder,string connectionString)
{
if (Const.DBType.Name == Enums.DbCurrentType.MySql.ToString())
{
optionsBuilder.UseMySql(connectionString);
}
else if (Const.DBType.Name == Enums.DbCurrentType.PgSql.ToString())
{
optionsBuilder.UseNpgsql(connectionString);
}
else
{
optionsBuilder.UseSqlServer(connectionString);
}
}
protected void OnModelCreating(ModelBuilder modelBuilder, Type type)
{
try
{
//获取所有类库
var compilationLibrary = DependencyContext
.Default
.CompileLibraries
.Where(x => !x.Serviceable && x.Type != "package" && x.Type == "project");
foreach (var _compilation in compilationLibrary)
{
//加载指定类
AssemblyLoadContext.Default
.LoadFromAssemblyName(new AssemblyName(_compilation.Name))
.GetTypes().Where(x => x.GetTypeInfo().BaseType != null
&& x.BaseType == (type)).ToList()
.ForEach(t => { modelBuilder.Entity(t); });
}
base.OnModelCreating(modelBuilder);
}
catch (Exception ex)
{
string mapPath = ($"Log/").MapPath();
Utilities.FileHelper.WriteFile(mapPath, $"syslog_{DateTime.Now.ToString("yyyyMMddHHmmss")}.txt", ex.Message + ex.StackTrace + ex.Source);
}
}
}
}

View File

@ -0,0 +1,34 @@
using iMES.Core.Utilities;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Text;
namespace iMES.Core.EFDbContext
{
public class EFLoggerProvider : ILoggerProvider
{
public ILogger CreateLogger(string categoryName) => new EFLogger(categoryName);
public void Dispose() { }
}
public class EFLogger : ILogger
{
private readonly string categoryName;
public EFLogger(string categoryName) => this.categoryName = categoryName;
public bool IsEnabled(LogLevel logLevel) => true;
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
//ef core执行数据库查询时的categoryName为Microsoft.EntityFrameworkCore.Database.Command,日志级别为Information
if (categoryName == "Microsoft.EntityFrameworkCore.Database.Command"
&& logLevel == LogLevel.Information)
{
var logContent = formatter(state, exception);
Console.WriteLine(logContent);
}
}
public IDisposable BeginScope<TState>(TState state) => null;
}
}

View File

@ -0,0 +1,36 @@
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Text;
using iMES.Core.DBManager;
using iMES.Core.Extensions.AutofacManager;
using iMES.Entity.SystemModels;
namespace iMES.Core.EFDbContext
{
public class ReportDbContext : BaseDbContext, IDependency
{
protected override string ConnectionString
{
get
{
return DBServerProvider.ReportConnectingString;
}
}
public ReportDbContext() : base() { }
public ReportDbContext(DbContextOptions<BaseDbContext> options) : base(options) { }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.UseDbType(optionsBuilder, ConnectionString);
//默认禁用实体跟踪
optionsBuilder = optionsBuilder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
base.OnConfiguring(optionsBuilder);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder, typeof(ReportEntity));
}
}
}

View File

@ -0,0 +1,36 @@
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Text;
using iMES.Core.DBManager;
using iMES.Core.Extensions.AutofacManager;
using iMES.Entity.SystemModels;
namespace iMES.Core.EFDbContext
{
public class ServiceDbContext : BaseDbContext, IDependency
{
protected override string ConnectionString
{
get
{
return DBServerProvider.ServiceUserCurrnetConnectingString;
}
}
public ServiceDbContext() : base() { }
public ServiceDbContext(DbContextOptions<BaseDbContext> options) : base(options) { }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.UseDbType(optionsBuilder, ConnectionString);
//默认禁用实体跟踪
optionsBuilder = optionsBuilder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
base.OnConfiguring(optionsBuilder);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder, typeof(ServiceEntity));
}
}
}

Some files were not shown because too many files have changed in this diff Show More