SceneApplicationService.cs 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Configuration;
  4. using System.Data.Entity;
  5. using System.Linq;
  6. using System.Threading.Tasks;
  7. using System.Web.Mvc;
  8. using Abp.Application.Services.Dto;
  9. using Abp.Auditing;
  10. using Abp.Authorization;
  11. using Abp.Domain.Repositories;
  12. using Abp.Runtime.Caching;
  13. using Abp.UI;
  14. using IwbZero.Auditing;
  15. using IwbZero.AppServiceBase;
  16. using IwbZero.ToolCommon.FileHelpers;
  17. using IwbZero.ToolCommon.Lambda;
  18. using IwbZero.ToolCommon.LogHelpers;
  19. using IwbZero.ToolCommon.StringModel;
  20. using NPOI.SS.UserModel;
  21. using NPOI.XSSF.UserModel;
  22. using WeEngine.Enum;
  23. using WePlatform.Authorization;
  24. using WePlatform.WeBase;
  25. using WePlatform.WeBase.SceneCategory.Dto;
  26. using WePlatform.WeLib.Scene.Dto;
  27. namespace WePlatform.WeLib.Scene
  28. {
  29. [AbpAuthorize, AuditLog("情景库管理")]
  30. public class SceneAppService : IwbAsyncCrudAppService<SceneInfo, SceneDto, string, IwbPagedRequestDto, SceneCreateDto, SceneUpdateDto>, ISceneAppService
  31. {
  32. public SceneAppService(
  33. ICacheManager cacheManager,
  34. IRepository<SceneInfo, string> repository, IRepository<SceneBehaviorInfo> sbRepository, IRepository<EnvironResourceRelatedInfo> errRepository, IRepository<GuideRelatedInfo> grRepository, IRepository<SceneCategoryInfo, string> scRepository, IRepository<BehaviorInfo, string> behaviorRepository, IRepository<RoleRelateCategoryInfo> rcRepository, IRepository<BehaviorRelateRoleInfo> brrRepository) : base(repository, "Id")
  35. {
  36. SbRepository = sbRepository;
  37. ErrRepository = errRepository;
  38. GrRepository = grRepository;
  39. ScRepository = scRepository;
  40. BehaviorRepository = behaviorRepository;
  41. RcRepository = rcRepository;
  42. BrrRepository = brrRepository;
  43. CacheManager = cacheManager;
  44. }
  45. protected override bool KeyIsAuto { get; set; } = false;
  46. protected IRepository<BehaviorInfo, string> BehaviorRepository { get; }
  47. protected IRepository<SceneBehaviorInfo> SbRepository { get; }
  48. protected IRepository<SceneCategoryInfo, string> ScRepository { get; }
  49. protected IRepository<EnvironResourceRelatedInfo> ErrRepository { get; }
  50. protected IRepository<GuideRelatedInfo> GrRepository { get; }
  51. protected IRepository<RoleRelateCategoryInfo> RcRepository { get; }
  52. protected IRepository<BehaviorRelateRoleInfo> BrrRepository { get; }
  53. #region GetSelect
  54. [DisableAuditing]
  55. public override async Task<List<SelectListItem>> GetSelectList()
  56. {
  57. var list = await Repository.GetAllListAsync();
  58. var sList = new List<SelectListItem> { new SelectListItem { Text = @"请选择...", Value = "", Selected = true } };
  59. foreach (var l in list)
  60. {
  61. sList.Add(new SelectListItem { Value = l.Id, Text = l.Name });
  62. }
  63. return sList;
  64. }
  65. [DisableAuditing]
  66. public override async Task<string> GetSelectStr()
  67. {
  68. var list = await Repository.GetAllListAsync();
  69. string str = "<option value=\"\" selected>请选择...</option>";
  70. foreach (var l in list)
  71. {
  72. str += $"<option value=\"{l.Id}\">{l.Name}</option>";
  73. }
  74. return str;
  75. }
  76. #endregion GetSelect
  77. #region CURD
  78. [AbpAuthorize(PermissionNames.PagesResourceMgSceneMgCreate)]
  79. public override async Task Create(SceneCreateDto input)
  80. {
  81. input.Id = await AppGuidManager.GetNextRecordIdAsync(DataLibType.SceneInfo);
  82. //添加关联行为
  83. if (input.SceneBehaviors != null && input.SceneBehaviors.Any())
  84. {
  85. foreach (var behaviorDto in input.SceneBehaviors)
  86. {
  87. var behavior = ObjectMapper.Map<SceneBehaviorInfo>(behaviorDto);
  88. behavior.SceneNo = input.Id;
  89. await SbRepository.InsertAsync(behavior);
  90. }
  91. }
  92. //添加关联环境资源
  93. if (input.EnvironResourceNos.Any())
  94. {
  95. foreach (var no in input.EnvironResourceNos)
  96. {
  97. if (no.IsEmpty())
  98. {
  99. continue;
  100. }
  101. var err = new EnvironResourceRelatedInfo()
  102. {
  103. EnvironResourceNo = no,
  104. RelatedNo = input.Id,
  105. RelatedType = DataLibType.SceneInfo.ToInt()
  106. };
  107. await ErrRepository.InsertAsync(err);
  108. }
  109. }
  110. //添加变量
  111. string variable = "";
  112. if (input.Variables != null && input.Variables.Any())
  113. {
  114. foreach (var v in input.Variables)
  115. {
  116. variable += (variable == "" ? "" : ",") + v;
  117. }
  118. //variable = StringExtensions.IsEmpty(variable) ? "" : $"[{variable}]";
  119. }
  120. input.Variable = variable;
  121. //添加引导信息
  122. if (input.GuideNos.IsNotEmpty())
  123. {
  124. var arr = input.GuideNos.Split(',');
  125. foreach (var no in arr)
  126. {
  127. if (no.IsEmpty())
  128. {
  129. continue;
  130. }
  131. var guide = new GuideRelatedInfo()
  132. {
  133. GuideNo = no,
  134. RelatedNo = input.Id,
  135. RelatedType = DataLibType.SceneInfo.ToInt()
  136. };
  137. await GrRepository.InsertAsync(guide);
  138. }
  139. }
  140. await CreateEntity(input);
  141. }
  142. [AbpAuthorize(PermissionNames.PagesResourceMgSceneMgUpdate)]
  143. public override async Task Update(SceneUpdateDto input)
  144. {
  145. //更新变量
  146. string variable = "";
  147. if (input.Variables != null && input.Variables.Any())
  148. {
  149. foreach (var v in input.Variables)
  150. {
  151. variable += (variable == "" ? "" : ",") + v;
  152. }
  153. //variable = StringExtensions.IsEmpty(variable) ? "" : $"[{variable}]";
  154. }
  155. input.Variable = variable;
  156. var dto = await UpdateEntity(input);
  157. //更新情景关联行为
  158. {
  159. var sceneBehaviorNos = await SbRepository.GetAll().Where(a => a.SceneNo == dto.Id).Select(a => a.BehaviorNo).ToListAsync();
  160. if (input.SceneBehaviors != null && input.SceneBehaviors.Any())
  161. {
  162. foreach (var behaviorDto in input.SceneBehaviors)
  163. {
  164. if (behaviorDto.BehaviorNo.IsEmpty())
  165. {
  166. continue;
  167. }
  168. if (!sceneBehaviorNos.Contains(behaviorDto.BehaviorNo))
  169. {
  170. //新增原集合中不存在的行为
  171. var behavior = ObjectMapper.Map<SceneBehaviorInfo>(behaviorDto);
  172. behavior.SceneNo = input.Id;
  173. await SbRepository.InsertAsync(behavior);
  174. }
  175. else
  176. {
  177. var behavior = await SbRepository.FirstOrDefaultAsync(a => a.SceneNo == input.Id && a.BehaviorNo == behaviorDto.BehaviorNo);
  178. behavior.BehaviorEvalType = behaviorDto.BehaviorEvalType;
  179. behavior.BehaviorWeight = behaviorDto.BehaviorWeight;
  180. await SbRepository.UpdateAsync(behavior);
  181. //移除原集合中已存在的行为(剩余不在新增集合中的需删除)
  182. sceneBehaviorNos.Remove(behaviorDto.BehaviorNo);
  183. }
  184. }
  185. }
  186. //删除多余的角色
  187. if (sceneBehaviorNos.Any())
  188. {
  189. foreach (var behaviorNo in sceneBehaviorNos)
  190. {
  191. await SbRepository.DeleteAsync(a => a.SceneNo == dto.Id && a.BehaviorNo == behaviorNo);
  192. }
  193. }
  194. }
  195. //更新关联环境资源
  196. {
  197. var errNos = await ErrRepository.GetAll().Where(a => a.RelatedNo == dto.Id).Select(a => a.EnvironResourceNo).ToListAsync();
  198. if (input.EnvironResourceNos.Any())
  199. {
  200. foreach (var no in input.EnvironResourceNos)
  201. {
  202. if (no.IsEmpty())
  203. {
  204. continue;
  205. }
  206. if (!errNos.Contains(no))
  207. {
  208. var err = new EnvironResourceRelatedInfo()
  209. {
  210. EnvironResourceNo = no,
  211. RelatedNo = input.Id,
  212. RelatedType = DataLibType.SceneInfo.ToInt()
  213. };
  214. await ErrRepository.InsertAsync(err);
  215. }
  216. else
  217. {
  218. errNos.Remove(no);
  219. }
  220. }
  221. }
  222. //删除多余的环境资源
  223. if (errNos.Any())
  224. {
  225. await ErrRepository.DeleteAsync(a => a.RelatedNo == dto.Id && errNos.Contains(a.EnvironResourceNo));
  226. }
  227. }
  228. //更新引导信息
  229. {
  230. var grNos = await GrRepository.GetAll().Where(a => a.RelatedNo == dto.Id).Select(a => a.GuideNo).ToListAsync();
  231. if (input.GuideNos.IsNotEmpty())
  232. {
  233. var arr = input.GuideNos.Split(',');
  234. foreach (var no in arr)
  235. {
  236. if (no.IsEmpty())
  237. {
  238. continue;
  239. }
  240. if (!grNos.Contains(no))
  241. {
  242. var guide = new GuideRelatedInfo()
  243. {
  244. GuideNo = no,
  245. RelatedNo = input.Id,
  246. RelatedType = DataLibType.SceneInfo.ToInt()
  247. };
  248. await GrRepository.InsertAsync(guide);
  249. }
  250. else
  251. {
  252. grNos.Remove(no);
  253. }
  254. }
  255. }
  256. //删除多余的引导信息
  257. if (grNos.Any())
  258. {
  259. await GrRepository.DeleteAsync(a => a.RelatedNo == dto.Id && grNos.Contains(a.GuideNo));
  260. }
  261. }
  262. }
  263. [AbpAuthorize(PermissionNames.PagesResourceMgSceneMgDelete)]
  264. public override Task Delete(EntityDto<string> input)
  265. {
  266. return base.Delete(input);
  267. }
  268. [DisableAuditing]
  269. [AbpAuthorize(PermissionNames.PagesResourceMgSceneMgQuery)]
  270. public override async Task<PagedResultDto<SceneDto>> GetAll(IwbPagedRequestDto input)
  271. {
  272. var query = CreateFilteredQuery(input);
  273. var totalCount = await AsyncQueryableExecuter.CountAsync(query);
  274. query = ApplySorting(query, input);
  275. query = ApplyPaging(query, input);
  276. var entities = await AsyncQueryableExecuter.ToListAsync(query);
  277. var dtoList = new PagedResultDto<SceneDto>(totalCount, entities.Select(MapToEntityDto).ToList());
  278. return dtoList;
  279. }
  280. #region GetEntity/Dto
  281. /// <summary>
  282. /// 查询实体Dto
  283. /// </summary>
  284. /// <param name="input"></param>
  285. /// <returns></returns>
  286. [DisableAuditing]
  287. [AbpAuthorize(PermissionNames.PagesResourceMgSceneMgQuery)]
  288. public override async Task<SceneDto> GetDto(EntityDto<string> input)
  289. {
  290. var entity = await GetEntity(input);
  291. return MapToEntityDto(entity);
  292. }
  293. /// <summary>
  294. /// 查询实体Dto
  295. /// </summary>
  296. /// <param name="id"></param>
  297. /// <returns></returns>
  298. [DisableAuditing]
  299. [AbpAuthorize(PermissionNames.PagesResourceMgSceneMgQuery)]
  300. public override async Task<SceneDto> GetDtoById(string id)
  301. {
  302. var entity = await GetEntityById(id);
  303. return MapToEntityDto(entity);
  304. }
  305. /// <summary>
  306. /// 查询实体Dto(需指明自定义字段)
  307. /// </summary>
  308. /// <param name="no"></param>
  309. /// <returns></returns>
  310. [DisableAuditing]
  311. [AbpAuthorize(PermissionNames.PagesResourceMgSceneMgQuery)]
  312. public override async Task<SceneDto> GetDtoByNo(string no)
  313. {
  314. var entity = await GetEntityByNo(no);
  315. return MapToEntityDto(entity);
  316. }
  317. /// <summary>
  318. /// 查询实体
  319. /// </summary>
  320. /// <param name="input"></param>
  321. /// <returns></returns>
  322. [DisableAuditing]
  323. [AbpAuthorize(PermissionNames.PagesResourceMgSceneMgQuery)]
  324. public override async Task<SceneInfo> GetEntity(EntityDto<string> input)
  325. {
  326. var entity = await GetEntityById(input.Id);
  327. return entity;
  328. }
  329. /// <summary>
  330. /// 查询实体
  331. /// </summary>
  332. /// <param name="id"></param>
  333. /// <returns></returns>
  334. [DisableAuditing]
  335. [AbpAuthorize(PermissionNames.PagesResourceMgSceneMgQuery)]
  336. public override async Task<SceneInfo> GetEntityById(string id)
  337. {
  338. return await Repository.FirstOrDefaultAsync(a => a.Id == id);
  339. }
  340. /// <summary>
  341. /// 查询实体(需指明自定义字段)
  342. /// </summary>
  343. /// <param name="no"></param>
  344. /// <returns></returns>
  345. [DisableAuditing]
  346. [AbpAuthorize(PermissionNames.PagesResourceMgSceneMgQuery)]
  347. public override async Task<SceneInfo> GetEntityByNo(string no)
  348. {
  349. //CheckGetPermission();
  350. if (string.IsNullOrEmpty(KeyFiledName))
  351. {
  352. ThrowError("NoKeyFieldName");
  353. }
  354. return await base.GetEntityByNo(no);
  355. }
  356. #endregion GetEntity/Dto
  357. #region Hide
  358. /// <summary>
  359. /// 根据给定的<see cref="IwbPagedRequestDto"/>创建 <see cref="IQueryable{SceneFlowInfo}"/>过滤查询.
  360. /// </summary>
  361. /// <param name="input">The input.</param>
  362. protected override IQueryable<SceneInfo> CreateFilteredQuery(IwbPagedRequestDto input)
  363. {
  364. var query = Repository.GetAllIncluding(a => a.SceneCategoryInfo);
  365. var pagedInput = input as IIwbPagedRequest;
  366. if (pagedInput == null)
  367. {
  368. return query;
  369. }
  370. if (!string.IsNullOrEmpty(pagedInput.KeyWords))
  371. {
  372. object keyWords = pagedInput.KeyWords;
  373. LambdaObject obj = new LambdaObject()
  374. {
  375. FieldType = (LambdaFieldType)pagedInput.FieldType,
  376. FieldName = pagedInput.KeyField,
  377. FieldValue = keyWords,
  378. ExpType = (LambdaExpType)pagedInput.ExpType
  379. };
  380. var exp = obj.GetExp<SceneInfo>();
  381. query = exp != null ? query.Where(exp) : query;
  382. }
  383. if (pagedInput.SearchList != null && pagedInput.SearchList.Count > 0)
  384. {
  385. List<LambdaObject> objList = new List<LambdaObject>();
  386. foreach (var o in pagedInput.SearchList)
  387. {
  388. if (string.IsNullOrEmpty(o.KeyWords))
  389. continue;
  390. if (o.KeyField.ToLower() == "sceneCategory".ToLower())
  391. {
  392. query = query.Where(a => a.SceneCategoryInfo.CategoryPath.Contains(o.KeyWords));
  393. continue;
  394. }
  395. object keyWords = o.KeyWords;
  396. objList.Add(new LambdaObject
  397. {
  398. FieldType = (LambdaFieldType)o.FieldType,
  399. FieldName = o.KeyField,
  400. FieldValue = keyWords,
  401. ExpType = (LambdaExpType)o.ExpType
  402. });
  403. }
  404. var exp = objList.GetExp<SceneInfo>();
  405. query = exp != null ? query.Where(exp) : query;
  406. }
  407. return query;
  408. }
  409. //protected override IQueryable<SceneInfo> ApplySorting(IQueryable<SceneInfo> query, IwbPagedRequestDto input)
  410. //{
  411. // if (input.Sorting.IsNotEmpty())
  412. // {
  413. // return query.OrderBy(input.Sorting);
  414. // }
  415. // return base.ApplySorting(query, input);
  416. //}
  417. //protected override IQueryable<SceneInfo> ApplyPaging(IQueryable<SceneInfo> query, IwbPagedRequestDto input)
  418. //{
  419. // if (input is IPagedResultRequest pagedInput)
  420. // {
  421. // return query.Skip(pagedInput.SkipCount).Take(pagedInput.MaxResultCount);
  422. // }
  423. // return query;
  424. //}
  425. #endregion Hide
  426. #endregion CURD
  427. /// <summary>
  428. /// 查询情景的引导信息
  429. /// </summary>
  430. /// <param name="no"></param>
  431. /// <returns></returns>
  432. [DisableAuditing]
  433. public async Task<List<string>> GetSceneGuideByNo(string no)
  434. {
  435. var list = new List<string>();
  436. var type = DataLibType.SceneInfo.ToInt();
  437. var guides = await GrRepository.GetAllIncluding(a => a.GuideInfo).Where(a => a.RelatedNo == no && a.RelatedType == type).ToListAsync();
  438. list.Add(string.Join(",", guides.Select(a => a.GuideNo).ToArray()));
  439. list.Add(string.Join(",", guides.Select(a => a.GuideInfo.Name).ToArray()));
  440. return list;
  441. }
  442. /// <summary>
  443. /// 查询情景的行为信息
  444. /// </summary>
  445. /// <param name="no"></param>
  446. /// <returns></returns>
  447. [DisableAuditing]
  448. public async Task<List<SceneBehaviorDto>> GetSceneBehavior(string no)
  449. {
  450. var sbs = await SbRepository.GetAllListAsync(a => a.SceneNo == no);
  451. return sbs.Select(ObjectMapper.Map<SceneBehaviorDto>).ToList();
  452. }
  453. /// <summary>
  454. /// 查询情景的环境资源信息
  455. /// </summary>
  456. /// <param name="no"></param>
  457. /// <returns></returns>
  458. [DisableAuditing]
  459. public async Task<List<string>> GetSceneEnvironResourceNos(string no)
  460. {
  461. var type = DataLibType.SceneInfo.ToInt();
  462. var errs = await ErrRepository.GetAllListAsync(a => a.RelatedNo == no && a.RelatedType == type);
  463. return errs.Select(a => a.EnvironResourceNo).ToList();
  464. }
  465. /// <summary>
  466. /// 查询情景变量
  467. /// </summary>
  468. /// <param name="no"></param>
  469. /// <returns></returns>
  470. [DisableAuditing]
  471. public async Task<List<VariableDto>> GetSceneVariable(string no)
  472. {
  473. var variables = (await Repository.FirstOrDefaultAsync(a => a.Id == no))?.Variable ?? "";
  474. var variableArr = variables.StrToArray();
  475. var variableList = new List<VariableDto>();
  476. foreach (var v in variableArr)
  477. {
  478. variableList.Add(new VariableDto(v));
  479. }
  480. return variableList;
  481. }
  482. #region Import
  483. private string Password => ConfigurationManager.AppSettings["TEMPLATE.EXCEL.SCENE.CHECK.NO"] ?? "Iwb_Scene_V1.0.0";
  484. /// <summary>
  485. /// 导入情景
  486. /// </summary>
  487. /// <param name="input"></param>
  488. /// <returns></returns>
  489. [AbpAuthorize(), AuditLog("导入情景")]
  490. public async Task Import(UploadSceneDto input)
  491. {
  492. if (input.ExcelInfo.IsEmpty())
  493. {
  494. CheckErrors("未接收到上传文件,请检查后再试!");
  495. }
  496. if (input.ExcelExt != "xlsx")
  497. {
  498. CheckErrors("模板异常,请使用正确的模板填充数据后再导入。");
  499. }
  500. string filePath = $"Upload/Excel/Scene/{DateTime.Now:yyyyMM}",
  501. fileName = $"{DateTime.Now:ddHHmmssff}-{input.ExcelName}";
  502. await AttachFileManager.FileUpload(input.ExcelInfo, filePath, fileName, input.ExcelExt);
  503. var work = ExcelHelper.CreateWorkBook07($"{AppDomain.CurrentDomain.BaseDirectory }{filePath}/{fileName}.{input.ExcelExt}");
  504. var sheet = work.GetSheet("Scene");
  505. if (sheet == null)
  506. {
  507. CheckErrors("模板异常,请使用最新的模板填充数据后再导入。(从系统中下载最新模板)");
  508. return;
  509. }
  510. if (sheet.GenerateCell(1, 27).StringCellValue != Password)
  511. {
  512. CheckErrors("模板异常,请使用最新的模板填充数据后再导入(从系统中下载最新模板)。");
  513. return;
  514. }
  515. int rowIndex = 3;
  516. if (sheet.LastRowNum > 10000)
  517. {
  518. CheckErrors("导入数量太大,请分批导入。(如果记录条数小于10000,请检查空白行的格式)");
  519. return;
  520. }
  521. while (rowIndex <= sheet.LastRowNum)
  522. {
  523. rowIndex = await ImportScene(sheet, rowIndex);
  524. }
  525. }
  526. /// <summary>
  527. /// 导入情景
  528. /// </summary>
  529. /// <param name="sheet"></param>
  530. /// <param name="rowIndex"></param>
  531. /// <returns></returns>
  532. private async Task<int> ImportScene(ISheet sheet, int rowIndex)
  533. {
  534. var row = sheet.GenerateRow(rowIndex);
  535. var name = row.GenerateCell(2).StringCellValue ?? "";
  536. if (name.IsEmpty())
  537. {
  538. rowIndex++;
  539. return rowIndex;
  540. }
  541. var sceneNo = await SaveScene(row);
  542. sheet.IsMergeCell(row.RowNum, 0, out var dimension);
  543. List<string> bNos = await SbRepository.GetAll().Where(a => a.SceneNo == sceneNo).Select(a => a.BehaviorNo).ToListAsync();
  544. for (int i = 0; i < dimension.RowSpan; i++)
  545. {
  546. var bRow = sheet.GenerateRow(rowIndex);
  547. var bNo = await SaveBehavior(bRow, sceneNo);
  548. if (bNos.Contains(bNo))
  549. {
  550. bNos.Remove(bNo);
  551. }
  552. rowIndex++;
  553. }
  554. if (bNos.Count > 0)
  555. {
  556. await SbRepository.DeleteAsync(a => a.SceneNo == sceneNo && bNos.Contains(a.BehaviorNo));
  557. }
  558. return rowIndex;
  559. }
  560. /// <summary>
  561. /// 保存情景
  562. /// </summary>
  563. /// <param name="row"></param>
  564. /// <returns></returns>
  565. private async Task<string> SaveScene(IRow row)
  566. {
  567. int columnIndex = 1;
  568. try
  569. {
  570. string id = row.GenerateCell(columnIndex).StringCellValue ?? "";
  571. SceneInfo scene = (id.IsEmpty() ? null : await Repository.FirstOrDefaultAsync(a => a.Id == id));
  572. columnIndex++;
  573. var name = row.GenerateCell(columnIndex).StringCellValue ?? "";
  574. if (name.Length > BehaviorInfo.NameLength)
  575. {
  576. name = name.Substring(0, BehaviorInfo.NameLength);
  577. }
  578. if (scene == null)
  579. {
  580. scene = new SceneInfo
  581. {
  582. Id = await AppGuidManager.GetNextRecordIdAsync(DataLibType.SceneInfo),
  583. Name = name
  584. };
  585. columnIndex++;
  586. scene.SceneCategory = GetTypeNo(row.GenerateCell(columnIndex).StringCellValue ?? "");
  587. columnIndex++;
  588. scene.SceneTag = row.GenerateCell(columnIndex).StringCellValue ?? "";
  589. columnIndex++;
  590. scene.Description = row.GenerateCell(columnIndex).StringCellValue ?? "";
  591. columnIndex++;
  592. scene.Variable = CheckString(row.GenerateCell(columnIndex).StringCellValue ?? "");
  593. scene.SceneType = (int)SceneType.Evolution;
  594. await Repository.InsertAndGetIdAsync(scene);
  595. }
  596. else
  597. {
  598. scene.Name = name;
  599. columnIndex++;
  600. scene.SceneCategory = GetTypeNo(row.GenerateCell(columnIndex).StringCellValue ?? $"({ scene.SceneCategory})");
  601. columnIndex++;
  602. scene.SceneTag = row.GenerateCell(columnIndex).StringCellValue ?? "";
  603. columnIndex++;
  604. scene.Description = row.GenerateCell(columnIndex).StringCellValue ?? "";
  605. columnIndex++;
  606. scene.Variable = CheckString(row.GenerateCell(columnIndex).StringCellValue ?? "");
  607. await Repository.UpdateAsync(scene);
  608. }
  609. return scene.Id;
  610. }
  611. catch (Exception e)
  612. {
  613. this.LogError(e);
  614. throw new UserFriendlyException($"[{(columnIndex - 1).ConvertColumnName()}{row.RowNum + 1}]内容出错,请检查后再试。");
  615. }
  616. }
  617. /// <summary>
  618. /// 保存行为
  619. /// </summary>
  620. /// <param name="row"></param>
  621. /// <param name="sceneNo"></param>
  622. /// <returns></returns>
  623. private async Task<string> SaveBehavior(IRow row, string sceneNo)
  624. {
  625. int columnIndex = 7;
  626. try
  627. {
  628. string id = row.GenerateCell(columnIndex).StringCellValue ?? "";
  629. BehaviorInfo behavior =
  630. (id.IsEmpty() ? null : await BehaviorRepository.FirstOrDefaultAsync(a => a.Id == id));
  631. columnIndex = 8;
  632. var name = row.GenerateCell(columnIndex).StringCellValue ?? "";
  633. if (name.Length > BehaviorInfo.NameLength)
  634. {
  635. name = name.Substring(0, BehaviorInfo.NameLength);
  636. }
  637. var description = row.GenerateCell(11).StringCellValue ?? "";
  638. if (behavior == null)
  639. {
  640. behavior = await BehaviorRepository.FirstOrDefaultAsync(a =>
  641. a.BehaviorName == name);
  642. if (behavior == null)
  643. {
  644. behavior = new BehaviorInfo
  645. {
  646. Id = await AppGuidManager.GetNextRecordIdAsync(DataLibType.BehaviorInfo),
  647. BehaviorName = name
  648. };
  649. columnIndex++;
  650. behavior.SceneCategory = GetTypeNo(row.GenerateCell(columnIndex).StringCellValue ?? "");
  651. columnIndex++;
  652. var behaviorTag = row.GenerateCell(columnIndex).StringCellValue ?? "";
  653. behaviorTag= behaviorTag.Trim().Replace(",",",");
  654. while (behaviorTag.Contains(",,"))
  655. {
  656. behaviorTag= behaviorTag.Trim().Replace(",,",",");
  657. }
  658. behavior.BehaviorTag = behaviorTag;
  659. columnIndex++;
  660. behavior.Description = description;
  661. columnIndex++;
  662. columnIndex++;
  663. behavior.RuleKeyword = CheckString(row.GenerateCell(columnIndex).StringCellValue ?? "");
  664. behavior.RoleLogicType = (int)BehaviorRoleLogicType.Or;
  665. await BehaviorRepository.InsertAndGetIdAsync(behavior);
  666. await CurrentUnitOfWork.SaveChangesAsync();
  667. }
  668. }
  669. else
  670. {
  671. behavior.BehaviorName = name;
  672. columnIndex++;
  673. behavior.SceneCategory = GetTypeNo(row.GenerateCell(columnIndex).StringCellValue ?? $"({ behavior.SceneCategory})");
  674. columnIndex++;
  675. behavior.BehaviorTag = row.GenerateCell(columnIndex).StringCellValue ?? "";
  676. columnIndex++;
  677. behavior.Description = description;
  678. columnIndex++;
  679. columnIndex++;
  680. behavior.RuleKeyword = CheckString(row.GenerateCell(columnIndex).StringCellValue ?? "");
  681. await BehaviorRepository.UpdateAsync(behavior);
  682. }
  683. columnIndex = 12;
  684. string roleNos = row.GenerateCell(columnIndex).StringCellValue ?? "";
  685. if (roleNos.IsNotEmpty())
  686. {
  687. await SaveBehaviorRoles(behavior.Id, roleNos);
  688. }
  689. #region 关联情景
  690. columnIndex = 14;
  691. int behaviorEvalType = GetEvalType(row.GenerateCell(columnIndex).StringCellValue ?? "");
  692. columnIndex++;
  693. decimal? behaviorWeight = null;
  694. try
  695. {
  696. behaviorWeight = (decimal)row.GenerateCell(columnIndex).NumericCellValue;
  697. }
  698. catch
  699. {
  700. var behaviorWeightStr = row.GenerateCell(columnIndex).StringCellValue;
  701. if (int.TryParse(behaviorWeightStr, out var behaviorWeight2))
  702. {
  703. behaviorWeight = behaviorWeight2;
  704. }
  705. }
  706. if (behaviorWeight != null)
  707. {
  708. await SaveSceneBehavior(sceneNo, behavior.Id, behaviorEvalType, (decimal)behaviorWeight);
  709. }
  710. #endregion 关联情景
  711. return behavior.Id;
  712. }
  713. catch (Exception e)
  714. {
  715. this.LogError(e);
  716. throw new UserFriendlyException($"[{(columnIndex - 1).ConvertColumnName()}{row.RowNum + 1}]内容出错,请检查后再试。");
  717. }
  718. }
  719. /// <summary>
  720. /// 保存行为的角色
  721. /// </summary>
  722. /// <param name="behaviorNo"></param>
  723. /// <param name="roleNos"></param>
  724. /// <returns></returns>
  725. private async Task SaveBehaviorRoles(string behaviorNo, string roleNos)
  726. {
  727. roleNos = roleNos.Replace(",", ",");
  728. var oldNos = await BrrRepository.GetAll().Where(a => a.BehaviorNo == behaviorNo).Select(a => a.RoleNo)
  729. .ToListAsync();
  730. List<string> roleNoList = roleNos.Split(',').ToList();
  731. foreach (var roleNo in roleNoList)
  732. {
  733. string no = GetTypeNo(roleNo);
  734. await SaveBehaviorRole(behaviorNo, no);
  735. if (oldNos.Contains(no))
  736. {
  737. oldNos.Remove(no);
  738. }
  739. }
  740. if (oldNos.Any())
  741. {
  742. await BrrRepository.DeleteAsync(a => oldNos.Contains(a.RoleNo));
  743. }
  744. }
  745. /// <summary>
  746. /// 保存行为的角色
  747. /// </summary>
  748. /// <param name="behaviorNo"></param>
  749. /// <param name="roleNo"></param>
  750. /// <returns></returns>
  751. private async Task SaveBehaviorRole(string behaviorNo, string roleNo)
  752. {
  753. var br = await BrrRepository.FirstOrDefaultAsync(a => a.BehaviorNo == behaviorNo && a.RoleNo == roleNo);
  754. if (br == null)
  755. {
  756. br = new BehaviorRelateRoleInfo()
  757. {
  758. BehaviorNo = behaviorNo,
  759. RoleNo = roleNo
  760. };
  761. await BrrRepository.InsertAsync(br);
  762. }
  763. else
  764. {
  765. br.RoleNo = roleNo;
  766. await BrrRepository.UpdateAsync(br);
  767. }
  768. }
  769. /// <summary>
  770. /// 行为关联情景
  771. /// </summary>
  772. /// <param name="sceneNo"></param>
  773. /// <param name="behaviorNo"></param>
  774. /// <param name="behaviorEvalType"></param>
  775. /// <param name="behaviorWeight"></param>
  776. /// <returns></returns>
  777. private async Task SaveSceneBehavior(string sceneNo, string behaviorNo, int behaviorEvalType, decimal behaviorWeight)
  778. {
  779. var sb = await SbRepository.FirstOrDefaultAsync(
  780. a => a.SceneNo == sceneNo && a.BehaviorNo == behaviorNo);
  781. if (sb == null)
  782. {
  783. await SbRepository.InsertAsync(new SceneBehaviorInfo()
  784. {
  785. BehaviorNo = behaviorNo,
  786. SceneNo = sceneNo,
  787. BehaviorEvalType = behaviorEvalType,
  788. BehaviorWeight = behaviorWeight
  789. });
  790. }
  791. else
  792. {
  793. sb.BehaviorEvalType = behaviorEvalType;
  794. sb.BehaviorWeight = behaviorWeight;
  795. await SbRepository.UpdateAsync(sb);
  796. }
  797. }
  798. private string CheckString(string str)
  799. {
  800. return str.Replace(",", ",")
  801. .Replace(":", ":")
  802. .Replace("【", "[")
  803. .Replace("】", "]");
  804. }
  805. /// <summary>
  806. /// 提取括号内的编码
  807. /// </summary>
  808. /// <param name="type"></param>
  809. /// <returns></returns>
  810. private string GetTypeNo(string type)
  811. {
  812. var str = type.SubstringSingle(@"\(", @"\)");
  813. return str;
  814. }
  815. private int GetEvalType(string type)
  816. {
  817. if (Enum.TryParse(type, out BehaviorScoreType t))
  818. {
  819. return t.ToInt();
  820. }
  821. return 0;
  822. }
  823. #endregion Import
  824. #region Export
  825. /// <summary>
  826. /// 导出情景模板
  827. /// </summary>
  828. /// <returns></returns>
  829. [AbpAuthorize(), AuditLog("导出情景模板")]
  830. public async Task<string> ExportTemplate()
  831. {
  832. string path = AppDomain.CurrentDomain.BaseDirectory + "Resources/Template/Scene.xlsx";
  833. var work = ExcelHelper.CreateWorkBook07(path);
  834. var sheet = work.GetSheet("Scene");
  835. await InitExcel(sheet, work);
  836. var savePath = "Download/Excel/Scene";
  837. var fileName = "SceneTemplate.xlsx";
  838. var result = work.SaveWorkBook($"{AppDomain.CurrentDomain.BaseDirectory}{savePath}", fileName);
  839. if (!result.IsEmpty())
  840. {
  841. return null;
  842. }
  843. return $"/{savePath}/{fileName}";
  844. }
  845. /// <summary>
  846. /// 导出情景
  847. /// </summary>
  848. /// <param name="input"></param>
  849. /// <returns></returns>
  850. [AbpAuthorize(), AuditLog("导出情景")]
  851. public async Task<string> Export(IwbPagedRequestDto input)
  852. {
  853. var query = CreateFilteredQuery(input);
  854. query = query.OrderBy(a => a.Id);
  855. var entities = await AsyncQueryableExecuter.ToListAsync(query);
  856. if (entities.Count <= 0)
  857. {
  858. CheckErrors("没有可导出的数据,请重置搜索条件!");
  859. return "";
  860. }
  861. string path = AppDomain.CurrentDomain.BaseDirectory + "Resources/Template/Scene.xlsx";
  862. var work = ExcelHelper.CreateWorkBook07(path);
  863. var sheet = work.GetSheet("Scene");
  864. int index = 3, count = entities.Count;
  865. if (count > 1)
  866. {
  867. sheet.InsertRows(index, count - 1);
  868. }
  869. foreach (var entity in entities)
  870. {
  871. ExportScene(sheet, entity, ref index);
  872. }
  873. await InitExcel(sheet, work);
  874. var savePath = "Download/Excel/Scene";
  875. var fileName = $"Scene-{DateTime.Now:yyMMddHHmmss}.xlsx";
  876. var result = work.SaveWorkBook($"{AppDomain.CurrentDomain.BaseDirectory}{savePath}", fileName);
  877. if (!result.IsEmpty())
  878. {
  879. return null;
  880. }
  881. return $"/{savePath}/{fileName}";
  882. }
  883. public ISheet ExportScene(ISheet sheet, SceneInfo scene, ref int rowIndex)
  884. {
  885. int columnIndex = 1;
  886. sheet.GenerateCell(rowIndex, columnIndex).SetValue(scene.Id ?? "");
  887. //sheet.SetCellPatriarch07(sheet.GenerateCell(rowIndex, columnIndex).SetValue(scene.Id ?? ""), "情景编码为空会自动创建,不为空则覆盖系统内同编号的数据,请谨慎修改。");
  888. columnIndex++;
  889. sheet.GenerateCell(rowIndex, columnIndex).SetValue(scene.Name ?? "");
  890. columnIndex++;
  891. sheet.GenerateCell(rowIndex, columnIndex).SetValue($"{scene.SceneCategoryName}\r\n({scene.SceneCategory})");
  892. //sheet.SetCellDropdownList07(sheet.GenerateCell(rowIndex, columnIndex).SetValue($"{scene.SceneCategoryName}({scene.SceneCategory})"), categoryNames);
  893. columnIndex++;
  894. sheet.GenerateCell(rowIndex, columnIndex).SetValue(scene.SceneTag ?? "");
  895. columnIndex++;
  896. sheet.GenerateCell(rowIndex, columnIndex).SetValue(scene.Description ?? "");
  897. columnIndex++;
  898. sheet.GenerateCell(rowIndex, columnIndex).SetValue(scene.Variable ?? "");
  899. var behaviors = SbRepository.GetAllIncluding(a => a.BehaviorInfo).Where(a => a.SceneNo == scene.Id).ToList();
  900. int count = behaviors.Count;
  901. if (count > 1)
  902. {
  903. sheet.InsertRows(rowIndex, count - 1);
  904. for (int i = 1; i <= columnIndex; i++)
  905. {
  906. var cellRegion = rowIndex.GetCellRegion(rowIndex + count - 1, i, i);
  907. sheet.AddMergedRegion(cellRegion);
  908. }
  909. }
  910. if (count > 0)
  911. {
  912. foreach (var behavior in behaviors)
  913. {
  914. sheet = ExportBehavior(sheet, behavior, columnIndex, ref rowIndex);
  915. rowIndex++;
  916. }
  917. }
  918. else
  919. {
  920. rowIndex++;
  921. }
  922. return sheet;
  923. }
  924. public ISheet ExportBehavior(ISheet sheet, SceneBehaviorInfo sb, int columnIndex, ref int rowIndex)
  925. {
  926. BehaviorInfo behavior = sb.BehaviorInfo;
  927. columnIndex++;
  928. sheet.GenerateCell(rowIndex, columnIndex).SetValue(behavior?.Id ?? "");
  929. columnIndex++;
  930. sheet.GenerateCell(rowIndex, columnIndex).SetValue(behavior?.BehaviorName ?? "");
  931. columnIndex++;
  932. sheet.GenerateCell(rowIndex, columnIndex).SetValue($"{behavior?.SceneCategoryName}\r\n({behavior?.SceneCategory})");
  933. columnIndex++;
  934. sheet.GenerateCell(rowIndex, columnIndex).SetValue(behavior?.BehaviorTag ?? "");
  935. columnIndex++;
  936. sheet.GenerateCell(rowIndex, columnIndex).SetValue(behavior?.Description ?? "");
  937. columnIndex++;
  938. var roles = BrrRepository.GetAllIncluding(a => a.RoleInfo).Where(a => a.BehaviorNo == behavior.Id)
  939. .Select(a => a.RoleInfo.RoleName + "(" + a.RoleNo + ")").ToArray();
  940. sheet.GenerateCell(rowIndex, columnIndex).SetValue(roles.Length > 0 ? string.Join(",", roles) : "");
  941. columnIndex++;
  942. sheet.GenerateCell(rowIndex, columnIndex).SetValue(behavior?.RuleKeyword ?? "");
  943. columnIndex++;
  944. sheet.GenerateCell(rowIndex, columnIndex).SetValue(Enum.GetName(typeof(BehaviorScoreType), sb.BehaviorEvalType));
  945. columnIndex++;
  946. sheet.GenerateCell(rowIndex, columnIndex).SetValue<decimal>(sb.BehaviorWeight);
  947. return sheet;
  948. }
  949. private async Task InitExcel(ISheet sheet, XSSFWorkbook work)
  950. {
  951. //var startRow = 1;
  952. sheet.GenerateCell(1, 27).SetCellValue(Password);
  953. var dataSheet = work.CreateSheet($"DATA{DateTime.Now:HHmmssff}");
  954. work.SetSheetHidden(work.GetSheetIndex(dataSheet.SheetName), true);
  955. var categoryNames = await GetCategoryNames();
  956. var data = await GetCategoryRoles(categoryNames);
  957. var index = 0;
  958. dataSheet.BuildListData(data, ref index);
  959. var r1 = 3.GetCellRegion(65536, 3, 3);
  960. var r2 = 3.GetCellRegion(65536, 9, 9);
  961. var c1 = sheet.CreateValidationConstraint(data.Name);
  962. sheet.SetCellDropdownList07(c1, r1, "请选择情景的场景类别...", "情景场景类别");
  963. sheet.SetCellDropdownList07(c1, r2, "请选择行为的场景类别...", "行为场景类别");
  964. var r3 = 3.GetCellRegion(65536, 12, 12);
  965. var flag = "INDIRECT(ADDRESS(ROW(),COLUMN()-3))";
  966. var formula = $"MID({flag}, FIND(\"(\", {flag}) + 1, FIND(\")\",{flag}) - FIND(\"(\", {flag}) - 1)";
  967. var c2 = sheet.CreateLinkValidationConstraint(formula);
  968. sheet.SetCellDropdownList07(c2, r3, "请在下拉框里选择行为的处理角色... \r\n(需要先选择行为的场景类别)", "行为角色");
  969. sheet.SetCellDropdownList07(14, 14, Enum.GetNames(typeof(BehaviorScoreType)), "请选择情景行为类型... \r\nNormal:正向行为(加分) \r\nNegative:负向行为(减分) \r\nImportantNegative:关键性负向行为(0分)", 2, "情景行为类型");
  970. //sheet.SetColumnMsg07("编码为空会自动创建,不为空则覆盖系统内同编号的数据,请谨慎修改。", 1, 1, startRow, "情景编码");
  971. //sheet.SetColumnMsg07("请在下拉框里选择情景的场景类别...", 3, 3, startRow, "情景场景类别");
  972. //sheet.SetCellDropdownList07(work, 3, 3, categoryNames, "请在下拉框里选择情景的场景类别...", startRow + 1, "情景场景类别");
  973. //sheet.SetColumnMsg07("描述中的变量 以\"@\"开头,且需要在情景变量中配置默认值!", 5, 5, startRow, "情景描述");
  974. //sheet.SetColumnMsg07("变量的格式为[@变量名:变量值类型:变量默认值] \r\n变量值类型有:string,decimal,date \r\n多个变量用,分隔(英文字符,) \r\n 例:\"[@Address:string:四川北路],[@Num:decimal:10],[@Date:date:2020-09-01]\"", 6, 6, startRow, "情景变量");
  975. //sheet.SetColumnMsg07("编码为空会自动创建,不为空则覆盖系统内同编号的数据,请谨慎修改。", 7, 7, startRow, "行为编码");
  976. //sheet.SetCellDropdownList07(work, 9, 9, categoryNames, "请在下拉框里选择行为的场景类别...", startRow + 1, "行为场景类别");
  977. //sheet.SetColumnMsg07("关键字格式\r\n[[关键字1,关键字2]:比重,[关键字3,关键字4]:比重] \r\n例:\"[[123,345]:60,[234,456]:70]\"", 12, 12, startRow, "行为关键字");
  978. //sheet.SetColumnMsg07("行为在情景中所占的比重\r\n", 14, 14, startRow, "行为权重");
  979. //sheet.SetCellMinNumeric07(14, 0, "行为在情景中所占的比重\r\n", startRow, "行为权重");
  980. }
  981. private async Task<string[]> GetCategoryNames()
  982. {
  983. List<string> sList = new List<string>();
  984. var scList = await ScRepository.GetAll().Where(a => a.ParentNo != null).OrderBy(a => a.CategoryPath).Select(a => new SceneCategoryDto()
  985. {
  986. CategoryName = a.CategoryName,
  987. Id = a.Id
  988. }).ToListAsync();
  989. foreach (var s in scList)
  990. {
  991. sList.Add($"{s.CategoryName}\r\n({s.Id})");
  992. }
  993. return sList.ToArray();
  994. }
  995. private async Task<DropdownListData> GetCategoryRoles(string[] categoryNames)
  996. {
  997. var data = new DropdownListData("CategoryRoles");
  998. foreach (var categoryName in categoryNames)
  999. {
  1000. var cData = new DropdownListData(GetTypeNo(categoryName), categoryName);
  1001. var no = GetTypeNo(categoryName);
  1002. var roleList = await RcRepository.GetAllIncluding(a => a.RoleInfo).Where(a => a.CategoryNo == no)
  1003. .ToListAsync();
  1004. var roles = roleList.Select(a => new { a.RoleNo, a.RoleName });
  1005. foreach (var role in roles)
  1006. {
  1007. cData.AddList(new DropdownListData(role.RoleNo, $"{role.RoleName}({role.RoleNo})"));
  1008. }
  1009. data.AddList(cData);
  1010. }
  1011. return data;
  1012. }
  1013. #endregion Export
  1014. }
  1015. }