SceneApplicationService.cs 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092
  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. behavior.BehaviorTag = row.GenerateCell(columnIndex).StringCellValue ?? "";
  653. columnIndex++;
  654. behavior.Description = description;
  655. columnIndex++;
  656. columnIndex++;
  657. behavior.RuleKeyword = CheckString(row.GenerateCell(columnIndex).StringCellValue ?? "");
  658. behavior.RoleLogicType = (int)BehaviorRoleLogicType.Or;
  659. await BehaviorRepository.InsertAndGetIdAsync(behavior);
  660. await CurrentUnitOfWork.SaveChangesAsync();
  661. }
  662. }
  663. else
  664. {
  665. behavior.BehaviorName = name;
  666. columnIndex++;
  667. behavior.SceneCategory = GetTypeNo(row.GenerateCell(columnIndex).StringCellValue ?? $"({ behavior.SceneCategory})");
  668. columnIndex++;
  669. behavior.BehaviorTag = row.GenerateCell(columnIndex).StringCellValue ?? "";
  670. columnIndex++;
  671. behavior.Description = description;
  672. columnIndex++;
  673. columnIndex++;
  674. behavior.RuleKeyword = CheckString(row.GenerateCell(columnIndex).StringCellValue ?? "");
  675. await BehaviorRepository.UpdateAsync(behavior);
  676. }
  677. columnIndex = 12;
  678. string roleNos = row.GenerateCell(columnIndex).StringCellValue ?? "";
  679. if (roleNos.IsNotEmpty())
  680. {
  681. await SaveBehaviorRoles(behavior.Id, roleNos);
  682. }
  683. #region 关联情景
  684. columnIndex = 14;
  685. int behaviorEvalType = GetEvalType(row.GenerateCell(columnIndex).StringCellValue ?? "");
  686. columnIndex++;
  687. decimal? behaviorWeight = null;
  688. try
  689. {
  690. behaviorWeight = (decimal)row.GenerateCell(columnIndex).NumericCellValue;
  691. }
  692. catch
  693. {
  694. var behaviorWeightStr = row.GenerateCell(columnIndex).StringCellValue;
  695. if (int.TryParse(behaviorWeightStr, out var behaviorWeight2))
  696. {
  697. behaviorWeight = behaviorWeight2;
  698. }
  699. }
  700. if (behaviorWeight != null)
  701. {
  702. await SaveSceneBehavior(sceneNo, behavior.Id, behaviorEvalType, (decimal)behaviorWeight);
  703. }
  704. #endregion 关联情景
  705. return behavior.Id;
  706. }
  707. catch (Exception e)
  708. {
  709. this.LogError(e);
  710. throw new UserFriendlyException($"[{(columnIndex - 1).ConvertColumnName()}{row.RowNum + 1}]内容出错,请检查后再试。");
  711. }
  712. }
  713. /// <summary>
  714. /// 保存行为的角色
  715. /// </summary>
  716. /// <param name="behaviorNo"></param>
  717. /// <param name="roleNos"></param>
  718. /// <returns></returns>
  719. private async Task SaveBehaviorRoles(string behaviorNo, string roleNos)
  720. {
  721. roleNos = roleNos.Replace(",", ",");
  722. var oldNos = await BrrRepository.GetAll().Where(a => a.BehaviorNo == behaviorNo).Select(a => a.RoleNo)
  723. .ToListAsync();
  724. List<string> roleNoList = roleNos.Split(',').ToList();
  725. foreach (var roleNo in roleNoList)
  726. {
  727. string no = GetTypeNo(roleNo);
  728. await SaveBehaviorRole(behaviorNo, no);
  729. if (oldNos.Contains(no))
  730. {
  731. oldNos.Remove(no);
  732. }
  733. }
  734. if (oldNos.Any())
  735. {
  736. await BrrRepository.DeleteAsync(a => oldNos.Contains(a.RoleNo));
  737. }
  738. }
  739. /// <summary>
  740. /// 保存行为的角色
  741. /// </summary>
  742. /// <param name="behaviorNo"></param>
  743. /// <param name="roleNo"></param>
  744. /// <returns></returns>
  745. private async Task SaveBehaviorRole(string behaviorNo, string roleNo)
  746. {
  747. var br = await BrrRepository.FirstOrDefaultAsync(a => a.BehaviorNo == behaviorNo && a.RoleNo == roleNo);
  748. if (br == null)
  749. {
  750. br = new BehaviorRelateRoleInfo()
  751. {
  752. BehaviorNo = behaviorNo,
  753. RoleNo = roleNo
  754. };
  755. await BrrRepository.InsertAsync(br);
  756. }
  757. else
  758. {
  759. br.RoleNo = roleNo;
  760. await BrrRepository.UpdateAsync(br);
  761. }
  762. }
  763. /// <summary>
  764. /// 行为关联情景
  765. /// </summary>
  766. /// <param name="sceneNo"></param>
  767. /// <param name="behaviorNo"></param>
  768. /// <param name="behaviorEvalType"></param>
  769. /// <param name="behaviorWeight"></param>
  770. /// <returns></returns>
  771. private async Task SaveSceneBehavior(string sceneNo, string behaviorNo, int behaviorEvalType, decimal behaviorWeight)
  772. {
  773. var sb = await SbRepository.FirstOrDefaultAsync(
  774. a => a.SceneNo == sceneNo && a.BehaviorNo == behaviorNo);
  775. if (sb == null)
  776. {
  777. await SbRepository.InsertAsync(new SceneBehaviorInfo()
  778. {
  779. BehaviorNo = behaviorNo,
  780. SceneNo = sceneNo,
  781. BehaviorEvalType = behaviorEvalType,
  782. BehaviorWeight = behaviorWeight
  783. });
  784. }
  785. else
  786. {
  787. sb.BehaviorEvalType = behaviorEvalType;
  788. sb.BehaviorWeight = behaviorWeight;
  789. await SbRepository.UpdateAsync(sb);
  790. }
  791. }
  792. private string CheckString(string str)
  793. {
  794. return str.Replace(",", ",")
  795. .Replace(":", ":")
  796. .Replace("【", "[")
  797. .Replace("】", "]");
  798. }
  799. /// <summary>
  800. /// 提取括号内的编码
  801. /// </summary>
  802. /// <param name="type"></param>
  803. /// <returns></returns>
  804. private string GetTypeNo(string type)
  805. {
  806. var str = type.SubstringSingle(@"\(", @"\)");
  807. return str;
  808. }
  809. private int GetEvalType(string type)
  810. {
  811. if (Enum.TryParse(type, out BehaviorScoreType t))
  812. {
  813. return t.ToInt();
  814. }
  815. return 0;
  816. }
  817. #endregion Import
  818. #region Export
  819. /// <summary>
  820. /// 导出情景模板
  821. /// </summary>
  822. /// <returns></returns>
  823. [AbpAuthorize(), AuditLog("导出情景模板")]
  824. public async Task<string> ExportTemplate()
  825. {
  826. string path = AppDomain.CurrentDomain.BaseDirectory + "Resources/Template/Scene.xlsx";
  827. var work = ExcelHelper.CreateWorkBook07(path);
  828. var sheet = work.GetSheet("Scene");
  829. await InitExcel(sheet, work);
  830. var savePath = "Download/Excel/Scene";
  831. var fileName = "SceneTemplate.xlsx";
  832. var result = work.SaveWorkBook($"{AppDomain.CurrentDomain.BaseDirectory}{savePath}", fileName);
  833. if (!result.IsEmpty())
  834. {
  835. return null;
  836. }
  837. return $"/{savePath}/{fileName}";
  838. }
  839. /// <summary>
  840. /// 导出情景
  841. /// </summary>
  842. /// <param name="input"></param>
  843. /// <returns></returns>
  844. [AbpAuthorize(), AuditLog("导出情景")]
  845. public async Task<string> Export(IwbPagedRequestDto input)
  846. {
  847. var query = CreateFilteredQuery(input);
  848. query = query.OrderBy(a => a.Id);
  849. var entities = await AsyncQueryableExecuter.ToListAsync(query);
  850. if (entities.Count <= 0)
  851. {
  852. CheckErrors("没有可导出的数据,请重置搜索条件!");
  853. return "";
  854. }
  855. string path = AppDomain.CurrentDomain.BaseDirectory + "Resources/Template/Scene.xlsx";
  856. var work = ExcelHelper.CreateWorkBook07(path);
  857. var sheet = work.GetSheet("Scene");
  858. int index = 3, count = entities.Count;
  859. if (count > 1)
  860. {
  861. sheet.InsertRows(index, count - 1);
  862. }
  863. foreach (var entity in entities)
  864. {
  865. ExportScene(sheet, entity, ref index);
  866. }
  867. await InitExcel(sheet, work);
  868. var savePath = "Download/Excel/Scene";
  869. var fileName = $"Scene-{DateTime.Now:yyMMddHHmmss}.xlsx";
  870. var result = work.SaveWorkBook($"{AppDomain.CurrentDomain.BaseDirectory}{savePath}", fileName);
  871. if (!result.IsEmpty())
  872. {
  873. return null;
  874. }
  875. return $"/{savePath}/{fileName}";
  876. }
  877. public ISheet ExportScene(ISheet sheet, SceneInfo scene, ref int rowIndex)
  878. {
  879. int columnIndex = 1;
  880. sheet.GenerateCell(rowIndex, columnIndex).SetValue(scene.Id ?? "");
  881. //sheet.SetCellPatriarch07(sheet.GenerateCell(rowIndex, columnIndex).SetValue(scene.Id ?? ""), "情景编码为空会自动创建,不为空则覆盖系统内同编号的数据,请谨慎修改。");
  882. columnIndex++;
  883. sheet.GenerateCell(rowIndex, columnIndex).SetValue(scene.Name ?? "");
  884. columnIndex++;
  885. sheet.GenerateCell(rowIndex, columnIndex).SetValue($"{scene.SceneCategoryName}\r\n({scene.SceneCategory})");
  886. //sheet.SetCellDropdownList07(sheet.GenerateCell(rowIndex, columnIndex).SetValue($"{scene.SceneCategoryName}({scene.SceneCategory})"), categoryNames);
  887. columnIndex++;
  888. sheet.GenerateCell(rowIndex, columnIndex).SetValue(scene.SceneTag ?? "");
  889. columnIndex++;
  890. sheet.GenerateCell(rowIndex, columnIndex).SetValue(scene.Description ?? "");
  891. columnIndex++;
  892. sheet.GenerateCell(rowIndex, columnIndex).SetValue(scene.Variable ?? "");
  893. var behaviors = SbRepository.GetAllIncluding(a => a.BehaviorInfo).Where(a => a.SceneNo == scene.Id).ToList();
  894. int count = behaviors.Count;
  895. if (count > 1)
  896. {
  897. sheet.InsertRows(rowIndex, count - 1);
  898. for (int i = 1; i <= columnIndex; i++)
  899. {
  900. var cellRegion = rowIndex.GetCellRegion(rowIndex + count - 1, i, i);
  901. sheet.AddMergedRegion(cellRegion);
  902. }
  903. }
  904. if (count > 0)
  905. {
  906. foreach (var behavior in behaviors)
  907. {
  908. sheet = ExportBehavior(sheet, behavior, columnIndex, ref rowIndex);
  909. rowIndex++;
  910. }
  911. }
  912. else
  913. {
  914. rowIndex++;
  915. }
  916. return sheet;
  917. }
  918. public ISheet ExportBehavior(ISheet sheet, SceneBehaviorInfo sb, int columnIndex, ref int rowIndex)
  919. {
  920. BehaviorInfo behavior = sb.BehaviorInfo;
  921. columnIndex++;
  922. sheet.GenerateCell(rowIndex, columnIndex).SetValue(behavior?.Id ?? "");
  923. columnIndex++;
  924. sheet.GenerateCell(rowIndex, columnIndex).SetValue(behavior?.BehaviorName ?? "");
  925. columnIndex++;
  926. sheet.GenerateCell(rowIndex, columnIndex).SetValue($"{behavior?.SceneCategoryName}\r\n({behavior?.SceneCategory})");
  927. columnIndex++;
  928. sheet.GenerateCell(rowIndex, columnIndex).SetValue(behavior?.BehaviorTag ?? "");
  929. columnIndex++;
  930. sheet.GenerateCell(rowIndex, columnIndex).SetValue(behavior?.Description ?? "");
  931. columnIndex++;
  932. var roles = BrrRepository.GetAllIncluding(a => a.RoleInfo).Where(a => a.BehaviorNo == behavior.Id)
  933. .Select(a => a.RoleInfo.RoleName + "(" + a.RoleNo + ")").ToArray();
  934. sheet.GenerateCell(rowIndex, columnIndex).SetValue(roles.Length > 0 ? string.Join(",", roles) : "");
  935. columnIndex++;
  936. sheet.GenerateCell(rowIndex, columnIndex).SetValue(behavior?.RuleKeyword ?? "");
  937. columnIndex++;
  938. sheet.GenerateCell(rowIndex, columnIndex).SetValue(Enum.GetName(typeof(BehaviorScoreType), sb.BehaviorEvalType));
  939. columnIndex++;
  940. sheet.GenerateCell(rowIndex, columnIndex).SetValue<decimal>(sb.BehaviorWeight);
  941. return sheet;
  942. }
  943. private async Task InitExcel(ISheet sheet, XSSFWorkbook work)
  944. {
  945. //var startRow = 1;
  946. sheet.GenerateCell(1, 27).SetCellValue(Password);
  947. var dataSheet = work.CreateSheet($"DATA{DateTime.Now:HHmmssff}");
  948. work.SetSheetHidden(work.GetSheetIndex(dataSheet.SheetName), true);
  949. var categoryNames = await GetCategoryNames();
  950. var data = await GetCategoryRoles(categoryNames);
  951. var index = 0;
  952. dataSheet.BuildListData(data, ref index);
  953. var r1 = 3.GetCellRegion(65536, 3, 3);
  954. var r2 = 3.GetCellRegion(65536, 9, 9);
  955. var c1 = sheet.CreateValidationConstraint(data.Name);
  956. sheet.SetCellDropdownList07(c1, r1, "请选择情景的场景类别...", "情景场景类别");
  957. sheet.SetCellDropdownList07(c1, r2, "请选择行为的场景类别...", "行为场景类别");
  958. var r3 = 3.GetCellRegion(65536, 12, 12);
  959. var flag = "INDIRECT(ADDRESS(ROW(),COLUMN()-3))";
  960. var formula = $"MID({flag}, FIND(\"(\", {flag}) + 1, FIND(\")\",{flag}) - FIND(\"(\", {flag}) - 1)";
  961. var c2 = sheet.CreateLinkValidationConstraint(formula);
  962. sheet.SetCellDropdownList07(c2, r3, "请在下拉框里选择行为的处理角色... \r\n(需要先选择行为的场景类别)", "行为角色");
  963. sheet.SetCellDropdownList07(14, 14, Enum.GetNames(typeof(BehaviorScoreType)), "请选择情景行为类型... \r\nNormal:正向行为(加分) \r\nNegative:负向行为(减分) \r\nImportantNegative:关键性负向行为(0分)", 2, "情景行为类型");
  964. //sheet.SetColumnMsg07("编码为空会自动创建,不为空则覆盖系统内同编号的数据,请谨慎修改。", 1, 1, startRow, "情景编码");
  965. //sheet.SetColumnMsg07("请在下拉框里选择情景的场景类别...", 3, 3, startRow, "情景场景类别");
  966. //sheet.SetCellDropdownList07(work, 3, 3, categoryNames, "请在下拉框里选择情景的场景类别...", startRow + 1, "情景场景类别");
  967. //sheet.SetColumnMsg07("描述中的变量 以\"@\"开头,且需要在情景变量中配置默认值!", 5, 5, startRow, "情景描述");
  968. //sheet.SetColumnMsg07("变量的格式为[@变量名:变量值类型:变量默认值] \r\n变量值类型有:string,decimal,date \r\n多个变量用,分隔(英文字符,) \r\n 例:\"[@Address:string:四川北路],[@Num:decimal:10],[@Date:date:2020-09-01]\"", 6, 6, startRow, "情景变量");
  969. //sheet.SetColumnMsg07("编码为空会自动创建,不为空则覆盖系统内同编号的数据,请谨慎修改。", 7, 7, startRow, "行为编码");
  970. //sheet.SetCellDropdownList07(work, 9, 9, categoryNames, "请在下拉框里选择行为的场景类别...", startRow + 1, "行为场景类别");
  971. //sheet.SetColumnMsg07("关键字格式\r\n[[关键字1,关键字2]:比重,[关键字3,关键字4]:比重] \r\n例:\"[[123,345]:60,[234,456]:70]\"", 12, 12, startRow, "行为关键字");
  972. //sheet.SetColumnMsg07("行为在情景中所占的比重\r\n", 14, 14, startRow, "行为权重");
  973. //sheet.SetCellMinNumeric07(14, 0, "行为在情景中所占的比重\r\n", startRow, "行为权重");
  974. }
  975. private async Task<string[]> GetCategoryNames()
  976. {
  977. List<string> sList = new List<string>();
  978. var scList = await ScRepository.GetAll().Where(a => a.ParentNo != null).OrderBy(a => a.CategoryPath).Select(a => new SceneCategoryDto()
  979. {
  980. CategoryName = a.CategoryName,
  981. Id = a.Id
  982. }).ToListAsync();
  983. foreach (var s in scList)
  984. {
  985. sList.Add($"{s.CategoryName}\r\n({s.Id})");
  986. }
  987. return sList.ToArray();
  988. }
  989. private async Task<DropdownListData> GetCategoryRoles(string[] categoryNames)
  990. {
  991. var data = new DropdownListData("CategoryRoles");
  992. foreach (var categoryName in categoryNames)
  993. {
  994. var cData = new DropdownListData(GetTypeNo(categoryName), categoryName);
  995. var no = GetTypeNo(categoryName);
  996. var roleList = await RcRepository.GetAllIncluding(a => a.RoleInfo).Where(a => a.CategoryNo == no)
  997. .ToListAsync();
  998. var roles = roleList.Select(a => new { a.RoleNo, a.RoleName });
  999. foreach (var role in roles)
  1000. {
  1001. cData.AddList(new DropdownListData(role.RoleNo, $"{role.RoleName}({role.RoleNo})"));
  1002. }
  1003. data.AddList(cData);
  1004. }
  1005. return data;
  1006. }
  1007. #endregion Export
  1008. }
  1009. }