| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211 | using Aspose.Cells;using AutoMapper;using EyeSoft.Collections.Generic;using Newtonsoft.Json;using OASystem.Domain;using OASystem.Domain.Dtos.PersonnelModule;using OASystem.Domain.Entities.Groups;using OASystem.Domain.Entities.PersonnelModule;using OASystem.Domain.ViewModels.PersonnelModule;using OASystem.Infrastructure.Repositories.System;using OASystem.Infrastructure.Tools;namespace OASystem.Infrastructure.Repositories.PersonnelModule{    /// <summary>    /// 物品进销存     /// 仓储    /// </summary>    public class GoodsRepository : BaseRepository<Pm_GoodsInfo, GoodsInfoView>    {        private readonly IMapper _mapper;        private JsonView _jv;        private string _url;        private string _excelPath;        private List<int> _goodsTypeIds; //多部门审核物品类型Id             private readonly ApprovalProcessRepository _approvalProcessRep;        public GoodsRepository(SqlSugarClient sqlSugar,            IMapper mapper,            ApprovalProcessRepository approvalProcessRep)            : base(sqlSugar)        {            _mapper = mapper;            _jv = new JsonView() { Code = StatusCodes.Status400BadRequest, Msg = "操作失败!" };            _url = AppSettingsHelper.Get("ExcelBaseUrl");            _excelPath = $"{AppSettingsHelper.Get("ExcelBasePath")}";            if (!Directory.Exists(_excelPath))            {                Directory.CreateDirectory(_excelPath);            }            _goodsTypeIds = new List<int>() {                1423, //1423	贵重物品            };            _approvalProcessRep = approvalProcessRep;        }        /// <summary>        /// 基础数据        /// </summary>        /// <returns></returns>        public async Task<JsonView> InitDataSource()        {            var typeData = await _sqlSugar.Queryable<GoodsTypeView>()                .Includes(x => x.SubTypeItems.Where(z => z.IsDel == 0)                //.Select(z => new {                //     z.Id,                //     z.STid,                //     z.Name                //})                .ToList())                .Where(x => x.IsDel == 0 &&                            x.Remark.Equals("GoodsType"))                //.Select(x => new {                 //        x.Id,                //        x.Name,                //        x.SubTypeItems                //})                .ToListAsync();            var groupData = await _sqlSugar.Queryable<Grp_DelegationInfo>()                .Where(x => x.IsDel == 0)                .Select(x => new                {                    id = x.Id,                    groupName = x.TeamName                })                .OrderByDescending(x => x.id)                .ToListAsync();            groupData.Insert(0, new { id = 0, groupName = "其他物资(公司内部物资)" });            groupData.Insert(0, new { id = -1, groupName = "拜访客户所使用的物资" });            groupData.Insert(0, new { id = -2, groupName = "库存调整" });            groupData.Insert(0, new { id = -3, groupName = "全部团组" });            var userData = await _sqlSugar.Queryable<Sys_Users>()                .Where(x => x.IsDel == 0)                .Select(x => new                {                    x.Id,                    UserName = x.CnName,                })                .ToListAsync();            //库存状态            var stockStatus = new List<dynamic>() {                new { Value = -1, Text = "全部" },                new { Value = 0, Text = "待确认" },                new { Value = 1, Text = "部分确认" },                new { Value = 2, Text = "已确认" },                new { Value = 3, Text = "已拒绝" },            };            //领用出库状态            var receiveStatus = new List<dynamic>() {                new { Value = -1, Text = "全部" },                new { Value = GoodsAuditEnum.Pending, Text = GoodsAuditEnum.Pending.GetEnumDescription() },                //new { Value = GoodsAuditEnum.Approved, Text = GoodsAuditEnum.Approved.GetEnumDescription() },                //new { Value = GoodsAuditEnum.UnApproved, Text = GoodsAuditEnum.UnApproved.GetEnumDescription() },                //new { Value = GoodsAuditEnum.OutPending, Text = GoodsAuditEnum.OutPending.GetEnumDescription() },                new { Value = GoodsAuditEnum.OutConfirming, Text = GoodsAuditEnum.OutConfirming.GetEnumDescription() },                new { Value = GoodsAuditEnum.OutConfirmed, Text = GoodsAuditEnum.OutConfirmed.GetEnumDescription() },                new { Value = GoodsAuditEnum.OutRejected, Text = GoodsAuditEnum.OutRejected.GetEnumDescription() },            };            _jv.Code = StatusCodes.Status200OK;            _jv.Data = new { goodsTypeData = typeData, stockStatus, receiveStatus, groupNameData = groupData, userNameData = userData };            _jv.Msg = $"操作成功";            return _jv;        }        /// <summary>        /// 物品列表        /// </summary>        /// <param name="dto"></param>        /// <returns></returns>        public async Task<JsonView> GoodsList(GoodsListDto dto)        {            var ids = new List<int>();            if (!string.IsNullOrEmpty(dto.TypeIds))            {                var strArray = dto.TypeIds.Split(',');                foreach (var str in strArray)                {                    if (int.TryParse(str, out int id))                    {                        ids.Add(id);                    }                }            }            var auditEnums = new List<GoodsAuditEnum>() {                GoodsAuditEnum.Pending,                GoodsAuditEnum.OutPending,                GoodsAuditEnum.OutConfirming            };            RefAsync<int> total = 0;            var data = await _sqlSugar.Queryable<GoodsListView>()                //.Includes(glv => glv.Receives.Where(z1 => z1.IsDel == 0 && z1.AuditStatus == GoodsAuditEnum.Pending).ToList())                .Includes(glv => glv.Receives.Where(z1 => z1.IsDel == 0 && auditEnums.Contains(z1.AuditStatus)).ToList())                .Includes(glv => glv.TypeData)                .Includes(glv => glv.UserData)                .LeftJoin<Sys_SetData>((glv, sd) => glv.Type == sd.Id)                .LeftJoin<Sys_Users>((glv, sd, u) => glv.LastUpdateUserId == u.Id)                .Where(glv => glv.IsDel == 0)                .WhereIF(ids.Count > 0, glv => ids.Contains(glv.Type))                .WhereIF(!string.IsNullOrEmpty(dto.GoodsName), glv => glv.Name.Contains(dto.GoodsName))                .OrderByDescending(glv => glv.LastUpdateTime)                .ToPageListAsync(dto.PageIndex, dto.PageSize, total);            var view = data.Select(x => new            {                x.Id,                x.Name,                x.Type,                TypeName = x.TypeData?.Name ?? string.Empty,                LastUpdateUserName = x.UserData?.CnName ?? string.Empty,                x.LastUpdateTime,                StockQuantity = x.StockQuantity - x.WaitAuditQuantity,                x.Unit,                x.StockQuantityLabel,                x.Remark            }).ToList();            _jv.Code = StatusCodes.Status200OK;            _jv.Data = view;            _jv.Count = total;            _jv.Msg = $"操作成功";            return _jv;        }        /// <summary>        /// 物品Info        /// </summary>        /// <param name="portType"></param>        /// <param name="id"></param>        /// <returns></returns>        public async Task<JsonView> GoodsInfo(int portType, int id)        {            var data = await _sqlSugar.Queryable<Pm_GoodsInfo>()                .LeftJoin<Sys_SetData>((gi, sd) => gi.Type == sd.Id)                .LeftJoin<Sys_Users>((gi, sd, u1) => gi.LastUpdateUserId == u1.Id)                .LeftJoin<Sys_Users>((gi, sd, u1, u2) => gi.CreateUserId == u2.Id)                .Where((gi, sd, u1, u2) => gi.IsDel == 0 && gi.Id == id)                .Select((gi, sd, u1, u2) => new                {                    gi.Id,                    gi.Name,                    ParentType = sd.STid,                    gi.Type,                    TypeName = sd.Name,                    gi.SQ_Total,                    gi.OQ_Total,                    gi.PriceTotal,                    gi.StockQuantity,                    gi.Unit,                    gi.Remark,                    LastUpdateUserName = u1.CnName,                    gi.LastUpdateTime,                    CreateUserName = u2.CnName,                    gi.CreateTime,                })                .FirstAsync();            _jv.Code = StatusCodes.Status200OK;            _jv.Data = data;            _jv.Msg = $"操作成功";            return _jv;        }        /// <summary>        /// 物品 OP(Create Or Edit)        /// </summary>        /// <param name="dto"></param>        /// <param name="currUserId"></param>        /// <returns></returns>        public async Task<JsonView> GoodsOp(GoodsOpDto dto, int currUserId)        {            var info = new Pm_GoodsInfo()            {                Id = dto.Id,                Name = dto.Name,                Type = dto.Type,                SQ_Total = 0,                OQ_Total = 0,                PriceTotal = 0,                StockQuantity = 0,                Unit = dto.Unit,                Remark = dto.Remark,                LastUpdateUserId = currUserId,                LastUpdateTime = DateTime.Now,                CreateUserId = currUserId            };            if (dto.Id > 0) //Edit            {                var upd = await _sqlSugar.Updateable(info)                    .UpdateColumns(x => new                    {                        x.Name,                        x.Type,                        x.Unit,                        x.Remark,                        x.LastUpdateUserId,                        x.LastUpdateTime,                    })                    .ExecuteCommandAsync();                if (upd > 0)                {                    _jv.Msg = $"修改成功!";                    _jv.Code = StatusCodes.Status200OK;                    return _jv;                }            }            else if (dto.Id < 1) //添加            {                var selectInfo = await _sqlSugar.Queryable<Pm_GoodsInfo>().FirstAsync(x => x.Name.Equals(info.Name));                if (selectInfo != null)                {                    _jv.Msg = $"“{info.Name}”该物品已存在,请勿重新添加!";                    return _jv;                }                var add = await _sqlSugar.Insertable(info).ExecuteCommandAsync();                if (add > 0)                {                    _jv.Msg = $"添加成功!";                    _jv.Code = StatusCodes.Status200OK;                    return _jv;                }            }            return _jv;        }        /// <summary>        /// 物品 Del        /// </summary>        /// <param name="id"></param>        /// <param name="currUserId"></param>        /// <returns></returns>        public async Task<JsonView> GoodsDel(int id, int currUserId)        {            _sqlSugar.BeginTran();            var goods = await _sqlSugar.Updateable<Pm_GoodsInfo>()                .SetColumns(x => new Pm_GoodsInfo()                {                    IsDel = 1,                    DeleteUserId = currUserId,                    DeleteTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")                })                .Where(x => x.Id == id)                .ExecuteCommandAsync();            if (goods < 1)            {                _sqlSugar.RollbackTran();                _jv.Msg = $"操作失败";                return _jv;            }            var goodsStorage = await _sqlSugar.Updateable<Pm_GoodsStorage>()                .SetColumns(x => new Pm_GoodsStorage()                {                    IsDel = 1,                    DeleteUserId = currUserId,                    DeleteTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")                })                .Where(x => x.Id == id)                .ExecuteCommandAsync();            var goodsReceive = await _sqlSugar.Updateable<Pm_GoodsReceive>()                .SetColumns(x => new Pm_GoodsReceive()                {                    IsDel = 1,                    DeleteUserId = currUserId,                    DeleteTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")                })                .Where(x => x.Id == id)                .ExecuteCommandAsync();            _sqlSugar.CommitTran();            _jv.Code = StatusCodes.Status200OK;            _jv.Msg = $"操作成功!";            return _jv;        }        /// <summary>        /// 入库/出库 审核类型        /// 根据物品类型 处理审核是否需要多部门审核        /// </summary>        /// <param name="goodsTypeId">物品类型Id </param>        /// <returns></returns>        public bool GoodsAuditType(int goodsTypeId)        {            if (_goodsTypeIds.Contains(goodsTypeId))            {                return true;            }            return false;        }        /// <summary>        /// 物品入库列表(带审核)        /// </summary>        /// <param name="dto"></param>        /// <returns></returns>        public async Task<JsonView> GoodsStorageList(GoodsStorageListDto dto)        {            string reqAuditLabel = dto.AuditLabel;            var auditLabel = Array.Empty<int>();            int userId = dto.CurrUserId;            if (!string.IsNullOrEmpty(reqAuditLabel))            {                if (!reqAuditLabel.Contains("-1"))                {                    auditLabel = reqAuditLabel                    .Split(',')                    .Select(x =>                    {                        if (int.TryParse(x, out var id)) return id;                        return id;                    })                    .ToArray();                }            }            var auditList = GoodsStorageConfirmAuditDep(1);            var hrAuditPer = false;            var finAuditPer = false;            var hrAuditInfo = auditList.FirstOrDefault(x => x.AuditDep == GoodsAuditDepEnum.Hr);            var finAuditInfo = auditList.FirstOrDefault(x => x.AuditDep == GoodsAuditDepEnum.Financial);            if (hrAuditInfo != null)            {                if (hrAuditInfo.AuditorIds.Any(x => x == userId)) hrAuditPer = true;            }            if (finAuditInfo != null)            {                if (finAuditInfo.AuditorIds.Any(x => x == userId)) finAuditPer = true;            }            RefAsync<int> total = 0;            var data = await _sqlSugar.Queryable<Pm_GoodsStorage>()                .LeftJoin<Pm_GoodsInfo>((gs, gi) => gs.GoodsId == gi.Id)                .LeftJoin<Sys_Users>((gs, gi, u) => gs.CreateUserId == u.Id)                .LeftJoin<Sys_Users>((gs, gi, u, u1) => gs.StorageUserId == u1.Id)                .Where((gs, gi, u, u1) => gs.IsDel == 0)                .WhereIF(dto.GoodsId > 0, (gs, gi, u, u1) => gs.GoodsId == dto.GoodsId)                .WhereIF(auditLabel.Length > 0, (gs, gi, u, u1) => auditLabel.Contains((int)gs.ConfirmStatus))                .WhereIF(!string.IsNullOrEmpty(dto.GoodsName), (gs, gi, u, u1) => gi.Name.Contains(dto.GoodsName))                .WhereIF(!string.IsNullOrEmpty(dto.BatchNo), (gs, gi, u, u1) => gs.BatchNo.Contains(dto.BatchNo))                .WhereIF(finAuditPer, (gs, gi, u, u1) => _goodsTypeIds.Contains(gi.Type))                .Select((gs, gi, u, u1) => new GoodsStorageListView()                {                    Id = gs.Id,                    GoodsId = gs.GoodsId,                    GoodsType = gi.Type,                    BatchNo = gs.BatchNo,                    GoodsName = gi.Name,                    Quantity = gs.Quantity,                    UnitPrice = gs.UnitPrice,                    TotalPrice = gs.TotalPrice,                    SupplierName = gs.SupplierName,                    SupplierTel = gs.SupplierTel,                    SupplierAddress = gs.SupplierAddress,                    SupplierSource = gs.SupplierSource,                    StorageUserName = u1.CnName,                    StorageTime = gs.StorageTime,                    CreateUserName = u.CnName,                    ConfirmStatus = gs.ConfirmStatus,                    StatusDesc = gs.StatusDesc,                    CreateTime = gs.CreateTime,                    Remark = gs.Remark                })                .OrderByDescending(gs => gs.CreateTime)                .ToPageListAsync(dto.PageIndex, dto.PageSize, total);            foreach (var item in data)            {                var auditDeps = new List<GoodsStorageAuditPerView>                {                    new() { AuditPer = hrAuditPer, AuditDep = GoodsAuditDepEnum.Hr, ButtonText = GoodsAuditDepEnum.Hr.GetEnumDescription() }                };                var auditPer = GoodsAuditType(item.GoodsType);                if (auditPer)                {                    auditDeps.Add(new() { AuditPer = finAuditPer, AuditDep = GoodsAuditDepEnum.Financial, ButtonText = GoodsAuditDepEnum.Financial.GetEnumDescription() });                }                item.AuditPers = auditDeps.ToArray();            }            _jv.Code = StatusCodes.Status200OK;            _jv.Data = data;            _jv.Count = total;            _jv.Msg = $"操作成功";            return _jv;        }        /// <summary>        /// 物品入库详情        /// </summary>        /// <param name="id"></param>        /// <returns></returns>        public async Task<JsonView> GoodsStorageInfo(int portType, int id)        {            var data = await _sqlSugar.Queryable<Pm_GoodsStorage>()                .LeftJoin<Pm_GoodsInfo>((gs, gi) => gs.GoodsId == gi.Id)                .LeftJoin<Sys_Users>((gs, gi, u) => gs.CreateUserId == u.Id)                .LeftJoin<Sys_Users>((gs, gi, u, u1) => gs.StorageUserId == u1.Id)                .Where((gs, gi, u, u1) => gs.IsDel == 0)                .WhereIF(id > 0, (gs, gi, u, u1) => gs.Id == id)                .Select((gs, gi, u, u1) => new                {                    gs.Id,                    gs.GoodsId,                    GoodsName = gi.Name,                    gs.Quantity,                    gs.UnitPrice,                    gs.TotalPrice,                    gs.SupplierName,                    gs.SupplierTel,                    gs.SupplierAddress,                    gs.SupplierSource,                    gs.ReceiveQuantity,                    gs.StorageUserId,                    StorageUser = u1.CnName,                    gs.StorageTime,                    CreateUserName = u.CnName,                    gs.CreateUserId,                    gs.CreateTime,                    gs.Remark,                    //gs.IsInConfirm                })                .FirstAsync();            _jv.Msg = $"操作成功!";            _jv.Code = StatusCodes.Status200OK;            _jv.Data = data;            return _jv;        }        /// <summary>        /// 物品入库 操作(Create Or Edit)        /// </summary>        /// <param name="dto"></param>        /// <param name="currUserId"></param>        /// <returns></returns>        public async Task<JsonView> GoodsStorageOp(GoodsStorageOpDto dto, int currUserId)        {            var info = _mapper.Map<Pm_GoodsStorage>(dto);            info.CreateUserId = currUserId;            info.BatchNo = DateTime.Now.ToString("yyyyMMddHHmmssfff");            var sign = dto.Id;            _sqlSugar.BeginTran();            if (info.Id > 0) //修改            {                var selectInfo = await _sqlSugar.Queryable<Pm_GoodsStorage>().FirstAsync(x => x.Id == dto.Id);                var auditStatus = selectInfo.ConfirmStatus;                if (auditStatus == GoodsConfirmEnum.Confirmed || auditStatus == GoodsConfirmEnum.PartConfirmed)                {                    _sqlSugar.RollbackTran();                    _jv.Msg = $"该条入库信息已确认或部分确认审核,不可更改!如若更改请取消已确认或部分确认审核状态!";                    return _jv;                }                var storageEdit = await _sqlSugar.Updateable(info)                    .UpdateColumns(x => new                    {                        x.Quantity,                        x.UnitPrice,                        x.TotalPrice,                        x.SupplierName,                        x.SupplierTel,                        x.SupplierAddress,                        x.SupplierSource,                        x.StorageUserId,                        x.StorageTime                    })                    .Where(x => x.Id == dto.Id)                    .ExecuteCommandAsync();                if (storageEdit < 1)                {                    _sqlSugar.RollbackTran();                    _jv.Msg = $"修改失败!";                    return _jv;                }                //入库确认默认状态 多条 or 单条                var auditInfos = await _sqlSugar.Queryable<Pm_GoodsAudit>().Where(x => x.Type == 1 && x.DataId == dto.Id).ToListAsync();                if (auditInfos.Any())                {                    var isAuditPer = false;                    var goodsInfo = await _sqlSugar.Queryable<Pm_GoodsInfo>().FirstAsync(x => x.IsDel == 0 && x.Id == dto.GoodsId);                    if (goodsInfo != null)                    {                        isAuditPer = GoodsAuditType(goodsInfo.Type);                    }                    if (!isAuditPer && auditInfos.Count == 1)                    {                        var auditInfo = new Pm_GoodsAudit(1, GoodsAuditDepEnum.Financial, dto.Id, GoodsConfirmEnum.WaitConfirm, currUserId);                        await _sqlSugar.Insertable(auditInfo).ExecuteCommandAsync();                    }                }            }            else if (info.Id < 1) //添加            {                info.ConfirmStatus = GoodsConfirmEnum.WaitConfirm;                sign = await _sqlSugar.Insertable(info).ExecuteReturnIdentityAsync();                if (sign < 1)                {                    _sqlSugar.RollbackTran();                    _jv.Msg = $"添加失败!";                    return _jv;                }                //入库确认默认状态                List<Pm_GoodsAudit> auditInfos = GoodsStorageConfirm(1, sign, info.CreateUserId);                if (auditInfos.Any())                {                    //验证添加多条或者单条审核状态                    var goodsInfo = await _sqlSugar.Queryable<Pm_GoodsInfo>().FirstAsync(x => x.IsDel == 0 && x.Id == dto.GoodsId);                    if (goodsInfo != null)                    {                        var isAuditPer = GoodsAuditType(goodsInfo.Type);                        if (!isAuditPer) auditInfos = auditInfos.Where(x => x.Dep == GoodsAuditDepEnum.Hr).ToList();                    }                    await _sqlSugar.Insertable(auditInfos).ExecuteCommandAsync();                }            }            _sqlSugar.CommitTran();            _jv.Data = new { sign };            _jv.Msg = $"操作成功!";            _jv.Code = StatusCodes.Status200OK;            return _jv;        }        /// <summary>        /// 物品入库 确认操作-默认审核部门        /// </summary>        /// <param name="auditType">        /// 审核类型        /// 1.入库 2.出库         /// </param>        /// <param name="dataId">dataId</param>        /// <param name="currUserId">审核人</param>        /// <returns></returns>        public List<Pm_GoodsAudit> GoodsStorageConfirm(int auditType, int dataId, int currUserId)        {            var goodsAuditList = new List<Pm_GoodsAudit>            {                new(auditType, GoodsAuditDepEnum.Hr, dataId, GoodsConfirmEnum.WaitConfirm, currUserId),                new(auditType, GoodsAuditDepEnum.Financial, dataId, GoodsConfirmEnum.WaitConfirm, currUserId)            };            return goodsAuditList;        }        /// <summary>        /// 物品入库 确认操作        /// </summary>        /// <param name="dto"></param>        /// <returns></returns>        public async Task<JsonView> GoodsStorageConfirmStatusChange(GoodsStorageConfirmDto dto, int currUserId)        {            int gsId = dto.Id;            var auditDep = dto.AuditDep;            if (gsId < 1)            {                _jv.Msg = string.Format("{0}", MsgTips.Id);                return _jv;            }            if (currUserId < 1)            {                _jv.Msg = string.Format("{0}", MsgTips.UserId);                return _jv;            }            //验证审核部门            (bool auditPer, GoodsAuditDepEnum goodsAuditDep) = GoodsAuditDep(currUserId, auditDep, 1);            if (!auditPer)            {                _jv.Msg = string.Format("未分配入库确认权限!");                return _jv;            }            //入库确认 更改审核状态            _sqlSugar.BeginTran();            var info = await _sqlSugar.Queryable<Pm_GoodsStorage>().Where(x => x.IsDel == 0 && x.Id == gsId).FirstAsync();            if (info == null)            {                _jv.Msg = string.Format("入库信息不存在!");                return _jv;            }            var goodsInfo = await _sqlSugar.Queryable<Pm_GoodsInfo>().Where(x => x.IsDel == 0 && x.Id == info.GoodsId).FirstAsync();            if (goodsInfo == null)            {                _jv.Msg = string.Format("物品信息不存在!");                return _jv;            }            int goodsTypeId = goodsInfo.Type;            var preChangeStatus = info.ConfirmStatus;            if (preChangeStatus == dto.ConfirmStatus)            {                _jv.Msg = string.Format("“{0}”已操作,请勿重复该操作!", dto.ConfirmStatus.GetEnumDescription());                return _jv;            }            var preInfos = await _sqlSugar.Queryable<Pm_GoodsAudit>().Where(x => x.IsDel == 0 && x.DataId == gsId).ToListAsync();            //验证是否需要多级确认            var isAuditPer = GoodsAuditType(goodsTypeId);            //单部门审核时默认人事部审核            if (!isAuditPer) goodsAuditDep = GoodsAuditDepEnum.Hr;            var auditInfo = preInfos.FirstOrDefault(x => x.Dep == goodsAuditDep);            if (auditInfo != null)            {                //移除部门审核状态                preInfos.Remove(auditInfo);                auditInfo.AuditStatus = dto.ConfirmStatus;                auditInfo.AuditUserId = currUserId;                auditInfo.AuditTime = DateTime.Now;                var updStatus = await _sqlSugar.Updateable(auditInfo)                    .UpdateColumns(x => new { x.AuditStatus, x.AuditUserId, x.AuditTime })                    .ExecuteCommandAsync();                if (updStatus < 1)                {                    _sqlSugar.RollbackTran();                    _jv.Msg = string.Format("入库确认失败!");                    return _jv;                }            }            else            {                auditInfo = new Pm_GoodsAudit(1, goodsAuditDep, gsId, dto.ConfirmStatus, currUserId, currUserId);                var addStatus = await _sqlSugar.Insertable(auditInfo).ExecuteCommandAsync();                if (addStatus < 1)                {                    _sqlSugar.RollbackTran();                    _jv.Msg = string.Format("入库确认失败!");                    return _jv;                }            }            preInfos.Add(auditInfo);            //入库确认 更改入库状态及扣或增加除库存数、金额            var confirmStatus = GoodsConfirmEnum.WaitConfirm;            if (isAuditPer) //多级审核确认            {                if (preInfos.Where(x => x.AuditStatus == GoodsConfirmEnum.Confirmed).Count() >= 2)                {                    confirmStatus = GoodsConfirmEnum.Confirmed;                }                else if (preInfos.Count(x => x.AuditStatus == GoodsConfirmEnum.Confirmed) >= 1)                {                    confirmStatus = GoodsConfirmEnum.PartConfirmed;                }                else if (preInfos.Where(x => x.AuditStatus == GoodsConfirmEnum.UnApproved).Count() > 0)                {                    confirmStatus = GoodsConfirmEnum.UnApproved;                }                else if (preInfos.Where(x => x.AuditStatus == GoodsConfirmEnum.PartConfirmed).Count() > 0)                {                    confirmStatus = GoodsConfirmEnum.PartConfirmed;                }            }            else //人事部审核确认            {                confirmStatus = GoodsConfirmEnum.Confirmed;                confirmStatus = dto.ConfirmStatus;                preInfos = preInfos.Where(x => x.Dep == GoodsAuditDepEnum.Hr).ToList();            }            //入库状态描述            var statusDesc = new StringBuilder();            foreach (var preInfo in preInfos)            {                string depName = preInfo.Dep.GetEnumDescription(),                       auditStatus = preInfo.AuditStatus.GetEnumDescription(),                       auditUserName = preInfo.AuditUserId > 0 ? _sqlSugar.Queryable<Sys_Users>().First(x => x.Id == preInfo.AuditUserId)?.CnName ?? "-" : "-",                       auditTime = preInfo.AuditUserId > 0 ? preInfo.AuditTime.ToString("yyyy-MM-dd HH:mm:ss") : "-";                statusDesc.Append(string.Format("{0}:状态:{1}  审核人:{2}  审核时间:{3};<br/>", depName, auditStatus, auditUserName, auditTime));            }            //更改入库状态及描述            info.ConfirmStatus = confirmStatus;            info.StatusDesc = statusDesc.ToString();            var goodsStorageUpd = await _sqlSugar.Updateable(info)                .UpdateColumns(x => new                {                    x.ConfirmStatus,                    x.StatusDesc,                })                .Where(x => x.Id == info.Id)                .ExecuteCommandAsync();            if (goodsStorageUpd < 1)            {                _sqlSugar.RollbackTran();                _jv.Msg = $"入库确认状态更改失败!";                return _jv;            }            //入库审核通过数量、金额            decimal auditQuantity = info.Quantity,                    auditTotalPrice = info.TotalPrice;            goodsInfo.LastUpdateUserId = currUserId;            goodsInfo.LastUpdateTime = DateTime.Now;            if (confirmStatus == GoodsConfirmEnum.Confirmed) // 确认状态            {                //更改后的状态和更改前的状态不一致时 更改库存数、金额                if (preChangeStatus != confirmStatus) //                {                    goodsInfo.SQ_Total += auditQuantity;                    goodsInfo.StockQuantity += auditQuantity;                    goodsInfo.PriceTotal += auditTotalPrice;                }            }            else //其他状态 拒绝、部分确认、等待确认            {                //更改前状态为确认状态时,减库存数、金额                if (preChangeStatus == GoodsConfirmEnum.Confirmed)                {                    goodsInfo.SQ_Total -= auditQuantity;                    goodsInfo.StockQuantity -= auditQuantity;                    goodsInfo.PriceTotal -= auditTotalPrice;                }            }            var goodsUpd = await _sqlSugar.Updateable(goodsInfo)                .UpdateColumns(x => new                {                    x.SQ_Total,                    x.StockQuantity,                    x.PriceTotal,                    x.LastUpdateUserId,                    x.LastUpdateTime,                })                .Where(x => x.Id == info.GoodsId)                .ExecuteCommandAsync();            if (goodsUpd > 0)            {                _sqlSugar.CommitTran();                _jv.Msg = $"操作成功!";                _jv.Code = StatusCodes.Status200OK;                return _jv;            }            _sqlSugar.RollbackTran();            _jv.Msg = $"操作失败!";            return _jv;        }        /// <summary>        /// 获取物品审核部门        /// </summary>        /// <param name="userId"> userId </param>        /// <param name="auditDepEnum"> 审核部门枚举 </param>        /// <param name="auditType">        /// 指定审核类型(入库/出库)        /// 1:入库审核        /// 2:出库审核        /// </param>        /// <returns></returns>        public static (bool, GoodsAuditDepEnum) GoodsAuditDep(int userId, GoodsAuditDepEnum auditDepEnum, int auditType = 1)        {            if (userId < 1) return (false, GoodsAuditDepEnum.Hr);            var auditList = GoodsStorageConfirmAuditDep(1);            if (auditType == 1)            {                if (auditList.Any(x => x.AuditDep == auditDepEnum && x.AuditorIds.Contains(userId)))                {                    return (true, auditDepEnum);                }            }            return (false, GoodsAuditDepEnum.Hr);        }        /// <summary>        /// 物品审核部门列表        /// </summary>        /// <param name="auditType">        /// 指定审核类型(入库/出库)        /// 1:入库审核        /// 2:出库审核        /// </param>        /// <returns></returns>        public static List<GoodsAuditDepView> GoodsStorageConfirmAuditDep(int auditType = 1)        {            var auditList = new List<GoodsAuditDepView>();            var hrAuditorIds = new GoodsAuditDepView()            {                AuditDep = GoodsAuditDepEnum.Hr,                AuditorIds = new int[] {                    309,    // 赖红燕                    343,    // 陈湘                     //374,    // 罗颖                    208,    // 雷怡                }            };            var finAuditorIds = new GoodsAuditDepView()            {                AuditDep = GoodsAuditDepEnum.Financial,                AuditorIds = new int[] {                    187,    // 曾艳                     281,    // 伏虹瑾                    208,    // 雷怡                }            };            if (auditType == 1)//入库            {                hrAuditorIds.AuditorIds = new int[] {                    //343,    // 陈湘                     374,    // 罗颖                    208,    // 雷怡                };                auditList.Add(hrAuditorIds);                auditList.Add(finAuditorIds);            }            else if (auditType == 2) //出库            {                auditList.Add(hrAuditorIds);                auditList.Add(finAuditorIds);            }            return auditList;        }        /// <summary>        /// 物品入库 Del        /// </summary>        /// <param name="id"></param>        /// <returns></returns>        public async Task<JsonView> GoodsStorageDel(int id, int userId)        {            var storageInfo = await _sqlSugar                .Queryable<Pm_GoodsStorage>()                .Where(x => x.Id == id)                .FirstAsync();            if (storageInfo == null) return _jv;            var auditStatus = storageInfo.ConfirmStatus;            if (auditStatus == GoodsConfirmEnum.Confirmed || auditStatus == GoodsConfirmEnum.PartConfirmed)            {                _sqlSugar.RollbackTran();                _jv.Msg = $"该条入库信息已确认或部分确认审核,不可删除!如若删除请取消已确认或部分确认审核状态!";                return _jv;            }            decimal delAgoQuantity = storageInfo.Quantity,                    delAgoTotalPrice = storageInfo.TotalPrice;            var goodsId = storageInfo.GoodsId;            _sqlSugar.BeginTran();            var storageDel = await _sqlSugar.Updateable<Pm_GoodsStorage>()                .SetColumns(x => new Pm_GoodsStorage                {                    DeleteUserId = userId,                    DeleteTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),                    IsDel = 1                })                .Where(x => x.Id == id)                .ExecuteCommandAsync();            if (storageDel < 1)            {                _sqlSugar.RollbackTran();                _jv.Msg = $"操作失败!";                return _jv;            }            var goodsInfo = await _sqlSugar.Queryable<Pm_GoodsInfo>().FirstAsync(x => x.Id == goodsId);            goodsInfo.SQ_Total -= delAgoQuantity;            goodsInfo.StockQuantity -= delAgoQuantity;            goodsInfo.PriceTotal -= delAgoTotalPrice;            goodsInfo.LastUpdateUserId = userId;            goodsInfo.LastUpdateTime = DateTime.Now;            var goodsEdit = await _sqlSugar.Updateable(goodsInfo)                .UpdateColumns(x => new                {                    x.SQ_Total,                    x.StockQuantity,                    x.PriceTotal,                    x.LastUpdateUserId,                    x.LastUpdateTime,                })                .Where(x => x.Id == goodsId)                .ExecuteCommandAsync();            if (goodsEdit > 0)            {                _sqlSugar.CommitTran();                _jv.Msg = $"操作成功!";                _jv.Code = StatusCodes.Status200OK;                return _jv;            }            _sqlSugar.RollbackTran();            _jv.Msg = $"操作失败!";            return _jv;        }        /// <summary>        /// 物品入库        /// excelDownload        /// </summary>        /// <param name="dto"></param>        /// <returns></returns>        public async Task<JsonView> GoodsStorageExcelDownload()        {            var fileName = $"物资入库{Guid.NewGuid()}.xlsx";            var excelTempPath = $"{_excelPath}Template/物资入库Temp.xlsx";            if (!File.Exists(excelTempPath))            {                _jv.Code = StatusCodes.Status204NoContent;                _jv.Msg = $"该模板文件不存在!";                return _jv;            }            _url = $"{_url}Office/Excel/GoodsFiles/";            _excelPath = $"{_excelPath}GoodsFiles";            if (!Directory.Exists(_excelPath))            {                Directory.CreateDirectory(_excelPath);            }            //入库记录            var storageData = await _sqlSugar.Queryable<Pm_GoodsStorage>()                .LeftJoin<Sys_Users>((gs, su) => gs.StorageUserId == su.Id)                .Where((gs, su) => gs.IsDel == 0)                .Select((gs, su) => new                {                    gs.GoodsId,                    gs.Quantity,                    su.CnName,                    gs.StorageTime                })                .ToListAsync();            //出库记录            var receiveData = await _sqlSugar.Queryable<Pm_GoodsReceive>()                .LeftJoin<Sys_Users>((gr, su) => gr.CreateUserId == su.Id)                .Where((gr, su) => gr.IsDel == 0)                .Select((gr, su) => new                {                    gr.GoodsId,                    gr.Quantity,                    su.CnName,                    gr.CreateTime,                    gr.Reason                })                .ToListAsync();            var data = await _sqlSugar.Queryable<Pm_GoodsInfo>()                .Where(gi => gi.IsDel == 0)                .Select(gi => new GoodsStorageExcelDownloadView                {                    Id = gi.Id,                    Name = gi.Name,                    SQ_Total = gi.SQ_Total,                    OQ_Total = gi.OQ_Total,                    StockQuantity = gi.StockQuantity,                    Unit = gi.Unit                })                .ToListAsync();            foreach (var item in data)            {                var storageData1 = storageData.Where(x => x.GoodsId == item.Id).ToList();                if (storageData1.Any())                {                    item.SQ_Total1 = storageData1.Sum(x => x.Quantity);                    item.SQ_Total -= item.SQ_Total1;                    item.StorageLabel = string.Join("\r\n", storageData1.Select(x => "数量:【" + x.Quantity.ToString("#0.00") + "】  入库人:【" + x.CnName + "】  入库时间:【" + x.StorageTime + "】").ToList());                }                var receiveData1 = receiveData.Where(x => x.GoodsId == item.Id).ToList();                if (receiveData1.Any())                {                    item.ReceiveLabel = string.Join("\r\n", receiveData1.Select(x => "数量:【" + x.Quantity.ToString("#0.00") + "】  申请人:【" + x.CnName + "】  申请时间:【" + x.CreateTime.ToString("yyyy-MM-dd HH:mm:ss") + "】  原因:【" + x.Reason + "】").ToList());                }            }            //载入模板            WorkbookDesigner designer = new()            {                Workbook = new Workbook(excelTempPath)            };            designer.SetDataSource("Export", data);            designer.Process();            #region 渲染Cell批注            var sheet = designer.Workbook.Worksheets[0];            for (int i = 0; i < data.Count; i++)            {                string storageComment = $"C{i + 2}",                       receiveComment = $"D{i + 2}",                       storageCommentText = data[i].StorageLabel,                       receiveCommentText = data[i].ReceiveLabel;                if (!string.IsNullOrEmpty(storageCommentText))                {                    int storageIndex = sheet.Comments.Add(storageComment);                    Aspose.Cells.Comment comment = sheet.Comments[storageIndex];                    comment.Note = storageCommentText;                    comment.Width = 500;                    comment.Height = 200;                    //comment.Font.Color = Color.Red;                }                if (!string.IsNullOrEmpty(receiveCommentText))                {                    int receiveIndex = sheet.Comments.Add(receiveComment);                    Aspose.Cells.Comment comment = sheet.Comments[receiveIndex];                    comment.Note = receiveCommentText;                    comment.Width = 800;                    comment.Height = 200;                    //comment.Font.Color = Color.Red;                }            }            #endregion            string serverPath = $"{_url}{fileName}";            designer.Workbook.Save($"{_excelPath}/{fileName}");            _jv.Code = StatusCodes.Status200OK;            _jv.Data = new { url = serverPath };            _jv.Msg = $"操作成功";            return _jv;        }        /// <summary>        /// 物品领用列表        /// </summary>        /// <param name="dto"></param>        /// <returns></returns>        public async Task<JsonView> GoodsReceiveList(GoodsReceiveListDTO dto)        {            //参数处理            int[] typeLabel = Array.Empty<int>(),                  userLabel = Array.Empty<int>(),                  auditLabel = Array.Empty<int>(),                  groupLabel = Array.Empty<int>();            string[] userNameLabel = Array.Empty<string>();            int currUserId = dto.CurrUserId;            if (!string.IsNullOrEmpty(dto.TypeLabel))            {                typeLabel = dto.TypeLabel                    .Split(',')                    .Select(x =>                    {                        if (int.TryParse(x, out var id)) return id;                        return id;                    })                    .ToArray();            }            if (!string.IsNullOrEmpty(dto.UserLabel))            {                userLabel = dto.UserLabel                    .Split(',')                    .Select(x =>                    {                        if (int.TryParse(x, out var id)) return id;                        return id;                    })                    .ToArray();                if (userLabel.Any())                {                    userNameLabel = await _sqlSugar.Queryable<Sys_Users>().Where(x => userLabel.Contains(x.Id)).Select(x => x.CnName).ToArrayAsync();                }            }            if (!string.IsNullOrEmpty(dto.AuditLabel))            {                auditLabel = dto.AuditLabel                    .Split(',')                    .Select(x =>                    {                        if (int.TryParse(x, out var id)) return id;                        return id;                    })                    .ToArray();                if (auditLabel.Any(x => x == -1))                {                    auditLabel = auditLabel.Where(x => x != -1).ToArray();                }            }            if (!string.IsNullOrEmpty(dto.GroupLabel))            {                groupLabel = dto.GroupLabel                    .Split(',')                    .Select(x =>                    {                        if (int.TryParse(x, out var id)) return id;                        return id;                    })                    .ToArray();            }            //全部团组            bool isAllGroups = false;            if (groupLabel.Contains(-3)) isAllGroups = true;            //物品ID和物品名称只能传一个            if (dto.GoodsId > 0) dto.GoodsName = string.Empty;            if (!string.IsNullOrEmpty(dto.GoodsName)) dto.GoodsId = 0;            if (currUserId == 343) //陈湘OAId登录 只显示贵重物品审核信息            {                if (_goodsTypeIds.Any())                {                    var newArray = typeLabel.ToList();                    newArray.AddRange(_goodsTypeIds);                    typeLabel = newArray.ToArray();                }            }            var beginBool = DateTime.TryParse(!string.IsNullOrEmpty(dto.BeginDt) ? $"{dto.BeginDt} 00:00:00" : string.Empty, out var begin);            var endBool = DateTime.TryParse(!string.IsNullOrEmpty(dto.EndDt) ? $"{dto.EndDt} 00:00:00" : string.Empty, out var end);            //新旧领用数据整合            var oldDatas = _sqlSugar.Queryable<Pm_GoodsReceive>()                .InnerJoin<Pm_GoodsInfo>((gr, gi) => gr.GoodsId == gi.Id)                .LeftJoin<Sys_SetData>((gr, gi, sd) => gi.Type == sd.Id)                .LeftJoin<Sys_Users>((gr, gi, sd, u1) => gr.AuditUserId == u1.Id)                .LeftJoin<Sys_Users>((gr, gi, sd, u1, u2) => gr.CreateUserId == u2.Id)                .LeftJoin<Grp_DelegationInfo>((gr, gi, sd, u1, u2, di) => gr.GroupId == di.Id)                .Where((gr, gi, sd, u1, u2, di) => gr.IsDel == 0 && gr.GoodsId > 0)                .Select((gr, gi, sd, u1, u2, di) => new GoodsReceiveListMobileView                {                    Id = gr.Id,                    GroupId = gr.GroupId,                    GroupName = di.TeamName,                    GoodsId = gr.GoodsId,                    GoodsName = gi.Name,                    GoodsTypeId = gi.Type,                    GoodsType = sd.Name,                    Quantity = gr.Quantity,                    Unit = gi.Unit,                    Reason = gr.Reason,                    Remark = gr.Remark,                    AuditStatus = gr.AuditStatus,                    StatusDesc = gr.StatusDesc,                    AuditUserId = gr.AuditUserId,                    AuditUserName = u1.CnName,                    AuditTime = gr.AuditTime,                    CreateUserName = u2.CnName,                    CreateTime = gr.CreateTime                });            var newDatas = _sqlSugar.Queryable<Pm_GoodsReceive>()                .LeftJoin<Pm_GoodsReceiveDetails>((gr, grd) => gr.Id == grd.GoodsReceiveId)                .LeftJoin<Pm_GoodsInfo>((gr, grd, gi) => grd.GoodsId == gi.Id)                .LeftJoin<Sys_SetData>((gr, grd, gi, sd) => gi.Type == sd.Id)                .LeftJoin<Sys_Users>((gr, grd, gi, sd, u1) => gr.AuditUserId == u1.Id)                .LeftJoin<Sys_Users>((gr, grd, gi, sd, u1, u2) => gr.CreateUserId == u2.Id)                .LeftJoin<Grp_DelegationInfo>((gr, grd, gi, sd, u1, u2, di) => gr.GroupId == di.Id)                .Where((gr, grd, gi, sd, u1, u2, di) => gr.IsDel == 0 && grd.IsDel == 0 && gr.GoodsId < 1)                .Select((gr, grd, gi, sd, u1, u2, di) => new GoodsReceiveListMobileView                {                    Id = gr.Id,                    GroupId = gr.GroupId,                    GroupName = di.TeamName,                    GoodsId = grd.GoodsId,                    GoodsName = gi.Name,                    GoodsTypeId = gi.Type,                    GoodsType = sd.Name,                    Quantity = grd.Quantity,                    Unit = gi.Unit,                    Reason = gr.Reason,                    Remark = gr.Remark,                    AuditStatus = gr.AuditStatus,                    StatusDesc = gr.StatusDesc,                    AuditUserId = gr.AuditUserId,                    AuditUserName = u1.CnName,                    AuditTime = gr.AuditTime,                    CreateUserName = u2.CnName,                    CreateTime = gr.CreateTime                });            var isIdSelect = false;            var isNameSelect = false;            if (dto.GoodsId > 0)            {                isIdSelect = true;                dto.GoodsName = string.Empty;            }            if (!string.IsNullOrEmpty(dto.GoodsName))            {                isIdSelect = false;                isNameSelect = true;            }            RefAsync<int> total = 0;            var data = _sqlSugar.UnionAll(oldDatas, newDatas)                .WhereIF(isIdSelect && !isNameSelect, x => x.GoodsId == dto.GoodsId)                .WhereIF(!isIdSelect && isNameSelect, x => x.GoodsName.Contains(dto.GoodsName))                .WhereIF(auditLabel.Length > 0, x => auditLabel.Contains((int)x.AuditStatus))                .WhereIF(typeLabel.Length > 0, x => typeLabel.Contains(x.GoodsTypeId))                .WhereIF(userNameLabel.Length > 0, x => userNameLabel.Contains(x.CreateUserName))                .WhereIF(!isAllGroups && groupLabel.Length > 0, x => groupLabel.Contains(x.GroupId))                .WhereIF(isAllGroups, x => x.GroupId > 0)                .WhereIF(beginBool && endBool, x => x.CreateTime >= begin && x.CreateTime <= end)                .OrderByDescending(x => x.CreateTime);            //excel导出            if (dto.IsExcelDownload)            {                var fileName = $"物资领用{Guid.NewGuid()}.xlsx";                var excelTempPath = $"{_excelPath}Template/物资领用Temp.xlsx";                if (!File.Exists(excelTempPath))                {                    _jv.Code = StatusCodes.Status204NoContent;                    _jv.Msg = $"该模板文件不存在!";                    return _jv;                }                _url = $"{_url}Office/Excel/GoodsFiles/";                _excelPath = $"{_excelPath}GoodsFiles";                if (!Directory.Exists(_excelPath))                {                    Directory.CreateDirectory(_excelPath);                }                //载入模板                WorkbookDesigner designer = new()                {                    Workbook = new Workbook(excelTempPath)                };                var tableData = await data.ToListAsync();                foreach (var item in tableData)                {                    var oldGroupName = item.GroupName;                    item.GroupName = item.GroupId switch                    {                        0 => "其他物资(公司内部物资)",                        -1 => "拜访客户所使用的物资",                        -2 => "库存调整",                        _ => oldGroupName                    };                    //审核相关处理                    if (string.IsNullOrEmpty(item.AuditUserName))                    {                        var oldAuditDatas = await _sqlSugar.Queryable<Pm_GoodsAudit>()                           .LeftJoin<Sys_Users>((x, u) => x.AuditUserId == u.Id)                           .Where((x, u) => x.IsDel == 0 && x.Type == 2 && x.DataId == item.Id)                           .Select((x, u) => new                           {                               x.AuditTime,                               u.CnName                           })                           .ToListAsync();                        if (oldAuditDatas.Any())                        {                            item.AuditUserName = string.Join("、", oldAuditDatas.Select(x => x.CnName).ToArray());                            if (!string.IsNullOrEmpty(item.AuditUserName))                            {                                item.AuditTime = oldAuditDatas.Last().AuditTime;                            }                            else item.AuditTime = DateTime.Now;                        }                        else                        {                            var newAuditDatas = await _sqlSugar.Queryable<Sys_AuditRecord>()                                .InnerJoin<Sys_AuditFlow>((x, y) => x.FlowId == y.Id)                               .Where((x, y) => x.IsDel == 0 && y.BusinessType == 1 && y.BusinessId == item.Id)                               .Select((x, y) => new                               {                                   x.AuditTime,                                   x.AuditorName                               })                               .ToListAsync();                            if (newAuditDatas.Any())                            {                                item.AuditUserName = string.Join("、", newAuditDatas.Select(x => x.AuditorName).Distinct().ToArray());                                if (!string.IsNullOrEmpty(item.AuditUserName))                                {                                    item.AuditTime = newAuditDatas.Last().AuditTime;                                }                                else item.AuditTime = DateTime.Now;                            }                        }                    }                }                designer.SetDataSource("Export", tableData);                designer.Process();                string serverPath = $"{_url}{fileName}";                designer.Workbook.Save($"{_excelPath}/{fileName}");                _jv.Code = StatusCodes.Status200OK;                _jv.Data = new { url = serverPath };                _jv.Msg = $"操作成功";                return _jv;            }            //返回分页数据            var view = await data.ToPageListAsync(dto.PageIndex, dto.PageSize, total);            foreach (var item in view)            {                //团组名称处理                var oldGroupName = item.GroupName;                item.GroupName = item.GroupId switch                {                    0 => "其他物资(公司内部物资)",                    -1 => "拜访客户所使用的物资",                    -2 => "库存调整",                    _ => oldGroupName                };                //审核相关处理                if (string.IsNullOrEmpty(item.AuditUserName))                {                    var oldAuditDatas = await _sqlSugar.Queryable<Pm_GoodsAudit>()                       .LeftJoin<Sys_Users>((x, u) => x.AuditUserId == u.Id)                       .Where((x, u) => x.IsDel == 0 && x.Type == 2 && x.DataId == item.Id)                       .Select((x, u) => new                       {                           x.AuditTime,                           u.CnName                       })                       .ToListAsync();                    if (oldAuditDatas.Any())                    {                        item.AuditUserName = string.Join("、", oldAuditDatas.Select(x => x.CnName).ToArray());                        if (!string.IsNullOrEmpty(item.AuditUserName))                        {                            item.AuditTime = oldAuditDatas.Last().AuditTime;                        }                        else item.AuditTime = DateTime.Now;                    }                    else                    {                        var newAuditDatas = await _sqlSugar.Queryable<Sys_AuditRecord>()                            .InnerJoin<Sys_AuditFlow>((x, y) => x.FlowId == y.Id)                           .Where((x, y) => x.IsDel == 0 && y.BusinessType == 1 && y.BusinessId == item.Id)                           .Select((x, y) => new                           {                               x.AuditTime,                               x.AuditorName                           })                           .ToListAsync();                        if (newAuditDatas.Any())                        {                            item.AuditUserName = string.Join("、", newAuditDatas.Select(x => x.AuditorName).Distinct().ToArray());                            if (!string.IsNullOrEmpty(item.AuditUserName))                            {                                item.AuditTime = newAuditDatas.Last().AuditTime;                            }                            else item.AuditTime = DateTime.Now;                        }                    }                }                //权限前台验证                var auditPers = new List<GoodsStorageAuditPerView>                {                    new() { AuditPer = true, AuditDep = GoodsAuditDepEnum.Hr, ButtonText = GoodsAuditDepEnum.Hr_Reception.GetDescription() }                };                if (_goodsTypeIds.Contains(item.GoodsTypeId))                {                    auditPers.Add(new() { AuditPer = true, AuditDep = GoodsAuditDepEnum.Hr, ButtonText = GoodsAuditDepEnum.Hr.GetDescription() });                }                item.AuditPers = auditPers.ToArray();            }            if (dto.PortType == 2 || dto.PortType == 3)            {                _jv.Data = view;            }            else if (dto.PortType == 1)            {                var view1 = _mapper.Map<List<GoodsReceiveListView>>(view);                _jv.Data = view1;            }            _jv.Code = StatusCodes.Status200OK;            _jv.Count = total;            _jv.Msg = $"操作成功";            return _jv;        }        /// <summary>        /// 物品领用详情        /// </summary>        /// <param name="portType"></param>        /// <param name="id"></param>        /// <returns></returns>        public async Task<JsonView> GoodsReceiveInfo(int portType, int id)        {            var data = await _sqlSugar.Queryable<Pm_GoodsReceive>()                .LeftJoin<Pm_GoodsInfo>((gr, gi) => gr.GoodsId == gi.Id)                .LeftJoin<Sys_Users>((gr, gi, u1) => gr.AuditUserId == u1.Id)                .LeftJoin<Sys_Users>((gr, gi, u1, u2) => gr.CreateUserId == u2.Id)                .LeftJoin<Grp_DelegationInfo>((gr, gi, u1, u2, di) => gr.GroupId == di.Id)                .Where((gr, gi, u1, u2, di) => gr.IsDel == 0)                .WhereIF(id > 0, (gr, gi, u1, u2, di) => gr.Id == id)                .Select((gr, gi, u1, u2, di) => new GoodsReceiveInfoMobileView                {                    Id = gr.Id,                    GroupId = gr.GroupId,                    GroupName = di.TeamName,                    GoodsId = gr.GoodsId,                    GoodsName = gi.Name,                    Quantity = gr.Quantity,                    Reason = gr.Reason,                    Remark = gr.Remark,                    GoodsStorageInfo = gr.GoodsStorageInfo,                    AuditStatus = gr.AuditStatus,                    AuditUserId = gr.AuditUserId,                    AuditUserName = u1.CnName,                    AuditTime = gr.AuditTime,                    CreateUserName = u2.CnName,                    CreateTime = gr.CreateTime                })                .FirstAsync();            if (!string.IsNullOrEmpty(data.GoodsStorageInfo))            {                var subData = new List<dynamic>();                try                {                    var subData1 = JsonConvert.DeserializeObject<List<GoodsReceiveLinkStorageView>>(data.GoodsStorageInfo);                    if (subData1.Count > 0)                    {                        string goodsStorageInfoStr = string.Empty;                        var storageIds = subData1.Select(x => x.StorageId).ToList();                        var storages = await _sqlSugar.Queryable<Pm_GoodsStorage>().Where(x => x.IsDel == 0 && storageIds.Contains(x.Id)).ToListAsync();                        foreach (var item in subData1)                        {                            var storageInfo = storages.Find(x => x.Id == item.StorageId);                            if (storageInfo != null)                            {                                subData.Add(new                                {                                    item.StorageId,                                    storageInfo.BatchNo,                                    RecsiveQuantity = item.Quantity                                });                                goodsStorageInfoStr += $"物品名称:{data.GoodsName} 批次号:{storageInfo.BatchNo} 领用数量:{item.Quantity} \r\n";                            }                        }                        data.QuantityInfos = subData;                        data.GoodsStorageInfoStr = goodsStorageInfoStr;                    }                }                catch (Exception e)                {                    Console.WriteLine(e);                }            }            _jv.Code = StatusCodes.Status200OK;            _jv.Msg = $"操作成功";            if (portType == 2 || portType == 3) //移动端            {                _jv.Data = data;            }            else if (portType == 1) //pc端            {                _jv.Data = _mapper.Map<GoodsReceiveInfoView>(data);            }            return _jv;        }        /// <summary>        /// 物品领用 OP(Add Or Edit)        /// </summary>        /// <param name="dto"></param>        /// <param name="currUserId"></param>        /// <returns></returns>        public async Task<JsonView> GoodsReceiveOp(GoodsReceiveOpDto dto, int currUserId)        {            var info = _mapper.Map<Pm_GoodsReceive>(dto);            info.CreateUserId = currUserId;            var auditEnums = new List<GoodsAuditEnum>() {                    GoodsAuditEnum.Approved,    // 1                    GoodsAuditEnum.UnApproved,  // 2                    GoodsAuditEnum.OutConfirmed,// 5                    GoodsAuditEnum.OutRejected  // 6                };            _sqlSugar.BeginTran();            //物品现有库存            var goodsInfo = _sqlSugar.Queryable<Pm_GoodsInfo>().First(x => x.Id == info.GoodsId);            var stockQuantity = goodsInfo?.StockQuantity ?? 0.00M;            //待审核 该物品数量            var waitAuditQuantity = await _sqlSugar.Queryable<Pm_GoodsReceive>().Where(x => x.IsDel == 0 &&                            x.GoodsId == dto.GoodsId &&                            !auditEnums.Contains(x.AuditStatus)                ).SumAsync(x => x.Quantity);            //验证默认审核 多条 or 单条            //出库确认默认审核状态            var isAuditPer = GoodsAuditType(goodsInfo?.Type ?? 0);            //验证默认审核 多条审核时添加            var goodsAuditInfo1 = new Pm_GoodsAudit(2, GoodsAuditDepEnum.Hr_Reception, info.Id, GoodsConfirmEnum.WaitConfirm, currUserId);            var goodsAuditInfo2 = new Pm_GoodsAudit(2, GoodsAuditDepEnum.Hr, info.Id, GoodsConfirmEnum.WaitConfirm, currUserId);            var goodsAuditInfos = new List<Pm_GoodsAudit>() { goodsAuditInfo1 };            //状态描述            StringBuilder stringBuilder = new();            stringBuilder.Append($"领用确认:状态:待确认  审核人:-  审核时间:-;<br/>");            if (isAuditPer)            {                goodsAuditInfos.Add(goodsAuditInfo2);                stringBuilder.Append($"人事部:状态:待确认  审核人:-  审核时间:-;<br/>");            }            info.StatusDesc = stringBuilder.ToString();            if (info.Id > 0) //修改            {                //审核验证                var selectInfo = await _sqlSugar.Queryable<Pm_GoodsReceive>().FirstAsync(x => x.Id == info.Id);                if (auditEnums.Contains(selectInfo.AuditStatus))                {                    _sqlSugar.RollbackTran();                    _jv.Msg = $"该条数据已执行操作({selectInfo.AuditStatus.GetEnumDescription()}),不可更改!";                    return _jv;                }                //物品数量验证                var editAfterQuantity = waitAuditQuantity - selectInfo.Quantity + info.Quantity;                if (editAfterQuantity > stockQuantity)                {                    _sqlSugar.RollbackTran();                    _jv.Msg = $"该物品现有库存不足,不可更改!请联系采购人员购买!";                    return _jv;                }                var edit = await _sqlSugar.Updateable(info)                    .UpdateColumns(x => new                    {                        x.GroupId,                        x.Quantity,                        x.Reason,                        x.Remark,                        x.StatusDesc,                    })                    .Where(x => x.Id == info.Id)                    .ExecuteCommandAsync();                if (edit > 0)                {                    var auditInfos = await _sqlSugar.Queryable<Pm_GoodsAudit>().Where(x => x.DataId == info.Id).ToListAsync();                    if (!auditInfos.Any()) await _sqlSugar.Insertable(goodsAuditInfos).ExecuteCommandAsync();                    _sqlSugar.CommitTran();                    _jv.Msg = $"操作成功!";                    _jv.Code = StatusCodes.Status200OK;                    return _jv;                }            }            else if (info.Id < 1) //添加            {                //物品数量验证                decimal addAgoQuantity = waitAuditQuantity + info.Quantity;                if (addAgoQuantity > stockQuantity)                {                    _sqlSugar.RollbackTran();                    _jv.Msg = $"该物品现有库存不足,不可更改!请联系采购人员购买!";                    return _jv;                }                var add = await _sqlSugar.Insertable(info).ExecuteReturnIdentityAsync();                if (add > 0)                {                    goodsAuditInfos.ForEach(x => x.DataId = add);                    await _sqlSugar.Insertable(goodsAuditInfos).ExecuteCommandAsync();                    _sqlSugar.CommitTran();                    _jv.Msg = $"操作成功!";                    _jv.Code = StatusCodes.Status200OK;                    return _jv;                }            }            _sqlSugar.RollbackTran();            return _jv;        }        /// <summary>        /// 物品领用 Audit        /// </summary>        /// <param name="idArray"></param>        /// <param name="userId"></param>        /// <param name="auditEnum"></param>        /// <returns></returns>        public async Task<JsonView> GoodsReceiveAudit(int[] idArray, int userId, GoodsAuditEnum auditEnum)        {            if (idArray.Length < 1) return _jv;            if (!Enum.IsDefined(typeof(GoodsAuditEnum), (int)auditEnum))            {                _jv.Msg = $"出库确认状态超出可用范围!";                return _jv;            }            int receiveId = idArray[0];            var currUserName = _sqlSugar.Queryable<Sys_Users>().First(x => x.Id == userId)?.CnName ?? "-";            _sqlSugar.BeginTran();            var receiveInfo = await _sqlSugar.Queryable<Pm_GoodsReceive>().FirstAsync(x => x.IsDel == 0 && receiveId == x.Id);            if (receiveInfo == null)            {                _sqlSugar.RollbackTran();                _jv.Msg = $"当前领用信息不存在!";                return _jv;            }            var goodsInfo = await _sqlSugar.Queryable<Pm_GoodsInfo>().FirstAsync(x => x.Id == receiveInfo.GoodsId);            int goodTypeId = goodsInfo?.Type ?? 0;            //审核前状态            var preChangeStatus = receiveInfo.AuditStatus;            //状态验证            //if (preChangeStatus == auditEnum)            //{            //    _sqlSugar.RollbackTran();            //    _jv.Msg = $"该条数据状态已设置,不可重复设置!";            //    return _jv;            //}            var isAuditPer = GoodsAuditType(goodTypeId);            if (isAuditPer) //多人审核            {                var auditDep = GoodsAuditDepEnum.Hr_Reception;                var auditInfo = await _sqlSugar.Queryable<Pm_GoodsAudit>()                    .FirstAsync(x => x.Type == 2 && x.DataId == receiveInfo.Id && x.Dep == GoodsAuditDepEnum.Hr_Reception);                if (auditInfo != null && auditInfo.AuditStatus == GoodsConfirmEnum.Confirmed)                {                    auditDep = GoodsAuditDepEnum.Hr;                    //多人审核的时候验证审核权限                    var auditList = GoodsStorageConfirmAuditDep(2);                    var auditDepInfo = auditList.Find(x => x.AuditorIds.Contains(userId));                    if (auditDepInfo == null)                    {                        _jv.Msg = string.Format("未分配出库确认权限!");                        _sqlSugar.RollbackTran();                        return _jv;                    }                }                // 确认中 确认 拒绝                 _jv = await GoodsReceiveOutConfirmingMultiple(receiveInfo, userId, auditDep, auditEnum);                //switch (auditEnum)                //{                //    case GoodsAuditEnum.Pending: //领用待确认(取消确认、取消拒绝)                //        _jv = await GoodsReceivePending(preChangeStatus, receiveId, userId, currUserName, auditEnum);                //        break;                //    case GoodsAuditEnum.Approved: //领用确认                //        _jv = await GoodsReceiveApproved(preChangeStatus, receiveId, userId, currUserName, auditEnum);                //        break;                //    case GoodsAuditEnum.UnApproved: //领用拒绝                //        _jv = await GoodsReceiveUnApproved(preChangeStatus, receiveId, userId, currUserName, auditEnum);                //        break;                //    case GoodsAuditEnum.OutPending: //出库待确认(取消出库确认、取消出库拒绝)                //        _jv = await GoodsReceiveOutPending(preChangeStatus, receiveInfo, userId, auditDep, auditEnum);                //        break;                //    case GoodsAuditEnum.OutConfirmed: //出库确认                //        _jv = await GoodsReceiveOutConfirming(receiveInfo, userId, auditDep, auditEnum);                //        break;                //    case GoodsAuditEnum.OutRejected:  //出库拒绝                //        _jv = await GoodsReceiveOutConfirming(receiveInfo, userId, auditDep, auditEnum);                //        break;                //}            }            else //单人审核             {                //领用确认 --> 已确认 / 领用拒绝 --> 已拒绝                _jv = await GoodsReceiveOutConfirmingSingle(receiveInfo, userId, currUserName, auditEnum);            }            if (_jv.Code == StatusCodes.Status200OK)            {                _sqlSugar.CommitTran();                _jv.Msg = $"操作成功!";                _jv.Data = auditEnum;                return _jv;            }            _sqlSugar.RollbackTran();            return _jv;        }        #region 多人审核状态变更        /// <summary>        /// 物品领用状态 - 领用待确认(取消确认、取消拒绝)        /// </summary>        /// <param name="preChangeStatus">更改前状态</param>        /// <param name="receiveId"></param>        /// <param name="userId"></param>        /// <param name="userName"></param>        /// <param name="auditEnum"></param>        /// <returns></returns>        public async Task<JsonView> GoodsReceivePending(GoodsAuditEnum preChangeStatus, int receiveId, int userId, string userName, GoodsAuditEnum auditEnum)        {            _jv.Code = StatusCodes.Status400BadRequest;            //领用待确认 操作范围            var audirEnumPers = new List<GoodsAuditEnum>() {                GoodsAuditEnum.Approved,                GoodsAuditEnum.UnApproved            };            if (!audirEnumPers.Contains(preChangeStatus))            {                _jv.Msg = $"{GoodsAuditEnum.Approved.GetEnumDescription()}、{GoodsAuditEnum.UnApproved.GetEnumDescription()},状态下可取消操作!";                return _jv;            }            var currUserOpDt = DateTime.Now;            var currUserOpTime = currUserOpDt.ToString("yyyy-MM-dd HH:mm:ss");            var statusDesc = string.Format(@"领用确认:状态:{0}  审核人:{1}  审核时间:{2};<br/>人事部确认:状态:待确认  审核人:-  审核时间:-;<br/>财务部确认:状态:待确认  审核人:-  审核时间:-;", auditEnum.GetEnumDescription(), userName, currUserOpTime);            auditEnum = GoodsAuditEnum.Pending;            var changeStatus = await _sqlSugar                .Updateable<Pm_GoodsReceive>()                .SetColumns(x => new Pm_GoodsReceive()                {                    AuditStatus = auditEnum,                    AuditUserId = userId,                    AuditTime = currUserOpDt,                    StatusDesc = statusDesc                })                .Where(x => x.Id == receiveId)                .ExecuteCommandAsync();            if (changeStatus > 0)            {                _jv.Code = StatusCodes.Status200OK;            }            return _jv;        }        /// <summary>        /// 物品领用状态 - 领用确认        /// </summary>        /// <param name="preChangeStatus">更改前状态</param>        /// <param name="receiveId"></param>        /// <param name="userId"></param>        /// <param name="userName"></param>        /// <param name="auditEnum"></param>        /// <returns></returns>        public async Task<JsonView> GoodsReceiveApproved(GoodsAuditEnum preChangeStatus, int receiveId, int userId, string userName, GoodsAuditEnum auditEnum)        {            _jv.Code = StatusCodes.Status400BadRequest;            if (preChangeStatus != GoodsAuditEnum.Pending)            {                _jv.Msg = $"{GoodsAuditEnum.Pending.GetEnumDescription()},状态下可取消操作!";                return _jv;            }            var currUserOpDt = DateTime.Now;            var currUserOpTime = currUserOpDt.ToString("yyyy-MM-dd HH:mm:ss");            var statusDesc = string.Format(@"领用确认:状态:{0}  审核人:{1}  审核时间:{2};<br/>人事部确认:状态:待确认  审核人:-  审核时间:-;<br/>财务部确认:状态:待确认  审核人:-  审核时间:-;", auditEnum.GetEnumDescription(), userName, currUserOpTime);            auditEnum = GoodsAuditEnum.OutPending;            var changeStatus = await _sqlSugar                .Updateable<Pm_GoodsReceive>()                .SetColumns(x => new Pm_GoodsReceive()                {                    AuditStatus = auditEnum,                    AuditUserId = userId,                    AuditTime = currUserOpDt,                    StatusDesc = statusDesc                })                .Where(x => x.Id == receiveId)                .ExecuteCommandAsync();            if (changeStatus > 0)            {                _jv.Code = StatusCodes.Status200OK;            }            return _jv;        }        /// <summary>        /// 物品领用状态 - 领用拒绝        /// </summary>        /// <param name="preChangeStatus">更改前状态</param>        /// <param name="receiveId"></param>        /// <param name="userId"></param>        /// <param name="userName"></param>        /// <param name="auditEnum"></param>        /// <returns></returns>        public async Task<JsonView> GoodsReceiveUnApproved(GoodsAuditEnum preChangeStatus, int receiveId, int userId, string userName, GoodsAuditEnum auditEnum)        {            _jv.Code = StatusCodes.Status400BadRequest;            if (preChangeStatus != GoodsAuditEnum.Pending)            {                _jv.Msg = $"{GoodsAuditEnum.Pending.GetEnumDescription()},状态下可取消操作!";                return _jv;            }            auditEnum = GoodsAuditEnum.UnApproved;            var currUserOpDt = DateTime.Now;            var currUserOpTime = currUserOpDt.ToString("yyyy-MM-dd HH:mm:ss");            var statusDesc = string.Format(@"领用确认:状态:{0}  审核人:{1}  审核时间:{2};<br/>人事部确认:状态:待确认  审核人:-  审核时间:-;<br/>财务部认:状态:待确认  审核人:-  审核时间:-;<br/>", auditEnum.GetEnumDescription(), userName, currUserOpTime);            var changeStatus = await _sqlSugar                .Updateable<Pm_GoodsReceive>()                .SetColumns(x => new Pm_GoodsReceive()                {                    AuditStatus = auditEnum,                    AuditUserId = userId,                    AuditTime = currUserOpDt,                    StatusDesc = statusDesc                })                .Where(x => x.Id == receiveId)                .ExecuteCommandAsync();            if (changeStatus > 0)            {                _jv.Code = StatusCodes.Status200OK;            }            return _jv;        }        /// <summary>        /// 物品领用状态 - 出库待确认(出库确认、出库拒绝)        /// </summary>        /// <param name="preChangeStatus">更改前状态</param>        /// <param name="receiveId"></param>        /// <param name="userId"></param>        /// <param name="userName"></param>        /// <param name="auditEnum"></param>        /// <returns></returns>        public async Task<JsonView> GoodsReceiveOutPending(GoodsAuditEnum preChangeStatus, Pm_GoodsReceive receiveInfo, int userId, GoodsAuditDepEnum depEnum, GoodsAuditEnum auditEnum)        {            _jv.Code = StatusCodes.Status400BadRequest;            //出库待确认 操作范围            var audirEnumPers = new List<GoodsAuditEnum>() {                GoodsAuditEnum.OutConfirmed,                GoodsAuditEnum.OutRejected            };            if (!audirEnumPers.Contains(preChangeStatus))            {                _jv.Msg = $"{GoodsAuditEnum.OutConfirmed.GetEnumDescription()}、{GoodsAuditEnum.OutRejected.GetEnumDescription()},状态下可取消操作!";                return _jv;            }            var currUserOpDt = DateTime.Now;            var currUserOpTime = currUserOpDt.ToString("yyyy-MM-dd HH:mm:ss");            var auditInfos = await _sqlSugar.Queryable<Pm_GoodsAudit>()                .Where(x => x.IsDel == 0 && x.DataId == receiveInfo.Id && x.Type == 2)                .ToListAsync();            auditEnum = GoodsAuditEnum.OutPending;            var auditStatus = GoodsConfirmEnum.WaitConfirm;            var auditInfo = auditInfos.Find(x => x.Dep == depEnum);            if (auditInfo == null)            {                auditInfo = new Pm_GoodsAudit(2, depEnum, receiveInfo.Id, auditStatus, userId);                var addStatus = await _sqlSugar.Insertable(auditInfo).ExecuteCommandAsync();                if (addStatus < 1)                {                    _jv.Msg = $"出库确认取消操作失败!";                    return _jv;                }                auditInfos.Add(auditInfo);            }            else            {                //移除旧数据                auditInfos.Remove(auditInfo);                auditInfo.AuditStatus = auditStatus;                auditInfo.AuditUserId = userId;                auditInfo.AuditTime = currUserOpDt;                var updStatus = await _sqlSugar.Updateable<Pm_GoodsAudit>()                    .SetColumns(x => new Pm_GoodsAudit()                    {                        AuditStatus = auditStatus,                        AuditUserId = userId,                        AuditTime = currUserOpDt                    })                    .Where(x => x.Id == auditInfo.Id)                    .ExecuteCommandAsync();                if (updStatus < 1)                {                    _jv.Msg = $"出库确认操作失败!";                    return _jv;                }                //添加更新后的数据                auditInfos.Add(auditInfo);            }            //处理状态描述            StringBuilder statusDesc = new();            var receiveUserName = _sqlSugar.Queryable<Sys_Users>().First(x => x.Id == receiveInfo.AuditUserId)?.CnName ?? "-";            string receiveStatusDesc = string.Format("{0}:状态:{1}  审核人:{2}  审核时间:{3};<br/>",                       "领用确认", GoodsAuditEnum.Approved.GetEnumDescription(), receiveUserName, receiveInfo.AuditTime.ToString("yyyy-MM-dd HH:mm:ss"));            statusDesc.Append(receiveStatusDesc);            foreach (var auditInf in auditInfos)            {                string userName = _sqlSugar.Queryable<Sys_Users>().First(x => x.Id == auditInf.AuditUserId)?.CnName ?? "-";                string userOpTime = !userName.Equals("-") ? auditInf.AuditTime.ToString("yyyy-MM-dd HH:mm:ss") : "-";                string auditInfStatusDesc = string.Format("{0}:状态:{1}  审核人:{2}  审核时间:{3};<br/>",                       auditInf.Dep.GetEnumDescription(), auditInf.AuditStatus.GetEnumDescription(), userName, currUserOpTime);                statusDesc.Append(auditInfStatusDesc);            }            //批次库存信息            string goodsStorageInfo = receiveInfo.GoodsStorageInfo;            //出库确认取消是单独处理            if (preChangeStatus == GoodsAuditEnum.OutConfirming)            {                if (auditInfos.Where(x => x.AuditStatus == GoodsConfirmEnum.Confirmed).Count() == 1)                {                    auditEnum = GoodsAuditEnum.OutConfirming;                }                //2.1 更改库存                var goodsInfo = await _sqlSugar.Queryable<Pm_GoodsInfo>().Where(x => x.Id == receiveInfo.GoodsId).FirstAsync();                goodsInfo.StockQuantity -= receiveInfo.Quantity;                goodsInfo.OQ_Total += receiveInfo.Quantity;                goodsInfo.LastUpdateTime = DateTime.Now;                goodsInfo.LastUpdateUserId = userId;                var editGoods = await _sqlSugar                    .Updateable(goodsInfo)                    .UpdateColumns(x => new                    {                        x.StockQuantity,                        x.OQ_Total,                        x.LastUpdateUserId,                        x.LastUpdateTime,                    })                    .Where(x => x.Id == receiveInfo.GoodsId)                    .ExecuteCommandAsync();                if (editGoods < 1)                {                    _jv.Msg = $"库存更新失败!";                    return _jv;                }                //2.2 入库批次关联领用人 更改批次库存                var goodsStorages = await _sqlSugar                    .Queryable<Pm_GoodsStorage>()                    .Where(x => x.IsDel == 0 &&                                x.GoodsId == receiveInfo.GoodsId &&                                (x.Quantity - x.ReceiveQuantity) > 0                        )                    .OrderBy(x => x.CreateTime)                    .ToListAsync();                var goodsReceiveInfos = new List<GoodsReceiveLinkStorageView>();                var batchStorageInfos = new List<Pm_GoodsStorage>();                var receiveQuantity = 0.00M; //领用总数量                foreach (var storage in goodsStorages)                {                    if (receiveInfo.Quantity == receiveQuantity) break;                    var thisBatchSurplusQuantity = storage.Quantity - storage.ReceiveQuantity;                    if (thisBatchSurplusQuantity <= 0.00M) continue;                    var thisBatchReceiveQuantity = 0.00M; //此批次领用数量                    const decimal unit = 0.50M;                    while (receiveQuantity < receiveInfo.Quantity)                    {                        if (thisBatchSurplusQuantity == thisBatchReceiveQuantity) break;                        thisBatchReceiveQuantity += unit;                        receiveQuantity += unit;                    }                    goodsReceiveInfos.Add(new GoodsReceiveLinkStorageView                    {                        StorageId = storage.Id,                        Quantity = thisBatchReceiveQuantity                    });                    storage.ReceiveQuantity += thisBatchReceiveQuantity;                    var storageUpd = storage;                    //storageUpd.ReceiveQuantity += thisBatchReceiveQuantity;                    batchStorageInfos.Add(storageUpd);                }                //2.2.1 更改批次库存                if (goodsReceiveInfos.Count > 0)                {                    var edit1 = await _sqlSugar.Updateable(batchStorageInfos)                        .UpdateColumns(x => x.ReceiveQuantity)                        .WhereColumns(x => x.Id)                        .ExecuteCommandAsync();                    if (edit1 < 1)                    {                        _jv.Msg = $"批次库存更新失败!";                        return _jv;                    }                }                //2.2.2 添加入库批次关联领用人                if (goodsReceiveInfos.Count > 0)                {                    goodsStorageInfo = JsonConvert.SerializeObject(goodsReceiveInfos);                }            }            var statusDesc1 = statusDesc.ToString();            var changeStatus = await _sqlSugar                .Updateable<Pm_GoodsReceive>()                .SetColumns(x => new Pm_GoodsReceive()                {                    AuditStatus = auditEnum,                    StatusDesc = statusDesc1,                    GoodsStorageInfo = goodsStorageInfo                })                .Where(x => x.Id == receiveInfo.Id)                .ExecuteCommandAsync();            if (changeStatus > 0)            {                _jv.Code = StatusCodes.Status200OK;            }            return _jv;        }        /// <summary>        /// 物品领用状态 - 出库确认中、出库确认完成、出库确认拒绝        /// </summary>        /// <param name="receiveInfo"></param>        /// <param name="userId"></param>        /// <param name="depEnum"></param>        /// <param name="auditEnum"></param>        /// <returns></returns>        public async Task<JsonView> GoodsReceiveOutConfirming(Pm_GoodsReceive receiveInfo, int userId, GoodsAuditDepEnum depEnum, GoodsAuditEnum auditEnum)        {            _jv.Code = StatusCodes.Status400BadRequest;            //更改前状态            var preChangeStatus = receiveInfo.AuditStatus;            if (preChangeStatus < GoodsAuditEnum.OutPending)            {                _jv.Msg = $"领用确认执行成功!才可执行出库确认或出库拒绝操作!";                return _jv;            }            var currUserOpDt = DateTime.Now;            var currUserOpTime = currUserOpDt.ToString("yyyy-MM-dd HH:mm:ss");            var auditInfos = await _sqlSugar.Queryable<Pm_GoodsAudit>()                .Where(x => x.IsDel == 0 && x.DataId == receiveInfo.Id && x.Type == 2)                .ToListAsync();            var auditStatus = GoodsConfirmEnum.WaitConfirm;            if (auditEnum == GoodsAuditEnum.OutRejected) auditStatus = GoodsConfirmEnum.UnApproved;            else if (auditEnum == GoodsAuditEnum.OutConfirmed) auditStatus = GoodsConfirmEnum.Confirmed;            var auditInfo = auditInfos.Find(x => x.Dep == depEnum);            if (auditInfo == null)            {                auditInfo = new Pm_GoodsAudit(2, depEnum, receiveInfo.Id, auditStatus, userId);                var addStatus = await _sqlSugar.Insertable(auditInfo).ExecuteCommandAsync();                if (addStatus < 1)                {                    _jv.Msg = $"出库确认操作失败!";                    return _jv;                }                auditInfos.Add(auditInfo);            }            else            {                //移除旧数据                auditInfos.Remove(auditInfo);                auditInfo.AuditStatus = auditStatus;                auditInfo.AuditUserId = userId;                auditInfo.AuditTime = currUserOpDt;                var updStatus = await _sqlSugar.Updateable<Pm_GoodsAudit>()                    .SetColumns(x => new Pm_GoodsAudit()                    {                        AuditStatus = auditStatus,                        AuditUserId = userId,                        AuditTime = currUserOpDt                    })                    .Where(x => x.Id == auditInfo.Id)                    .ExecuteCommandAsync();                if (updStatus < 1)                {                    _jv.Msg = $"出库确认操作失败!";                    return _jv;                }                //添加更新后的数据                auditInfos.Add(auditInfo);            }            //处理状态描述            StringBuilder statusDesc = new();            var receiveUserName = _sqlSugar.Queryable<Sys_Users>().First(x => x.Id == receiveInfo.AuditUserId)?.CnName ?? "-";            string receiveStatusDesc = string.Format("{0}:状态:{1}  审核人:{2}  审核时间:{3};<br/>",                       "领用确认", GoodsAuditEnum.Approved.GetEnumDescription(), receiveUserName, receiveInfo.AuditTime.ToString("yyyy-MM-dd HH:mm:ss"));            statusDesc.Append(receiveStatusDesc);            foreach (var auditInf in auditInfos)            {                string userName = _sqlSugar.Queryable<Sys_Users>().First(x => x.Id == auditInf.AuditUserId)?.CnName ?? "-";                string userOpTime = !userName.Equals("-") ? auditInf.AuditTime.ToString("yyyy-MM-dd HH:mm:ss") : "-";                string auditInfStatusDesc = string.Format("{0}:状态:{1}  审核人:{2}  审核时间:{3};<br/>",                       auditInf.Dep.GetEnumDescription(), auditInf.AuditStatus.GetEnumDescription(), userName, currUserOpTime);                statusDesc.Append(auditInfStatusDesc);            }            if (preChangeStatus == auditEnum)            {                _jv.Msg = $"此操作已执行,不可重复操作!";                return _jv;            }            //批次库存信息            string goodsStorageInfo = receiveInfo.GoodsStorageInfo;            //更改领用状态及库存            if (auditInfos.Any(x => x.AuditStatus == GoodsConfirmEnum.UnApproved))            {                //出库确认拒绝                auditEnum = GoodsAuditEnum.OutRejected;            }            else if (auditInfos.Where(x => x.AuditStatus == GoodsConfirmEnum.Confirmed).Count() == 2)            {                //1.出库确认完成                auditEnum = GoodsAuditEnum.OutConfirmed;                //2.更改前的状态为出库确认中 且 更改后的状态为出库确认完成 执行库存减操作                if (preChangeStatus == GoodsAuditEnum.OutConfirming || preChangeStatus == GoodsAuditEnum.OutRejected)                {                    //2.1 更改库存                    var goodsInfo = await _sqlSugar.Queryable<Pm_GoodsInfo>().Where(x => x.Id == receiveInfo.GoodsId).FirstAsync();                    goodsInfo.StockQuantity -= receiveInfo.Quantity;                    goodsInfo.OQ_Total += receiveInfo.Quantity;                    goodsInfo.LastUpdateTime = DateTime.Now;                    goodsInfo.LastUpdateUserId = userId;                    var editGoods = await _sqlSugar                        .Updateable(goodsInfo)                        .UpdateColumns(x => new                        {                            x.StockQuantity,                            x.OQ_Total,                            x.LastUpdateUserId,                            x.LastUpdateTime,                        })                        .Where(x => x.Id == receiveInfo.GoodsId)                        .ExecuteCommandAsync();                    if (editGoods < 1)                    {                        _jv.Msg = $"库存更新失败!";                        return _jv;                    }                    //2.2 入库批次关联领用人 更改批次库存                    var goodsStorages = await _sqlSugar                        .Queryable<Pm_GoodsStorage>()                        .Where(x => x.IsDel == 0 &&                                    x.GoodsId == receiveInfo.GoodsId &&                                    (x.Quantity - x.ReceiveQuantity) > 0                            )                        .OrderBy(x => x.CreateTime)                        .ToListAsync();                    var goodsReceiveInfos = new List<GoodsReceiveLinkStorageView>();                    var batchStorageInfos = new List<Pm_GoodsStorage>();                    var receiveQuantity = 0.00M; //领用总数量                    foreach (var storage in goodsStorages)                    {                        if (receiveInfo.Quantity == receiveQuantity) break;                        var thisBatchSurplusQuantity = storage.Quantity - storage.ReceiveQuantity;                        if (thisBatchSurplusQuantity <= 0.00M) continue;                        var thisBatchReceiveQuantity = 0.00M; //此批次领用数量                        const decimal unit = 0.50M;                        while (receiveQuantity < receiveInfo.Quantity)                        {                            if (thisBatchSurplusQuantity == thisBatchReceiveQuantity) break;                            thisBatchReceiveQuantity += unit;                            receiveQuantity += unit;                        }                        goodsReceiveInfos.Add(new GoodsReceiveLinkStorageView                        {                            StorageId = storage.Id,                            Quantity = thisBatchReceiveQuantity                        });                        storage.ReceiveQuantity += thisBatchReceiveQuantity;                        var storageUpd = storage;                        //storageUpd.ReceiveQuantity += thisBatchReceiveQuantity;                        batchStorageInfos.Add(storageUpd);                    }                    //2.2.1 更改批次库存                    if (goodsReceiveInfos.Count > 0)                    {                        var edit1 = await _sqlSugar.Updateable(batchStorageInfos)                            .UpdateColumns(x => x.ReceiveQuantity)                            .WhereColumns(x => x.Id)                            .ExecuteCommandAsync();                        if (edit1 < 1)                        {                            _jv.Msg = $"批次库存更新失败!";                            return _jv;                        }                    }                    //2.2.2 添加入库批次关联领用人                    if (goodsReceiveInfos.Count > 0)                    {                        goodsStorageInfo = JsonConvert.SerializeObject(goodsReceiveInfos);                    }                }            }            else if (auditInfos.Where(x => x.AuditStatus == GoodsConfirmEnum.Confirmed).Count() == 1)            {                //出库确认中                auditEnum = GoodsAuditEnum.OutConfirming;                if (preChangeStatus == GoodsAuditEnum.OutConfirmed)                {                    var goodsStorageInfo1 = receiveInfo.GoodsStorageInfo;                    if (!string.IsNullOrEmpty(goodsStorageInfo))                    {                        var goodsStorageInfos = JsonConvert.DeserializeObject<List<GoodsReceiveLinkStorageView>>(goodsStorageInfo);                        if (goodsStorageInfos.Any())                        {                            foreach (var item in goodsStorageInfos)                            {                                var newStorageInfo = await _sqlSugar.Queryable<Pm_GoodsStorage>()                                    .Where(x => x.IsDel == 0 && x.Id == item.StorageId)                                    .FirstAsync();                                if (newStorageInfo == null) continue;                                var newEdit = await _sqlSugar.Updateable(newStorageInfo)                                        .ReSetValue(x => x.ReceiveQuantity -= item.Quantity)                                        .ExecuteCommandAsync();                                if (newEdit < 1)                                {                                    _jv.Msg = $"批次领用库存更新失败!";                                    return _jv;                                }                            }                        }                    }                }            }            else            {                auditEnum = GoodsAuditEnum.OutPending;            }            var statusDesc1 = statusDesc.ToString();            var changeStatus = await _sqlSugar                .Updateable<Pm_GoodsReceive>()                .SetColumns(x => new Pm_GoodsReceive()                {                    AuditStatus = auditEnum,                    StatusDesc = statusDesc1,                    GoodsStorageInfo = goodsStorageInfo,                })                .Where(x => x.Id == receiveInfo.Id)                .ExecuteCommandAsync();            if (changeStatus > 0)            {                _jv.Code = StatusCodes.Status200OK;            }            return _jv;        }        /// <summary>        ///         /// </summary>        /// <param name="receiveInfo"></param>        /// <param name="userId"></param>        /// <param name="depEnum"></param>        /// <param name="auditEnum"></param>        /// <returns></returns>        public async Task<JsonView> GoodsReceiveOutConfirmingMultiple(Pm_GoodsReceive receiveInfo, int userId, GoodsAuditDepEnum depEnum, GoodsAuditEnum auditEnum)        {            _jv.Code = StatusCodes.Status400BadRequest;            //更改前状态            receiveInfo.CreateUserId = userId;            var preChangeStatus = receiveInfo.AuditStatus;            var currUserOpDt = DateTime.Now;            var currUserOpTime = currUserOpDt.ToString("yyyy-MM-dd HH:mm:ss");            var receiveUserName = _sqlSugar.Queryable<Sys_Users>().First(x => x.Id == receiveInfo.AuditUserId)?.CnName ?? "-";            var auditInfos = await _sqlSugar.Queryable<Pm_GoodsAudit>()                .Where(x => x.IsDel == 0 && x.DataId == receiveInfo.Id && x.Type == 2)                .ToListAsync();            var auditStatus = GoodsConfirmEnum.WaitConfirm;            if (auditEnum == GoodsAuditEnum.UnApproved) auditStatus = GoodsConfirmEnum.UnApproved;            else if (auditEnum == GoodsAuditEnum.Approved) auditStatus = GoodsConfirmEnum.Confirmed;            var auditInfo = auditInfos.Find(x => x.Dep == depEnum);            if (auditInfo == null)            {                auditInfo = new Pm_GoodsAudit(2, depEnum, receiveInfo.Id, auditStatus, userId)                {                    AuditUserId = userId                };                var addStatus = await _sqlSugar.Insertable(auditInfo).ExecuteCommandAsync();                if (addStatus < 1)                {                    _jv.Msg = $"出库确认操作失败!";                    return _jv;                }                auditInfos.Add(auditInfo);            }            else            {                //移除旧数据                auditInfos.Remove(auditInfo);                auditInfo.AuditStatus = auditStatus;                auditInfo.AuditUserId = userId;                auditInfo.AuditTime = currUserOpDt;                var updStatus = await _sqlSugar.Updateable<Pm_GoodsAudit>()                    .SetColumns(x => new Pm_GoodsAudit()                    {                        AuditStatus = auditStatus,                        AuditUserId = userId,                        AuditTime = currUserOpDt                    })                    .Where(x => x.Id == auditInfo.Id)                    .ExecuteCommandAsync();                if (updStatus < 1)                {                    _jv.Msg = $"出库确认操作失败!";                    return _jv;                }                //添加更新后的数据                auditInfos.Add(auditInfo);            }            auditInfos = auditInfos.OrderBy(x => x.Dep).ToList();            //处理状态描述            StringBuilder statusDesc = new();            foreach (var auditInf in auditInfos)            {                string auditType = auditInf.Dep == GoodsAuditDepEnum.Hr ? "人事部" : "领用确认";                string userName = _sqlSugar.Queryable<Sys_Users>().First(x => x.Id == auditInf.AuditUserId)?.CnName ?? "-";                string userOpTime = !userName.Equals("-") ? auditInf.AuditTime.ToString("yyyy-MM-dd HH:mm:ss") : "-";                string auditInfStatusDesc = string.Format("{0}:状态:{1}  审核人:{2}  审核时间:{3};<br/>",                       auditType, auditInf.AuditStatus.GetEnumDescription(), userName, currUserOpTime);                statusDesc.Append(auditInfStatusDesc);            }            if (preChangeStatus == auditEnum)            {                _jv.Msg = $"此操作已执行,不可重复操作!";                return _jv;            }            //批次库存信息            string goodsStorageInfo = receiveInfo.GoodsStorageInfo;            //更改领用状态及库存            if (auditInfos.Any(x => x.AuditStatus == GoodsConfirmEnum.UnApproved))            {                //出库确认拒绝                auditEnum = GoodsAuditEnum.OutRejected;                if (preChangeStatus == GoodsAuditEnum.OutConfirmed)                {                    //回滚库存                    _jv = await GoodsInventoryRollback(receiveInfo);                    if (_jv.Code != StatusCodes.Status200OK) return _jv;                }            }            else if (auditInfos.Where(x => x.AuditStatus == GoodsConfirmEnum.Confirmed).Count() == 2)            {                //1.出库确认完成                auditEnum = GoodsAuditEnum.OutConfirmed;                //2.更改前的状态为出库确认中 且 更改后的状态为出库确认完成 执行库存减操作                if (preChangeStatus == GoodsAuditEnum.OutConfirming || preChangeStatus == GoodsAuditEnum.OutRejected)                {                    //2.1 更改库存                    var goodsInfo = await _sqlSugar.Queryable<Pm_GoodsInfo>().Where(x => x.Id == receiveInfo.GoodsId).FirstAsync();                    goodsInfo.StockQuantity -= receiveInfo.Quantity;                    goodsInfo.OQ_Total += receiveInfo.Quantity;                    goodsInfo.LastUpdateTime = DateTime.Now;                    goodsInfo.LastUpdateUserId = userId;                    var editGoods = await _sqlSugar                        .Updateable(goodsInfo)                        .UpdateColumns(x => new                        {                            x.StockQuantity,                            x.OQ_Total,                            x.LastUpdateUserId,                            x.LastUpdateTime,                        })                        .Where(x => x.Id == receiveInfo.GoodsId)                        .ExecuteCommandAsync();                    if (editGoods < 1)                    {                        _jv.Msg = $"库存更新失败!";                        return _jv;                    }                    //2.2 入库批次关联领用人 更改批次库存                    var goodsStorages = await _sqlSugar                        .Queryable<Pm_GoodsStorage>()                        .Where(x => x.IsDel == 0 &&                                    x.GoodsId == receiveInfo.GoodsId &&                                    (x.Quantity - x.ReceiveQuantity) > 0                            )                        .OrderBy(x => x.CreateTime)                        .ToListAsync();                    var goodsReceiveInfos = new List<GoodsReceiveLinkStorageView>();                    var batchStorageInfos = new List<Pm_GoodsStorage>();                    var receiveQuantity = 0.00M; //领用总数量                    foreach (var storage in goodsStorages)                    {                        if (receiveInfo.Quantity == receiveQuantity) break;                        var thisBatchSurplusQuantity = storage.Quantity - storage.ReceiveQuantity;                        if (thisBatchSurplusQuantity <= 0.00M) continue;                        var thisBatchReceiveQuantity = 0.00M; //此批次领用数量                        const decimal unit = 0.50M;                        while (receiveQuantity < receiveInfo.Quantity)                        {                            if (thisBatchSurplusQuantity == thisBatchReceiveQuantity) break;                            thisBatchReceiveQuantity += unit;                            receiveQuantity += unit;                        }                        goodsReceiveInfos.Add(new GoodsReceiveLinkStorageView                        {                            StorageId = storage.Id,                            Quantity = thisBatchReceiveQuantity                        });                        storage.ReceiveQuantity += thisBatchReceiveQuantity;                        var storageUpd = storage;                        //storageUpd.ReceiveQuantity += thisBatchReceiveQuantity;                        batchStorageInfos.Add(storageUpd);                    }                    //2.2.1 更改批次库存                    if (goodsReceiveInfos.Count > 0)                    {                        var edit1 = await _sqlSugar.Updateable(batchStorageInfos)                            .UpdateColumns(x => x.ReceiveQuantity)                            .WhereColumns(x => x.Id)                            .ExecuteCommandAsync();                        if (edit1 < 1)                        {                            _jv.Msg = $"批次库存更新失败!";                            return _jv;                        }                    }                    //2.2.2 添加入库批次关联领用人                    if (goodsReceiveInfos.Count > 0)                    {                        goodsStorageInfo = JsonConvert.SerializeObject(goodsReceiveInfos);                    }                }            }            else if (auditInfos.Where(x => x.AuditStatus == GoodsConfirmEnum.Confirmed).Count() == 1)            {                //出库确认中                auditEnum = GoodsAuditEnum.OutConfirming;                if (preChangeStatus == GoodsAuditEnum.OutConfirmed)                {                    //回滚库存                    _jv = await GoodsInventoryRollback(receiveInfo);                    if (_jv.Code != StatusCodes.Status200OK) return _jv;                }            }            else auditEnum = GoodsAuditEnum.OutPending;            var statusDesc1 = statusDesc.ToString();            var changeStatus = await _sqlSugar                .Updateable<Pm_GoodsReceive>()                .SetColumns(x => new Pm_GoodsReceive()                {                    AuditStatus = auditEnum,                    StatusDesc = statusDesc1,                    GoodsStorageInfo = goodsStorageInfo,                })                .Where(x => x.Id == receiveInfo.Id)                .ExecuteCommandAsync();            if (changeStatus > 0)            {                _jv.Code = StatusCodes.Status200OK;            }            return _jv;        }        /// <summary>        /// 物品库存回滚        /// </summary>        /// <param name="receiveInfo"></param>        /// <returns></returns>        public async Task<JsonView> GoodsInventoryRollback(Pm_GoodsReceive receiveInfo)        {            var goodsInfo = await _sqlSugar.Queryable<Pm_GoodsInfo>().FirstAsync(x => x.Id == receiveInfo.GoodsId);            //回滚库存            var changeGoods = await _sqlSugar                .Updateable(goodsInfo)                .ReSetValue(it =>                {                    it.StockQuantity += receiveInfo.Quantity;                    it.OQ_Total -= receiveInfo.Quantity;                    it.LastUpdateTime = DateTime.Now;                    it.LastUpdateUserId = receiveInfo.CreateUserId;                })                .ExecuteCommandAsync();            if (changeGoods < 1)            {                _jv.Msg = $"库存回滚失败!";                return _jv;            }            //批次领用记录            _jv.Code = StatusCodes.Status200OK;            var goodsStorageInfo = receiveInfo.GoodsStorageInfo;            if (string.IsNullOrEmpty(goodsStorageInfo)) return _jv;            var goodsStorageInfos = JsonConvert.DeserializeObject<List<GoodsReceiveLinkStorageView>>(goodsStorageInfo);            if (!goodsStorageInfos.Any()) return _jv;            foreach (var item in goodsStorageInfos)            {                var newStorageInfo = await _sqlSugar.Queryable<Pm_GoodsStorage>()                    .Where(x => x.IsDel == 0 && x.Id == item.StorageId)                    .FirstAsync();                if (newStorageInfo == null) continue;                var newEdit = await _sqlSugar.Updateable(newStorageInfo)                        .ReSetValue(x => x.ReceiveQuantity -= item.Quantity)                        .ExecuteCommandAsync();                if (newEdit < 1)                {                    _jv.Code = StatusCodes.Status400BadRequest;                    _jv.Msg = $"批次领用库存更新失败!";                    return _jv;                }            }            _jv.Code = StatusCodes.Status200OK;            return _jv;        }        #endregion        #region 单人审核状态变更        /// <summary>        /// 物品领用状态 - 出库确认完成、出库确认拒绝        /// </summary>        /// <param name="receiveInfo"></param>        /// <param name="userId"></param>        /// <param name="currUserName"></param>        /// <param name="auditEnum"></param>        /// <returns></returns>        public async Task<JsonView> GoodsReceiveOutConfirmingSingle(Pm_GoodsReceive receiveInfo, int userId, string currUserName, GoodsAuditEnum auditEnum)        {            _jv.Code = StatusCodes.Status400BadRequest;            //状态操作范围验证            var auditEnums = new List<GoodsAuditEnum>() {                GoodsAuditEnum.Pending,                GoodsAuditEnum.Approved,                GoodsAuditEnum.UnApproved,            };            if (!auditEnums.Contains(auditEnum))            {                _jv.Msg = $"{GoodsAuditEnum.Pending.GetEnumDescription()}、{GoodsAuditEnum.OutConfirmed.GetEnumDescription()}、{GoodsAuditEnum.OutRejected.GetEnumDescription()},状态下可操作!";                return _jv;            }            var currUserOpDt = DateTime.Now;            var currUserOpTime = currUserOpDt.ToString("yyyy-MM-dd HH:mm:ss");            //更改前状态            var preChangeStatus = receiveInfo.AuditStatus;            //前台状态验证            var auditInfo = await _sqlSugar.Queryable<Pm_GoodsAudit>().FirstAsync(x => x.IsDel == 0 && x.Type == 2 && x.DataId == receiveInfo.Id);            if (auditInfo == null)            {                var addInfo = new Pm_GoodsAudit(2, GoodsAuditDepEnum.Hr_Reception, receiveInfo.Id, GoodsConfirmEnum.WaitConfirm, userId);                auditInfo = await _sqlSugar.Insertable(addInfo).ExecuteReturnEntityAsync();                if (auditInfo == null)                {                    _jv.Msg = $"确认操作失败!";                    return _jv;                }            }            if (auditEnum == GoodsAuditEnum.Approved)            {                auditInfo.AuditStatus = GoodsConfirmEnum.Confirmed;                auditEnum = GoodsAuditEnum.OutConfirmed;            }            else if (auditEnum == GoodsAuditEnum.UnApproved)            {                auditInfo.AuditStatus = GoodsConfirmEnum.UnApproved;                auditEnum = GoodsAuditEnum.OutRejected;            }            if (preChangeStatus == auditEnum)            {                _jv.Msg = $"此操作已执行,不可重复操作!";                return _jv;            }            //更新子表审核状态            var updStatus = await _sqlSugar.Updateable<Pm_GoodsAudit>()                    .SetColumns(x => new Pm_GoodsAudit()                    {                        AuditStatus = auditInfo.AuditStatus,                        AuditUserId = userId,                        AuditTime = currUserOpDt                    })                    .Where(x => x.Id == auditInfo.Id)                    .ExecuteCommandAsync();            if (updStatus < 1)            {                _jv.Msg = $"确认操作失败!";                return _jv;            }            //处理状态描述            StringBuilder statusDesc = new();            statusDesc.Append(string.Format("领用确认:状态:{0}  审核人:{1}  审核时间:{2};", auditInfo.AuditStatus.GetEnumDescription(), currUserName, currUserOpTime));            //批次库存信息            string goodsStorageInfo = receiveInfo.GoodsStorageInfo;            if (auditEnum == GoodsAuditEnum.OutConfirmed) //出库确认            {                //1 更改库存                var goodsInfo = await _sqlSugar.Queryable<Pm_GoodsInfo>().Where(x => x.Id == receiveInfo.GoodsId).FirstAsync();                goodsInfo.StockQuantity -= receiveInfo.Quantity;                goodsInfo.OQ_Total += receiveInfo.Quantity;                goodsInfo.LastUpdateTime = DateTime.Now;                goodsInfo.LastUpdateUserId = userId;                var editGoods = await _sqlSugar.Updateable(goodsInfo)                    .UpdateColumns(x => new                    {                        x.StockQuantity,                        x.OQ_Total,                        x.LastUpdateUserId,                        x.LastUpdateTime,                    })                    .Where(x => x.Id == receiveInfo.GoodsId)                    .ExecuteCommandAsync();                if (editGoods < 1)                {                    _jv.Msg = $"库存更新失败!";                    return _jv;                }                //2 入库批次关联领用人 更改批次库存                var goodsStorages = await _sqlSugar                    .Queryable<Pm_GoodsStorage>()                    .Where(x => x.IsDel == 0 &&                                x.GoodsId == receiveInfo.GoodsId &&                                (x.Quantity - x.ReceiveQuantity) > 0                        )                    .OrderBy(x => x.CreateTime)                    .ToListAsync();                var goodsReceiveInfos = new List<GoodsReceiveLinkStorageView>();                var batchStorageInfos = new List<Pm_GoodsStorage>();                var receiveQuantity = 0.00M; //领用总数量                foreach (var storage in goodsStorages)                {                    if (receiveInfo.Quantity == receiveQuantity) break;                    var thisBatchSurplusQuantity = storage.Quantity - storage.ReceiveQuantity;                    if (thisBatchSurplusQuantity <= 0.00M) continue;                    var thisBatchReceiveQuantity = 0.00M; //此批次领用数量                    const decimal unit = 0.50M;                    while (receiveQuantity < receiveInfo.Quantity)                    {                        if (thisBatchSurplusQuantity == thisBatchReceiveQuantity) break;                        thisBatchReceiveQuantity += unit;                        receiveQuantity += unit;                    }                    goodsReceiveInfos.Add(new GoodsReceiveLinkStorageView                    {                        StorageId = storage.Id,                        Quantity = thisBatchReceiveQuantity                    });                    storage.ReceiveQuantity += thisBatchReceiveQuantity;                    var storageUpd = storage;                    //storageUpd.ReceiveQuantity += thisBatchReceiveQuantity;                    batchStorageInfos.Add(storageUpd);                }                //3 更改批次库存                if (goodsReceiveInfos.Count > 0)                {                    var edit1 = await _sqlSugar.Updateable(batchStorageInfos)                        .UpdateColumns(x => x.ReceiveQuantity)                        .WhereColumns(x => x.Id)                        .ExecuteCommandAsync();                    if (edit1 < 1)                    {                        _jv.Msg = $"批次库存更新失败!";                        return _jv;                    }                }                //4 添加入库批次关联领用人                if (goodsReceiveInfos.Count > 0)                {                    goodsStorageInfo = JsonConvert.SerializeObject(goodsReceiveInfos);                }            }            else if (auditEnum == GoodsAuditEnum.OutRejected) //出库拒绝            {                //拒绝之前的状态为已完成 回滚库存                if (preChangeStatus == GoodsAuditEnum.OutConfirmed)                {                    //回滚库存                    var goodsInfo = await _sqlSugar.Queryable<Pm_GoodsInfo>().FirstAsync(x => x.Id == receiveInfo.GoodsId);                    var changeGoods = await _sqlSugar                        .Updateable(goodsInfo)                        .ReSetValue(it =>                        {                            it.StockQuantity += receiveInfo.Quantity;                            it.OQ_Total -= receiveInfo.Quantity;                            it.LastUpdateTime = DateTime.Now;                            it.LastUpdateUserId = userId;                        })                        .ExecuteCommandAsync();                    if (changeGoods < 1)                    {                        _jv.Msg = $"库存回滚失败!";                        return _jv;                    }                    //批次号库存 信息更新                    var goodsStorageInfo1 = receiveInfo.GoodsStorageInfo;                    if (!string.IsNullOrEmpty(goodsStorageInfo))                    {                        var goodsStorageInfos = JsonConvert.DeserializeObject<List<GoodsReceiveLinkStorageView>>(goodsStorageInfo);                        if (goodsStorageInfos.Any())                        {                            foreach (var item in goodsStorageInfos)                            {                                var newStorageInfo = await _sqlSugar.Queryable<Pm_GoodsStorage>()                                    .Where(x => x.IsDel == 0 && x.Id == item.StorageId)                                    .FirstAsync();                                if (newStorageInfo == null) continue;                                var newEdit = await _sqlSugar.Updateable(newStorageInfo)                                        .ReSetValue(x => x.ReceiveQuantity -= item.Quantity)                                        .ExecuteCommandAsync();                                if (newEdit < 1)                                {                                    _jv.Msg = $"批次领用库存更新失败!";                                    return _jv;                                }                            }                        }                    }                }            }            var statusDesc1 = statusDesc.ToString();            var changeStatus = await _sqlSugar                .Updateable<Pm_GoodsReceive>()                .SetColumns(x => new Pm_GoodsReceive()                {                    AuditStatus = auditEnum,                    StatusDesc = statusDesc1,                    GoodsStorageInfo = goodsStorageInfo,                })                .Where(x => x.Id == receiveInfo.Id)                .ExecuteCommandAsync();            if (changeStatus > 0) _jv.Code = StatusCodes.Status200OK;            return _jv;        }        #endregion        /// <summary>        /// 物品领用 Del        /// </summary>        /// <param name="id"></param>        /// <param name="currUserId"></param>        /// <returns></returns>        public async Task<JsonView> GoodsReceiveDel(int id, int currUserId)        {            _jv.Msg = $"操作失败";            var receiveInfo = await _sqlSugar                .Queryable<Pm_GoodsReceive>()                .Where(x => x.IsDel == 0 && x.Id == id)                .FirstAsync();            if (receiveInfo.AuditStatus >= GoodsAuditEnum.Approved)            {                _jv.Msg = $"该条数据已进入审批流程,不可删除!";                return _jv;            }            _sqlSugar.BeginTran();            var edit = await _sqlSugar                .Updateable<Pm_GoodsReceive>()                .SetColumns(x => new Pm_GoodsReceive()                {                    IsDel = 1,                    DeleteUserId = currUserId,                    DeleteTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),                })                .Where(x => x.Id == id)                .ExecuteCommandAsync();            if (edit < 1)            {                _sqlSugar.RollbackTran();                return _jv;            }            var editSub = await _sqlSugar                .Updateable<Pm_GoodsReceiveDetails>()                .SetColumns(x => new Pm_GoodsReceiveDetails()                {                    IsDel = 1,                    DeleteUserId = currUserId,                    DeleteTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),                })                .Where(x => x.GoodsReceiveId == id)                .ExecuteCommandAsync();            if (editSub < 1)            {                _sqlSugar.RollbackTran();                return _jv;            }            _sqlSugar.CommitTran();            _jv.Msg = $"操作成功!";            _jv.Code = StatusCodes.Status200OK;            return _jv;        }        #region New 物品领用、审核        /// <summary>        /// 物品领用审核列表        /// </summary>        /// <param name="dto"></param>        /// <returns></returns>        public async Task<JsonView> GoodsReceiveAuditList(GoodsReceiveAuditListDTO dto)        {            var currUserId = dto.CurrUserId;            var auditStatus = dto.AuditStatus;            var goodsName = dto.GoodsName;            var sql = string.Format(@"SELECT  ROW_NUMBER() OVER (ORDER BY CreateTime DESC) AS RowNumber,  *FROM  (    Select      gr.Id,      gr.GroupId,      CASE        WHEN gr.GroupId = 0 THEN '其他物资(公司内部物资)'        WHEN gr.GroupId = -1 THEN '拜访客户所使用的物资'        WHEN gr.GroupId = -2 THEN '库存调整'        ELSE di.TeamName      END [GroupName],      gr.GoodsId,      CASE        WHEN gr.GoodsId = 0 THEN gr.GoodsName        ELSE gi.Name      END [GoodsName],      gi.Type [GoodsTypeId],      sd.Name [GoodsType],      CASE        WHEN gi.Type = 0        OR gi.Type IS NULL THEN CASE          WHEN af.TemplateId = 3 THEN 1          ELSE 0        END        WHEN gi.Type = 1423 THEN 1        ELSE 0      END [IsValuable],      gr.Quantity,      gi.Unit,      gr.Reason,      gr.Remark,      gr.AuditStatus,      gr.StatusDesc,      gr.AuditUserId,      u1.CnName [AuditUserName],      gr.AuditTime,      u2.CnName [CreateUserName],      gr.CreateTime    FROM      OA2023DB.dbo.Pm_GoodsReceive gr      LEFT JOIN Pm_GoodsInfo gi ON gr.GoodsId = gi.Id      LEFT JOIN Grp_DelegationInfo di ON gr.GroupId = di.Id      LEFT JOIN Sys_Users u1 ON gr.AuditUserId = u1.Id      LEFT JOIN Sys_Users u2 ON gr.CreateUserId = u2.Id      LEFT JOIN Sys_AuditFlow af ON gr.Id = af.BusinessId      LEFT JOIN Sys_SetData sd ON gi.Type = sd.Id    WHERE      gr.IsDel = 0  ) Temp ");            var checkValuableUserIds = new List<int>() {                343 , //陈湘OAId                309 , //赖红燕AId            };            var isValueable = false;            if (checkValuableUserIds.Contains(currUserId)) //陈湘OAId登录 只显示贵重物品审核信息            {                isValueable = true;            }            RefAsync<int> total = 0;            var view = await _sqlSugar.SqlQueryable<GoodsReceiveListMobileView>(sql)                .WhereIF(isValueable, x => x.IsValuable == true)                .WhereIF(!string.IsNullOrEmpty(goodsName), x => x.GoodsName.Contains(goodsName))                .ToPageListAsync(dto.PageIndex, dto.PageSize, total);            //普通物品领用审核模板            var normAuditTemps = await _approvalProcessRep.GetTemplateByBusinessTypeAsync(2); //普通物品            var normAuditUsers = new List<GoodsStorageAuditPerView>();            normAuditTemps?.TempNodes.ForEach(x =>            {                var auditDep = GoodsAuditDepEnum.Hr_Reception;                if (x.NodeName.Contains("人事部主管/经理审核")) auditDep = GoodsAuditDepEnum.Hr;                else if (x.NodeName.Contains("前台审核")) auditDep = GoodsAuditDepEnum.Hr;                x.NodeUsers.ForEach(y =>                {                    var userFlang = false;                    if (y.UserId == currUserId) userFlang = true;                    var info = new GoodsStorageAuditPerView() { ButtonText = x.NodeName, AuditDep = auditDep, AuditPer = userFlang };                    normAuditUsers.Add(info);                });            });            //贵重物品领用审核模板            var valuableAuditTemps = await _approvalProcessRep.GetTemplateByBusinessTypeAsync(3); //贵重物品            var valuableAuditUsers = new List<GoodsStorageAuditPerView>();            valuableAuditTemps?.TempNodes.ForEach(x =>            {                var auditDep = GoodsAuditDepEnum.Hr_Reception;                if (x.NodeName.Contains("人事部主管/经理审核")) auditDep = GoodsAuditDepEnum.Hr;                else if (x.NodeName.Contains("前台审核")) auditDep = GoodsAuditDepEnum.Hr;                x.NodeUsers.ForEach(y =>                {                    var userFlang = false;                    if (y.UserId == currUserId) userFlang = true;                    var info = new GoodsStorageAuditPerView() { ButtonText = x.NodeName, AuditDep = auditDep, AuditPer = userFlang };                    valuableAuditUsers.Add(info);                });            });            foreach (var item in view)            {                var details = $"暂无物品信息数据";                //设置领用详情                if (item.GoodsTypeId < 1)                {                    var detailsData = await _sqlSugar.Queryable<Pm_GoodsReceiveDetails>()                    .LeftJoin<Pm_GoodsInfo>((grd, gi) => grd.GoodsId == gi.Id)                    .LeftJoin<Sys_SetData>((grd, gi, sd) => gi.Type == sd.Id)                    .Where((grd, gi, sd) => grd.IsDel == 0 && grd.GoodsReceiveId == item.Id)                    .Select((grd, gi, sd) => new                    {                        gi.Name,                        TypeName = sd.Name,                        grd.Quantity,                        grd.Remark                    })                    .ToListAsync();                    if (detailsData.Any())                    {                        //设置领用数量 多个物品 计算领用合计                        item.Quantity = detailsData.Sum(x => x.Quantity);                        var text = new StringBuilder();                        text.Append($"归属团组:{item.GroupName} <br/><br/>");                        detailsData.ForEach(x =>                        {                            var str = $"物品名称:{x.Name}   物品类型:{x.TypeName}   领用数量:{x.Quantity}   备注:{x.Remark}<br/>";                            text.Append(str);                        });                        details = text.ToString();                    }                }                else details = $"归属团组/类型:{item.GroupName} <br/><br/>物品名称:{item.GoodsName}   物品类型:{item.GoodsType}   领用数量:{item.Quantity}   备注:{item.Remark}<br/>";                item.GoodsDetails = details;                //设置领用状态描述                var auditRecords = await _sqlSugar.Queryable<Sys_AuditRecord>()                    .InnerJoin<Sys_AuditFlow>((ar, af) => ar.FlowId == af.Id)                    .Where((ar, af) => ar.IsDel == 0 && af.BusinessId == item.Id && af.BusinessType == 1)                    .Select((ar, af) => new                    {                        ar.NodeId,                        ar.NodeName,                        ar.AuditResult,                        ar.AuditorName,                        ar.AuditTime                    })                    //.OrderBy((ar, af) => ar.AuditTime)                    .ToListAsync();                if (auditRecords.Any())                {                    var text = new StringBuilder();                    auditRecords.ForEach(x =>                    {                        var statusText = x.AuditResult switch                        {                            0 => "待审核",                            1 => "已审核",                            2 => "已拒绝",                            3 => "无需处理",                            _ => "未知"                        };                        var auditTime = $"-";                        if (x.AuditResult == 1 || x.AuditResult == 2 || x.AuditResult == 3) auditTime = x.AuditTime.ToString("yyyy-MM-dd HH:mm:ss");                        var str = $"{x.NodeName}:状态:{statusText}  审核人:{x.AuditorName}  审核时间:{auditTime}<br/>";                        text.Append(str);                    });                    item.StatusDesc = text.ToString();                }                //多情况下审核、操作权限验证                if (item.GoodsTypeId == 0)                {                    int tempId = 2;                    if (item.IsValuable) tempId = 3;                    item.IsAuditPer = await _approvalProcessRep.VerifyAuditAuthAsync(tempId, 1, item.Id, currUserId);                }                else                {                    if (item.AuditStatus == GoodsAuditEnum.Pending)                    {                        item.IsAuditPer = normAuditTemps?.TempNodes.FirstOrDefault()?.NodeUsers.Any(x => x.UserId == currUserId) ?? false;                    }                    else if (item.AuditStatus == GoodsAuditEnum.OutConfirming)                    {                        item.IsAuditPer = valuableAuditTemps?.TempNodes.FirstOrDefault(x => x.NodeOrder == 1)?.NodeUsers.Any(x => x.UserId == currUserId) ?? false;                    }                }                //前端权限验证                if (item.IsValuable)                {                    item.AuditPers = valuableAuditUsers.ToArray();                }                else item.AuditPers = normAuditUsers.ToArray();            }            if (dto.PortType == 2 || dto.PortType == 3)            {                _jv.Data = view;            }            else if (dto.PortType == 1)            {                var view1 = _mapper.Map<List<GoodsReceiveListView>>(view);                _jv.Data = view1;            }            _jv.Code = StatusCodes.Status200OK;            _jv.Count = total;            _jv.Msg = $"操作成功";            return _jv;        }        /// <summary>        /// 物品领用 可批量 OP(Add Or Edit)        /// </summary>        /// <param name="dto"></param>        /// <param name="currUserId"></param>        /// <returns></returns>        public async Task<JsonView> GoodsReceiveBatchOpAsync(GoodsReceiveBatchOpDto dto)        {            var goodsReceiveId = dto.Id;            var currUserId = dto.CurrUserId;            //请求参数处理            var receiveInfo = new Pm_GoodsReceive()            {                Id = goodsReceiveId,                GroupId = dto.GroupId,                Reason = dto.Reason,                Remark = dto.Remark,                AuditStatus = GoodsAuditEnum.Pending,                IsReplace = dto.IsReplace,                CreateUserId = currUserId,            };            var receiveDetails = _mapper.Map<Pm_GoodsReceiveDetails[]>(dto.ReceiveDetails);            //receiveDetails.ForEach(x => { x.CreateUserId = dto.CurrUserId; });            _sqlSugar.BeginTran();            //审核状态验证 false:其他物品 true:贵重物品            var isBatchVail = false;            //物品库存验证            int goodsIndex = 1;            var goodsNames = new List<string>();            foreach (var item in receiveDetails)            {                item.CreateUserId = currUserId;                int goodsId = item.GoodsId;                //物品验证                var goodsInfo = _sqlSugar.Queryable<Pm_GoodsInfo>().First(x => x.IsDel == 0 && x.Id == goodsId);                if (goodsInfo == null)                {                    _jv.Msg = $"第{goodsIndex}项物品不存在!";                    _sqlSugar.RollbackTran();                    return _jv;                }                goodsNames.Add(goodsInfo.Name);                //物品库存验证                var stockQuantity = goodsInfo.StockQuantity;                var awaitAuditQuantity = await GoodsAwaitQuantityAsync(goodsId);                stockQuantity -= awaitAuditQuantity;                if (item.Quantity > stockQuantity)                {                    _jv.Msg = $"“{goodsInfo.Name}”物品库存不足!剩余库存:{stockQuantity} {goodsInfo.Unit}(待审数量:{awaitAuditQuantity});";                    _sqlSugar.RollbackTran();                    return _jv;                }                //物品类型验证                if (_goodsTypeIds.Contains(goodsInfo.Type)) isBatchVail = true;                //入库批次关联领用人 更改批次库存                var goodsStorages = await _sqlSugar                    .Queryable<Pm_GoodsStorage>()                    .Where(x => x.IsDel == 0 &&                                x.GoodsId == receiveInfo.GoodsId &&                                (x.Quantity - x.ReceiveQuantity) > 0                        )                    .OrderBy(x => x.CreateTime)                    .ToListAsync();                var goodsReceiveInfos = new List<GoodsReceiveLinkStorageView>();                var batchStorageInfos = new List<Pm_GoodsStorage>();                var receiveQuantity = 0.00M; //领用总数量                foreach (var storage in goodsStorages)                {                    if (receiveInfo.Quantity == receiveQuantity) break;                    var thisBatchSurplusQuantity = storage.Quantity - storage.ReceiveQuantity;                    if (thisBatchSurplusQuantity <= 0.00M) continue;                    var thisBatchReceiveQuantity = 0.00M; //此批次领用数量                    const decimal unit = 0.50M;                    while (receiveQuantity < receiveInfo.Quantity)                    {                        if (thisBatchSurplusQuantity == thisBatchReceiveQuantity) break;                        thisBatchReceiveQuantity += unit;                        receiveQuantity += unit;                    }                    goodsReceiveInfos.Add(new GoodsReceiveLinkStorageView                    {                        StorageId = storage.Id,                        Quantity = thisBatchReceiveQuantity                    });                    storage.ReceiveQuantity += thisBatchReceiveQuantity;                    var storageUpd = storage;                    //storageUpd.ReceiveQuantity += thisBatchReceiveQuantity;                    batchStorageInfos.Add(storageUpd);                }                goodsIndex++;            }            if (goodsNames.Any())            {                receiveInfo.GoodsName = string.Join("、", goodsNames);            }            //验证领用 添加OR编辑            var goodsReceiveInfo = await _sqlSugar.Queryable<Pm_GoodsReceive>().FirstAsync(x => x.IsDel == 0 && x.Id == goodsReceiveId);            if (goodsReceiveInfo == null) //添加            {                goodsReceiveId = await _sqlSugar.Insertable(receiveInfo).ExecuteReturnIdentityAsync();                if (goodsReceiveId < 1)                {                    _jv.Msg = $"领用添加失败!";                    _sqlSugar.RollbackTran();                    return _jv;                }                receiveDetails.ForEach(x => { x.GoodsReceiveId = goodsReceiveId; });                var receiveDetailsStatus = await _sqlSugar.Insertable(receiveDetails).ExecuteCommandAsync();                if (receiveDetailsStatus < 1)                {                    _jv.Msg = $"领用明细添加失败!";                    _sqlSugar.RollbackTran();                    return _jv;                }            }            else //修改            {                //更改前状态验证                if (goodsReceiveInfo.AuditStatus != GoodsAuditEnum.Pending)                {                    _jv.Msg = $"领用状态在“领用待确认”,即可修改!";                    _sqlSugar.RollbackTran();                    return _jv;                }                var receiveStatus = await _sqlSugar.Updateable(receiveInfo).ExecuteCommandAsync();                if (receiveStatus < 1)                {                    _jv.Msg = $"领用更新失败!";                    _sqlSugar.RollbackTran();                    return _jv;                }                //更新子表数据                if (receiveDetails.Any())                {                    receiveDetails.ForEach(x => { x.GoodsReceiveId = receiveInfo.Id; });                    var db_receiveDetails = await _sqlSugar.Queryable<Pm_GoodsReceiveDetails>()                   .Where(x => x.IsDel == 0 && x.GoodsReceiveId == goodsReceiveId)                   .ToListAsync();                    var toDelete = db_receiveDetails.Where(p => !receiveDetails.Any(np => np.Id == p.Id)).ToList();                    if (toDelete.Any())                    {                        var delStatus = _sqlSugar.Deleteable(toDelete).ExecuteCommand();                        if (delStatus < 1)                        {                            _jv.Msg = $"领用明细旧数据删除失败!";                            _sqlSugar.RollbackTran();                            return _jv;                        }                    }                    var addOrUpdStatus = await _sqlSugar.Storageable<Pm_GoodsReceiveDetails>(receiveDetails.ToList()).ExecuteCommandAsync();                    if (addOrUpdStatus < 1)                    {                        _jv.Msg = $"领用明细更新失败!";                        _sqlSugar.RollbackTran();                        return _jv;                    }                }            }            #region 审批流程验证、创建            //审核验证 物品含有贵重物品 使用贵重物品审批流程            var auditTempInfo = new ApprovalProcessView();            if (isBatchVail)  //贵重物品审核模板            {                auditTempInfo = await _approvalProcessRep.GetTemplateByBusinessTypeAsync(3);            }            else //其他物品审核模板            {                auditTempInfo = await _approvalProcessRep.GetTemplateByBusinessTypeAsync(2);            }            if (auditTempInfo == null)            {                _jv.Msg = $"未配置审核模板!";                _sqlSugar.RollbackTran();                return _jv;            }            if (auditTempInfo == null && !auditTempInfo.TempNodes.Any())            {                _jv.Msg = $"审核模板未配置节点!";                _sqlSugar.RollbackTran();                return _jv;            }            //创建审核流程            var firstNode = auditTempInfo.TempNodes.OrderBy(x => x.NodeOrder).First();            var flow = await _approvalProcessRep.GetFlowByBusinessAsync(goodsReceiveId, 1);            int flowId;            if (flow == null)            {                flow = new Sys_AuditFlow()                {                    BusinessId = goodsReceiveId,                    BusinessType = 1,                    TemplateId = auditTempInfo.Id,                    CurrentNodeId = firstNode.Id,                    Status = 1,                };                flowId = await _sqlSugar.Insertable(flow).ExecuteReturnIdentityAsync();                if (flowId < 1)                {                    _jv.Msg = $"审核流程添加失败!";                    _sqlSugar.RollbackTran();                    return _jv;                }            }            else flowId = flow.Id;            #endregion            //获取第一个节点的审核人员            var nodeUsers = firstNode.NodeUsers;            //删除旧的审核记录            var delRecords = await _sqlSugar.Deleteable<Sys_AuditRecord>()                .Where(x => x.FlowId == flowId && x.NodeId == firstNode.Id && x.NodeName == firstNode.NodeName)                .ExecuteCommandHasChangeAsync();            //创建审核记录            var records = nodeUsers.Select(user => new Sys_AuditRecord            {                FlowId = flowId,                NodeId = firstNode.Id,                NodeName = firstNode.NodeName,                AuditorId = user.UserId,                AuditorName = user.UserName,                AuditResult = 0, // 审核中                AuditTime = DateTime.Now            }).ToList();            var recordStatus = await _sqlSugar.Insertable(records).ExecuteCommandAsync();            if (recordStatus < 1)            {                _jv.Msg = $"审核记录创建失败!";                _sqlSugar.RollbackTran();                return _jv;            }            _sqlSugar.CommitTran();            _jv.Code = StatusCodes.Status200OK;            _jv.Data = new { sign = goodsReceiveId };            _jv.Msg = $"操作成功!";            return _jv;        }        /// <summary>        /// 物品领用 批量 List        /// </summary>        /// <param name="dto"></param>        /// <param name="currUserId"></param>        /// <returns></returns>        public async Task<JsonView> GoodsReceiveBatchListAsync(GoodsReceiveBatchListDto dto)        {            int currUserId = dto.CurrUserId;            string goodsName = dto.GoodsName;            var showAllPeopleIds = new List<int>() {                374, // 罗颖                233, // 刘华举                208, // 雷怡                343, // 陈湘            };            var isShowAllPeople = showAllPeopleIds.Any(x => x == currUserId);            RefAsync<int> total = 0;            var receiveList = await _sqlSugar.Queryable<Pm_GoodsReceive>()                .LeftJoin<Sys_Users>((x, y) => x.CreateUserId == y.Id)                .Where((x, y) => x.IsDel == 0 && x.GoodsId == 0)                .WhereIF(!string.IsNullOrEmpty(goodsName), (x, y) => x.GoodsName.Contains(goodsName))                .WhereIF(!isShowAllPeople, (x, y) => x.CreateUserId == currUserId)                .OrderByDescending((x, y) => x.CreateTime)                .Select((x, y) => new GoodsReceiveBatchListView()                {                    Id = x.Id,                    GoodsName = x.GoodsName,                    AccumQty = SqlFunc.Subqueryable<Pm_GoodsReceiveDetails>().Where(z => z.IsDel == 0 && z.GoodsReceiveId == x.Id).Sum(z => z.Quantity),                    Reason = x.Reason,                    Remark = x.Remark,                    Status = x.AuditStatus,                    Applicant = y.CnName,                    ApplyTime = x.CreateTime,                })                .ToPageListAsync(dto.PageIndex, dto.PageSize, total);            foreach (var item in receiveList)            {                var detailsText = new StringBuilder();                if (item.AccumQty > 0)                {                    var goodsInfos = await _sqlSugar.Queryable<Pm_GoodsReceiveDetails>()                        .InnerJoin<Pm_GoodsInfo>((x, y) => x.GoodsId == y.Id)                        .LeftJoin<Sys_SetData>((x, y, z) => y.Type == z.Id)                        .Where((x, y, z) => x.IsDel == 0 && x.GoodsReceiveId == item.Id)                        .Select((x, y, z) => new                        {                            goodsId = x.GoodsId,                            goodsName = y.Name,                            goodsType = z.Name,                            quantity = x.Quantity,                            remark = x.Remark,                        })                        .ToListAsync();                    if (goodsInfos.Any())                    {                        int index = 1;                        goodsInfos.ForEach(x =>                        {                            detailsText.Append($"{index}.{x.goodsName}({x.goodsType})  数量:{x.quantity:#0.00}  备注:{x.remark ?? "-"} <br/>");                            index++;                        });                    }                }                else detailsText.Append($"暂无数据!");                item.GoodsDetails = detailsText.ToString();            }            _jv.Code = StatusCodes.Status200OK;            _jv.Msg = $"操作成功!";            _jv.Data = receiveList;            _jv.Count = total;            return _jv;        }        /// <summary>        /// 物品领用 批量 详情        /// </summary>        /// <param name="dto"></param>        /// <param name="currUserId"></param>        /// <returns></returns>        public async Task<JsonView> GoodsReceiveBatchInfoAsync(int id)        {            var receiveInfo = await _sqlSugar.Queryable<Pm_GoodsReceive>()                .Where(x => x.IsDel == 0 && x.Id == id)                .FirstAsync();            if (receiveInfo == null)            {                _jv.Msg = "暂无数据!";                return _jv;            }            var info = new GoodsReceiveBatchView            {                Id = receiveInfo.Id,                GroupId = receiveInfo.GroupId,                Reason = receiveInfo.Reason,                IsReplace = receiveInfo.IsReplace,                Remark = receiveInfo.Remark,            };            info.ReceiveDetails = await _sqlSugar                .Queryable<Pm_GoodsReceiveDetails>()                .LeftJoin<Pm_GoodsInfo>((x, y) => x.GoodsId == y.Id)                .Where((x, y) => x.IsDel == 0 && x.GoodsReceiveId == receiveInfo.Id)                .Select((x, y) => new GoodsReceiveDetailsView()                {                    Id = x.Id,                    GoodsId = x.GoodsId,                    GoodsName = y.Name,                    Quantity = x.Quantity,                    Remark = x.Remark,                })                .ToArrayAsync();            _jv.Code = StatusCodes.Status200OK;            _jv.Msg = $"操作成功!";            _jv.Data = info;            return _jv;        }        /// <summary>        /// 物品领用 审核 通过        /// </summary>        /// <param name="id"></param>        /// <param name="currUserId"></param>        /// <returns></returns>        public async Task<JsonView> GoodsReceiveApproveAsync(int id, int currUserId)        {            var appId = id;            //验证审核流程            var flow = await _approvalProcessRep.GetFlowByBusinessAsync(appId, 1);            if (flow == null)            {                _jv.Msg = $"审核流程不存在";                return _jv;            }            if (flow.Status != 1)            {                _jv.Msg = $"当前流程不在审核中";                return _jv;            }            //获取当前节点            var currNode = (await _approvalProcessRep.GetTemplateNodesAsync(flow.TemplateId)).FirstOrDefault(x => x.Id == flow.CurrentNodeId);            if (currNode == null)            {                _jv.Msg = $"当前审核节点不存在";                return _jv;            }            //检查用户是否有权审核            var canAudit = (await _approvalProcessRep.GetTemplateNodeUsersAsync(currNode.Id))                .Any(x => x.UserId == currUserId);            if (!canAudit)            {                _jv.Msg = $"您无权审核此领用";                return _jv;            }            //检查是否已审核过            var existingRecord = await _sqlSugar.Queryable<Sys_AuditRecord>()                .Where(x => x.FlowId == flow.Id && x.NodeId == currNode.Id && x.AuditorId == currUserId)                .FirstAsync();            if (existingRecord != null && existingRecord.AuditResult == 1)            {                _jv.Msg = $"您已审核过此领用";                return _jv;            }            // 创建或更新审核记录            var currUserName = _sqlSugar.Queryable<Sys_Users>().First(x => x.Id == currUserId)?.CnName ?? "-";            var record = existingRecord ?? new Sys_AuditRecord            {                FlowId = flow.Id,                NodeId = currNode.Id,                NodeName = currNode.NodeName,                AuditorId = currUserId,                AuditorName = currUserName,                AuditResult = 1, // 通过                AuditTime = DateTime.Now,                AuditOpinion = "",            };            _sqlSugar.BeginTran();            if (existingRecord == null) await _sqlSugar.Insertable(record).ExecuteCommandAsync();            else            {                record.AuditResult = 1; // 通过                record.AuditTime = DateTime.Now;                await _sqlSugar.Updateable(record).ExecuteCommandAsync();            }            //检查节点是否完成            var nodeRecords = await _sqlSugar.Queryable<Sys_AuditRecord>()                .Where(x => x.FlowId == flow.Id && x.NodeId == currNode.Id)                .ToListAsync();            bool isNodeComplete = false;            if (currNode.ApproveType == 2) // 或签模式            {                //或签逻辑:任意一人通过即通过                if (nodeRecords.Any(x => x.AuditResult == 1))                {                    isNodeComplete = true;                    // 标记其他未审核的记录为"无需处理"                    var unprocessed = nodeRecords                        .Where(x => x.AuditResult == 0 && x.AuditorId != currUserId)                        .ToList();                    foreach (var r in unprocessed)                    {                        r.AuditResult = 3; // 无需处理                        r.AuditTime = DateTime.Now;                        r.AuditOpinion = "其他审核人已处理";                    }                    if (unprocessed.Any())                    {                        await _sqlSugar.Updateable(unprocessed).ExecuteCommandAsync();                    }                }            }            else // 会签模式            {                // 会签逻辑:全部通过才通过                isNodeComplete = nodeRecords.All(x => x.AuditResult == 1);            }            if (isNodeComplete)            {                // 查找下一个节点                var nextNode = (await _approvalProcessRep.GetTemplateNodesAsync(flow.TemplateId))                    .Where(x => x.NodeOrder > currNode.NodeOrder)                    .OrderBy(x => x.NodeOrder)                    .FirstOrDefault();                if (nextNode == null)                {                    // 所有节点完成,审核通过                    flow.Status = 2; // 已完成                    flow.CurrentNodeId = 0;                    // 更新业务状态为审核通过                    var auditStatus = await UpdateStatusAsync(appId, GoodsAuditEnum.OutConfirmed);                    if (!auditStatus)                    {                        _jv.Msg = $"审核失败!";                        _sqlSugar.RollbackTran();                        return _jv;                    }                    // 扣除库存                    var deductStatus = await DeductStockAsync(appId);                    if (!deductStatus)                    {                        _jv.Msg = $"库存扣除失败!";                        _sqlSugar.RollbackTran();                        return _jv;                    }                }                else                {                    // 进入下一个节点                    flow.CurrentNodeId = nextNode.Id;                    // 更新业务状态为审核中                    var auditStatus = await UpdateStatusAsync(appId, GoodsAuditEnum.OutConfirming);                    if (!auditStatus)                    {                        _jv.Msg = $"审核状态更新失败!";                        _sqlSugar.RollbackTran();                        return _jv;                    }                    // 为下一个节点创建审核记录                    var nextNodeUsers = await _approvalProcessRep.GetTemplateNodeUsersAsync(nextNode.Id);                    var records = nextNodeUsers.Select(user => new Sys_AuditRecord                    {                        FlowId = flow.Id,                        NodeId = nextNode.Id,                        NodeName = nextNode.NodeName,                        AuditorId = user.UserId,                        AuditorName = user.UserName,                        AuditResult = 0,                        AuditTime = DateTime.Now                    }).ToList();                    var recordStatus = await _sqlSugar.Insertable(records).ExecuteCommandAsync();                    if (recordStatus < 1)                    {                        _jv.Msg = $"下一节点审批记录创建失败!";                        _sqlSugar.RollbackTran();                        return _jv;                    }                }                var flowStatus = await _sqlSugar.Updateable(flow).ExecuteCommandAsync();                if (flowStatus < 1)                {                    _jv.Msg = $"审批流程更新失败!";                    _sqlSugar.RollbackTran();                    return _jv;                }            }            _sqlSugar.CommitTran();            _jv.Code = StatusCodes.Status200OK;            _jv.Msg = $"操作成功!";            return _jv;        }        /// <summary>        /// 物品领用 审核 拒绝        /// </summary>        /// <param name="id"></param>        /// <param name="currUserId"></param>        /// <returns></returns>        public async Task<JsonView> GoodsReceiveRejectAsync(int id, int currUserId)        {            var appId = id;            //验证领用单            var receviveInfo = await _sqlSugar.Queryable<Pm_GoodsReceive>().FirstAsync(x => x.Id == appId);            if (receviveInfo == null)            {                _jv.Msg = $"当前领用信息不存在";                return _jv;            }            //验证审核流程            var flow = await _approvalProcessRep.GetFlowByBusinessAsync(appId, 1);            if (flow == null)            {                _jv.Msg = $"审核流程不存在";                return _jv;            }            //if (flow.Status != 1)            //{            //    _jv.Msg = $"当前流程不在审核中";            //    return _jv;            //}            //获取当前节点            var currNode = (await _approvalProcessRep.GetTemplateNodesAsync(flow.TemplateId)).FirstOrDefault(x => x.Id == flow.CurrentNodeId);            if (currNode == null)            {                _jv.Msg = $"当前审核节点不存在";                return _jv;            }            //检查用户是否有权审核            var canAudit = (await _approvalProcessRep.GetTemplateNodeUsersAsync(currNode.Id))                .Any(x => x.UserId == currUserId);            if (!canAudit)            {                _jv.Msg = $"您无权审核此申请";                return _jv;            }            //检查是否已审核过            var existingRecord = await _sqlSugar.Queryable<Sys_AuditRecord>()                .Where(x => x.FlowId == flow.Id && x.NodeId == currNode.Id && x.AuditorId == currUserId)                .FirstAsync();            if (existingRecord != null && existingRecord.AuditResult == 2)            {                _jv.Msg = $"您已审核过此申请";                return _jv;            }            //验证是否已经审核通过            bool isApproved = receviveInfo.AuditStatus == GoodsAuditEnum.OutConfirmed;            _sqlSugar.BeginTran();            if (isApproved) //审核通过拒绝            {                //回滚库存                var rollbackStatus = await RollbackStockAsync(appId);                if (!rollbackStatus)                {                    _jv.Msg = $"物品库存回滚失败!";                    _sqlSugar.RollbackTran();                    return _jv;                }            }            //更新流程状态为已拒绝            flow.Status = 3; // 已拒绝            flow.CurrentNodeId = currNode.Id;            var flowStatus = await _sqlSugar.Updateable(flow).ExecuteCommandAsync();            if (flowStatus < 1)            {                _jv.Msg = $"流程状态更新失败!";                _sqlSugar.RollbackTran();                return _jv;            }            // 更新领用状态为已拒绝            var receviveStatus = await UpdateStatusAsync(appId, GoodsAuditEnum.OutRejected); // 已拒绝            if (!receviveStatus)            {                _jv.Msg = $"领用物品状态更新失败!";                _sqlSugar.RollbackTran();                return _jv;            }            // 创建拒绝记录            var currUserName = _sqlSugar.Queryable<Sys_Users>().First(x => x.Id == currUserId)?.CnName ?? "-";            var record = new Sys_AuditRecord            {                FlowId = flow.Id,                NodeId = flow.CurrentNodeId,                NodeName = $"{currNode.NodeName}-撤销",                AuditorId = currUserId,                AuditorName = currUserName,                AuditResult = 2, // 拒绝                AuditTime = DateTime.Now,                AuditOpinion = $"用户操作撤销",            };            var recordStatus = await _sqlSugar.Insertable(record).ExecuteCommandAsync();            if (recordStatus < 1)            {                _jv.Msg = $"领用物品拒绝记录创建失败!";                _sqlSugar.RollbackTran();                return _jv;            }            _sqlSugar.CommitTran();            _jv.Code = StatusCodes.Status200OK;            _jv.Msg = $"操作成功!";            return _jv;        }        /// <summary>        /// 物品待审核数量        /// </summary>        /// <param name="goodsId"></param>        /// <returns></returns>        public async Task<decimal> GoodsAwaitQuantityAsync(int goodsId)        {            decimal quantity = 0.00M;            //单条领用 待审核、确认中 物品数量            var waitAuditQuantity = await _sqlSugar.Queryable<Pm_GoodsReceive>().Where(x => x.IsDel == 0 &&                            x.GoodsId == goodsId &&                            (x.AuditStatus == GoodsAuditEnum.Pending || x.AuditStatus == GoodsAuditEnum.OutConfirming)                ).SumAsync(x => x.Quantity);            //批量领用 待审核、确认中 物品数量             var waitAuditBatchQuantity = await _sqlSugar.Queryable<Pm_GoodsReceive>()                .InnerJoin<Pm_GoodsReceiveDetails>((gr, grd) => gr.Id == grd.GoodsReceiveId)                .Where((gr, grd) => gr.IsDel == 0 &&                                    (gr.AuditStatus == GoodsAuditEnum.Pending || gr.AuditStatus == GoodsAuditEnum.OutConfirming) &&                                    grd.GoodsId == goodsId                )                .Select((gr, grd) => new                {                    grd.GoodsReceiveId,                    gr.AuditStatus,                    grd.Quantity                })                .SumAsync(gr => gr.Quantity);            quantity = waitAuditQuantity + waitAuditBatchQuantity;            return quantity;        }        /// <summary>        /// 更改领用状态        /// </summary>        /// <param name="id"></param>        /// <param name="status"></param>        /// <returns></returns>        public async Task<bool> UpdateStatusAsync(int id, GoodsAuditEnum status)        {            return await _sqlSugar.Updateable<Pm_GoodsReceive>()                .SetColumns(x => x.AuditStatus == status)                .Where(x => x.Id == id)                .ExecuteCommandHasChangeAsync();        }        /// <summary>        /// 领用状态完成扣除库存        /// </summary>        /// <param name="id"></param>        /// <param name="status"></param>        /// <returns></returns>        public async Task<bool> DeductStockAsync(int id)        {            var receiveInfo = await _sqlSugar.Queryable<Pm_GoodsReceive>().FirstAsync(x => x.Id == id);            if (receiveInfo == null) return false;            var receiveDetails = await _sqlSugar.Queryable<Pm_GoodsReceiveDetails>()                .Where(x => x.IsDel == 0 && x.GoodsReceiveId == id)                .ToListAsync();            if (!receiveDetails.Any()) return false;            var goodsInfos = new List<Pm_GoodsInfo>();            foreach (var item in receiveDetails)            {                var goodsInfo = await _sqlSugar.Queryable<Pm_GoodsInfo>().FirstAsync(x => x.Id == item.GoodsId);                if (goodsInfo == null) return false;                //1、物品库存扣除                goodsInfo.StockQuantity -= item.Quantity;                goodsInfo.OQ_Total += item.Quantity;                //2、入库批次关联领用人 更改批次库存                var goodsStorages = await _sqlSugar                    .Queryable<Pm_GoodsStorage>()                    .Where(x => x.IsDel == 0 &&                                x.GoodsId == item.GoodsId &&                                x.ConfirmStatus == GoodsConfirmEnum.Confirmed &&                                (x.Quantity - x.ReceiveQuantity) > 0                        )                    .OrderBy(x => x.CreateTime)                    .ToListAsync();                var goodsReceiveInfos = new List<GoodsReceiveLinkStorageView>();                var batchStorageInfos = new List<Pm_GoodsStorage>();                var receiveQuantity = 0.00M; //领用总数量                foreach (var storage in goodsStorages)                {                    if (item.Quantity == receiveQuantity) break;                    var thisBatchSurplusQuantity = storage.Quantity - storage.ReceiveQuantity;                    if (thisBatchSurplusQuantity <= 0.00M) continue;                    var thisBatchReceiveQuantity = 0.00M; //此批次领用数量                    const decimal unit = 0.50M;                    while (receiveQuantity < storage.Quantity)                    {                        if (thisBatchSurplusQuantity == thisBatchReceiveQuantity || receiveQuantity == item.Quantity) break;                        thisBatchReceiveQuantity += unit;                        receiveQuantity += unit;                    }                    goodsReceiveInfos.Add(new GoodsReceiveLinkStorageView                    {                        StorageId = storage.Id,                        Quantity = thisBatchReceiveQuantity                    });                    storage.ReceiveQuantity += thisBatchReceiveQuantity;                    batchStorageInfos.Add(storage);                }                //3 更改批次库存                if (goodsReceiveInfos.Count > 0)                {                    var edit1 = await _sqlSugar.Updateable(batchStorageInfos)                        .UpdateColumns(x => x.ReceiveQuantity)                        .WhereColumns(x => x.Id)                        .ExecuteCommandAsync();                    if (edit1 < 1) return false;                }                //4 添加入库批次关联领用人                if (goodsReceiveInfos.Count > 0)                {                    item.GoodsStorageInfo = JsonConvert.SerializeObject(goodsReceiveInfos);                }                goodsInfos.Add(goodsInfo);            }            //库存更改            var editGoods = await _sqlSugar.Updateable(goodsInfos)                .UpdateColumns(x => new                {                    x.StockQuantity,                    x.OQ_Total,                })                .Where(x => x.Id == x.Id)                .ExecuteCommandAsync();            if (editGoods < 1) return false;            //领用明细更改            var editDetails = await _sqlSugar.Updateable(receiveDetails)                .UpdateColumns(x => new                {                    x.GoodsStorageInfo,                })                .Where(x => x.GoodsReceiveId == x.GoodsReceiveId)                .ExecuteCommandAsync();            if (editDetails < 1) return false;            return true;        }        /// <summary>        /// 领用状态拒绝回滚所有物资的库存        /// </summary>        /// <param name="id"></param>        /// <param name="status"></param>        /// <returns></returns>        public async Task<bool> RollbackStockAsync(int id)        {            var receiveInfo = await _sqlSugar.Queryable<Pm_GoodsReceive>().FirstAsync(x => x.Id == id);            if (receiveInfo == null) return false;            var receiveDetails = await _sqlSugar.Queryable<Pm_GoodsReceiveDetails>()                .Where(x => x.IsDel == 0 && x.GoodsReceiveId == id)                .ToListAsync();            if (!receiveDetails.Any()) return false;            var goodsInfos = new List<Pm_GoodsInfo>();            foreach (var item in receiveDetails)            {                var goodsInfo = await _sqlSugar.Queryable<Pm_GoodsInfo>().FirstAsync(x => x.Id == item.GoodsId);                if (goodsInfo == null) return false;                //1、物品表库存回滚                var receiveQuantity = item.Quantity;                goodsInfo.StockQuantity += receiveQuantity;                goodsInfo.OQ_Total -= receiveQuantity;                //2、入库批次关联领用人 更改批次库存 回滚                var goodsStorages = await _sqlSugar                    .Queryable<Pm_GoodsStorage>()                    .Where(x => x.IsDel == 0 &&                                x.GoodsId == receiveInfo.GoodsId &&                                (x.Quantity - x.ReceiveQuantity) > 0                        )                    .OrderBy(x => x.CreateTime)                    .ToListAsync();                var goodsReceiveInfos = new List<GoodsReceiveLinkStorageView>();                var batchStorageInfos = new List<Pm_GoodsStorage>();                foreach (var storage in goodsStorages)                {                    if (receiveInfo.Quantity == receiveQuantity) break;                    var thisBatchSurplusQuantity = storage.Quantity - storage.ReceiveQuantity;                    if (thisBatchSurplusQuantity <= 0.00M) continue;                    var thisBatchReceiveQuantity = 0.00M; //此批次领用数量                    const decimal unit = 0.50M;                    while (receiveQuantity < receiveInfo.Quantity)                    {                        if (thisBatchSurplusQuantity == thisBatchReceiveQuantity) break;                        thisBatchReceiveQuantity -= unit;                        receiveQuantity -= unit;                    }                    goodsReceiveInfos.Add(new GoodsReceiveLinkStorageView                    {                        StorageId = storage.Id,                        Quantity = thisBatchReceiveQuantity                    });                    storage.ReceiveQuantity -= thisBatchReceiveQuantity;                    batchStorageInfos.Add(storage);                }                //3 批次库存 回滚                if (goodsReceiveInfos.Count > 0)                {                    var edit1 = await _sqlSugar.Updateable(batchStorageInfos)                        .UpdateColumns(x => x.ReceiveQuantity)                        .WhereColumns(x => x.Id)                        .ExecuteCommandAsync();                    if (edit1 < 1) return false;                }                item.GoodsStorageInfo = null;                goodsInfos.Add(goodsInfo);            }            //库存 回滚            var editGoods = await _sqlSugar.Updateable(goodsInfos)                .UpdateColumns(x => new                {                    x.StockQuantity,                    x.OQ_Total,                })                .Where(x => x.Id == x.Id)                .ExecuteCommandAsync();            if (editGoods < 1) return false;            //领用明细 回滚            var editDetails = await _sqlSugar.Updateable(receiveDetails)                .UpdateColumns(x => new                {                    x.GoodsStorageInfo,                })                .Where(x => x.GoodsReceiveId == x.GoodsReceiveId)                .ExecuteCommandAsync();            if (editDetails < 1) return false;            return true;        }        #endregion    }}
 |