Service.cs.vm 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. // Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
  2. //
  3. // 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
  4. //
  5. // 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
  6. using Admin.NET.Core.Service;
  7. using Microsoft.AspNetCore.Http;
  8. @{
  9. string joinTableName = "u";
  10. Dictionary<string, int> definedObjects = new Dictionary<string, int>();
  11. bool haveLikeCdt = false;
  12. foreach (var column in Model.TableField){
  13. if (column.QueryWhether == "Y" && column.QueryType == "like"){
  14. haveLikeCdt = true;
  15. }
  16. }
  17. var dictTableField = Model.TableField.Where(x => x.WhetherImport == "Y" && x.EffectType == "Select") ?? default;
  18. var hasdictService = dictTableField.Count() > 0;
  19. var importField = Model.TableField.Where(x => x.WhetherImport == "Y");
  20. }
  21. namespace @Model.NameSpace;
  22. /// <summary>
  23. /// @(@Model.BusName)服务
  24. /// </summary>
  25. [ApiDescriptionSettings(@(@Model.ProjectLastName)Const.GroupName, Order = 100)]
  26. public class @(@Model.ClassName)Service : IDynamicApiController, ITransient
  27. {
  28. private readonly SqlSugarRepository<@(@Model.ClassName)> _@(@Model.LowerClassName)Rep;
  29. @if (hasdictService) {
  30. @:private readonly SysDictTypeService _sysDictTypeService;
  31. }
  32. public @(@Model.ClassName)Service(SqlSugarRepository<@(@Model.ClassName)> @(@Model.LowerClassName)Rep
  33. @if (hasdictService) {
  34. @:,SysDictTypeService sysDictTypeService
  35. }
  36. ){
  37. _@(@Model.LowerClassName)Rep = @(@Model.LowerClassName)Rep;
  38. @if (hasdictService) {
  39. @:_sysDictTypeService = sysDictTypeService;
  40. }
  41. }
  42. /// <summary>
  43. /// 分页查询@(@Model.BusName)
  44. /// </summary>
  45. /// <param name="input"></param>
  46. /// <returns></returns>
  47. [HttpPost]
  48. [ApiDescriptionSettings(Name = "Page")]
  49. [DisplayName("分页查询@(@Model.BusName)")]
  50. public async Task<SqlSugarPagedList<@(@Model.ClassName)Output>> Page(Page@(@Model.ClassName)Input input)
  51. {
  52. @if (haveLikeCdt) {
  53. @:input.SearchKey = input.SearchKey?.Trim();
  54. }
  55. var query = _@(@Model.LowerClassName)Rep.AsQueryable()
  56. @{string conditionFlag = "";}
  57. @if (haveLikeCdt) {
  58. @:.WhereIF(!string.IsNullOrEmpty(input.SearchKey), u =>
  59. @foreach (var column in Model.TableField){
  60. if (@column.QueryWhether == "Y" && column.QueryType == "like"){
  61. @:@(conditionFlag)u.@(@column.PropertyName).Contains(input.SearchKey)
  62. conditionFlag="|| ";
  63. }
  64. }
  65. @:)
  66. }
  67. @foreach (var column in Model.TableField){
  68. if (@column.QueryWhether == "Y"){
  69. if (@column.NetType?.TrimEnd('?') == "string"){
  70. if(@column.QueryType == "like"){
  71. @:.WhereIF(!string.IsNullOrWhiteSpace(input.@column.PropertyName), u => u.@(@column.PropertyName).Contains(input.@(@column.PropertyName).Trim()))
  72. }else{
  73. @:.WhereIF(!string.IsNullOrWhiteSpace(input.@column.PropertyName), u => u.@(@column.PropertyName) @column.QueryType input.@(@column.PropertyName))
  74. }
  75. }else if(@column.NetType?.TrimEnd('?') == "int" || @column.NetType?.TrimEnd('?') == "long"){
  76. @:.WhereIF(input.@column.PropertyName>0, u => u.@(@column.PropertyName) @column.QueryType input.@(@column.PropertyName))
  77. }else if(@column.NetType?.TrimEnd('?') == "DateTime" && @column.QueryType == "~"){
  78. @:.WhereIF(input.@(@column.PropertyName)Range != null && input.@(@column.PropertyName)Range.Length == 2, u => u.@(@column.PropertyName) >= input.@(@column.PropertyName)Range[0] && u.@(@column.PropertyName) <= input.@(@column.PropertyName)Range[1])
  79. }else if(@column.NetType?.TrimEnd('?').EndsWith("Enum") == true) {
  80. @:.WhereIF(input.@(@column.PropertyName).HasValue, u => u.@(@column.PropertyName) @column.QueryType input.@(@column.PropertyName))
  81. }
  82. }
  83. }
  84. @if(Model.IsJoinTable){
  85. @://处理外键和TreeSelector相关字段的连接
  86. @foreach (var column in Model.TableField){
  87. if(@column.EffectType == "fk"){
  88. joinTableName += ", " + column.PropertyName.ToLower();
  89. @:.LeftJoin<@(@column.FkEntityName)>((@(@joinTableName)) => u.@(@column.PropertyName) == @(@column.PropertyName.ToLower()).@(@column.FkLinkColumnName) )
  90. } else if(@column.EffectType == "ApiTreeSelect"){
  91. joinTableName += ", " + column.PropertyName.ToLower();
  92. @:.LeftJoin<@(@column.FkEntityName)>((@(@joinTableName)) => u.@(@column.PropertyName) == @(@column.PropertyName.ToLower()).@(@column.ValueColumn) )
  93. }
  94. }
  95. @:.Select((@(@joinTableName)) => new @(@Model.ClassName)Output
  96. @:{
  97. @foreach (var column in Model.TableField){
  98. if(@column.EffectType == "fk"){
  99. @:@(@column.PropertyName) = u.@(@column.PropertyName),
  100. @:@(@column.PropertyName)@(@column.FkColumnName) = @(@column.PropertyName.ToLower()).@(@column.FkColumnName),
  101. } else if(@column.EffectType == "ApiTreeSelect"){
  102. @:@(@column.PropertyName) = u.@(@column.PropertyName),
  103. @:@(@column.PropertyName)@(@column.DisplayColumn) = @(@column.PropertyName.ToLower()).@(@column.DisplayColumn),
  104. } else if(@column.NetType?.TrimEnd('?').EndsWith("Enum") == true){
  105. @:@(@column.PropertyName) = (@(@column.NetType))u.@(@column.PropertyName),
  106. } else {
  107. @:@(@column.PropertyName) = u.@(@column.PropertyName),
  108. }
  109. }
  110. @:});
  111. @foreach (var column in Model.TableField){
  112. if(@column.EffectType == "fk"){
  113. }else if(@column.EffectType == "Upload"){
  114. @://.Mapper(c => c.@(@column.PropertyName)Attachment, c => c.@(@column.PropertyName))
  115. }
  116. }
  117. } else {
  118. @:.Select<@(@Model.ClassName)Output>();
  119. }
  120. return await query.OrderBuilder(input).ToPagedListAsync(input.Page, input.PageSize);
  121. }
  122. /// <summary>
  123. /// 增加@(@Model.BusName)
  124. /// </summary>
  125. /// <param name="input"></param>
  126. /// <returns></returns>
  127. [HttpPost]
  128. [ApiDescriptionSettings(Name = "Add")]
  129. [DisplayName("增加@(@Model.BusName)")]
  130. public async Task<long> Add(Add@(@Model.ClassName)Input input)
  131. {
  132. var entity = input.Adapt<@(@Model.ClassName)>();
  133. await _@(@Model.LowerClassName)Rep.InsertAsync(entity);
  134. return entity.Id;
  135. }
  136. /// <summary>
  137. /// 删除@(@Model.BusName)
  138. /// </summary>
  139. /// <param name="input"></param>
  140. /// <returns></returns>
  141. [HttpPost]
  142. [ApiDescriptionSettings(Name = "Delete")]
  143. [DisplayName("删除@(@Model.BusName)")]
  144. public async Task Delete(Delete@(@Model.ClassName)Input input)
  145. {
  146. @foreach (var column in Model.TableField){
  147. if (@column.ColumnKey == "True"){
  148. @:var entity = await _@(@Model.LowerClassName)Rep.GetFirstAsync(u => u.@(@column.PropertyName) == input.@(@column.PropertyName)) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
  149. }
  150. }
  151. await _@(@Model.LowerClassName)Rep.FakeDeleteAsync(entity); //假删除
  152. //await _@(@Model.LowerClassName)Rep.DeleteAsync(entity); //真删除
  153. }
  154. /// <summary>
  155. /// 更新@(@Model.BusName)
  156. /// </summary>
  157. /// <param name="input"></param>
  158. /// <returns></returns>
  159. [HttpPost]
  160. [ApiDescriptionSettings(Name = "Update")]
  161. [DisplayName("更新@(@Model.BusName)")]
  162. public async Task Update(Update@(@Model.ClassName)Input input)
  163. {
  164. var entity = input.Adapt<@(@Model.ClassName)>();
  165. await _@(@Model.LowerClassName)Rep.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
  166. }
  167. /// <summary>
  168. /// 获取@(@Model.BusName)
  169. /// </summary>
  170. /// <param name="input"></param>
  171. /// <returns></returns>
  172. [HttpGet]
  173. [ApiDescriptionSettings(Name = "Detail")]
  174. [DisplayName("获取@(@Model.BusName)")]
  175. public async Task<@(@Model.ClassName)> Detail([FromQuery] QueryById@(@Model.ClassName)Input input)
  176. {
  177. @foreach (var column in Model.TableField){
  178. if (@column.ColumnKey == "True"){
  179. @:return await _@(@Model.LowerClassName)Rep.GetFirstAsync(u => u.@(@column.PropertyName) == input.@(@column.PropertyName));
  180. }
  181. }
  182. }
  183. /// <summary>
  184. /// 获取@(@Model.BusName)列表
  185. /// </summary>
  186. /// <param name="input"></param>
  187. /// <returns></returns>
  188. [HttpGet]
  189. [ApiDescriptionSettings(Name = "List")]
  190. [DisplayName("获取@(@Model.BusName)列表")]
  191. public async Task<List<@(@Model.ClassName)Output>> List([FromQuery] Page@(@Model.ClassName)Input input)
  192. {
  193. return await _@(@Model.LowerClassName)Rep.AsQueryable().Select<@(@Model.ClassName)Output>().ToListAsync();
  194. }
  195. @foreach (var column in Model.TableField){
  196. if(@column.EffectType == "fk" && (@column.WhetherAddUpdate == "Y" || column.QueryWhether == "Y")){
  197. @:
  198. @:/// <summary>
  199. @:/// 获取@(@column.ColumnComment)列表
  200. @:/// </summary>
  201. @:/// <returns></returns>
  202. @:[ApiDescriptionSettings(Name = "@(@column.FkEntityName)@(@column.PropertyName)Dropdown"), HttpGet]
  203. @:[DisplayName("获取@(@column.ColumnComment)列表")]
  204. @:public async Task<dynamic> @(@column.FkEntityName)@(@column.PropertyName)Dropdown()
  205. @:{
  206. @:return await _@(@Model.LowerClassName)Rep.Context.Queryable<@(@column.FkEntityName)>()
  207. @:.Select(u => new
  208. @:{
  209. @:Label = u.@(@column.FkColumnName),
  210. @:Value = u.@(@column.FkLinkColumnName)
  211. @:}
  212. @:).ToListAsync();
  213. @:}
  214. }
  215. }
  216. @foreach (var column in Model.TableField){
  217. if(@column.EffectType == "Upload"){
  218. @:
  219. @:/// <summary>
  220. @:/// 上传@(@column.ColumnComment)
  221. @:/// </summary>
  222. @:/// <param name="file"></param>
  223. @:/// <returns></returns>
  224. @:[ApiDescriptionSettings(Name = "Upload@(@column.PropertyName)"), HttpPost]
  225. @:[DisplayName("上传@(@column.ColumnComment)")]
  226. @:public async Task<SysFile> Upload@(@column.PropertyName)([Required] IFormFile file)
  227. @:{
  228. @:var service = App.GetRequiredService<SysFileService>();
  229. @:return await service.UploadFile(new FileUploadInput { File = file, Path = "upload/@(@column.PropertyName)" });
  230. @:}
  231. }
  232. }
  233. @foreach (var column in Model.TableField){
  234. if(@column.EffectType == "ApiTreeSelect" && !definedObjects.ContainsKey("@(@column.FkEntityName)Tree")){
  235. @:
  236. @{definedObjects.Add("@(@column.FkEntityName)Tree", 1);}
  237. @:[HttpGet("@(@column.FkEntityName)Tree")]
  238. @:[DisplayName("获取@(@column.FkEntityName)Tree")]
  239. @:public async Task<dynamic> @(@column.FkEntityName)Tree()
  240. @:{
  241. @:return await _@(@Model.LowerClassName)Rep.Context.Queryable<@(@column.FkEntityName)>().ToTreeAsync(u => u.Children, u => u.@(@column.PidColumn), 0);
  242. @:}
  243. }
  244. }
  245. @if (hasdictService) {
  246. @:
  247. @:/// <summary>
  248. @:/// 获取字典文本列表
  249. @:/// </summary>
  250. @:/// <param name="dictTypeCode"></param>
  251. @:/// <returns></returns>
  252. @:private List<string> GetDictDataTextList(string dictTypeCode)
  253. @:{
  254. @: return _sysDictTypeService.GetDataList(new GetDataDictTypeInput { Code = dictTypeCode }).Result?.Select(x => x.Value).ToList();
  255. @:}
  256. }
  257. @if (importField?.Count() > 0) {
  258. @:
  259. @:/// <summary>
  260. @:/// 下载@(@Model.BusName)数据导入模板
  261. @:/// </summary>
  262. @:/// <returns></returns>
  263. @:[DisplayName("下载@(@Model.BusName)数据导入模板")]
  264. @:[ApiDescriptionSettings(Name = "Import"), HttpGet, NonUnify]
  265. @:public IActionResult DownloadTemplate()
  266. @:{
  267. @:return ExcelHelper.ExportTemplate(new List<Export@(@Model.ClassName)Output>(), "@(@Model.BusName)导入模板");
  268. @:}
  269. @:
  270. @:/// <summary>
  271. @:/// 导入@(@Model.BusName)记录 📃
  272. @:/// </summary>
  273. @:/// <returns></returns>
  274. @:[DisplayName("导入@(@Model.BusName)记录")]
  275. @:[ApiDescriptionSettings(Name = "Import"), HttpPost, NonUnify, UnitOfWork]
  276. @:public IActionResult ImportData([Required] IFormFile file)
  277. @:{
  278. @:lock (this)
  279. @:{
  280. foreach (var column in dictTableField){
  281. @:var @(@column.LowerPropertyName)DictMap = _sysDictTypeService.GetDataList(new GetDataDictTypeInput { Code = "@(@column.DictTypeCode)" }).Result.ToDictionary(x => x.Value, x => x.Code);
  282. }
  283. @:var stream = ExcelHelper.ImportData<Import@(@Model.ClassName)Input, @(@Model.ClassName)>(file, (list, markerErrorAction) =>
  284. @:{
  285. @:_@(@Model.LowerClassName)Rep.Context.Utilities.PageEach(list, 2048, pageItems =>
  286. @:{
  287. @:// 校验并过滤必填基本类型为null的字段
  288. @:var rows = pageItems.Where(x => {
  289. foreach (var column in importField.Where(x => x.WhetherRequired == "Y" && Regex.IsMatch(x.NetType, "(int|long|double|float|bool|Enum[?]?)"))){
  290. @:if (x.@(@column.PropertyName) == null){
  291. @:x.Error = "@(@column.ColumnComment)不能为空";
  292. @:return false;
  293. @:}
  294. }
  295. @:return true;
  296. @:}).Adapt<List<@(@Model.ClassName)>>();
  297. if (hasdictService){
  298. @:// 映射字典值
  299. @:foreach(var row in rows){
  300. foreach (var column in dictTableField){
  301. @:row.@(@column.PropertyName) = @(@column.LowerPropertyName)DictMap.GetValueOrDefault(row.@(@column.PropertyName) ?? "");
  302. }
  303. @:}
  304. }
  305. @:var storageable = _@(@Model.LowerClassName)Rep.Context.Storageable(rows)
  306. foreach (var column in importField){
  307. if (@column.WhetherRequired == "Y"){
  308. if(@column.NetType.TrimEnd('?') == "string"){
  309. @:.SplitError(it => string.IsNullOrWhiteSpace(it.Item.@(@column.PropertyName)), "@(@column.ColumnComment)不能为空")
  310. } else if(@column.NetType.EndsWith('?') == true){
  311. @:.SplitError(it => it.Item.@(@column.PropertyName) == null, "@(@column.ColumnComment)不能为空")
  312. }}
  313. if (@column.NetType?.TrimEnd('?') == "string"){
  314. @:.SplitError(it => it.Item.@(@column.PropertyName)?.Length > @column.ColumnLength, "@(@column.ColumnComment)长度不能超过@(@column.ColumnLength)个字符")
  315. }}
  316. @:.ToStorage();
  317. @:storageable.BulkCopy();
  318. @:storageable.BulkUpdate();
  319. @:markerErrorAction.Invoke(storageable, pageItems, rows);
  320. @:});
  321. @:});
  322. @:
  323. @:return stream;
  324. @:}
  325. @:}
  326. }
  327. @}