PersonnelModuleController.cs 140 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420
  1. using Aspose.Cells;
  2. using FluentValidation;
  3. using Microsoft.AspNetCore.SignalR;
  4. using OASystem.API.OAMethodLib;
  5. using OASystem.API.OAMethodLib.DeepSeekAPI;
  6. using OASystem.API.OAMethodLib.Hub.HubClients;
  7. using OASystem.API.OAMethodLib.Hub.Hubs;
  8. using OASystem.API.OAMethodLib.QiYeWeChatAPI;
  9. using OASystem.API.OAMethodLib.QiYeWeChatAPI.AppNotice;
  10. using OASystem.Domain.Dtos.Groups;
  11. using OASystem.Domain.Dtos.PersonnelModule;
  12. using OASystem.Domain.Dtos.Statistics;
  13. using OASystem.Domain.Entities.Groups;
  14. using OASystem.Domain.Entities.PersonnelModule;
  15. using OASystem.Domain.ViewModels.PersonnelModule;
  16. using OASystem.Domain.ViewModels.QiYeWeChat;
  17. using OASystem.Domain.ViewModels.Statistics;
  18. using OASystem.Infrastructure.Repositories.Groups;
  19. using OASystem.Infrastructure.Repositories.PersonnelModule;
  20. using System.Data;
  21. using System.Diagnostics;
  22. using System.Globalization;
  23. using static OASystem.API.OAMethodLib.JWTHelper;
  24. namespace OASystem.API.Controllers
  25. {
  26. /// <summary>
  27. /// 人事模块
  28. /// </summary>
  29. [Route("api/[controller]/[action]")]
  30. public class PersonnelModuleController : ControllerBase
  31. {
  32. private Result _result;
  33. private readonly IMapper _mapper;
  34. //private readonly decimal _chengDuMinimumWage = 2100.00M;
  35. private readonly IQiYeWeChatApiService _qiYeWeChatApiService;
  36. private readonly WageSheetRepository _wageSheetRep;
  37. private readonly UsersRepository _usersRep;
  38. private readonly TaskAllocationRepository _taskAllocationRep;
  39. private readonly SqlSugarClient _sqlSugar;
  40. private readonly IHubContext<ChatHub, IChatClient> _hubContext;
  41. private readonly GoodsRepository _goodsRep;
  42. private readonly DecreasePaymentsRepository _otherPaymentRep;
  43. private readonly FeeAuditRepository _feeAuditRep;
  44. private readonly IDeepSeekService _deepSeekService;
  45. private readonly string url;
  46. private readonly string path;
  47. /// <summary>
  48. /// 初始化
  49. /// </summary>
  50. /// <param name="qiYeWeChatApiService"></param>
  51. /// <param name="wageSheetRep"></param>
  52. /// <param name="usersRep"></param>
  53. /// <param name="mapper"></param>
  54. /// <param name="taskAllocationRep"></param>
  55. /// <param name="hubContext"></param>
  56. /// <param name="goodsRep"></param>
  57. /// <param name="sqlSugar"></param>
  58. /// <param name="otherPaymentRep"></param>
  59. /// <param name="feeAuditRep"></param>
  60. /// <param name="deepSeekService"></param>
  61. public PersonnelModuleController(
  62. IHubContext<ChatHub, IChatClient> hubContext,
  63. IMapper mapper,
  64. IQiYeWeChatApiService qiYeWeChatApiService,
  65. WageSheetRepository wageSheetRep,
  66. UsersRepository usersRep,
  67. TaskAllocationRepository taskAllocationRep,
  68. GoodsRepository goodsRep,
  69. SqlSugarClient sqlSugar,
  70. DecreasePaymentsRepository otherPaymentRep,
  71. FeeAuditRepository feeAuditRep,
  72. IDeepSeekService deepSeekService
  73. )
  74. {
  75. _mapper = mapper;
  76. _usersRep = usersRep;
  77. _qiYeWeChatApiService = qiYeWeChatApiService;
  78. _wageSheetRep = wageSheetRep;
  79. _result = new Result();
  80. _sqlSugar = sqlSugar;
  81. url = AppSettingsHelper.Get("ExcelBaseUrl");
  82. path = AppSettingsHelper.Get("ExcelBasePath");
  83. if (!System.IO.Directory.Exists(path))
  84. {
  85. System.IO.Directory.CreateDirectory(path);//不存在就创建文件夹
  86. }
  87. this._taskAllocationRep = taskAllocationRep;
  88. _hubContext = hubContext;
  89. _goodsRep = goodsRep;
  90. _otherPaymentRep = otherPaymentRep;
  91. _feeAuditRep = feeAuditRep;
  92. _deepSeekService = deepSeekService;
  93. }
  94. #region 工资表单
  95. /// <summary>
  96. /// 工资 月列表
  97. /// </summary>
  98. /// <returns></returns>
  99. [HttpPost]
  100. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  101. public async Task<IActionResult> GetWageSheetMonth()
  102. {
  103. string sql = string.Format("Select * From Pm_WageIssueWorkingDay Where IsDel = 0 Order By YearMonth Desc");
  104. var data = await _wageSheetRep._sqlSugar.SqlQueryable<WageSheetMonthView>(sql).ToListAsync();
  105. return Ok(JsonView(true, "查询成功!", data));
  106. }
  107. /// <summary>
  108. /// 工资 工作日信息
  109. /// 查询
  110. /// </summary>
  111. /// <returns></returns>
  112. [HttpPost]
  113. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  114. public async Task<IActionResult> GetWageSheetMonthWorkdays(string startDt, string endDt)
  115. {
  116. //参数处理
  117. var dtFormat = "yyyy-MM-dd";
  118. var startDtIsValid = DateTime.TryParseExact(startDt, dtFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out _);
  119. var endDtIsValid = DateTime.TryParseExact(endDt, dtFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out _);
  120. if (!startDtIsValid) return Ok(JsonView(false, "开始日期格式错误!正确时间格式:yyyy-MM-dd "));
  121. if (!endDtIsValid) return Ok(JsonView(false, "结束格式错误!正确时间格式:yyyy-MM-dd "));
  122. string sql = string.Format(@"Select * From Sys_Calendar Where Isdel = 0 And Dt between '{0}' And '{1}'", startDt, endDt);
  123. var data = await _sqlSugar.SqlQueryable<CalendarInfoView>(sql).ToListAsync();
  124. return Ok(JsonView(true, "查询成功!", data));
  125. }
  126. /// <summary>
  127. /// 工资 工作日信息
  128. /// 编辑
  129. /// </summary>
  130. /// <returns></returns>
  131. [HttpPost]
  132. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  133. public async Task<IActionResult> GetWageSheetMonthWorkdaysAddOrEdit(WageSheetMonthWorkdaysAddOrEditDto dto)
  134. {
  135. //参数处理
  136. string yearFormat = "yyyy-MM";
  137. string dtFormat = "yyyy-MM-dd";
  138. bool yearDtIsValid = DateTime.TryParseExact(dto.YearMonth, yearFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime yearDt);
  139. bool startDtIsValid = DateTime.TryParseExact(dto.StartDate, dtFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime startDt1);
  140. bool endDtIsValid = DateTime.TryParseExact(dto.EndDate, dtFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime endDt1);
  141. if (!yearDtIsValid) return Ok(JsonView(false, "年月日期格式错误!正确时间格式:yyyy-MM "));
  142. if (!startDtIsValid) return Ok(JsonView(false, "开始日期格式错误!正确时间格式:yyyy-MM-dd "));
  143. if (!endDtIsValid) return Ok(JsonView(false, "结束格式错误!正确时间格式:yyyy-MM-dd "));
  144. #region 处理数据
  145. Pm_WageIssueWorkingDay pm_WageIssueWorkingDay1 = new();
  146. pm_WageIssueWorkingDay1 = _mapper.Map<Pm_WageIssueWorkingDay>(dto);
  147. List<Sys_Calendar> sys_Calendars = new();
  148. sys_Calendars = _mapper.Map<List<Sys_Calendar>>(dto.CalendarInfos);
  149. if (sys_Calendars.Count > 0)
  150. {
  151. sys_Calendars = sys_Calendars.OrderBy(it => it.Dt).ToList();
  152. }
  153. pm_WageIssueWorkingDay1.Workdays = sys_Calendars.Where(it => it.IsWorkDay == true).ToList().Count;
  154. foreach (var item in sys_Calendars)
  155. {
  156. item.Remark = pm_WageIssueWorkingDay1.Remark;
  157. item.CreateUserId = pm_WageIssueWorkingDay1.CreateUserId;
  158. item.CreateTime = pm_WageIssueWorkingDay1.CreateTime;
  159. }
  160. #endregion
  161. var _sqlSugar = _wageSheetRep._sqlSugar;
  162. _sqlSugar.BeginTran();
  163. try
  164. {
  165. List<Sys_Calendar> sys_Calendars_add = new();
  166. List<Sys_Calendar> sys_Calendars_update = new();
  167. sys_Calendars_add = sys_Calendars.Where(it => it.Id == 0).OrderBy(it => it.Dt).ToList();
  168. sys_Calendars_update = sys_Calendars.Where(it => it.Id != 0).OrderBy(it => it.Dt).ToList();
  169. //int add1 = 0;
  170. //int upd = 0;
  171. if (sys_Calendars_add.Count > 0)
  172. {
  173. var calendarsAdd = await _sqlSugar.Insertable(sys_Calendars_add).ExecuteReturnIdentityAsync();
  174. if (calendarsAdd < 0)
  175. {
  176. _sqlSugar.RollbackTran();
  177. return Ok(JsonView(false, "工作日/节假日/休息日添加失败!"));
  178. }
  179. }
  180. if (sys_Calendars_update.Count > 0)
  181. {
  182. var calendarsUpdate = await _sqlSugar.Updateable<Sys_Calendar>(sys_Calendars)
  183. .UpdateColumns(it => new { it.Dt, it.IsWorkDay, it.IsHoliDay, it.HoliName })
  184. .WhereColumns(it => it.Id)
  185. .ExecuteCommandAsync();
  186. if (calendarsUpdate < 0)
  187. {
  188. _sqlSugar.RollbackTran();
  189. return Ok(JsonView(false, "工作日/节假日/休息日编辑失败!"));
  190. }
  191. }
  192. var calendarsDatas = await _sqlSugar.Queryable<Sys_Calendar>()
  193. .Where(it => Convert.ToDateTime(it.Dt) >= Convert.ToDateTime(dto.StartDate) && Convert.ToDateTime(it.Dt) <= Convert.ToDateTime(dto.EndDate)).ToListAsync();
  194. if (calendarsDatas.Count < 0)
  195. {
  196. _sqlSugar.RollbackTran();
  197. return Ok(JsonView(false, "日期包暂无工作日/节假日/休息日的信息!"));
  198. }
  199. //月份表是否存在
  200. Pm_WageIssueWorkingDay pm_WageIssueWorkingDay = new()
  201. {
  202. YearMonth = dto.YearMonth,
  203. StartDate = dto.StartDate,
  204. EndDate = dto.EndDate,
  205. Workdays = calendarsDatas.Where(it => it.IsWorkDay == true).ToList().Count
  206. };
  207. string sql = string.Format("Select * From Pm_WageIssueWorkingDay Where Isdel = 0 And YearMonth='{0}'", dto.YearMonth);
  208. var workdsys = await _sqlSugar.SqlQueryable<Pm_WageIssueWorkingDay>(sql).FirstAsync();
  209. pm_WageIssueWorkingDay.CreateUserId = dto.UserId;
  210. pm_WageIssueWorkingDay.IsDel = 0;
  211. if (workdsys == null) //添加
  212. {
  213. int addId = await _sqlSugar.Insertable(pm_WageIssueWorkingDay).ExecuteReturnIdentityAsync();
  214. if (addId < 0)
  215. {
  216. _sqlSugar.RollbackTran();
  217. return Ok(JsonView(false, "工作日设置添加失败!"));
  218. }
  219. }
  220. else //更新
  221. {
  222. int updCount = await _sqlSugar.Updateable(pm_WageIssueWorkingDay)
  223. .IgnoreColumns(z => new { z.CreateUserId, z.CreateTime, z.DeleteUserId, z.DeleteTime, z.IsDel })
  224. .WhereColumns(it => it.YearMonth)
  225. .ExecuteCommandAsync();
  226. if (updCount < 0)
  227. {
  228. _sqlSugar.RollbackTran();
  229. return Ok(JsonView(false, "工作日设置编辑失败!"));
  230. }
  231. }
  232. _sqlSugar.CommitTran();
  233. return Ok(JsonView(true, "操作成功!"));
  234. }
  235. catch (Exception ex)
  236. {
  237. _sqlSugar.RollbackTran();
  238. return Ok(JsonView(false, ex.Message));
  239. }
  240. }
  241. /// <summary>
  242. /// 工资表单 基础数据源
  243. /// </summary>
  244. /// <returns></returns>
  245. [HttpPost]
  246. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  247. public async Task<IActionResult> GetWageSheetBasicsDataSource()
  248. {
  249. string companySql = string.Format("Select * From Sys_Company Where IsDel = 0");
  250. var compnayData = await _wageSheetRep._sqlSugar.SqlQueryable<CompanyNameView>(companySql).ToListAsync();
  251. string depSql = string.Format("Select * From Sys_Department Where IsDel = 0");
  252. var depData = await _wageSheetRep._sqlSugar.SqlQueryable<Domain.ViewModels.System.DepartmentView>(depSql).ToListAsync();
  253. //获取OA系统内所有用户
  254. var nameData = await _usersRep.GetUserNameList(1);
  255. if (nameData.Code != 0)
  256. {
  257. return Ok(JsonView(false, nameData.Msg));
  258. }
  259. var data = new
  260. {
  261. compnayData,
  262. depData,
  263. userNames = nameData.Data
  264. };
  265. return Ok(JsonView(true, "查询成功!", data));
  266. }
  267. /// <summary>
  268. /// 获取工资发放月份
  269. /// </summary>
  270. /// <param name="dto"></param>
  271. /// <returns></returns>
  272. [HttpPost]
  273. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  274. public async Task<IActionResult> GetWageYaerMonths(WageYearDto dto)
  275. {
  276. string sql = string.Format(@"Select * From Pm_WageIssueWorkingDay
  277. Where Isdel = 0 And YearMonth Like '%{0}%'
  278. Order By YearMonth Asc", dto.Year);
  279. var data = await _wageSheetRep._sqlSugar.SqlQueryable<WageYearMonthView>(sql).ToListAsync();
  280. return Ok(JsonView(true, "操作成功!", data));
  281. }
  282. /// <summary>
  283. /// 获取工资表单
  284. /// </summary>
  285. /// <param name="dto"></param>
  286. /// <returns></returns>
  287. [HttpPost]
  288. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  289. public async Task<IActionResult> GetWageSheetList(WageSheetListDto dto)
  290. {
  291. if (string.IsNullOrEmpty(dto.YearMonth)) return Ok(JsonView(false, "请选择日期格式"));
  292. //验证日期格式
  293. if (!DateTime.TryParse(dto.YearMonth, out DateTime yearMonthDt))
  294. {
  295. return Ok(JsonView(false, "无效的日期格式"));
  296. }
  297. //参数处理
  298. //string ymFormat = "yyyy-MM";
  299. //bool yearMonthDttIsValid = DateTime.TryParseExact(dto.YearMonth, ymFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime yearMonthDt);
  300. //if (!yearMonthDttIsValid)
  301. //{
  302. // _result.Msg = "年月格式错误!正确时间格式:yyyy-MM ";
  303. // return Ok(JsonView(false, _result.Msg));
  304. //}
  305. //获取月工资数据
  306. string yearMonth = yearMonthDt.ToString("yyyy-MM");
  307. if (dto.PortType == 1)
  308. {
  309. _result = await _wageSheetRep.Get_WageSheet_ListByYearMonthAsync(yearMonth);
  310. if (_result.Code != 0)
  311. {
  312. return Ok(JsonView(false, _result.Msg));
  313. }
  314. }
  315. else if (dto.PortType == 2)
  316. { }
  317. else if (dto.PortType == 3)
  318. { }
  319. else
  320. {
  321. return Ok(JsonView(false, "请选择正确的端口参数"));
  322. }
  323. return Ok(JsonView(true, _result.Msg, _result.Data));
  324. }
  325. /// <summary>
  326. /// 获取工资 详情
  327. /// </summary>
  328. /// <param name="dto"></param>
  329. /// <returns></returns>
  330. [HttpPost]
  331. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  332. public async Task<IActionResult> GetWageSheetById(WageSheetInfoDto dto)
  333. {
  334. if (dto.PortType == 1)
  335. {
  336. _result = await _wageSheetRep.Get_WageSheet_InfoByIdAsync(dto.Id);
  337. if (_result.Code != 0)
  338. {
  339. return Ok(JsonView(false, _result.Msg));
  340. }
  341. }
  342. else if (dto.PortType == 2)
  343. { }
  344. else if (dto.PortType == 3)
  345. { }
  346. else
  347. {
  348. return Ok(JsonView(false, "请选择正确的端口参数"));
  349. }
  350. return Ok(JsonView(true, _result.Msg, _result.Data));
  351. }
  352. /// <summary>
  353. /// 人事模块 工资表单 删除
  354. /// </summary>
  355. /// <param name="dto"></param>
  356. /// <returns></returns>
  357. [HttpPost]
  358. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  359. public async Task<IActionResult> PostWageSheetDel(WageDelDto dto)
  360. {
  361. try
  362. {
  363. _result = await _wageSheetRep.Post_WageSheet_DelAsync(dto);
  364. if (_result.Code != 0)
  365. {
  366. return Ok(JsonView(false, _result.Msg));
  367. }
  368. }
  369. catch (Exception ex)
  370. {
  371. return Ok(JsonView(false, ex.Message));
  372. }
  373. return Ok(JsonView(true, _result.Msg, _result.Data));
  374. }
  375. /// <summary>
  376. /// 人事模块 工资表单 添加 Or 修改
  377. /// </summary>
  378. /// <param name="dto"></param>
  379. /// <returns></returns>
  380. [HttpPost]
  381. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  382. public async Task<IActionResult> PostWageSheetAddOrEdit(WageAddOrEditDto dto)
  383. {
  384. try
  385. {
  386. Pm_WageSheet pm_WageSheet = new();
  387. pm_WageSheet = _mapper.Map<Pm_WageSheet>(dto);
  388. pm_WageSheet.LastUpdateUserId = dto.CreateUserId;
  389. #region 计算工资
  390. //月工资
  391. decimal salary = pm_WageSheet.Basic + pm_WageSheet.Floats + pm_WageSheet.PostAllowance + pm_WageSheet.InformationSecurityFee + pm_WageSheet.OtherSubsidies;
  392. //扣款合计
  393. decimal totalDeduction = pm_WageSheet.SickLeave + pm_WageSheet.SomethingFalse + pm_WageSheet.LateTo + pm_WageSheet.LeaveEarly + pm_WageSheet.Absenteeism + pm_WageSheet.NotPunch +
  394. pm_WageSheet.ReservedFunds + pm_WageSheet.WithholdingInsurance + pm_WageSheet.OtherDeductions + pm_WageSheet.OtherDeductions;
  395. //实发合计 不含个税
  396. if (pm_WageSheet.RegularDays >= pm_WageSheet.WorkDays)
  397. {
  398. pm_WageSheet.RegularDays = pm_WageSheet.WorkDays;
  399. salary = salary + pm_WageSheet.Mealsupplement + pm_WageSheet.OtherHandle;
  400. }
  401. else
  402. {
  403. if (dto.UserId == 21) //21==张海麟
  404. {
  405. salary = salary + pm_WageSheet.Mealsupplement + pm_WageSheet.OtherHandle;
  406. }
  407. else
  408. {
  409. salary = PayrollComputation.ConvertToDecimal(salary / pm_WageSheet.WorkDays * pm_WageSheet.RegularDays + pm_WageSheet.Mealsupplement + pm_WageSheet.OtherHandle);
  410. }
  411. }
  412. decimal actualTotal = salary - totalDeduction;
  413. pm_WageSheet.Should = salary;
  414. pm_WageSheet.TotalDeductions = totalDeduction;
  415. pm_WageSheet.TotalRealHair = actualTotal - pm_WageSheet.WithholdingTax;
  416. pm_WageSheet.AfterTax = actualTotal - pm_WageSheet.WithholdingTax;
  417. #endregion
  418. _result = await _wageSheetRep.Post_WageSheet_AddOrEditAsync(dto, pm_WageSheet);
  419. if (_result.Code != 0)
  420. {
  421. return Ok(JsonView(false, _result.Msg));
  422. }
  423. }
  424. catch (Exception ex)
  425. {
  426. return Ok(JsonView(false, ex.Message));
  427. }
  428. return Ok(JsonView(true, _result.Msg, _result.Data));
  429. }
  430. /// <summary>
  431. /// 计算工资
  432. /// </summary>
  433. /// <returns></returns>
  434. [HttpPost]
  435. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  436. public async Task<IActionResult> SalaryCalculatorAsync(SalaryCalculatorDto dto)
  437. {
  438. Result result = new();
  439. Stopwatch sw = new();
  440. sw.Start();
  441. //参数处理
  442. string ymFormat = "yyyy-MM";
  443. string dtFormat = "yyyy-MM-dd";
  444. bool yearMonthDtIsValid = DateTime.TryParseExact(dto.yearMonth, ymFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime yearMonthDt);
  445. bool startDtIsValid = DateTime.TryParseExact(dto.startDt, dtFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime startDt);
  446. bool endDtIsValid = DateTime.TryParseExact(dto.endDt, dtFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime endDt);
  447. if (!yearMonthDtIsValid) return Ok(JsonView(false, "年月格式错误!正确时间格式:yyyy-MM "));
  448. if (!startDtIsValid) return Ok(JsonView(false, "开始日期格式错误!正确时间格式:yyyy-MM-dd "));
  449. if (!endDtIsValid) return Ok(JsonView(false, "结束格式错误!正确时间格式:yyyy-MM-dd "));
  450. string thisYearMonth = dto.yearMonth;
  451. string preYearMonth = yearMonthDt.AddMonths(-1).ToString("yyyy-MM");
  452. //计算本月工资起止时间 比如是2月的1号-28号,那就是2月1号的零点到3月1号的零点
  453. DateTime thisStartDt = startDt;
  454. DateTime thisEndDt = endDt; //
  455. //本月工资是否有数据 有数据则不计算
  456. result = await _wageSheetRep.Get_WageSheet_ListByYearMonthAsync(thisYearMonth);
  457. if (result.Code == 0)
  458. {
  459. return Ok(JsonView(false, thisYearMonth + " 工资数据已存在,若无人员工资请手动添加!"));
  460. }
  461. //获取上个月工资信息
  462. List<Pm_WageSheet> preWageSheetItems = await _wageSheetRep._sqlSugar.Queryable<Pm_WageSheet>().Where(it => it.IsDel == 0 && it.YearMonth == preYearMonth).ToListAsync();
  463. preWageSheetItems = preWageSheetItems.OrderBy(it => it.UserId).ToList();
  464. if (preWageSheetItems.Count <= 0)
  465. {
  466. return Ok(JsonView(false, thisYearMonth + " 上月工资数据不存在,请手动添加!"));
  467. }
  468. //处理上个月同月同人 多条数据
  469. List<Pm_WageSheet> preWageSheetItems1 = new();
  470. //preWageSheetItems1 = preWageSheetItems.GroupBy(it => new { it.YearMonth, it.UserId })
  471. // .Select(it => it.FirstOrDefault(item => item.Basic != 0))
  472. // .ToList();
  473. preWageSheetItems1 = preWageSheetItems
  474. .GroupBy(it => new { it.YearMonth, it.UserId })
  475. .Select(it => it.FirstOrDefault(item => item.Basic != 0))
  476. .Where(it => it != null)
  477. .ToList()!;
  478. //获取OA系统内所有用户
  479. List<UserNameView> userNames = _usersRep._sqlSugar.SqlQueryable<UserNameView>("Select Id,CnName From Sys_Users").ToList();
  480. List<Pm_WageSheet> wageSheets = new();
  481. _result = await PayrollComputation.SalaryCalculatorAsync(preWageSheetItems1, userNames, dto.UserId, thisYearMonth, thisStartDt, thisEndDt);
  482. #region 批量添加
  483. if (_result.Code != 0)
  484. {
  485. return Ok(JsonView(false, _result.Msg));
  486. }
  487. wageSheets = _result.Data;
  488. var add = await _wageSheetRep._sqlSugar.Insertable(wageSheets).ExecuteCommandAsync();
  489. if (add <= 0)
  490. {
  491. return Ok(JsonView(false, "操作失败!"));
  492. }
  493. #endregion
  494. #region 处理返回数据
  495. //List <WageSheetItemInfoView> wageSheetItems = new List<WageSheetItemInfoView>();
  496. //wageSheetItems = _mapper.Map<List<WageSheetItemInfoView>>(wageSheets);
  497. //wageSheetItems = wageSheetItems.Select(it =>
  498. // {
  499. // UserNameView? uName1 = new UserNameView();
  500. // UserNameView? uName2 = new UserNameView();
  501. // uName1 = userNames.Where(it1 => it.UserId == it1.Id).FirstOrDefault();
  502. // if (uName1 != null) it.Name = uName1.CnName;
  503. // uName2 = userNames.Where(it1 => it.LastUpdateUserId == it1.Id).FirstOrDefault();
  504. // if (uName2 != null) it.LastUpdateUserName = uName2.CnName;
  505. // return it; }
  506. // ).ToList();
  507. #endregion
  508. sw.Stop();
  509. return Ok(JsonView(true, "操作成功! 耗时:" + (sw.ElapsedMilliseconds / 1000) + "s"));
  510. }
  511. /// <summary>
  512. /// 计算工资 By YearMonth And UserId
  513. /// </summary>
  514. /// <returns></returns>
  515. [HttpPost]
  516. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  517. public async Task<IActionResult> SalaryCalculatorSingleAsync(SalaryCalculatorSingleDto dto)
  518. {
  519. Result result = new();
  520. Stopwatch sw = new();
  521. sw.Start();
  522. //参数处理
  523. string ymFormat = "yyyy-MM";
  524. string ymdFormat = "yyyy-MM-dd";
  525. bool yearMonthDtIsValid = DateTime.TryParseExact(dto.YearMonth, ymFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime yearMonthDt);
  526. bool startDtIsValid = DateTime.TryParseExact(dto.StartDate, ymdFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime startDt);
  527. bool endDtIsValid = DateTime.TryParseExact(dto.EndDate, ymdFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime endDt);
  528. if (!yearMonthDtIsValid) return Ok(JsonView(false, "年月格式错误!正确时间格式:yyyy-MM "));
  529. if (!startDtIsValid) return Ok(JsonView(false, "开始时间格式错误!正确时间格式:yyyy-MM-dd "));
  530. if (!yearMonthDtIsValid) return Ok(JsonView(false, "结束时间格式错误!正确时间格式:yyyy-MM-dd "));
  531. List<Pm_WageSheet> wageSheets = new();
  532. Pm_WageSheet wageSheet = _mapper.Map<Pm_WageSheet>(dto);
  533. Pm_WageSheet wageSheet1 = await _wageSheetRep._sqlSugar.Queryable<Pm_WageSheet>().Where(it => it.UserId == dto.UserId && it.YearMonth == dto.YearMonth && it.StartDate == dto.StartDate && it.EndDate == dto.EndDate).FirstAsync();
  534. if (wageSheet1 != null)
  535. {
  536. wageSheet.Id = wageSheet1.Id;
  537. }
  538. wageSheets.Add(wageSheet);
  539. //获取OA系统内所有用户
  540. List<UserNameView> userNames = _usersRep._sqlSugar.SqlQueryable<UserNameView>("Select Id,CnName From Sys_Users").ToList();
  541. _result = await PayrollComputation.SalaryCalculatorAsync(wageSheets, userNames, dto.UserId, dto.YearMonth, startDt, endDt);
  542. if (_result.Code != 0)
  543. {
  544. return Ok(JsonView(false, _result.Msg));
  545. }
  546. List<Pm_WageSheet> wageSheets1 = new();
  547. wageSheets1 = _result.Data;
  548. #region 处理返回数据
  549. List<WageSheetInfoView> wageSheetItems = new();
  550. wageSheetItems = _mapper.Map<List<WageSheetInfoView>>(wageSheets1);
  551. wageSheetItems = wageSheetItems.Select(it =>
  552. {
  553. UserNameView? uName1 = new();
  554. UserNameView? uName2 = new();
  555. uName1 = userNames.Where(it1 => it.UserId == it1.Id).FirstOrDefault();
  556. if (uName1 != null) it.Name = uName1.CnName;
  557. uName2 = userNames.Where(it1 => it.LastUpdateUserId == it1.Id).FirstOrDefault();
  558. if (uName2 != null) it.LastUpdateUserName = uName2.CnName;
  559. return it;
  560. }
  561. ).ToList();
  562. #endregion
  563. sw.Stop();
  564. return Ok(JsonView(true, "操作成功!耗时:" + (sw.ElapsedMilliseconds / 1000) + "s", wageSheetItems[0]));
  565. }
  566. /// <summary>
  567. /// 导出工资单
  568. /// </summary>
  569. /// <returns></returns>
  570. [HttpPost]
  571. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  572. public async Task<IActionResult> ExportWageCard(string yearMonth)
  573. {
  574. Stopwatch sw = new();
  575. sw.Start();
  576. //参数处理
  577. string ymFormat = "yyyy-MM";
  578. bool yearMonthDtIsValid = DateTime.TryParseExact(yearMonth, ymFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out _);
  579. if (!yearMonthDtIsValid) return Ok(JsonView(false, "年月格式错误!正确时间格式:yyyy-MM "));
  580. //公司部门
  581. string sql = string.Format(@"Select row_number() over(order by pm_ws.Id) as Row_Number,
  582. sc.Id as CompanyId,sc.CompanyName,sd.Id as DepId,sd.DepName,
  583. sys_u1.CnName Name,sys_u2.CnName LastUpdateUserName,pm_ws.*
  584. From Pm_WageSheet pm_ws
  585. Left Join Sys_Users sys_u1 On pm_ws.UserId = sys_u1.Id
  586. Left Join Sys_Users sys_u2 On pm_ws.LastUpdateUserId = sys_u2.Id
  587. Left Join Sys_Company sc On sys_u1.companyId = sc.Id
  588. Left Join Sys_Department sd On sys_u1.DepId = sd.Id
  589. Where pm_ws.IsDel = 0 And pm_ws.YearMonth = '{0}'", yearMonth);
  590. var wageSheetList = await _wageSheetRep._sqlSugar.SqlQueryable<ExportWageSheetItemView>(sql).ToListAsync();
  591. if (wageSheetList.Count <= 0)
  592. {
  593. return Ok(JsonView(false, yearMonth + "暂无工资数据!"));
  594. }
  595. decimal SumPrice = 0.00M;
  596. foreach (var item in wageSheetList)
  597. {
  598. SumPrice += item.AfterTax;
  599. }
  600. WorkbookDesigner designer = new()
  601. {
  602. Workbook = new Workbook(AppSettingsHelper.Get("ExcelBasePath") + "Template/工资详细清单.xlsx")
  603. };
  604. designer.Workbook.Worksheets[0].Name = yearMonth + " 工资单";
  605. designer.SetDataSource("WageSheet", wageSheetList);
  606. designer.SetDataSource("YearMonth", yearMonth);
  607. designer.SetDataSource("StartEndDt", wageSheetList[0].StartDate + " - " + wageSheetList[0].EndDate);
  608. designer.SetDataSource("WorkDays", wageSheetList[0].WorkDays);
  609. designer.SetDataSource("SumPrice", SumPrice);
  610. designer.SetDataSource("WageSheetTitle", "工资单");//
  611. designer.Process();
  612. string fileName = "WageCard/" + yearMonth + "_工资单_" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".xlsx";
  613. string path = AppSettingsHelper.Get("ExcelBasePath");
  614. designer.Workbook.Save(path + fileName);
  615. string excelPath = AppSettingsHelper.Get("ExcelFtpPath") + fileName;
  616. string url = AppSettingsHelper.Get("ExcelBaseUrl");
  617. string fileUrl = url + excelPath;
  618. sw.Stop();
  619. return Ok(JsonView(true, "操作成功!耗时:" + (sw.ElapsedMilliseconds / 1000) + "s", new { FileUrl = fileUrl }));
  620. }
  621. /// <summary>
  622. /// 下载个税模板
  623. /// </summary>
  624. /// <returns></returns>
  625. [HttpPost]
  626. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  627. public async Task<IActionResult> WageSheetTaxTemplate()
  628. {
  629. //string serverUrl = AppSettingsHelper.Get("WageSheetExcelBaseUrl");
  630. var userData = await _usersRep.GetUserNameList(1);
  631. if (userData.Code == 0)
  632. {
  633. var userNames = userData.Data;
  634. List<string> names = new()
  635. {
  636. "管理员",
  637. "国交共享号",
  638. "人事审核号",
  639. "国交主管号"
  640. };
  641. List<TaxTemlateViuw> taxs = new();
  642. List<UserNameView> users = JsonConvert.DeserializeObject<List<UserNameView>>(JsonConvert.SerializeObject(userNames));
  643. foreach (UserNameView item in users)
  644. {
  645. string uName = item.CnName;
  646. if (!names.Contains(uName))
  647. {
  648. taxs.Add(new TaxTemlateViuw { UserName = item.CnName });
  649. }
  650. }
  651. if (taxs.Count > 0)
  652. {
  653. WorkbookDesigner designer = new()
  654. {
  655. Workbook = new Workbook(AppSettingsHelper.Get("ExcelBasePath") + "Template/个税导入模板.xlsx")
  656. };
  657. designer.Workbook.Worksheets[0].Name = "个税模板";
  658. designer.SetDataSource("TaxTemp", taxs);
  659. designer.Process();
  660. string fileName = "WageSheetTaxFile/个税模板" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".xlsx";
  661. string path = AppSettingsHelper.Get("ExcelBasePath");
  662. designer.Workbook.Save(path + fileName);
  663. string excelPath = AppSettingsHelper.Get("ExcelFtpPath") + fileName;
  664. string url = AppSettingsHelper.Get("ExcelBaseUrl");
  665. string fileUrl = url + excelPath;
  666. return Ok(JsonView(true, "操作成功!", new { FileUrl = fileUrl }));
  667. }
  668. }
  669. return Ok(JsonView(false, "操作失败!"));
  670. }
  671. /// <summary>
  672. /// 上传个税
  673. /// </summary>
  674. /// <returns></returns>
  675. [HttpPost]
  676. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  677. public async Task<IActionResult> UploadTax(IFormFile file)
  678. {
  679. try
  680. {
  681. var yearMonth = Request.Headers["YearMonth"].ToString();
  682. //string yearMonth = "2023-10";
  683. string ymFormat = "yyyy-MM";
  684. bool yearMonthDtIsValid = DateTime.TryParseExact(yearMonth, ymFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime yearMonthDt);
  685. if (!yearMonthDtIsValid) return Ok(JsonView(false, "年月格式错误!正确时间格式:yyyy-MM "));
  686. if (file != null)
  687. {
  688. var fileDir = AppSettingsHelper.Get("WageSheetExcelFptPath");
  689. //文件名称
  690. string projectFileName = file.FileName;
  691. //上传的文件的路径
  692. string filePath = "";
  693. if (!Directory.Exists(fileDir))
  694. {
  695. Directory.CreateDirectory(fileDir);
  696. }
  697. //上传的文件的路径
  698. filePath = fileDir + $@"\{projectFileName}";
  699. if (System.IO.File.Exists(filePath))
  700. {
  701. //删除文件
  702. System.IO.File.Delete(filePath);
  703. }
  704. using (FileStream fs = System.IO.File.Create(filePath))
  705. {
  706. file.CopyTo(fs);
  707. fs.Flush();
  708. }
  709. if (System.IO.File.Exists(filePath))
  710. {
  711. Workbook book = new(filePath);
  712. DataSet dataSet = new();
  713. if (book.Worksheets.Count > 0)
  714. {
  715. var sheet = book.Worksheets[0];
  716. if (sheet != null)
  717. {
  718. // sheets 中的数据必须存在
  719. if (sheet.Cells.MaxDataRow != -1 && sheet.Cells.MaxDataColumn != -1)
  720. {
  721. // 方法 ExportDataTable 的参数说明
  722. // 要导出的第一个单元格的行号。
  723. // 要导出的第一个单元格的列号。
  724. // 要导入的行数。
  725. // 要导入的列数。
  726. // 指示第一行的数据是否导出到DataTable的列名。
  727. DataTable dataTable = sheet.Cells.ExportDataTable(0, 0, sheet.Cells.MaxDataRow + 1, sheet.Cells.MaxDataColumn + 1, true);
  728. dataSet.Tables.Add(dataTable);
  729. DataTable taxData = dataSet.Tables[0];
  730. //公司部门
  731. string sql = string.Format(@"Select row_number() over(order by pm_ws.Id) as Row_Number,
  732. sc.Id as CompanyId,sc.CompanyName,sd.Id as DepId,sd.DepName,
  733. sys_u1.CnName Name,sys_u2.CnName LastUpdateUserName,pm_ws.*
  734. From Pm_WageSheet pm_ws
  735. Left Join Sys_Users sys_u1 On pm_ws.UserId = sys_u1.Id
  736. Left Join Sys_Users sys_u2 On pm_ws.LastUpdateUserId = sys_u2.Id
  737. Left Join Sys_Company sc On sys_u1.companyId = sc.Id
  738. Left Join Sys_Department sd On sys_u1.DepId = sd.Id
  739. Where pm_ws.IsDel = 0 And pm_ws.YearMonth = '{0}'
  740. Order By UserId Asc ", yearMonth);
  741. var wageSheetList = await _wageSheetRep._sqlSugar.SqlQueryable<WageSheetInfoView>(sql).ToListAsync();
  742. if (wageSheetList.Count <= 0)
  743. {
  744. return Ok(JsonView(false, yearMonth + "工资数据不存在,请先添加工资数据!"));
  745. }
  746. for (int i = 0; i < taxData.Rows.Count; i++)
  747. {
  748. string name = taxData.Rows[i][0].ToString().Trim();
  749. List<WageSheetInfoView> wageSheets = new();
  750. wageSheets = wageSheetList.Where(it => it.Name.Equals(name)).ToList();
  751. if (wageSheets.Count > 0)
  752. {
  753. wageSheetList.Where(it => it.Name.Equals(name))
  754. .Select(it =>
  755. {
  756. //修改 绩效不等于0.00M的数据
  757. //decimal oldTax = it.WithholdingTax;
  758. var newTax = Convert.ToDecimal(taxData.Rows[i][1].ToString());
  759. it.WithholdingTax = newTax;
  760. it.TotalRealHair = it.Should - it.TotalDeductions - newTax;
  761. return it;
  762. })
  763. .ToList();
  764. }
  765. }
  766. List<Pm_WageSheet> wageSheets1 = new();
  767. wageSheets1 = _mapper.Map<List<Pm_WageSheet>>(wageSheetList);
  768. var updateStatus = _wageSheetRep._sqlSugar
  769. .Updateable(wageSheets1)
  770. .UpdateColumns(it => new { it.WithholdingTax, it.TotalRealHair })
  771. .ExecuteCommand();
  772. if (updateStatus < 0)
  773. {
  774. return Ok(JsonView(false, "操作失败!"));
  775. }
  776. if (System.IO.File.Exists(filePath))
  777. {
  778. //删除文件
  779. System.IO.File.Delete(filePath);
  780. }
  781. return Ok(JsonView(true, "操作成功!"));
  782. }
  783. }
  784. else
  785. {
  786. return Ok(JsonView(false, "工作薄没有数据!"));
  787. }
  788. }
  789. }
  790. return Ok(JsonView(true, "上传成功!", projectFileName));
  791. }
  792. else
  793. {
  794. return Ok(JsonView(false, "上传失败!"));
  795. }
  796. }
  797. catch (Exception ex)
  798. {
  799. return Ok(JsonView(false, "程序错误!"));
  800. throw;
  801. }
  802. //return Ok(JsonView(true, "操作成功!"));
  803. }
  804. /// <summary>
  805. /// 打卡记录测试
  806. /// </summary>
  807. /// <returns></returns>
  808. [HttpPost]
  809. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  810. public async Task<IActionResult> Test(string startDt, string endDt, int code)
  811. {
  812. UserIdListView userIdListView = await _qiYeWeChatApiService.GetUserIdListAsync();
  813. if (userIdListView.errcode != 0)
  814. {
  815. _result.Msg = "【企业微信】【打卡】【获取员工ID】【Msg】" + userIdListView.errmsg;
  816. return Ok(JsonView(false, _result.Msg));
  817. }
  818. List<string> qyWhchatIdList = new();
  819. //qyWhchatIdList = userIdListView.dept_user.Select(it => it.userid).ToList();
  820. qyWhchatIdList = userIdListView.dept_user.Select(it => it.userid!).ToList();
  821. var data = await _qiYeWeChatApiService.GetCheckinDataAsync(qyWhchatIdList, code, Convert.ToDateTime(startDt), Convert.ToDateTime(endDt));
  822. return Ok(JsonView(true, "操作成功!", data.checkindata));
  823. }
  824. /// <summary>
  825. /// 审批详情
  826. /// </summary>
  827. /// <returns></returns>
  828. [HttpPost]
  829. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  830. public async Task<IActionResult> PostApprovalDetailAsync(string spNo)
  831. {
  832. if (string.IsNullOrEmpty(spNo))
  833. {
  834. return Ok(JsonView(false, "审批单号不能为空!!"));
  835. }
  836. var data = await _qiYeWeChatApiService.GetApprovalDetailAsync(spNo);
  837. return Ok(JsonView(true, "操作成功!", data));
  838. }
  839. #endregion
  840. #region 任务单
  841. /// <summary>
  842. /// 任务分配
  843. /// 基础数据源
  844. /// </summary>
  845. /// <returns></returns>
  846. [HttpPost]
  847. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  848. public async Task<IActionResult> PostTaskAllocationInit(TaskAllocationInitDto dto)
  849. {
  850. #region 参数验证
  851. if (dto.UserId < 1) return Ok(JsonView(false, "员工Id为空"));
  852. if (dto.PageId < 1) dto.PageId = 172; //任务指派Id
  853. #region 页面操作权限验证
  854. PageFunAuthViewBase pageFunAuthView = await GeneralMethod.PostUserPageFuncDatas(dto.UserId, dto.PageId);
  855. if (pageFunAuthView.CheckAuth == 0) return Ok(JsonView(false, "您没有查看权限!"));
  856. #endregion
  857. #endregion
  858. var _view = await _taskAllocationRep._Init(dto.PortType, dto.UserId);
  859. if (_view.Code == 0)
  860. {
  861. return Ok(JsonView(true, "查询成功!", _view.Data));
  862. }
  863. return Ok(JsonView(false, _view.Msg));
  864. }
  865. /// <summary>
  866. /// 任务分配
  867. /// page
  868. /// </summary>
  869. /// <returns></returns>
  870. [HttpPost]
  871. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  872. public async Task<IActionResult> PostTaskAllocationPage(TaskAllocationPageDto dto)
  873. {
  874. #region 参数验证
  875. if (dto.UserId < 1) return Ok(JsonView(false, "员工Id为空"));
  876. if (dto.PageId < 1) dto.PageId = 172; //任务指派Id
  877. PageFunAuthViewBase pageFunAuthView = new();
  878. #region 页面操作权限验证
  879. pageFunAuthView = await GeneralMethod.PostUserPageFuncDatas(dto.UserId, dto.PageId);
  880. if (pageFunAuthView.CheckAuth == 0) return Ok(JsonView(false, "您没有查看权限!"));
  881. #endregion
  882. #endregion
  883. var groupNames = dto.GroupNames;
  884. var groupArr = Array.Empty<string>();
  885. if (!string.IsNullOrEmpty(groupNames))
  886. {
  887. groupArr = groupNames.Split(',').Select(part => part.Trim()).ToArray();
  888. }
  889. string whereSql = "", currUserName = "";
  890. #region 分页参数处理
  891. //类型处理
  892. if (dto.Type == 0) whereSql = "";
  893. else if (dto.Type == 1) //1 由我指派
  894. {
  895. //whereSql = string.Format(@" And ta.CreateUserId = {0} Or (Select COUNT(1) As PeopleNumber From Pm_TaskRelevanceUser Where IsDel = 0 And ta.Id = TAId And UserId = {0}) > 0", dto.UserId);
  896. }
  897. else if (dto.Type == 2)// 2 指派给我
  898. {
  899. //whereSql = string.Format(@" And (Select COUNT(1) As PeopleNumber From Pm_TaskRelevanceUser Where IsDel = 0 And ta.Id = TAId And UserId = {0}) > 0", dto.UserId);
  900. }
  901. //状态 -1 全部 0 未开始 1 进行中 2 待审核 3 未完成 4 已完成
  902. if (dto.Status == -1) //全部
  903. {
  904. whereSql += "";
  905. }
  906. else
  907. {
  908. whereSql += string.Format(@" And ta.Status = {0} ", dto.Status);
  909. }
  910. //任务名称
  911. if (!string.IsNullOrEmpty(dto.TaskName))
  912. {
  913. whereSql += string.Format(@" And ta.TaskName Like '%{0}%' ", dto.TaskName);
  914. }
  915. #endregion
  916. var currUserInfo = await _sqlSugar.Queryable<Sys_Users>().FirstAsync(x => x.Id == dto.UserId);
  917. if (currUserInfo != null) currUserName = currUserInfo.CnName;
  918. string pageSql = string.Format(@"Select
  919. ROW_NUMBER() OVER(
  920. ORDER BY
  921. CreateTime Desc
  922. ) AS RowNumber,
  923. *
  924. From
  925. (
  926. Select
  927. ta.Id,
  928. ta.TaskName,
  929. ta.TaskContent,
  930. ta.TaskPriority,
  931. d.DepName,
  932. di.TeamName,
  933. ta.Status,
  934. ta.PredictBeginTime,
  935. ta.PredictEndTime,
  936. u.CnName As CreateUserName,
  937. ta.CreateTime,
  938. (
  939. SELECT
  940. STUFF(
  941. (
  942. Select
  943. ',' + u.CnName
  944. From
  945. Pm_TaskRelevanceUser tra
  946. Left Join Sys_Users u On tra.UserId = u.Id
  947. Where
  948. tra.Isdel = 0
  949. And tra.TAId = ta.Id FOR XML PATH('')
  950. ),
  951. 1,
  952. 1,
  953. ''
  954. )
  955. ) As Participant,
  956. (
  957. SELECT
  958. STUFF(
  959. (
  960. Select
  961. ',' + u.CnName
  962. From
  963. Pm_TaskRelevanceUser tra
  964. Left Join Sys_Users u On tra.UserId = u.Id
  965. Where
  966. tra.Isdel = 0
  967. And tra.TAId = ta.Id
  968. And tra.TaskStatus = 4 FOR XML PATH('')
  969. ),
  970. 1,
  971. 1,
  972. ''
  973. )
  974. ) As Consummator
  975. From
  976. Pm_TaskAllocation ta
  977. Left Join Sys_Department d On ta.DepId = d.Id
  978. Left Join Grp_DelegationInfo di On ta.DiId = di.Id
  979. Left Join Sys_Users u On ta.CreateUserId = u.Id
  980. Where
  981. ta.IsDel = 0 {0}
  982. ) As temp
  983. WHERE
  984. [CreateUserName] like '%{1}%'
  985. OR [Participant] like '%{2}%' ", whereSql, currUserName, currUserName);
  986. RefAsync<int> total = 0;
  987. var _view = await _sqlSugar.SqlQueryable<TaskListView>(pageSql)
  988. .WhereIF(groupArr.Any(), x => groupArr.Contains(x.TeamName))
  989. .ToPageListAsync(dto.PageIndex, dto.PageSize, total);//ToPageAsync
  990. List<int> taskIds = taskIds = _view.Select(it => it.Id).ToList();
  991. string taskerSql = string.Format(@"Select tau.TAId,tau.Id,tau.UserId,u.CnName As UserName,tau.BeginTime,tau.OverTime,tau.TaskStatus,
  992. tau.Cause,tau.Score,tau.Remark As ScoreRemark,tau.CreateUserId As TaskCreateUserId
  993. From Pm_TaskRelevanceUser tau
  994. Left Join Sys_Users u On tau.UserId = u.Id
  995. Where tau.IsDel = 0");
  996. var taskerData = _sqlSugar.SqlQueryable<TaskerDetailsView>(taskerSql).Where(it => taskIds.Contains(it.TAId)).ToList();
  997. foreach (var item in _view)
  998. {
  999. //任务接收者显示自己任务状态
  1000. if (!item.CreateUserName.Equals(currUserName))
  1001. {
  1002. var subTaskInfo = taskerData.FirstOrDefault(x => item.Id == x.TAId && x.UserId == dto.UserId);
  1003. if (subTaskInfo != null) item.Status = subTaskInfo.TaskStatus;
  1004. }
  1005. else
  1006. {
  1007. item.TaskerDetails = taskerData.Where(it => it.TAId == item.Id).ToArray();
  1008. }
  1009. ////处理任务总状态 And 任务人状态
  1010. //var taskerStatusData = taskerData.Where(it => it.TAId == item.Id && it.TaskCreateUserId != dto.UserId && it.UserId == dto.UserId).FirstOrDefault();
  1011. //if (taskerStatusData != null)
  1012. //{
  1013. // item.Status = taskerStatusData.TaskStatus;
  1014. //}
  1015. }
  1016. return Ok(JsonView(true, "查询成功!", _view, total));
  1017. }
  1018. /// <summary>
  1019. /// 任务分配
  1020. /// 详情
  1021. /// </summary>
  1022. /// <returns></returns>
  1023. [HttpPost]
  1024. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  1025. public async Task<IActionResult> PostTaskAllocationDetails(TaskAllocationDetailsDto dto)
  1026. {
  1027. #region 参数验证
  1028. if (dto.UserId < 1) return Ok(JsonView(false, "员工Id为空"));
  1029. if (dto.PageId < 1) dto.PageId = 172; //任务指派Id
  1030. #region 页面操作权限验证
  1031. PageFunAuthViewBase pageFunAuthView = await GeneralMethod.PostUserPageFuncDatas(dto.UserId, dto.PageId);
  1032. if (pageFunAuthView.CheckAuth == 0) return Ok(JsonView(false, "您没有查看权限!"));
  1033. #endregion
  1034. #endregion
  1035. var _view = await _taskAllocationRep._Details(dto.PortType, dto.Id);
  1036. if (_view.Code == 0)
  1037. {
  1038. return Ok(JsonView(true, "查询成功!", _view.Data));
  1039. }
  1040. return Ok(JsonView(false, _view.Msg));
  1041. }
  1042. /// <summary>
  1043. /// 任务分配
  1044. /// Add Or Edit
  1045. /// </summary>
  1046. /// <returns></returns>
  1047. [HttpPost]
  1048. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  1049. public async Task<IActionResult> PostTaskAllocationAddOrEdit(TaskAllocationAddOrEditDto dto)
  1050. {
  1051. #region 参数验证
  1052. if (dto.UserId < 1) return Ok(JsonView(false, "员工Id为空"));
  1053. if (dto.PageId < 1) dto.PageId = 172; //任务指派Id
  1054. PageFunAuthViewBase pageFunAuthView = new();
  1055. #region 页面操作权限验证
  1056. pageFunAuthView = await GeneralMethod.PostUserPageFuncDatas(dto.UserId, dto.PageId);
  1057. if (dto.Id == 0)
  1058. {
  1059. if (pageFunAuthView.AddAuth == 0) return Ok(JsonView(false, "您没有添加权限!"));
  1060. }
  1061. else if (dto.Id > 0)
  1062. {
  1063. if (pageFunAuthView.EditAuth == 0) return Ok(JsonView(false, "您没有编辑权限!"));
  1064. }
  1065. #endregion
  1066. #endregion
  1067. var _view = await _taskAllocationRep._AddOrEdit(dto);
  1068. if (_view.Code == 0)
  1069. {
  1070. if (dto.Id == 0) //添加提示任务单创建
  1071. {
  1072. string title = $"[{dto.TaskName}] 任务新建成功!";
  1073. string content = $"[{dto.TaskName}] 任务新建成功,请前往任务页面查看详情!";
  1074. await GeneralMethod.MessageIssueAndNotification(MessageTypeEnum.TaskProgressUpdate, title, content, dto.UserIds);
  1075. var userIds = dto.UserIds.Select(x => x.ToString()).ToList();
  1076. await AppNoticeLibrary.SendUserMsg_Task_ToUser(userIds, dto.DiId, title, dto.UserId);
  1077. }
  1078. return Ok(JsonView(true, "操作成功!"));
  1079. }
  1080. return Ok(JsonView(false, _view.Msg));
  1081. }
  1082. /// <summary>
  1083. /// 任务分配
  1084. /// 状态任务归属人详情
  1085. /// </summary>
  1086. /// <returns></returns>
  1087. [HttpPost]
  1088. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  1089. public async Task<IActionResult> PostTaskAllocationTaskerDetails(TaskerDetailsDto dto)
  1090. {
  1091. var _view = await _taskAllocationRep._TaskerDetails(dto.Id);
  1092. if (_view.Code == 0)
  1093. {
  1094. return Ok(JsonView(true, "操作成功!", _view.Data));
  1095. }
  1096. return Ok(JsonView(false, _view.Msg));
  1097. }
  1098. /// <summary>
  1099. /// 任务分配
  1100. /// 状态任务归属人设置开始状态
  1101. /// </summary>
  1102. /// <returns></returns>
  1103. [HttpPost]
  1104. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  1105. public async Task<IActionResult> PostTaskAllocationSetStartStatus(TaskerStatusDto dto)
  1106. {
  1107. var _view = await _taskAllocationRep._TaskerSetStartStatus(dto.UserId, dto.Id);
  1108. if (_view.Code == 0)
  1109. {
  1110. //发送消息
  1111. var taskData = _taskAllocationRep._sqlSugar.Queryable<Pm_TaskAllocation>().Where(it => it.Id == dto.Id).First();
  1112. if (taskData != null)
  1113. {
  1114. var taskUserIds = _taskAllocationRep._sqlSugar.Queryable<Pm_TaskRelevanceUser>().Where(it => it.TAId == dto.Id).Select(it => it.UserId).ToList();
  1115. if (taskUserIds.Count > 0)
  1116. {
  1117. taskUserIds.Remove(dto.UserId);
  1118. }
  1119. var UserName = _taskAllocationRep._sqlSugar.Queryable<Sys_Users>().Where(it => it.Id == dto.UserId).Select(it => it.CnName).First();
  1120. string title_createUser = $"[{taskData.TaskName}] 进度更新!";
  1121. string conten_createUser = $"[{UserName}] 已开始任务,请注意该工作人员任务进度!";
  1122. //创建人发送消息
  1123. List<int> createUserIds = new() { taskData.CreateUserId };
  1124. await GeneralMethod.MessageIssueAndNotification(MessageTypeEnum.TaskProgressUpdate, title_createUser, conten_createUser, createUserIds);
  1125. await AppNoticeLibrary.SendUserMsg_Task_ToUser(createUserIds.Select(x => x.ToString()).ToList(), taskData.DiId, conten_createUser, taskData.CreateUserId);
  1126. //其他人发送消息
  1127. string title = $"[{taskData.TaskName}] 进度更新!";
  1128. string content = $"[{UserName}] 已开始任务.若需查看,请前往任务页面查看详情!";
  1129. await GeneralMethod.MessageIssueAndNotification(MessageTypeEnum.TaskProgressUpdate, title, content, taskUserIds);
  1130. await AppNoticeLibrary.SendUserMsg_Task_ToUser(taskUserIds.Select(x => x.ToString()).ToList(), taskData.DiId, content, dto.UserId);
  1131. }
  1132. return Ok(JsonView(true, "操作成功!"));
  1133. }
  1134. return Ok(JsonView(false, _view.Msg));
  1135. }
  1136. /// <summary>
  1137. /// 任务分配
  1138. /// 状态 任务归属人 设置完成状态
  1139. /// </summary>
  1140. /// <returns></returns>
  1141. [HttpPost]
  1142. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  1143. public async Task<IActionResult> PostTaskAllocationSetOverStatus(TaskerStatusDto dto)
  1144. {
  1145. var _view = await _taskAllocationRep._TaskerSetOverStatus(dto.UserId, dto.Id);
  1146. if (_view.Code == 0)
  1147. {
  1148. //发送消息
  1149. var taskData = _sqlSugar.Queryable<Pm_TaskAllocation>().Where(it => it.Id == dto.Id).First();
  1150. if (taskData != null)
  1151. {
  1152. var taskUserIds = _sqlSugar.Queryable<Pm_TaskRelevanceUser>().Where(it => it.TAId == dto.Id).Select(it => it.UserId).Distinct().ToList();
  1153. var UserName = _sqlSugar.Queryable<Sys_Users>().Where(it => it.Id == dto.UserId).Select(it => it.CnName).First();
  1154. string title_createUser = $"[{taskData.TaskName}] 进度更新!";
  1155. string conten_createUser = $"[{UserName}] 已完成任务,请前往任务页面进行审核操作!";
  1156. await GeneralMethod.MessageIssueAndNotification(MessageTypeEnum.TaskProgressUpdate, title_createUser, conten_createUser, new List<int>() { taskData.CreateUserId }); //创建人发送消息
  1157. await AppNoticeLibrary.SendUserMsg_Task_ToUser(new List<string>() { taskData.CreateUserId.ToString() }, taskData.DiId, conten_createUser, dto.UserId);
  1158. string title = $"[{taskData.TaskName}] 进度更新!";
  1159. string content = $"[{UserName}] 已完成任务,请注意在规定时间内完成任务.若需查看,请前往任务页面查看详情!";
  1160. string yw_content = $"[{UserName}] 已完成任务,请注意在规定时间内完成任务!";
  1161. await GeneralMethod.MessageIssueAndNotification(MessageTypeEnum.TaskProgressUpdate, title, content, taskUserIds); //其他人发送消息
  1162. await AppNoticeLibrary.SendUserMsg_Task_ToUser(taskUserIds.Select(x => x.ToString()).ToList(), taskData.DiId, yw_content, dto.UserId);
  1163. string content1 = $"任务已完成,等待任务发布人审核!若需查看,请前往任务页面查看详情!";
  1164. string yw_content1 = $"任务已完成,等待任务发布人审核!";
  1165. await GeneralMethod.MessageIssueAndNotification(MessageTypeEnum.TaskProgressUpdate, title, content1, new List<int>() { dto.UserId }); //设置任务人 发送消息
  1166. await AppNoticeLibrary.SendUserMsg_Task_ToUser(new List<string>() { dto.UserId.ToString() }, taskData.DiId, yw_content1, dto.UserId);
  1167. }
  1168. return Ok(JsonView(true, "操作成功!"));
  1169. }
  1170. return Ok(JsonView(false, _view.Msg));
  1171. }
  1172. /// <summary>
  1173. /// 任务分配
  1174. /// 状态 任务归属人 设置知晓状态
  1175. /// </summary>
  1176. /// <returns></returns>
  1177. [HttpPost]
  1178. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  1179. public async Task<IActionResult> PostTaskAllocationSetHaveStatus(TaskAllocationStatusDto dto)
  1180. {
  1181. var _view = await _taskAllocationRep._TaskSetHaveStatus(dto.SubId);
  1182. if (_view.Code == 0)
  1183. {
  1184. //发送消息
  1185. var taskUserData = _taskAllocationRep._sqlSugar.Queryable<Pm_TaskRelevanceUser>().Where(it => it.Id == dto.SubId).First();
  1186. if (taskUserData != null)
  1187. {
  1188. var taskData = _taskAllocationRep._sqlSugar.Queryable<Pm_TaskAllocation>().Where(it => it.Id == taskUserData.TAId).First();
  1189. if (taskData != null)
  1190. {
  1191. var UserName = _taskAllocationRep._sqlSugar.Queryable<Sys_Users>().Where(it => it.Id == taskData.CreateUserId).Select(it => it.CnName).First();
  1192. string title = $"[{taskData.TaskName}] 进度更新!";
  1193. string conten_createUser = $"[{UserName}] 已知晓任务.若需查看,请前往任务页面查看详情!";
  1194. string qw_conten_createUser = $"[{UserName}] 已知晓任务!";
  1195. await GeneralMethod.MessageIssueAndNotification(MessageTypeEnum.TaskProgressUpdate, title, conten_createUser, new List<int>() { taskData.CreateUserId }); //创建人发送消息
  1196. await AppNoticeLibrary.SendUserMsg_Task_ToUser(new List<string>() { taskData.CreateUserId.ToString() }, taskData.DiId, qw_conten_createUser, taskData.CreateUserId);
  1197. string content = $"请注意任务完成时间!若需查看,请前往任务页面查看详情!";
  1198. string yw_content = $"请注意任务完成时间!";
  1199. await GeneralMethod.MessageIssueAndNotification(MessageTypeEnum.TaskProgressUpdate, title, content, new List<int>() { taskUserData.UserId }); //设置任务人 发送消息
  1200. await AppNoticeLibrary.SendUserMsg_Task_ToUser(new List<string>() { taskUserData.UserId.ToString() }, taskData.DiId, yw_content, taskUserData.UserId);
  1201. }
  1202. }
  1203. return Ok(JsonView(true, "操作成功!"));
  1204. }
  1205. return Ok(JsonView(false, _view.Msg));
  1206. }
  1207. /// <summary>
  1208. /// 任务分配
  1209. /// 任务发布者 单人设置审批状态
  1210. /// </summary>
  1211. /// <returns></returns>
  1212. [HttpPost]
  1213. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  1214. public async Task<IActionResult> PostTaskAllocationSetAuditStatus(TaskAllocationStatusDto dto)
  1215. {
  1216. var _view = await _taskAllocationRep._TaskSetAuditStatus(dto.SubId);
  1217. if (_view.Code == 0)
  1218. {
  1219. //发送消息
  1220. var taskUserData = _taskAllocationRep._sqlSugar.Queryable<Pm_TaskRelevanceUser>().Where(it => it.Id == dto.SubId).First();
  1221. if (taskUserData != null)
  1222. {
  1223. var taskData = _taskAllocationRep._sqlSugar.Queryable<Pm_TaskAllocation>().Where(it => it.Id == taskUserData.TAId).First();
  1224. if (taskData != null)
  1225. {
  1226. string title = $"[{taskData.TaskName}] 进度更新!";
  1227. string content = $"任务已完成!若需查看,请前往任务页面查看详情!";
  1228. string yw_content = $"任务已完成!";
  1229. await GeneralMethod.MessageIssueAndNotification(MessageTypeEnum.TaskProgressUpdate, title, content, new List<int>() { taskUserData.UserId }); //设置任务人 发送消息
  1230. await AppNoticeLibrary.SendUserMsg_Task_ToUser(new List<string>() { taskUserData.UserId.ToString() }, taskData.DiId, yw_content, taskUserData.UserId);
  1231. }
  1232. }
  1233. return Ok(JsonView(true, "操作成功!"));
  1234. }
  1235. return Ok(JsonView(false, _view.Msg));
  1236. }
  1237. /// <summary>
  1238. /// 任务分配
  1239. /// 任务发布者 单人设置未完成状态
  1240. /// </summary>
  1241. /// <returns></returns>
  1242. [HttpPost]
  1243. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  1244. public async Task<IActionResult> PostTaskAllocationSetUnFinishedStatus(TaskAllocationSetUnFinishedStatusDto dto)
  1245. {
  1246. var _view = await _taskAllocationRep._TaskSetUnFinishedStatus(dto.SubId, dto.Cause);
  1247. if (_view.Code == 0)
  1248. {
  1249. //发送消息
  1250. var taskUserData = _taskAllocationRep._sqlSugar.Queryable<Pm_TaskRelevanceUser>().Where(it => it.Id == dto.SubId).First();
  1251. if (taskUserData != null)
  1252. {
  1253. var taskData = _taskAllocationRep._sqlSugar.Queryable<Pm_TaskAllocation>().Where(it => it.Id == taskUserData.TAId).First();
  1254. if (taskData != null)
  1255. {
  1256. string title = $"[{taskData.TaskName}] 进度更新!";
  1257. string content = $"任务未完成!若需查看,请前往任务页面查看详情!";
  1258. string yw_content = $"任务未完成!";
  1259. await GeneralMethod.MessageIssueAndNotification(MessageTypeEnum.TaskProgressUpdate, title, content, new List<int>() { taskUserData.UserId }); //设置任务人 发送消息
  1260. await AppNoticeLibrary.SendUserMsg_Task_ToUser(new List<string>() { taskUserData.UserId.ToString() }, taskData.DiId, yw_content, taskUserData.UserId);
  1261. }
  1262. }
  1263. return Ok(JsonView(true, "操作成功!"));
  1264. }
  1265. return Ok(JsonView(false, _view.Msg));
  1266. }
  1267. ///// <summary>
  1268. ///// 任务分配
  1269. ///// 确认任务是否可操作完成
  1270. ///// </summary>
  1271. ///// <returns></returns>
  1272. //[HttpPost]
  1273. //[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  1274. //public async Task<IActionResult> PostTaskAllocationIsConfirmCompletion(TaskAllocationScoreDto dto)
  1275. //{
  1276. // try
  1277. // {
  1278. // #region 参数验证
  1279. // if (dto.UserId < 1) return Ok(JsonView(false, "员工Id为空"));
  1280. // if (dto.PageId < 1) dto.PageId = 172; //任务指派Id
  1281. // PageFunAuthViewBase pageFunAuthView = new PageFunAuthViewBase();
  1282. // #region 页面操作权限验证
  1283. // pageFunAuthView = await GeneralMethod.PostUserPageFuncDatas(dto.UserId, dto.PageId);
  1284. // if (pageFunAuthView.EditAuth == 0) return Ok(JsonView(false, "您没有编辑权限!"));
  1285. // #endregion
  1286. // #endregion
  1287. // var _view = await _taskAllocationRep._TaskConfirmCompletion(dto.PortType, dto.Id);
  1288. // if (_view.Code == 0)
  1289. // {
  1290. // return Ok(JsonView(true, "操作成功!"));
  1291. // }
  1292. // return Ok(JsonView(false, _view.Msg));
  1293. // }
  1294. // catch (Exception ex)
  1295. // {
  1296. // return Ok(JsonView(false, ex.Message));
  1297. // }
  1298. //}
  1299. ///// <summary>
  1300. ///// 任务分配
  1301. ///// 任务确认完成
  1302. ///// </summary>
  1303. ///// <returns></returns>
  1304. //[HttpPost]
  1305. //[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  1306. //public async Task<IActionResult> PostTaskAllocationConfirmCompletion(TaskAllocationConfirmCompletionDto dto)
  1307. //{
  1308. // try
  1309. // {
  1310. // #region 参数验证
  1311. // if (dto.UserId < 1) return Ok(JsonView(false, "员工Id为空"));
  1312. // if (dto.PageId < 1) dto.PageId = 172; //任务指派Id
  1313. // PageFunAuthViewBase pageFunAuthView = new PageFunAuthViewBase();
  1314. // #region 页面操作权限验证
  1315. // pageFunAuthView = await GeneralMethod.PostUserPageFuncDatas(dto.UserId, dto.PageId);
  1316. // if (pageFunAuthView.EditAuth == 0) return Ok(JsonView(false, "您没有编辑权限!"));
  1317. // #endregion
  1318. // #endregion
  1319. // var _view = await _taskAllocationRep._TaskConfirmCompletion(dto.PortType,dto.Id);
  1320. // if (_view.Code == 0)
  1321. // {
  1322. // return Ok(JsonView(true, "操作成功!"));
  1323. // }
  1324. // return Ok(JsonView(false, _view.Msg));
  1325. // }
  1326. // catch (Exception ex)
  1327. // {
  1328. // return Ok(JsonView(false, ex.Message));
  1329. // }
  1330. //}
  1331. /// <summary>
  1332. /// 任务分配
  1333. /// 任务发布者 任务评分
  1334. /// </summary>
  1335. /// <returns></returns>
  1336. [HttpPost]
  1337. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  1338. public async Task<IActionResult> PostTaskAllocationScore(TaskAllocationScoreDto dto)
  1339. {
  1340. #region 参数验证
  1341. if (dto.UserId < 1) return Ok(JsonView(false, "员工Id为空"));
  1342. if (dto.PageId < 1) dto.PageId = 172; //任务指派Id
  1343. #region 页面操作权限验证
  1344. PageFunAuthViewBase pageFunAuthView = await GeneralMethod.PostUserPageFuncDatas(dto.UserId, dto.PageId);
  1345. if (pageFunAuthView.EditAuth == 0) return Ok(JsonView(false, "您没有编辑权限!"));
  1346. #endregion
  1347. #endregion
  1348. var _view = await _taskAllocationRep._TaskScore(dto);
  1349. if (_view.Code == 0)
  1350. {
  1351. //发送消息
  1352. var taskUserData = _taskAllocationRep._sqlSugar.Queryable<Pm_TaskRelevanceUser>().Where(it => it.Id == dto.SubId).First();
  1353. if (taskUserData != null)
  1354. {
  1355. var taskData = _taskAllocationRep._sqlSugar.Queryable<Pm_TaskAllocation>().Where(it => it.Id == taskUserData.TAId).First();
  1356. if (taskData != null)
  1357. {
  1358. string title = $"[{taskData.TaskName}] 进度更新!";
  1359. string content = $"任务评分已完成!若需查看,请前往任务页面查看详情!";
  1360. string yw_content = $"任务评分已完成!";
  1361. await GeneralMethod.MessageIssueAndNotification(MessageTypeEnum.TaskProgressUpdate, title, content, new List<int>() { taskUserData.UserId }); //设置任务人 发送消息
  1362. await AppNoticeLibrary.SendUserMsg_Task_ToUser(new List<string>() { taskUserData.UserId.ToString() }, taskData.DiId, yw_content, taskUserData.UserId);
  1363. }
  1364. }
  1365. return Ok(JsonView(true, "操作成功!"));
  1366. }
  1367. return Ok(JsonView(false, _view.Msg));
  1368. }
  1369. /// <summary>
  1370. /// 任务分配
  1371. /// 任务发布者 任务终止
  1372. /// </summary>
  1373. /// <returns></returns>
  1374. [HttpPost]
  1375. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  1376. public async Task<IActionResult> PostTaskAllocationTermination(TaskAllocationConfirmCompletionDto dto)
  1377. {
  1378. #region 参数验证
  1379. if (dto.UserId < 1) return Ok(JsonView(false, "员工Id为空"));
  1380. if (dto.PageId < 1) dto.PageId = 172; //任务指派Id
  1381. #region 页面操作权限验证
  1382. PageFunAuthViewBase pageFunAuthView = await GeneralMethod.PostUserPageFuncDatas(dto.UserId, dto.PageId);
  1383. if (pageFunAuthView.EditAuth == 0) return Ok(JsonView(false, "您没有编辑权限!"));
  1384. #endregion
  1385. #endregion
  1386. var _view = await _taskAllocationRep._TaskTermination(dto.Id);
  1387. if (_view.Code == 0)
  1388. {
  1389. //发送消息
  1390. var taskData = _taskAllocationRep._sqlSugar.Queryable<Pm_TaskAllocation>().Where(it => it.Id == dto.Id).First();
  1391. if (taskData != null)
  1392. {
  1393. var taskUserIds = _taskAllocationRep._sqlSugar.Queryable<Pm_TaskRelevanceUser>().Where(it => it.Id == dto.Id).Select(it => it.UserId).ToList();
  1394. taskUserIds.Add(taskData.CreateUserId);
  1395. string title = $"[{taskData.TaskName}] 进度更新!";
  1396. string content = $"任务已终止!若需查看,请前往任务页面查看详情!";
  1397. string yw_content = $"[{taskData.TaskName}]任务已终止!";
  1398. await GeneralMethod.MessageIssueAndNotification(MessageTypeEnum.TaskProgressUpdate, title, content, taskUserIds); //设置任务人 发送消息
  1399. await AppNoticeLibrary.SendUserMsg_Task_ToUser(taskUserIds.Select(x => x.ToString()).ToList(), taskData.DiId, yw_content, taskData.CreateUserId);
  1400. }
  1401. return Ok(JsonView(true, "操作成功!"));
  1402. }
  1403. return Ok(JsonView(false, _view.Msg));
  1404. }
  1405. /// <summary>
  1406. /// 任务分配
  1407. /// 任务发布者 任务删除
  1408. /// </summary>
  1409. /// <returns></returns>
  1410. [HttpPost]
  1411. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  1412. public async Task<IActionResult> PostTaskAllocationDel(TaskAllocationConfirmCompletionDto dto)
  1413. {
  1414. #region 参数验证
  1415. if (dto.UserId < 1) return Ok(JsonView(false, "员工Id为空"));
  1416. if (dto.PageId < 1) dto.PageId = 172; //任务指派Id
  1417. #region 页面操作权限验证
  1418. PageFunAuthViewBase pageFunAuthView = await GeneralMethod.PostUserPageFuncDatas(dto.UserId, dto.PageId);
  1419. if (pageFunAuthView.DeleteAuth == 0) return Ok(JsonView(false, "您没有删除权限!"));
  1420. #endregion
  1421. #endregion
  1422. var _view = await _taskAllocationRep._TaskDel(dto.Id);
  1423. if (_view.Code == 0)
  1424. {
  1425. return Ok(JsonView(true, "操作成功!"));
  1426. }
  1427. return Ok(JsonView(false, _view.Msg));
  1428. }
  1429. #endregion
  1430. #region 团组状态通知
  1431. ///// <summary>
  1432. ///// 测试
  1433. ///// </summary>
  1434. ///// <param name="dto"></param>
  1435. ///// <returns></returns>
  1436. //[HttpPost]
  1437. //[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  1438. //public async Task<IActionResult> Test_QIYEWX(PostTourClientListDownloadFile dto)
  1439. //{
  1440. // //List<string> templist = new List<string>() { 234.ToString() };
  1441. // //await AppNoticeLibrary.SendUserMsg_GroupStatus_AuditFee(14090, templist, QiyeWeChatEnum.TestChat);
  1442. // //await AppNoticeLibrary.SendUserMsg_GroupShare_ToJob(dto.DiId); ;
  1443. // //DeleReminderMessage.PostMessageByWebhook();
  1444. // //GroupStatus_UserSimplelistView list = await _qiYeWeChatApiService.GroupStatus_GetUserList();
  1445. // //创建群聊
  1446. // //List<string> userList1 = new List<string>() { "Feint", "amy.zhu@pan-american-intl.com", "judy.zeng@pan-american-intl.com", "FuHongJin" };
  1447. // //List<string> userList2 = new List<string>() { "Feint", "ZhaoYaQi", "LiaoWenYa" };
  1448. // //List<string> userList3 = new List<string>() { "Feint", "amy.zhu@pan-american-intl.com", "judy.zeng@pan-american-intl.com", "FuHongJin", "ZhaoYaQi", "LiaoWenYa" };
  1449. // //GroupStatus_CreateChatView rst1 = await _qiYeWeChatApiService.GroupStatus_CreateChat("团组通知", "Feint", userList1, "CaiWuChat01");
  1450. // //GroupStatus_CreateChatView rst2 = await _qiYeWeChatApiService.GroupStatus_CreateChat("OA通知-国交部", "Feint", userList2, "GuoJiaoLeader01");
  1451. // //GroupStatus_CreateChatView rst3 = await _qiYeWeChatApiService.GroupStatus_CreateChat("OA通知-团组(公司客户)", "Feint", userList3, "CompanyCRMChat01");
  1452. // //推送消息(模板)
  1453. // //List<string> userList = new List<string>() { "Feint", "huaju.liu", "johnny.yang@pan-american-intl.com" };
  1454. // //List<string> userList = new List<string>() { "Feint", "johnny.yang@pan-american-intl.com" };
  1455. // //GroupStatus_CreateChatView rst1 = await _qiYeWeChatApiService.GroupStatus_CreateChat("团组费用提示", "Feint", userList, "GuoJiaoChat01");
  1456. // //团组出发
  1457. // //AppNoticeLibrary.SendUserMsg_GroupStatus_Create(2358, userList);
  1458. // //费用审核
  1459. // //AppNoticeLibrary.SendChatMsg_GroupStatus_ApplyFee(dto.DiId, QiyeWeChatEnum.TestChat);
  1460. // //费用审核结果通知(通过情况下发送财务群)
  1461. // //List<string> userList = new List<string>() { "234" };
  1462. // //AppNoticeLibrary.SendUserMsg_GroupStatus_AuditFee(dto.DiId, userList, QiyeWeChatEnum.CaiWuChat02);
  1463. // //4、财务付款时:(1)对应版块人员【单独发,状态为已付款才发】
  1464. // //AppNoticeLibrary.SendUserMsg_GroupStatus_PayResult(dto.DiId, userList);
  1465. // //团组提醒财务群
  1466. // //DateTime dtNow = DateTime.Now;
  1467. // //List<Grp_DelegationInfo> listSource = _usersRep.Query<Grp_DelegationInfo>(s => s.IsDel == 0 && s.VisitStartDate >= dtNow).Take(3).ToList();
  1468. // //List<Grp_DelegationInfo> listAdd7day = _usersRep.Query<Grp_DelegationInfo>(s => s.IsDel == 0 && s.VisitStartDate >= dtNow).Take(3).ToList();
  1469. // //List<Grp_DelegationInfo> listAdd3day = new List<Grp_DelegationInfo>() { };
  1470. // //AppNoticeLibrary.SendChatMsg_GroupRemindersToCaiwu(listAdd7day, listAdd3day, QiyeWeChatEnum.TestChat);
  1471. // //日付申请提醒财务群
  1472. // //AppNoticeLibrary.DailyPayReminders_Create_ToCaiwuChat(dto.DiId, QiyeWeChatEnum.CaiWuChat02);
  1473. // //日付申请结果推送用户、成功通知财务群
  1474. // //AppNoticeLibrary.DailyPayReminder_Audit_ToUser(dto.DiId, userList, QiyeWeChatEnum.TestChat);
  1475. // //AppNoticeLibrary.DailyPayReminder_Pay_ToUser(dto.DiId, userList);
  1476. // //string q = "";
  1477. // DeleReminderMessage.PostMessageByWebhook_CRMStatistics();
  1478. // return Ok(JsonView(true, "操作成功!"));
  1479. //}
  1480. #endregion
  1481. #region 物资进销存
  1482. /// <summary>
  1483. /// 物资进销存
  1484. /// 基础数据类型
  1485. /// </summary>
  1486. /// <returns></returns>
  1487. [HttpGet]
  1488. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  1489. public async Task<IActionResult> GoodsInitDataSource()
  1490. {
  1491. return Ok(await _goodsRep.InitDataSource());
  1492. }
  1493. /// <summary>
  1494. /// 物资进销存
  1495. /// 基础数据类型 --> 团组名称列表 分页
  1496. /// </summary>
  1497. /// <returns></returns>
  1498. [HttpPost]
  1499. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  1500. public async Task<IActionResult> GoodsGroupNameInit(QueryGroupListOffsetDto dto)
  1501. {
  1502. var watch = new Stopwatch();
  1503. watch.Start();
  1504. var countyDatas = await _sqlSugar
  1505. .Queryable<Grp_DelegationInfo>()
  1506. .Where((di) => di.IsDel == 0 && !string.IsNullOrWhiteSpace(di.TeamName))
  1507. .OrderBy((di) => new { id = SqlFunc.Desc(di.Id) })
  1508. .Select((di) => new { id = di.Id, name = di.TeamName })
  1509. .ToListAsync();
  1510. countyDatas.Insert(0, new { id = 0, name = "其他物资(公司内部物资)" });
  1511. countyDatas.Insert(0, new { id = -1, name = "拜访客户所使用的物资" });
  1512. countyDatas.Insert(0, new { id = -2, name = "库存调整" });
  1513. countyDatas.Insert(0, new { id = -3, name = "全部团组" });
  1514. var total = countyDatas.Count;
  1515. countyDatas = countyDatas.WhereIF(!string.IsNullOrEmpty(dto.Search), x => x.name.Contains(dto.Search)).ToList();
  1516. countyDatas = countyDatas
  1517. .Skip((dto.PageIndex - 1) * dto.PageSize)
  1518. .Take(dto.PageSize)
  1519. .ToList();
  1520. watch.Stop();
  1521. return Ok(JsonView(true, $"{MsgTips.Succeed},耗时 {watch.ElapsedMilliseconds} ms", countyDatas, total));
  1522. }
  1523. /// <summary>
  1524. /// 物资进销存
  1525. /// 物品 列表
  1526. /// </summary>
  1527. /// <returns></returns>
  1528. [HttpPost]
  1529. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  1530. public async Task<IActionResult> GoodsList(GoodsListDto dto)
  1531. {
  1532. if (dto.PortType < 1 || dto.PortType > 3) return Ok(JsonView(false, MsgTips.Port));
  1533. if (dto.PageIndex < 1 || dto.PageSize < 1) return Ok(JsonView(false, MsgTips.PageIndex));
  1534. return Ok(await _goodsRep.GoodsList(dto));
  1535. }
  1536. /// <summary>
  1537. /// 物资进销存
  1538. /// 物品 详情
  1539. /// </summary>
  1540. /// <returns></returns>
  1541. [HttpGet()]
  1542. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  1543. public async Task<IActionResult> GoodsInfo(int portType, int id)
  1544. {
  1545. if (portType < 1 || portType > 3) return Ok(JsonView(false, MsgTips.Port));
  1546. if (id < 1) return Ok(JsonView(false, MsgTips.Id));
  1547. return Ok(await _goodsRep.GoodsInfo(portType, id));
  1548. }
  1549. /// <summary>
  1550. /// 物资进销存
  1551. /// 物品 OP(Add OR Edit)
  1552. /// </summary>
  1553. /// <returns></returns>
  1554. [HttpPost]
  1555. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  1556. public async Task<IActionResult> GoodsOP(GoodsOpDto dto)
  1557. {
  1558. var currUserInfo = JwtHelper.SerializeJwt(HttpContext.Request.Headers.Authorization);
  1559. if (currUserInfo == null) return Ok(JsonView(false, "请传入token!"));
  1560. var validator = new GoodsOPDTOValidator();
  1561. var validatorRes = await validator.ValidateAsync(dto);
  1562. if (!validatorRes.IsValid)
  1563. {
  1564. var sb = new StringBuilder();
  1565. foreach (var error in validatorRes.Errors) sb.AppendLine(error.ErrorMessage);
  1566. return Ok(JsonView(false, sb.ToString()));
  1567. }
  1568. return Ok(await _goodsRep.GoodsOp(dto, currUserInfo.UserId));
  1569. }
  1570. /// <summary>
  1571. /// 物资进销存
  1572. /// 物品 Del
  1573. /// </summary>
  1574. /// <returns></returns>
  1575. [HttpDelete("{id}")]
  1576. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  1577. public async Task<IActionResult> GoodsDel(int id)
  1578. {
  1579. if (id < 1) return Ok(JsonView(false, MsgTips.Id));
  1580. var currUserInfo = JwtHelper.SerializeJwt(HttpContext.Request.Headers.Authorization);
  1581. if (currUserInfo == null) return Ok(JsonView(false, "请传入token!"));
  1582. return Ok(await _goodsRep.GoodsDel(id, currUserInfo.UserId));
  1583. }
  1584. /// <summary>
  1585. /// 物资进销存(审核,需传token)
  1586. /// 入库 列表
  1587. /// </summary>
  1588. /// <returns></returns>
  1589. [HttpPost]
  1590. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  1591. public async Task<IActionResult> GoodsStorageList(GoodsStorageListDto dto)
  1592. {
  1593. //var currUserInfo = JwtHelper.SerializeJwt(HttpContext.Request.Headers.Authorization);
  1594. //if (currUserInfo == null) return Ok(JsonView(false, "请传入token!"));
  1595. if (dto.PortType < 1 || dto.PortType > 3) return Ok(JsonView(false, MsgTips.Port));
  1596. if (dto.PageIndex < 1 || dto.PageSize < 1) return Ok(JsonView(false, MsgTips.PageIndex));
  1597. return Ok(await _goodsRep.GoodsStorageList(dto));
  1598. //return Ok(await _goodsRep.GoodsStorageList(dto, 0));
  1599. }
  1600. /// <summary>
  1601. /// 物资进销存
  1602. /// 入库 详情
  1603. /// </summary>
  1604. /// <returns></returns>
  1605. [HttpGet("{id}")]
  1606. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  1607. public async Task<IActionResult> GoodsStorageInfo([FromQuery] int portType, int id)
  1608. {
  1609. if (portType < 1 || portType > 3) return Ok(JsonView(false, MsgTips.Port));
  1610. if (id < 1) return Ok(JsonView(false, MsgTips.Id));
  1611. return Ok(await _goodsRep.GoodsStorageInfo(portType, id));
  1612. }
  1613. /// <summary>
  1614. /// 物资进销存
  1615. /// 入库 OP(Add OR Edit)
  1616. /// </summary>
  1617. /// <returns></returns>
  1618. [HttpPost]
  1619. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  1620. public async Task<IActionResult> GoodsStorageOp(GoodsStorageOpDto dto)
  1621. {
  1622. var currUserInfo = JwtHelper.SerializeJwt(HttpContext.Request.Headers.Authorization);
  1623. if (currUserInfo == null) return Ok(JsonView(false, "请传入token!"));
  1624. var validator = new GoodsStorageOpDtoValidator();
  1625. var validatorRes = await validator.ValidateAsync(dto);
  1626. if (!validatorRes.IsValid)
  1627. {
  1628. var sb = new StringBuilder();
  1629. foreach (var error in validatorRes.Errors) sb.AppendLine(error.ErrorMessage);
  1630. return Ok(JsonView(false, sb.ToString()));
  1631. }
  1632. return Ok(await _goodsRep.GoodsStorageOp(dto, currUserInfo.UserId));
  1633. }
  1634. /// <summary>
  1635. /// 物资进销存
  1636. /// 入库确认状态变更
  1637. /// </summary>
  1638. /// <returns></returns>
  1639. [HttpPost]
  1640. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  1641. public async Task<IActionResult> GoodsStorageConfirmStatusChange(GoodsStorageConfirmDto dto)
  1642. {
  1643. if (dto.Id < 1) return Ok(JsonView(false, MsgTips.Id));
  1644. if (!Enum.IsDefined(typeof(GoodsAuditDepEnum), (int)dto.AuditDep))
  1645. {
  1646. return Ok(JsonView(false, $"审核部门类型超出可用范围!"));
  1647. }
  1648. if (!Enum.IsDefined(typeof(GoodsConfirmEnum), (int)dto.ConfirmStatus))
  1649. {
  1650. return Ok(JsonView(false, $"入库审核状态超出可用范围!"));
  1651. }
  1652. if (dto.ConfirmStatus == GoodsConfirmEnum.WaitConfirm || dto.ConfirmStatus == GoodsConfirmEnum.PartConfirmed)
  1653. {
  1654. return Ok(JsonView(false, $"入库审核状态(待确认、部分确认)不可用!"));
  1655. }
  1656. var currUserInfo = JwtHelper.SerializeJwt(HttpContext.Request.Headers.Authorization);
  1657. if (currUserInfo == null) return Ok(JsonView(false, "请传入token!"));
  1658. return Ok(await _goodsRep.GoodsStorageConfirmStatusChange(dto, currUserInfo.UserId));
  1659. }
  1660. /// <summary>
  1661. /// 物资进销存
  1662. /// 入库 Del
  1663. /// </summary>
  1664. /// <returns></returns>
  1665. [HttpDelete("{id}")]
  1666. //[Authorize]
  1667. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  1668. public async Task<IActionResult> GoodsStorageDel(int id)
  1669. {
  1670. var currUserInfo = JwtHelper.SerializeJwt(HttpContext.Request.Headers.Authorization);
  1671. if (currUserInfo == null) return Ok(JsonView(false, "请传入token!"));
  1672. if (id < 1) return Ok(JsonView(false, MsgTips.Id));
  1673. return Ok(await _goodsRep.GoodsStorageDel(id, currUserInfo.UserId));
  1674. }
  1675. /// <summary>
  1676. /// 物资进销存
  1677. /// 入库 excelDownload
  1678. /// </summary>
  1679. /// <returns></returns>
  1680. [HttpPost]
  1681. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  1682. public async Task<IActionResult> GoodsStorageExcelDownload()
  1683. {
  1684. //token验证
  1685. var currUserInfo = JwtHelper.SerializeJwt(HttpContext.Request.Headers.Authorization);
  1686. if (currUserInfo == null) return Ok(JsonView(false, "请传入token!"));
  1687. //文件下载权限验证
  1688. int userId = currUserInfo.UserId,
  1689. pageId = 191;
  1690. #region 页面操作权限验证
  1691. PageFunAuthViewBase pageFunAuthView = await GeneralMethod.PostUserPageFuncDatas(userId, pageId);
  1692. if (pageFunAuthView.FilesDownloadAuth == 0) return Ok(JsonView(false, "您未分配文件下载权限!"));
  1693. #endregion
  1694. return Ok(await _goodsRep.GoodsStorageExcelDownload());
  1695. }
  1696. /// <summary>
  1697. /// 物资进销存
  1698. /// 领用记录 List
  1699. /// </summary>
  1700. /// <returns></returns>
  1701. [HttpPost]
  1702. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  1703. public async Task<IActionResult> GoodsReceiveList(GoodsReceiveListDTO dto)
  1704. {
  1705. //token验证
  1706. var currUserInfo = JwtHelper.SerializeJwt(HttpContext.Request.Headers.Authorization);
  1707. if (currUserInfo == null) return Ok(JsonView(false, "请传入token!"));
  1708. if (dto.PortType < 1 || dto.PortType > 3) return Ok(JsonView(false, MsgTips.Port));
  1709. if (dto.PageIndex < 1 || dto.PageSize < 1) return Ok(JsonView(false, MsgTips.PageIndex));
  1710. //文件下载权限验证
  1711. int userId = currUserInfo.UserId,
  1712. pageId = 191;
  1713. if (dto.IsExcelDownload)
  1714. {
  1715. if (userId < 1) return Ok(JsonView(false, "excel导出时,需传入正确的当前操作人UserId!"));
  1716. ;
  1717. #region 页面操作权限验证
  1718. PageFunAuthViewBase pageFunAuthView = await GeneralMethod.PostUserPageFuncDatas(userId, pageId);
  1719. if (pageFunAuthView.FilesDownloadAuth == 0) return Ok(JsonView(false, "您未分配文件下载权限!"));
  1720. #endregion
  1721. }
  1722. dto.CurrUserId = currUserInfo.UserId;
  1723. return Ok(await _goodsRep.GoodsReceiveList(dto));
  1724. }
  1725. /// <summary>
  1726. /// 物资进销存
  1727. /// 领用 审核 List
  1728. /// </summary>
  1729. /// <returns></returns>
  1730. [HttpPost]
  1731. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  1732. public async Task<IActionResult> GoodsReceiveAuditList(GoodsReceiveAuditListDTO dto)
  1733. {
  1734. //token验证
  1735. var currUserInfo = JwtHelper.SerializeJwt(HttpContext.Request.Headers.Authorization);
  1736. if (currUserInfo == null) return Ok(JsonView(false, "请传入token!"));
  1737. if (dto.PortType < 1 || dto.PortType > 3) return Ok(JsonView(false, MsgTips.Port));
  1738. if (dto.PageIndex < 1 || dto.PageSize < 1) return Ok(JsonView(false, MsgTips.PageIndex));
  1739. dto.CurrUserId = currUserInfo.UserId;
  1740. return Ok(await _goodsRep.GoodsReceiveAuditList(dto));
  1741. }
  1742. /// <summary>
  1743. /// 物资进销存
  1744. /// 领用详情
  1745. /// </summary>
  1746. /// <returns></returns>
  1747. [HttpGet("{id}")]
  1748. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  1749. public async Task<IActionResult> GoodsReceiveInfo([FromQuery] int portType, int id)
  1750. {
  1751. if (portType < 1 || portType > 3) return Ok(JsonView(false, MsgTips.Port));
  1752. if (id < 1) return Ok(JsonView(false, MsgTips.Id));
  1753. return Ok(await _goodsRep.GoodsReceiveInfo(portType, id));
  1754. }
  1755. /// <summary>
  1756. /// 物资进销存
  1757. /// 领用 OP
  1758. /// </summary>
  1759. /// <returns></returns>
  1760. [HttpPost]
  1761. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  1762. public async Task<IActionResult> GoodsReceiveOP(GoodsReceiveOpDto dto)
  1763. {
  1764. var currUserInfo = JwtHelper.SerializeJwt(HttpContext.Request.Headers.Authorization);
  1765. if (currUserInfo == null) return Ok(JsonView(false, "请传入token!"));
  1766. var validator = new GoodsReceiveOpDtoValidator();
  1767. var validatorRes = await validator.ValidateAsync(dto);
  1768. if (!validatorRes.IsValid)
  1769. {
  1770. var sb = new StringBuilder();
  1771. foreach (var error in validatorRes.Errors) sb.AppendLine(error.ErrorMessage);
  1772. return Ok(JsonView(false, sb.ToString()));
  1773. }
  1774. //Return Ok(await _goodsRep.GoodsReceiveOp(dto, currUserInfo.UserId));
  1775. //TODO:调试完成后 单个领用使用批量领用方法
  1776. var receiveDetails = new GoodsReceiveDetailsView[] {
  1777. new () {
  1778. Id = 0,
  1779. GoodsId = dto.GoodsId,
  1780. Quantity = dto.Quantity,
  1781. Remark = dto.Remark
  1782. }
  1783. };
  1784. var newDto = new GoodsReceiveBatchOpDto()
  1785. {
  1786. Id = dto.Id,
  1787. GroupId = dto.GroupId,
  1788. ReceiveDetails = receiveDetails,
  1789. Reason = dto.Reason,
  1790. Remark = dto.Remark,
  1791. IsReplace = dto.IsReplace,
  1792. CurrUserId = currUserInfo.UserId,
  1793. };
  1794. var res = await _goodsRep.GoodsReceiveBatchOpAsync(newDto);
  1795. //企业微信消息通知
  1796. if (res.Code == StatusCodes.Status200OK && dto.Id < 1)
  1797. {
  1798. var signProperty = res.Data?.GetType().GetProperty("sign");
  1799. int sign = signProperty != null && signProperty.GetValue(res.Data, null) is int value ? value : 0;
  1800. //物资领用通知
  1801. await AppNoticeLibrary.SendUserMsg_CompanyShare_ToHR(sign, dto.GroupId, currUserInfo.UserId);
  1802. }
  1803. return Ok(res);
  1804. }
  1805. /// <summary>
  1806. /// 物资进销存
  1807. /// 领用 审核
  1808. /// </summary>
  1809. /// <param name="dto"></param>
  1810. /// <returns></returns>
  1811. [HttpPost]
  1812. [ApiExplorerSettings(IgnoreApi = true)]
  1813. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  1814. public async Task<IActionResult> GoodsReceiveAudit(GoodsReceiveAuditDTO dto)
  1815. {
  1816. var currUserInfo = JwtHelper.SerializeJwt(HttpContext.Request.Headers.Authorization);
  1817. if (currUserInfo == null) return Ok(JsonView(false, "请传入token!"));
  1818. var validator = new GoodsReceiveAuditDTOValidator();
  1819. var validatorRes = await validator.ValidateAsync(dto);
  1820. if (!validatorRes.IsValid)
  1821. {
  1822. var sb = new StringBuilder();
  1823. foreach (var error in validatorRes.Errors) sb.AppendLine(error.ErrorMessage);
  1824. return Ok(JsonView(false, sb.ToString()));
  1825. }
  1826. int[] idArray = dto.Label
  1827. .Split(',')
  1828. .Select(x =>
  1829. {
  1830. if (int.TryParse(x, out var id)) return id;
  1831. return id;
  1832. })
  1833. .ToArray();
  1834. var view = await _goodsRep.GoodsReceiveAudit(idArray, currUserInfo.UserId, dto.AuditEnum);
  1835. //var view = new JsonView() { Code = StatusCodes.Status200OK};
  1836. //TODO:出库成功 并且是团组相关物资 向团组其他款项添加信息
  1837. #region 出库成功 && 不需要归还的物资(IsReplace == false) && 团组相关物资 向团组其他款项添加信息
  1838. if (view.Code != StatusCodes.Status200OK) return Ok(view);
  1839. if (idArray.Length < 1) return Ok(view);
  1840. int receiveId = idArray[0];
  1841. var receiveInfo = await _sqlSugar.Queryable<Pm_GoodsReceive>().FirstAsync(x => x.IsDel == 0 && x.Id == receiveId);
  1842. if (receiveInfo == null) return Ok(view);
  1843. if (receiveInfo.IsReplace)
  1844. {
  1845. view.Msg += $"\r\n 需要归还的物资不向团组其他款项添加信息!";
  1846. return Ok(view);
  1847. }
  1848. var auditEnums = new List<GoodsAuditEnum>() { GoodsAuditEnum.OutConfirmed, GoodsAuditEnum.OutRejected };
  1849. if (!auditEnums.Contains(receiveInfo.AuditStatus)) return Ok(view);
  1850. var groupInfo = await _sqlSugar.Queryable<Grp_DelegationInfo>().FirstAsync(x => x.IsDel == 0 && x.Id == receiveInfo.GroupId);
  1851. if (groupInfo == null) return Ok(view);
  1852. var basicData = await _sqlSugar.Queryable<Sys_SetData>().Where(x => x.IsDel == 0 && x.STid == 91).ToListAsync();
  1853. var goodsInfo = await _sqlSugar.Queryable<Pm_GoodsInfo>().FirstAsync(x => x.IsDel == 0 && x.Id == receiveInfo.GoodsId);
  1854. if (goodsInfo == null) return Ok(view);
  1855. var basicInfo = basicData.FirstOrDefault(x => x.Name.Equals(goodsInfo.Name));
  1856. if (basicInfo == null) return Ok(view);
  1857. string priceName = basicInfo.Name;
  1858. _ = decimal.TryParse(basicInfo.Remark, out decimal price);
  1859. decimal total = price * receiveInfo.Quantity;
  1860. var requestData = new DecreasePaymentsOpDto()
  1861. {
  1862. Status = 1,
  1863. DiId = groupInfo.Id,
  1864. PriceName = priceName,
  1865. Price = price,
  1866. Quantity = receiveInfo.Quantity,
  1867. FeeTotal = total,
  1868. Currency = 836,
  1869. FilePath = "",
  1870. OrbitalPrivateTransfer = 0,
  1871. OTAOrderNo = "-",
  1872. OtherBankName = "-",
  1873. OtherSideName = "-",
  1874. OtherSideNo = "-",
  1875. PayDId = 105,
  1876. SupplierAddress = "-",
  1877. SupplierArea = 1,
  1878. SupplierContact = "-",
  1879. SupplierContactNumber = "-",
  1880. SupplierEmail = "-",
  1881. SupplierName = "-",
  1882. SupplierSocialAccount = "-",
  1883. SupplierTypeId = 0,
  1884. CreateUserId = receiveInfo.CreateUserId,
  1885. Remark = $"物资领用模块添加!!"
  1886. };
  1887. //其他费用
  1888. #region 调用方法
  1889. JsonView groupData = await _otherPaymentRep.OpDecreasePayments(requestData);
  1890. if (groupData.Code != 200)
  1891. {
  1892. view.Msg += groupData.Msg;
  1893. return Ok(view);
  1894. }
  1895. #region 应用推送
  1896. int diId = requestData.DiId, status = requestData.Status;
  1897. int otherId = Convert.ToInt32(groupData.Data.GetType().GetProperty("dataId").GetValue(groupData.Data, null) ?? 0);
  1898. int ccpId = Convert.ToInt32(groupData.Data.GetType().GetProperty("ccpId").GetValue(groupData.Data, null) ?? 0);
  1899. int sign = Convert.ToInt32(groupData.Data.GetType().GetProperty("sign").GetValue(groupData.Data, null) ?? 0);
  1900. //自动审核
  1901. var autoAdit = await _feeAuditRep.FeeAutomaticAudit(3, diId, otherId);
  1902. await AppNoticeLibrary.SendChatMsg_GroupStatus_ApplyFee(ccpId, sign, QiyeWeChatEnum.GuoJiaoLeaderChat);
  1903. //2024-10-21 新增LZ UID
  1904. var userIds = new List<int>() { 208 };
  1905. //var userIds = new List<int>() { 21 };
  1906. string title = $"系统通知";
  1907. string content = "";
  1908. var ccpInfo = await _sqlSugar.Queryable<Grp_CreditCardPayment>().Where(x => x.Id == ccpId).FirstAsync();
  1909. if (status == 1) content = $"[新增-其他款项({groupInfo?.TeamName ?? "-"})]一项费用:{ccpInfo.PayMoney * ccpInfo.DayRate:#0.00} CNY;";
  1910. else if (status == 2) content = $"[更新-其他款项({groupInfo?.TeamName ?? "-"})]一项费用:{ccpInfo.PayMoney * ccpInfo.DayRate:#0.00} CNY;";
  1911. await GeneralMethod.MessageIssueAndNotification(MessageTypeEnum.GroupBusinessOperations, title, content, userIds, diId);
  1912. //await APNsTools.iOS_PushNotifications1("051", $"其他款项费用审核", "", content);
  1913. #endregion
  1914. #endregion
  1915. #endregion
  1916. return Ok(view);
  1917. }
  1918. /// <summary>
  1919. /// 物资进销存
  1920. /// 领用 List(含批量)
  1921. /// </summary>
  1922. /// <returns></returns>
  1923. [HttpPost]
  1924. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  1925. public async Task<IActionResult> GoodsReceiveBatchList(GoodsReceiveBatchListDto dto)
  1926. {
  1927. var currUserId = dto.CurrUserId;
  1928. var userInfo = await _sqlSugar.Queryable<Sys_Users>().FirstAsync(x => x.IsDel == 0 && x.Id == currUserId);
  1929. if (userInfo == null)
  1930. {
  1931. var currUserInfo = JwtHelper.SerializeJwt(HttpContext.Request.Headers.Authorization);
  1932. if (currUserInfo == null) return Ok(JsonView(false, "请传入token!"));
  1933. dto.CurrUserId = currUserInfo.UserId;
  1934. }
  1935. return Ok(await _goodsRep.GoodsReceiveBatchListAsync(dto));
  1936. }
  1937. /// <summary>
  1938. /// 物资进销存
  1939. /// 领用 OP 批量领用
  1940. /// </summary>
  1941. /// <returns></returns>
  1942. [HttpPost]
  1943. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  1944. public async Task<IActionResult> GoodsReceiveBatchOp(GoodsReceiveBatchOpDto dto)
  1945. {
  1946. var currUserId = dto.CurrUserId;
  1947. var userInfo = await _sqlSugar.Queryable<Sys_Users>().FirstAsync(x => x.IsDel == 0 && x.Id == currUserId);
  1948. if (userInfo == null)
  1949. {
  1950. var currUserInfo = JwtHelper.SerializeJwt(HttpContext.Request.Headers.Authorization);
  1951. if (currUserInfo == null) return Ok(JsonView(false, "请传入token!"));
  1952. dto.CurrUserId = currUserInfo.UserId;
  1953. }
  1954. //参数验证
  1955. if (!dto.ReceiveDetails.Any()) Ok(JsonView(false, "请传入领用明细!"));
  1956. int index = 1;
  1957. foreach (var item in dto.ReceiveDetails)
  1958. {
  1959. //物品验证
  1960. if (item.GoodsId < 1) return Ok(JsonView(false, $"第{index}项物品无效!"));
  1961. //数量验证
  1962. if (item.Quantity <= 0.00M) return Ok(JsonView(false, $"第{index}项物品的数量无效!"));
  1963. index++;
  1964. }
  1965. var res = await _goodsRep.GoodsReceiveBatchOpAsync(dto);
  1966. //企业微信消息通知
  1967. if (res.Code == StatusCodes.Status200OK && dto.Id < 1)
  1968. {
  1969. var signProperty = res.Data?.GetType().GetProperty("sign");
  1970. int sign = signProperty != null && signProperty.GetValue(res.Data, null) is int value ? value : 0;
  1971. //物资领用通知
  1972. await AppNoticeLibrary.SendUserMsg_CompanyShare_ToHR(sign, dto.GroupId, dto.CurrUserId);
  1973. }
  1974. return Ok(res);
  1975. }
  1976. /// <summary>
  1977. /// 物资进销存
  1978. /// 领用 详情(含批量)
  1979. /// </summary>
  1980. /// <param name="id">id</param>
  1981. /// <returns></returns>
  1982. [HttpGet("{id}")]
  1983. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  1984. public async Task<IActionResult> GoodsReceiveBatchInfo(int id)
  1985. {
  1986. return Ok(await _goodsRep.GoodsReceiveBatchInfoAsync(id));
  1987. }
  1988. /// <summary>
  1989. /// 物资进销存
  1990. /// 领用 审核 (含批量)
  1991. /// </summary>
  1992. /// <param name="dto"></param>
  1993. /// <returns></returns>
  1994. [HttpPost]
  1995. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  1996. public async Task<IActionResult> GoodsReceiveAuditNew(GoodsReceiveAuditDTO dto)
  1997. {
  1998. var currUserInfo = JwtHelper.SerializeJwt(HttpContext.Request.Headers.Authorization);
  1999. if (currUserInfo == null) return Ok(JsonView(false, "请传入token!"));
  2000. var validator = new GoodsReceiveAuditDTOValidator();
  2001. var validatorRes = await validator.ValidateAsync(dto);
  2002. if (!validatorRes.IsValid)
  2003. {
  2004. var sb = new StringBuilder();
  2005. foreach (var error in validatorRes.Errors) sb.AppendLine(error.ErrorMessage);
  2006. return Ok(JsonView(false, sb.ToString()));
  2007. }
  2008. int[] idArray = dto.Label
  2009. .Split(',')
  2010. .Select(x =>
  2011. {
  2012. if (int.TryParse(x, out var id)) return id;
  2013. return id;
  2014. })
  2015. .ToArray();
  2016. if (idArray.Length < 1) return Ok(JsonView(false, "请传入有效的领用ID"));
  2017. int receiveId = idArray[0];
  2018. var receiveInfo = await _sqlSugar.Queryable<Pm_GoodsReceive>().FirstAsync(x => x.IsDel == 0 && x.Id == receiveId);
  2019. if (receiveInfo == null) return Ok(JsonView(false, "请传入有效的领用ID"));
  2020. var view = new JsonView();
  2021. if (dto.AuditEnum == GoodsAuditEnum.Approved) //审核通过
  2022. {
  2023. view = await _goodsRep.GoodsReceiveApproveAsync(receiveId, currUserInfo.UserId);
  2024. }
  2025. else if (dto.AuditEnum == GoodsAuditEnum.UnApproved) //审核拒绝
  2026. {
  2027. view = await _goodsRep.GoodsReceiveRejectAsync(receiveId, currUserInfo.UserId);
  2028. }
  2029. if (view.Code != StatusCodes.Status200OK) return Ok(view);
  2030. receiveInfo = await _sqlSugar.Queryable<Pm_GoodsReceive>().FirstAsync(x => x.IsDel == 0 && x.Id == receiveId);
  2031. var auditEnums = new List<GoodsAuditEnum>() { GoodsAuditEnum.OutConfirmed, GoodsAuditEnum.OutRejected };
  2032. if (receiveInfo.AuditStatus == GoodsAuditEnum.OutConfirming)
  2033. {
  2034. //物资领用通知
  2035. await AppNoticeLibrary.SendUserMsg_CompanyShare_ToHR(receiveId, receiveInfo.GroupId, receiveInfo.CreateUserId);
  2036. }
  2037. #region 出库成功 && 不需要归还的物资(IsReplace == false) && 团组相关物资 向团组其他款项添加信息
  2038. //if (!auditEnums.Contains(receiveInfo.AuditStatus)) return Ok(view);
  2039. if (receiveInfo.IsReplace)
  2040. {
  2041. view.Msg += $"\r\n 需要归还的物资不向团组其他款项添加信息!";
  2042. return Ok(view);
  2043. }
  2044. var groupInfo = await _sqlSugar.Queryable<Grp_DelegationInfo>().FirstAsync(x => x.IsDel == 0 && x.Id == receiveInfo.GroupId);
  2045. if (groupInfo == null) return Ok(view);
  2046. var basicData = await _sqlSugar.Queryable<Sys_SetData>().Where(x => x.IsDel == 0 && x.STid == 91).ToListAsync();
  2047. var receiveDetails = await _sqlSugar.Queryable<Pm_GoodsReceiveDetails>()
  2048. .Where(x => x.IsDel == 0 && x.GoodsReceiveId == receiveInfo.Id)
  2049. .ToListAsync();
  2050. if (!receiveDetails.Any()) return Ok(view);
  2051. var goodsIds = receiveDetails.Select(y => y.GoodsId).ToList();
  2052. var goodsInfos = await _sqlSugar.Queryable<Pm_GoodsInfo>()
  2053. .Where(x => x.IsDel == 0 && goodsIds.Contains(x.Id))
  2054. .ToListAsync();
  2055. if (!goodsInfos.Any()) return Ok(view);
  2056. string priceName = string.Join("、", goodsInfos.Select(x => x.Name).ToList());
  2057. //物品价格 按照物品批次单价计算
  2058. var goodsPriceDetails = new StringBuilder();
  2059. decimal price = 0.00M; //物品累计价格
  2060. var goodsStorages = await _sqlSugar.Queryable<Pm_GoodsStorage>().Where(x => x.IsDel == 0 && goodsIds.Contains(x.GoodsId)).ToListAsync();
  2061. foreach (var item in receiveDetails)
  2062. {
  2063. List<GoodsReceiveLinkStorageView> storageFlows = new();
  2064. if (!string.IsNullOrEmpty(item.GoodsStorageInfo))
  2065. {
  2066. storageFlows = JsonConvert.DeserializeObject<List<GoodsReceiveLinkStorageView>>(item.GoodsStorageInfo);
  2067. }
  2068. if (storageFlows.Any())
  2069. {
  2070. storageFlows.ForEach(storage =>
  2071. {
  2072. price += goodsStorages.FirstOrDefault(x => x.Id == storage.StorageId)?.UnitPrice ?? 0m * storage.Quantity;
  2073. });
  2074. }
  2075. }
  2076. decimal quantity = 1m;
  2077. var total = price * quantity;
  2078. string remark = $"物资领用模块添加!需核对领用物品价格!!!";
  2079. if (!string.IsNullOrEmpty(receiveInfo.Remark)) remark = $"{receiveInfo.Remark}\n物资领用模块添加!需核对领用物品价格!!!";
  2080. var requestData = new DecreasePaymentsOpDto()
  2081. {
  2082. Status = 1,
  2083. DiId = groupInfo.Id,
  2084. PriceName = priceName,
  2085. Price = price,
  2086. Quantity = quantity,
  2087. FeeTotal = total,
  2088. Currency = 836,
  2089. FilePath = "",
  2090. OrbitalPrivateTransfer = 0,
  2091. OTAOrderNo = "-",
  2092. OtherBankName = "-",
  2093. OtherSideName = "-",
  2094. OtherSideNo = "-",
  2095. PayDId = 105,
  2096. SupplierAddress = "-",
  2097. SupplierArea = 1,
  2098. SupplierContact = "-",
  2099. SupplierContactNumber = "-",
  2100. SupplierEmail = "-",
  2101. SupplierName = "-",
  2102. SupplierSocialAccount = "-",
  2103. SupplierTypeId = 0,
  2104. CreateUserId = receiveInfo.CreateUserId,
  2105. Remark = remark
  2106. };
  2107. //1 2590 √
  2108. //2 2737 √ √
  2109. //3 2760 √ √
  2110. //4 2761 √ √
  2111. //5 2788 √ √
  2112. //6 2796 √ √
  2113. //7 2809 √ √
  2114. //8 2833 √ √
  2115. //9 2834 √ √
  2116. //10 2839 √ √
  2117. //11 2846 √ √
  2118. //其他费用
  2119. #region 调用方法
  2120. JsonView groupData = await _otherPaymentRep.OpDecreasePayments(requestData);
  2121. if (groupData.Code != 200)
  2122. {
  2123. view.Msg += groupData.Msg;
  2124. return Ok(view);
  2125. }
  2126. #region 应用推送
  2127. int diId = requestData.DiId, status = requestData.Status;
  2128. int otherId = Convert.ToInt32(groupData.Data.GetType().GetProperty("dataId").GetValue(groupData.Data, null) ?? 0);
  2129. int ccpId = Convert.ToInt32(groupData.Data.GetType().GetProperty("ccpId").GetValue(groupData.Data, null) ?? 0);
  2130. int sign = Convert.ToInt32(groupData.Data.GetType().GetProperty("sign").GetValue(groupData.Data, null) ?? 0);
  2131. //自动审核
  2132. //var autoAdit = await _feeAuditRep.FeeAutomaticAudit(3, diId, otherId);
  2133. await AppNoticeLibrary.SendChatMsg_GroupStatus_ApplyFee(ccpId, sign, QiyeWeChatEnum.GuoJiaoLeaderChat);
  2134. //2024-10-21 新增LZ UID
  2135. var userIds = new List<int>() { 208 };
  2136. //var userIds = new List<int>() { 21 };
  2137. string title = $"系统通知";
  2138. string content = "";
  2139. var ccpInfo = await _sqlSugar.Queryable<Grp_CreditCardPayment>().Where(x => x.Id == ccpId).FirstAsync();
  2140. if (status == 1) content = $"[新增-其他款项({groupInfo?.TeamName ?? "-"})]一项费用:{(ccpInfo.PayMoney * ccpInfo.DayRate).ToString("#0.00")} CNY;";
  2141. else if (status == 2) content = $"[更新-其他款项({groupInfo?.TeamName ?? "-"})]一项费用:{(ccpInfo.PayMoney * ccpInfo.DayRate).ToString("#0.00")} CNY;";
  2142. await GeneralMethod.MessageIssueAndNotification(MessageTypeEnum.GroupBusinessOperations, title, content, userIds, diId);
  2143. //await APNsTools.iOS_PushNotifications1("051", $"其他款项费用审核", "", content);
  2144. #endregion
  2145. #endregion
  2146. #endregion
  2147. return Ok(view);
  2148. }
  2149. /// <summary>
  2150. /// 物资进销存
  2151. /// 领用 Del
  2152. /// </summary>
  2153. /// <returns></returns>
  2154. [HttpDelete("{id}")]
  2155. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  2156. public async Task<IActionResult> GoodsReceiveDel(int id)
  2157. {
  2158. var currUserInfo = JwtHelper.SerializeJwt(HttpContext.Request.Headers.Authorization);
  2159. if (currUserInfo == null) return Ok(JsonView(false, "请传入token!"));
  2160. if (id < 1) return Ok(JsonView(false, MsgTips.Id));
  2161. return Ok(await _goodsRep.GoodsReceiveDel(id, currUserInfo.UserId));
  2162. }
  2163. #endregion
  2164. #region 员工绩效
  2165. /// <summary>
  2166. /// 员工绩效组成结构获取
  2167. /// </summary>
  2168. /// <param name="userid"></param>
  2169. /// <param name="date"></param>
  2170. /// <param name="loginUser"></param>
  2171. /// <returns></returns>
  2172. [HttpGet]
  2173. public IActionResult GetPerformanceList(int userid, string date, int loginUser)
  2174. {
  2175. var jw = JsonView(false);
  2176. if (!DateTime.TryParse(date, out DateTime date_Dt))
  2177. {
  2178. jw.Msg = "日期格式有误!";
  2179. return Ok(jw);
  2180. }
  2181. string sql_CTE = $@"-- 定义递归查询的CTE
  2182. WITH PerAssessmentSettingsCTE AS (
  2183. -- 选择指定ID的记录作为起点
  2184. SELECT
  2185. pac.Id,
  2186. pac.Name,
  2187. pac.AssessmentProportion,
  2188. pac.AssessmentStandard,
  2189. pac.ParentId,
  2190. 1 AS Depth
  2191. FROM
  2192. Per_AssessmentSetting pac
  2193. INNER JOIN
  2194. Per_AssessmentContentSetting pacs
  2195. ON
  2196. pac.id = pacs.assessmentSettingid AND pacs.isdel = 0
  2197. WHERE
  2198. pacs.userid = {userid}
  2199. AND
  2200. pac.isdel = 0
  2201. UNION ALL
  2202. -- 递归部分,选择所有子级记录
  2203. SELECT
  2204. ps.Id,
  2205. ps.Name,
  2206. ps.AssessmentProportion,
  2207. ps.AssessmentStandard,
  2208. ps.ParentId,
  2209. CAST(caste.Depth as int) + 1
  2210. FROM
  2211. Per_AssessmentSetting ps
  2212. INNER JOIN PerAssessmentSettingsCTE caste ON ps.Id = caste.ParentId)
  2213. -- 从CTE中选择最终结果
  2214. SELECT * FROM PerAssessmentSettingsCTE
  2215. OPTION (MAXRECURSION 0); -- 允许无限递归 ";
  2216. var result_CTE = _sqlSugar.Ado.SqlQuery<Per_AssessmentSetting>(sql_CTE);
  2217. var ids = result_CTE.Select(x => x.Id);
  2218. var List = _sqlSugar.Queryable<Per_AssessmentSetting>()
  2219. .LeftJoin<Per_AssessmentContentSetting>((a, b) => a.Id == b.AssessmentSettingId && b.IsDel == 0 && b.UserId == userid)
  2220. .LeftJoin<Per_AssessmentScore>((a, b, c) => b.Id == c.AssessmentContentSettingId && c.IsDel == 0 && c.YearMonth.Year == date_Dt.Year && c.YearMonth.Month == date_Dt.Month)
  2221. .Where((a, b) => a.IsDel == 0 && ids.Contains(a.Id))
  2222. .Select((a, b, c) => new TreeNode
  2223. {
  2224. Id = a.Id,
  2225. ContentId = b.Id,
  2226. Name = a.Name,
  2227. ParentId = a.ParentId,
  2228. AssessmentProportion = a.AssessmentProportion, //占比
  2229. AssessmentStandard = a.AssessmentStandard, //描述
  2230. AssessmentProportionChi = b.AssessmentProportionChi, //占比
  2231. UserId = b.UserId,
  2232. JobId = b.JobId,
  2233. AssessmentSettingId = b.AssessmentSettingId,
  2234. Fixed = b.Fixed,
  2235. TargetValue = b.TargetValue,
  2236. AssessmentProportion_Percentage = a.AssessmentProportion * 100,
  2237. HigherUpAssessment = c.HigherUpAssessment,
  2238. HigherUpConfig = c.HigherUpConfig,
  2239. HigherUpUserId = c.HigherUpUserId,
  2240. Score = c.Score,
  2241. ScoreTotal = c.ScoreTotal,
  2242. SelfAssessment = c.SelfAssessment,
  2243. Status = c.Status,
  2244. YearMonth = c.YearMonth,
  2245. })
  2246. .ToList();
  2247. var rootNodeList = List.Where(x => x.ParentId == 0);
  2248. var rootResult = rootNodeList.Select(x => BuildSubTree(x, List));
  2249. jw.Data = new
  2250. {
  2251. Root = rootResult,
  2252. IsLeader = IsLeader(userid, loginUser)
  2253. };
  2254. jw.Code = 200;
  2255. jw.Msg = "成功";
  2256. return Ok(jw);
  2257. }
  2258. private static TreeNode BuildSubTree(TreeNode parent, List<TreeNode> nodes)
  2259. {
  2260. var children = nodes
  2261. .Where(n => n.ParentId == parent.Id)
  2262. .Select(n => BuildSubTree(n, nodes))
  2263. .ToList();
  2264. parent.Children = children;
  2265. return parent;
  2266. }
  2267. /// <summary>
  2268. /// 绩效项增改
  2269. /// </summary>
  2270. /// <param name="dto"></param>
  2271. /// <returns></returns>
  2272. [HttpPost]
  2273. public async Task<IActionResult> AssessmentSettingOperationAsync(PerAssessmentSettingOperationDto dto)
  2274. {
  2275. var jw = JsonView(false);
  2276. if (!ModelState.IsValid)
  2277. {
  2278. jw.Msg = "参数错误";
  2279. jw.Data = ModelState;
  2280. return Ok(jw);
  2281. }
  2282. try
  2283. {
  2284. if (dto.ParentId != 0)
  2285. {
  2286. var parent = await _sqlSugar.Queryable<Per_AssessmentSetting>().FirstAsync(x => x.IsDel == 0 && x.Id == dto.ParentId);
  2287. if (parent == null)
  2288. {
  2289. jw.Msg = "父级节点不存在";
  2290. return Ok(jw);
  2291. }
  2292. }
  2293. var entity = new Per_AssessmentSetting
  2294. {
  2295. Name = dto.Name,
  2296. AssessmentProportion = dto.AssessmentProportion,
  2297. AssessmentStandard = dto.AssessmentStandard,
  2298. ParentId = dto.ParentId,
  2299. Id = dto.Id,
  2300. Remark = dto.Remark,
  2301. };
  2302. jw.Code = 200;
  2303. if (dto.Id == 0)
  2304. {
  2305. entity.CreateUserId = dto.CreateId;
  2306. entity.CreateTime = DateTime.Now;
  2307. await _sqlSugar.Insertable(entity).ExecuteCommandAsync();
  2308. jw.Msg = "添加成功!";
  2309. }
  2310. else
  2311. {
  2312. await _sqlSugar.Updateable(entity).ExecuteCommandAsync();
  2313. jw.Msg = "修改成功!";
  2314. }
  2315. }
  2316. catch (Exception ex)
  2317. {
  2318. jw.Msg = "Api error " + ex.Message;
  2319. jw.Code = 400;
  2320. }
  2321. return Ok(jw);
  2322. }
  2323. /// <summary>
  2324. /// 绩效内容增改
  2325. /// </summary>
  2326. /// <param name="dto"></param>
  2327. /// <returns></returns>
  2328. [HttpPost]
  2329. public IActionResult AssessmentSettingOperationContentAsync(AssessmentSettingOperationContenDto dto)
  2330. {
  2331. var jw = JsonView(false, "", "");
  2332. var entity = new Per_AssessmentContentSetting
  2333. {
  2334. AssessmentProportionChi = dto.AssessmentProportionChi,
  2335. AssessmentSettingId = dto.AssessmentSettingId,
  2336. CreateTime = DateTime.Now,
  2337. CreateUserId = dto.CreateUserId,
  2338. Fixed = dto.Fixed,
  2339. Id = dto.Id,
  2340. JobId = dto.JobId,
  2341. TargetValue = dto.TargetValue,
  2342. UserId = dto.UserId,
  2343. Remark = dto.Remark,
  2344. };
  2345. var entity_Fk = _sqlSugar.Queryable<Per_AssessmentSetting>().First(x => x.Id == dto.AssessmentSettingId && x.IsDel == 0);
  2346. if (entity_Fk == null)
  2347. {
  2348. jw.Msg = "考核设置不存在";
  2349. return Ok(jw);
  2350. }
  2351. try
  2352. {
  2353. if (dto.Id == 0)
  2354. {
  2355. //add
  2356. var insertCount = _sqlSugar.Insertable(entity).ExecuteCommand();
  2357. jw.Msg = "添加成功!";
  2358. }
  2359. else
  2360. {
  2361. //update
  2362. var updateCount = _sqlSugar.Updateable(entity).ExecuteCommand();
  2363. jw.Msg = "修改成功!";
  2364. }
  2365. jw.Code = 200;
  2366. }
  2367. catch (Exception ex)
  2368. {
  2369. jw.Msg = "Api error " + ex.Message;
  2370. jw.Code = 400;
  2371. }
  2372. return Ok(jw);
  2373. }
  2374. /// <summary>
  2375. /// 绩效项查询
  2376. /// </summary>
  2377. /// <param name="dto"></param>
  2378. /// <returns></returns>
  2379. [HttpPost]
  2380. public async Task<IActionResult> QueryAssessmentSettingListOffsetAsync(QueryAssessmentSettingListOffsetAsyncDto dto)
  2381. {
  2382. var jw = JsonView(false);
  2383. RefAsync<int> total = 0;//REF和OUT不支持异步,想要真的异步这是最优解
  2384. var entities = await _sqlSugar.Queryable<Per_AssessmentSetting>()
  2385. .Where(x => x.IsDel == 0)
  2386. .WhereIF(!string.IsNullOrEmpty(dto.SearchValue), e => e.Name.Contains(dto.SearchValue))
  2387. .ToPageListAsync(dto.pageIndex, dto.pageSize, total);
  2388. var DtoResult = entities.Select(e => new
  2389. {
  2390. e.Id,
  2391. e.Name,
  2392. e.AssessmentProportion,
  2393. e.AssessmentStandard,
  2394. e.ParentId,
  2395. e.Remark
  2396. }).ToList();
  2397. jw.Data = new
  2398. {
  2399. total = total.Value,
  2400. dto.pageIndex,
  2401. dto.pageSize,
  2402. List = DtoResult
  2403. };
  2404. jw.Code = 200;
  2405. jw.Msg = "查询成功!";
  2406. return Ok(jw);
  2407. }
  2408. /// <summary>
  2409. /// 绩效分数保存
  2410. /// </summary>
  2411. /// <param name="dto"></param>
  2412. /// <returns></returns>
  2413. [HttpPost]
  2414. public IActionResult SaveUserAssessmen(SaveUserAssessmenDto dto)
  2415. {
  2416. var jw = JsonView(false, "请传入正确的数据!");
  2417. if (dto.Data.Any())
  2418. {
  2419. if (!DateTime.TryParse(dto.AssessmenData, out DateTime yearMonth_Dt))
  2420. {
  2421. jw.Data = "月份参数有误!";
  2422. return Ok(jw);
  2423. }
  2424. try
  2425. {
  2426. var ids = dto.Data.Select(x => x.AssessmentContentSettingId).ToList();
  2427. var QueryContent_DB = _sqlSugar.Queryable<Per_AssessmentContentSetting>()
  2428. .InnerJoin<Per_AssessmentSetting>((a, b) => b.IsDel == 0 && a.AssessmentSettingId == b.Id)
  2429. .Where((a, b) => a.IsDel == 0 && ids.Contains(a.Id))
  2430. .Select((a, b) => new
  2431. {
  2432. ContentSettingId = a.Id,
  2433. SettingId = b.Id,
  2434. a.TargetValue,
  2435. b.AssessmentStandard,
  2436. MergeStr = $"【项名称:{b.Name}/目标值:{a.TargetValue}/评估标准:{b.AssessmentStandard}】",
  2437. a.AssessmentProportionChi,
  2438. b.Name
  2439. })
  2440. .ToList()
  2441. .ToDictionary(x => x.ContentSettingId);
  2442. //删除上级未确认数据
  2443. var expressionWhere = Expressionable
  2444. .Create<Per_AssessmentScore>()
  2445. .And(x => x.YearMonth.Year == yearMonth_Dt.Year && x.YearMonth.Month == yearMonth_Dt.Month)
  2446. .And(x => ids.Contains(x.AssessmentContentSettingId))
  2447. .And(x => x.HigherUpConfig == 0)
  2448. .ToExpression();
  2449. if (IsLeader(dto.AssessmenUserId, dto.CreateUserId))
  2450. {
  2451. expressionWhere = Expressionable
  2452. .Create<Per_AssessmentScore>()
  2453. .And(x => x.YearMonth.Year == yearMonth_Dt.Year && x.YearMonth.Month == yearMonth_Dt.Month)
  2454. .And(x => ids.Contains(x.AssessmentContentSettingId))
  2455. .ToExpression();
  2456. }
  2457. _sqlSugar.BeginTran();
  2458. _sqlSugar.Updateable<Per_AssessmentScore>()
  2459. .Where(expressionWhere)
  2460. .SetColumns(x => new Per_AssessmentScore { IsDel = 1, DeleteUserId = dto.CreateUserId, DeleteTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") })
  2461. .ExecuteCommand();
  2462. var entityList = new List<Per_AssessmentScore>();
  2463. foreach (var x in dto.Data)
  2464. {
  2465. if (x.HigherUpAssessment > 100 || x.SelfAssessment > 100)
  2466. {
  2467. jw.Msg = QueryContent_DB[x.AssessmentContentSettingId].Name + "项分数不能超过100。";
  2468. return Ok(jw);
  2469. }
  2470. Per_AssessmentScore item = new Per_AssessmentScore
  2471. {
  2472. AssessmentContentSettingId = x.AssessmentContentSettingId,
  2473. CreateTime = DateTime.Now,
  2474. CreateUserId = dto.CreateUserId,
  2475. Details = QueryContent_DB[x.AssessmentContentSettingId].MergeStr,
  2476. HigherUpAssessment = x.HigherUpAssessment,
  2477. HigherUpUserId = x.LeadersId,
  2478. HigherUpConfig = x.HigherUpAssessment > 0 ? 1 : 0,
  2479. SelfAssessment = x.SelfAssessment,
  2480. IsDel = 0,
  2481. Status = x.Status,
  2482. YearMonth = yearMonth_Dt,
  2483. Score = x.SelfAssessment * 0.3M + x.HigherUpAssessment * 0.7M,
  2484. ScoreTotal = (x.SelfAssessment * 0.3M + x.HigherUpAssessment * 0.7M) * QueryContent_DB[x.AssessmentContentSettingId].AssessmentProportionChi,
  2485. };
  2486. entityList.Add(item);
  2487. }
  2488. var influenceRow = _sqlSugar.Insertable(entityList).ExecuteCommand();
  2489. _sqlSugar.CommitTran();
  2490. jw.Code = 200;
  2491. jw.Msg = "保存成功!";
  2492. jw.Data = $"{influenceRow}条数据操作成功!";
  2493. }
  2494. catch (Exception ex)
  2495. {
  2496. _sqlSugar.RollbackTran();
  2497. jw.Code = 500;
  2498. jw.Data = $"API ERROR ({ex.Message})";
  2499. }
  2500. }
  2501. return Ok(jw);
  2502. }
  2503. /// <summary>
  2504. /// 绩效项删除
  2505. /// </summary>
  2506. /// <param name="dto"></param>
  2507. /// <returns></returns>
  2508. [HttpPost]
  2509. public IActionResult DeleteAssessmentSetting(DeleteAssessmentSettingDto dto)
  2510. {
  2511. var jw = JsonView(false, "删除失败!");
  2512. if (!dto.IdArr.Any())
  2513. {
  2514. jw.Msg = "id不能为空!";
  2515. return Ok(jw);
  2516. }
  2517. var rowCount = _sqlSugar.Updateable<Per_AssessmentSetting>()
  2518. .Where(x => dto.IdArr.Contains(x.Id) && x.IsDel == 0)
  2519. .SetColumns(x => new Per_AssessmentSetting
  2520. {
  2521. IsDel = 1,
  2522. DeleteTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm"),
  2523. DeleteUserId = dto.UserId,
  2524. })
  2525. .ExecuteCommand();
  2526. jw.Code = 200;
  2527. jw.Msg = $"修改成功!,修改数量{rowCount}";
  2528. return Ok(jw);
  2529. }
  2530. /// <summary>
  2531. /// 绩效内容删除
  2532. /// </summary>
  2533. /// <param name="dto"></param>
  2534. /// <returns></returns>
  2535. [HttpPost]
  2536. public IActionResult DeleteAssessmentContentSetting(DeleteAssessmentSettingDto dto)
  2537. {
  2538. var jw = JsonView(false, "删除失败!");
  2539. if (!dto.IdArr.Any())
  2540. {
  2541. jw.Msg = "id不能为空!";
  2542. return Ok(jw);
  2543. }
  2544. var rowCount = _sqlSugar.Updateable<Per_AssessmentContentSetting>()
  2545. .Where(x => dto.IdArr.Contains(x.Id) && x.IsDel == 0)
  2546. .SetColumns(x => new Per_AssessmentContentSetting
  2547. {
  2548. IsDel = 1,
  2549. DeleteTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm"),
  2550. DeleteUserId = dto.UserId,
  2551. })
  2552. .ExecuteCommand();
  2553. jw.Code = 200;
  2554. jw.Msg = $"修改成功!,修改数量{rowCount}";
  2555. return Ok(jw);
  2556. }
  2557. private bool IsLeader(int userId, int higherUserId)
  2558. {
  2559. Dictionary<int, List<int>> keyValues = new Dictionary<int, List<int>>()
  2560. {
  2561. { 5 , new List<int>{ 258 , 235, 234, 233, 208 } }
  2562. };
  2563. if (keyValues.ContainsKey(higherUserId))
  2564. {
  2565. return keyValues[higherUserId].Contains(userId);
  2566. }
  2567. return false;
  2568. }
  2569. #endregion
  2570. #region 企微Api测试
  2571. [HttpPost]
  2572. public async Task<IActionResult> GetCheckin_MonthDataAsync(DateTime start, DateTime end)
  2573. {
  2574. var jw = JsonView(false);
  2575. jw.Data = await _qiYeWeChatApiService.GetCheckin_MonthDataAsync1(start, end);
  2576. return Ok(jw);
  2577. }
  2578. [HttpPost]
  2579. public async Task<IActionResult> QueryAssessmentByUser(QueryAssessmentByUser Dto)
  2580. {
  2581. var jw = JsonView(false);
  2582. var user_entity = _sqlSugar.Queryable<Sys_Users>()
  2583. .First(e => e.Id == Dto.UserId && e.IsDel == 0);
  2584. var start_Bool = DateTime.TryParse(Dto.Start, out DateTime start);
  2585. var end_Bool = DateTime.TryParse(Dto.End, out DateTime end);
  2586. if (!start_Bool || !end_Bool)
  2587. {
  2588. jw.Msg = "时间格式不正确!";
  2589. return Ok(jw);
  2590. }
  2591. jw.Msg = "用户企业微信Id未绑定!";
  2592. if (user_entity != null && !string.IsNullOrEmpty(user_entity.QiyeChatUserId))
  2593. {
  2594. var data = await _qiYeWeChatApiService.QueryAssessmentByUser(start, end, new List<string> { user_entity.QiyeChatUserId });
  2595. jw.Data = data;
  2596. jw.Msg = "查询成功!";
  2597. jw.Code = 200;
  2598. }
  2599. return Ok(jw);
  2600. }
  2601. //[HttpPost]
  2602. //public IActionResult TempTest(QueryAssessmentSettingListOffsetAsyncDto Dto)
  2603. //{
  2604. // var jw = JsonView(false);
  2605. // return Ok(jw);
  2606. //}
  2607. #endregion
  2608. #region Ai绩效分析
  2609. [HttpGet]
  2610. public async Task<IActionResult> AiPerformanceAnalysis_JobMarketingAsync(int userId, DateTime start, DateTime end)
  2611. {
  2612. var jw = JsonView(false);
  2613. var user_entity = _sqlSugar.Queryable<Sys_Users>()
  2614. .First(e => e.Id == userId && e.IsDel == 0);
  2615. if (user_entity == null)
  2616. {
  2617. jw.Msg = "用户不存在!";
  2618. return Ok(jw);
  2619. }
  2620. List<string> useridlist = new List<string> { user_entity.QiyeChatUserId };
  2621. //获取企微外出打卡信息
  2622. var checkin_data = await _qiYeWeChatApiService.GetCheckinDataAsync(useridlist, 2, start, end);
  2623. if (checkin_data.errcode != 0)
  2624. {
  2625. jw.Msg = "获取企微外出打卡信息失败!" + checkin_data.errmsg;
  2626. return Ok(jw);
  2627. }
  2628. //获取企微外出申请信息
  2629. var approval_data = await _qiYeWeChatApiService.GetApprovalInfoUpdateAsync(start, end, newCursor: "", size: 100, filters: new List<IQiYeWeChatApiService.FilterCondition>(){
  2630. new
  2631. IQiYeWeChatApiService.FilterCondition{
  2632. key = "creator",
  2633. value = user_entity.QiyeChatUserId
  2634. },
  2635. new IQiYeWeChatApiService.FilterCondition{
  2636. key="record_type",
  2637. value="4"
  2638. }
  2639. });
  2640. if (approval_data.errcode != 0)
  2641. {
  2642. jw.Msg = "获取企微外出申请信息失败!" + approval_data.errmsg;
  2643. return Ok(jw);
  2644. }
  2645. List<ApprovalDetailView> detailViews = new List<ApprovalDetailView>();
  2646. foreach (var item in approval_data.sp_no_list)
  2647. {
  2648. var approval_detail = await _qiYeWeChatApiService.GetApprovalDetailAsync(item);
  2649. if (approval_detail.errcode != 0)
  2650. {
  2651. jw.Msg = "获取企微外出申请详情失败!" + approval_detail.errmsg;
  2652. return Ok(jw);
  2653. }
  2654. detailViews.Add(approval_detail);
  2655. }
  2656. string question = $"请根据以下数据分析用户绩效:";
  2657. question += $"外出打卡信息:{JsonConvert.SerializeObject(checkin_data.checkindata)}";
  2658. if (approval_data.sp_no_list.Count > 0)
  2659. {
  2660. question += $"外出申请信息:{JsonConvert.SerializeObject(detailViews)}";
  2661. }
  2662. question += $"请根据我提供的{user_entity.CnName}数据信息(提供的数据已经是一个月的数据),按照一个月拜访20个客户的标准判断是否合格,并给出分析报告。";
  2663. try
  2664. {
  2665. var resp = await _deepSeekService.ChatAsync(question);
  2666. if (!resp.Success)
  2667. {
  2668. jw.Msg = "Ai分析用户绩效失败!" + resp.Message;
  2669. return Ok(jw);
  2670. }
  2671. jw.Data = new
  2672. {
  2673. checkin_data = checkin_data.checkindata,
  2674. approval_data = approval_data.sp_no_list,
  2675. detailViews = detailViews,
  2676. Answer = resp.Answer
  2677. };
  2678. }
  2679. catch (Exception ex)
  2680. {
  2681. jw.Msg = "Ai分析用户绩效失败!" + ex.Message;
  2682. return Ok(jw);
  2683. }
  2684. jw.Code = 200;
  2685. jw.Msg = "查询成功!";
  2686. return Ok(jw);
  2687. }
  2688. /// <summary>
  2689. /// Ai绩效分析
  2690. /// 列表查询基础数据
  2691. /// </summary>
  2692. /// <returns></returns>
  2693. [HttpGet]
  2694. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  2695. public async Task<IActionResult> AiPerformanceAnalysis_InitAsync()
  2696. {
  2697. var companyDatas = await _sqlSugar.Queryable<Sys_Company>().Where(x => x.IsDel == 0).Select(x => new { x.Id, x.CompanyName }).ToListAsync();
  2698. var jobPostDatas = await _sqlSugar.Queryable<Sys_JobPost>().Where(x => x.IsDel == 0).Select(x => new { x.Id, x.CompanyId, x.JobName }).ToListAsync();
  2699. var userDatas = await _sqlSugar.Queryable<Sys_Users>().Where(x => x.IsDel == 0).Select(x => new { x.Id, x.JobPostId, x.CnName }).ToListAsync();
  2700. companyDatas.Insert(0, new { Id = 0, CompanyName = "全部" });
  2701. jobPostDatas.Insert(0, new { Id = 0, CompanyId = 0, JobName = "全部" });
  2702. userDatas.Insert(0, new { Id = 0, JobPostId = 0, CnName = "全部" });
  2703. return Ok(JsonView(true, "操作成功!", new
  2704. {
  2705. companyDatas,
  2706. jobPostDatas,
  2707. userDatas
  2708. }));
  2709. }
  2710. /// <summary>
  2711. /// Ai绩效分析
  2712. /// 用户列表
  2713. /// </summary>
  2714. /// <returns></returns>
  2715. [HttpPost]
  2716. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  2717. public async Task<IActionResult> AiPerformanceAnalysis_UserListAsync(AiPerformanceAnalysis_UserListDto dto)
  2718. {
  2719. if (dto.CompanyId < 0)
  2720. {
  2721. return Ok(JsonView(false, "请传入有效的公司Id。"));
  2722. }
  2723. if (dto.JobPostId < 0)
  2724. {
  2725. return Ok(JsonView(false, "请传入有效的岗位Id。"));
  2726. }
  2727. if (dto.UserId < 0)
  2728. {
  2729. return Ok(JsonView(false, "请传入有效的员工Id。"));
  2730. }
  2731. if (dto.PageIndex < 1)
  2732. {
  2733. dto.PageIndex = 1;
  2734. }
  2735. if (dto.PageSize < 1 || dto.PageSize > 100)
  2736. {
  2737. dto.PageSize = 10;
  2738. }
  2739. RefAsync<int> total = 0;
  2740. var query = _sqlSugar.Queryable<Sys_Users>()
  2741. .LeftJoin<Sys_Company>((u, c) => u.CompanyId == c.Id)
  2742. .LeftJoin<Sys_JobPost>((u, c, jp) => u.JobPostId == jp.Id)
  2743. .Where((u, c, jp) => u.IsDel == 0)
  2744. .WhereIF(dto.CompanyId > 0, (u, c, jp) => u.CompanyId == dto.CompanyId)
  2745. .WhereIF(dto.JobPostId > 0, (u, c, jp) => u.JobPostId == dto.JobPostId)
  2746. .WhereIF(dto.UserId > 0, (u, c, jp) => u.Id == dto.UserId)
  2747. .OrderBy(u => u.CompanyId)
  2748. .OrderBy(u => u.JobPostId)
  2749. .OrderBy(u => u.Id);
  2750. var view = await query.Select((u, c, jp) => new AiPerformanceAnalysis_UserView()
  2751. {
  2752. RowNumber = SqlFunc.RowNumber("u.CompanyId ASC, u.JobPostId ASC, u.Id ASC"),
  2753. Id = u.Id,
  2754. UserName = u.CnName,
  2755. CompanyId = u.CompanyId,
  2756. CompanyName = c.CompanyName,
  2757. JobPostId = u.JobPostId,
  2758. JobName = jp.JobName,
  2759. WorkYears = SqlFunc.DateDiff(DateType.Year, u.Edate, DateTime.Now)
  2760. })
  2761. .ToPageListAsync(dto.PageIndex, dto.PageSize, total);
  2762. return Ok(JsonView(true, "操作成功!", view, total));
  2763. }
  2764. /// <summary>
  2765. /// Ai绩效分析
  2766. /// 团组统计
  2767. /// </summary>
  2768. /// <param name="userId">用户ID</param>
  2769. /// <param name="start">开始日期(eg:2025-01-01)</param>
  2770. /// <param name="end">结束日期(eg:2025-12-31)</param>
  2771. /// <returns></returns>
  2772. [HttpGet]
  2773. [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
  2774. public async Task<IActionResult> AiPerformanceAnalysis_GroupStatisticsAsync(int userId, DateTime start, DateTime end)
  2775. {
  2776. #region 参数验证
  2777. if (userId < 1)
  2778. {
  2779. return Ok(JsonView(false, "请传入有效UserId。"));
  2780. }
  2781. if (start > end)
  2782. {
  2783. return Ok(JsonView(false, "开始日期不能晚于结束日期。"));
  2784. }
  2785. #endregion
  2786. var parameters = new
  2787. {
  2788. UserId = userId,
  2789. StartDate = start.Date,
  2790. EndDate = end.Date.AddDays(1).AddSeconds(-1) // 包含结束日期的最后一秒
  2791. };
  2792. string sql = @"
  2793. SELECT
  2794. ROW_NUMBER() OVER (ORDER BY MonthNumber, CollectionDays) AS RowNumber,
  2795. Id,
  2796. TeamName,
  2797. ClientUnit,
  2798. ClientName,
  2799. VisitDate,
  2800. VisitPNumber,
  2801. JietuanOperator,
  2802. VisitEndDate,
  2803. MonthNumber,
  2804. GroupSales,
  2805. GroupPickupUser,
  2806. CollectionDays
  2807. FROM
  2808. (
  2809. SELECT
  2810. di.Id,
  2811. di.TeamName,
  2812. di.ClientUnit,
  2813. di.ClientName,
  2814. di.VisitDate,
  2815. di.VisitPNumber,
  2816. di.JietuanOperator,
  2817. di.VisitEndDate,
  2818. DATEPART(MONTH, di.VisitEndDate) AS MonthNumber,
  2819. (
  2820. SELECT CAST(COALESCE(SUM(ItemSumPrice * Rate), 0) AS DECIMAL(12, 2))
  2821. FROM Fin_ForeignReceivables
  2822. WHERE IsDel = 0
  2823. AND di.Id = Diid
  2824. AND AddingWay IN (0, 1, 2)
  2825. ) AS GroupSales,
  2826. u.CnName AS GroupPickupUser,
  2827. DATEADD(DAY, 7, di.VisitEndDate) AS CollectionDays
  2828. FROM Grp_DelegationInfo di WITH (NOLOCK)
  2829. LEFT JOIN Sys_Users u ON di.JietuanOperator = u.Id
  2830. WHERE di.Isdel = 0
  2831. AND di.IsBid = 0
  2832. AND di.JietuanOperator = @UserId
  2833. AND di.TeamName NOT LIKE '%投标%'
  2834. AND di.VisitDate BETWEEN @StartDate AND @EndDate
  2835. AND EXISTS (
  2836. SELECT 1
  2837. FROM Fin_ForeignReceivables fr
  2838. WHERE fr.IsDel = 0
  2839. AND fr.Diid = di.Id
  2840. AND fr.AddingWay IN (0, 1, 2)
  2841. )
  2842. ) Temp
  2843. ORDER BY MonthNumber, CollectionDays";
  2844. var groupData = await _sqlSugar.SqlQueryable<AiPerformanceAnalysis_GroupStatisticsView>(sql)
  2845. .AddParameters(parameters)
  2846. .ToListAsync();
  2847. return Ok(JsonView(true, "操作成功!", groupData, groupData?.Count ?? 0));
  2848. }
  2849. private class AiPerformanceAnalysis_GroupStatisticsView : MarketingSalesGroupList
  2850. {
  2851. /// <summary>
  2852. ///月份
  2853. /// </summary>
  2854. public int MonthNumber { get; set; }
  2855. }
  2856. /// <summary>
  2857. /// AI绩效分析用户列表视图模型
  2858. /// </summary>
  2859. private class AiPerformanceAnalysis_UserView
  2860. {
  2861. public int RowNumber { get; set; }
  2862. public int Id { get; set; }
  2863. public string UserName { get; set; }
  2864. public int CompanyId { get; set; }
  2865. public string CompanyName { get; set; }
  2866. public int JobPostId { get; set; }
  2867. public string JobName { get; set; }
  2868. public int WorkYears { get; set; }
  2869. }
  2870. #endregion
  2871. }
  2872. }