From d74f0cd354b4b91752f82aac2fd3c6939c82508b Mon Sep 17 00:00:00 2001 From: lcj <2331845269@qq.com> Date: Sun, 6 Jul 2025 14:38:28 +0800 Subject: [PATCH] =?UTF-8?q?[add]=20=E7=89=A9=E6=96=99=E6=8E=A5=E6=94=B6?= =?UTF-8?q?=E9=A2=86=E6=96=99=E5=8D=95=EF=BC=8C=E6=98=8E=E7=BB=86=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=E5=A2=9E=E5=88=A0=E6=94=B9=E6=9F=A5=E3=80=81=E6=8C=89?= =?UTF-8?q?=E6=A8=A1=E7=89=88=E5=AF=BC=E5=87=BA=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resources/template/物料接收单模版.docx | Bin 0 -> 19783 bytes .../resources/template/物料领料单模版.docx | Bin 0 -> 23969 bytes .../template/设计变更申请单模版.docx | Bin 13965 -> 13823 bytes .../test/java/org/dromara/test/DemoTest.java | 17 + .../ruoyi-modules/ruoyi-system/pom.xml | 6 + .../org/dromara/common/utils/JSTUtil.java | 3 + .../documentOperations/WordToPdfToImg.java | 22 +- .../impl/BusContactnoticeServiceImpl.java | 25 +- .../design/constant/DesDrawingConstant.java | 23 - .../constant/DesSpecialSchemeConstant.java | 24 - .../controller/DesDesignChangeController.java | 2 +- .../impl/DesDesignChangeServiceImpl.java | 17 +- .../impl/FacPhotovoltaicPanelServiceImpl.java | 24 +- .../constants/MatMaterialsConstant.java | 67 +++ .../MatMaterialIssueController.java | 105 ++++ .../MatMaterialReceiveController.java | 105 ++++ .../materials/domain/MatMaterialIssue.java | 126 ++++ .../domain/MatMaterialIssueItem.java | 77 +++ .../materials/domain/MatMaterialReceive.java | 126 ++++ .../domain/MatMaterialReceiveItem.java | 77 +++ .../MatMaterialIssueCreateReq.java | 105 ++++ .../MatMaterialIssueQueryReq.java | 63 ++ .../MatMaterialIssueUpdateReq.java | 100 ++++ .../MatMaterialIssueWordDto.java | 39 ++ .../MatMaterialIssueItemDto.java | 58 ++ .../MatMaterialIssueItemWordDto.java | 21 + .../MatMaterialReceiveCreateReq.java | 100 ++++ .../MatMaterialReceiveQueryReq.java | 63 ++ .../MatMaterialReceiveUpdateReq.java | 100 ++++ .../MatMaterialReceiveWordDto.java | 48 ++ .../MatMaterialReceiveItemDto.java | 58 ++ .../MatMaterialReceiveItemWordDto.java | 56 ++ .../vo/materialissue/MatMaterialIssueVo.java | 152 +++++ .../MatMaterialIssueItemVo.java | 75 +++ .../materialreceive/MatMaterialReceiveVo.java | 152 +++++ .../MatMaterialReceiveItemVo.java | 75 +++ .../mapper/MatMaterialIssueItemMapper.java | 15 + .../mapper/MatMaterialIssueMapper.java | 15 + .../mapper/MatMaterialReceiveItemMapper.java | 15 + .../mapper/MatMaterialReceiveMapper.java | 15 + .../service/IMatMaterialIssueItemService.java | 41 ++ .../service/IMatMaterialIssueService.java | 106 ++++ .../IMatMaterialReceiveItemService.java | 41 ++ .../service/IMatMaterialReceiveService.java | 106 ++++ .../impl/MatMaterialIssueItemServiceImpl.java | 59 ++ .../impl/MatMaterialIssueServiceImpl.java | 529 +++++++++++++++++ .../MatMaterialReceiveItemServiceImpl.java | 59 ++ .../impl/MatMaterialReceiveServiceImpl.java | 546 ++++++++++++++++++ .../impl/PgsProgressCategoryServiceImpl.java | 11 +- .../materials/MatMaterialIssueItemMapper.xml | 7 + .../materials/MatMaterialIssueMapper.xml | 7 + .../MatMaterialReceiveItemMapper.xml | 7 + .../materials/MatMaterialReceiveMapper.xml | 7 + xinnengyuan/script/sql/menuInitValue.sql | 160 +++++ xinnengyuan/script/sql/xinnengyuan.sql | 108 ++++ 55 files changed, 3876 insertions(+), 89 deletions(-) create mode 100644 xinnengyuan/ruoyi-admin/src/main/resources/template/物料接收单模版.docx create mode 100644 xinnengyuan/ruoyi-admin/src/main/resources/template/物料领料单模版.docx delete mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/design/constant/DesDrawingConstant.java delete mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/design/constant/DesSpecialSchemeConstant.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/constants/MatMaterialsConstant.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/controller/MatMaterialIssueController.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/controller/MatMaterialReceiveController.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/MatMaterialIssue.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/MatMaterialIssueItem.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/MatMaterialReceive.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/MatMaterialReceiveItem.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialissue/MatMaterialIssueCreateReq.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialissue/MatMaterialIssueQueryReq.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialissue/MatMaterialIssueUpdateReq.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialissue/MatMaterialIssueWordDto.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialissueitem/MatMaterialIssueItemDto.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialissueitem/MatMaterialIssueItemWordDto.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialreceive/MatMaterialReceiveCreateReq.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialreceive/MatMaterialReceiveQueryReq.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialreceive/MatMaterialReceiveUpdateReq.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialreceive/MatMaterialReceiveWordDto.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialreceiveitem/MatMaterialReceiveItemDto.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialreceiveitem/MatMaterialReceiveItemWordDto.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/vo/materialissue/MatMaterialIssueVo.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/vo/materialissueitem/MatMaterialIssueItemVo.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/vo/materialreceive/MatMaterialReceiveVo.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/vo/materialreceiveitem/MatMaterialReceiveItemVo.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/mapper/MatMaterialIssueItemMapper.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/mapper/MatMaterialIssueMapper.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/mapper/MatMaterialReceiveItemMapper.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/mapper/MatMaterialReceiveMapper.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/service/IMatMaterialIssueItemService.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/service/IMatMaterialIssueService.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/service/IMatMaterialReceiveItemService.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/service/IMatMaterialReceiveService.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/service/impl/MatMaterialIssueItemServiceImpl.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/service/impl/MatMaterialIssueServiceImpl.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/service/impl/MatMaterialReceiveItemServiceImpl.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/service/impl/MatMaterialReceiveServiceImpl.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/materials/MatMaterialIssueItemMapper.xml create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/materials/MatMaterialIssueMapper.xml create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/materials/MatMaterialReceiveItemMapper.xml create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/materials/MatMaterialReceiveMapper.xml diff --git a/xinnengyuan/ruoyi-admin/src/main/resources/template/物料接收单模版.docx b/xinnengyuan/ruoyi-admin/src/main/resources/template/物料接收单模版.docx new file mode 100644 index 0000000000000000000000000000000000000000..5c54f75f568f7ed8d78849397d9d8cb1b07439e3 GIT binary patch literal 19783 zcmZ^~b8sk4w>=yuC$?>!*tTukwr%^wwr$(C?GxMi@;qZEhacVz9dsea7nI}t}8paqbH*7sA+ zyXv`-#Kd0p%u3u!^1Lf&H^E8e4XUtC5`4A}n)_{{)f#y=G66c^=oLsAoAcrUw8h9R zPSRa{kj-&P`a3aoLY>*ZH>~t6KyP3b|HZni&Q*$GE;5TJZS%b(&>vC{44#p6t*nDM ztZTjLxztFp@DcaD|EA%5W$9m{nre+rimkVqj{#<^!s<)A|FbaVfa3MFTrWMJech8n zT0p!(lhERm-h(Rt#z2|R&s&kNo=_y8iL!=|J8Z8p>E|TA>#0q^i@rC_1UCQY%klbh z9`C>T5F{)wGymbE_JHDArNw9xfpM8~E$Ue%n;n%ozZ2XLcPS!NZm5t0K;SrR<5h|(T0WajsB z6oXb+z_4@p3*Ya*Q69h?HTgG{VbRG1z;KCcj%Q$BW?GUDCtvf?W4VVu?H98|u=A$> zwn6{a)9n34fK=H_--kW$o6bsv@H{>scJz2b35U-P8ijmzdY>)gwq?a%{%Iyyrp=D> zOeXqzaiq%#$_G{Sd2W2pjSV|raDC|J)$pU)!{e$vM4{z70+^Dauj7E6wHG_A7x?tG zmET<&4|jru5;0*j$Oti^k(e>PI4SNK8m`)>2Q*u~i2_wX{C5@O`wQO&>@P?J%yY33|Fb|#zXK*kK_lIu1R!{0V&S;J7aOghciV+$vlir+8c zEW^nV>W-)Yi-EoPmAl4MDuAuxWXAyL3P+WbSkqzv9E5$hr#HPl@SP+AOG22KeMSIR ze=I_iNg_Q39M=};7sQ7^r~dFn{28h!rxBZsgdveqNAD-9SQQ&8Tl3lP<+N>8?h#Jz zTwNOzUT@NHJ@oD6EXXgX0lq=xl*i_rrMKS~CJi8G>gqm8w*w%6wP(5=9;2dL*QN&p zn<%sSym-?xoRH4zm)=T(B4qNY2$6m#|AVf7s)w|fovjZ?1jpX}i1N0)y%)>!*)_$a z;pNHWK(x`MpTM`+q8}viPA)ZEjnvN4j6~Zl`00yK|199aMUiKnSg{on-a6fK7=f&n zw8JItI^K|Ytlxh8h%LJ;nf_xeqAAna^upOaL)I*H_k~FdqjyS`soN`839GX+1_&>+ z-sSS=7lx?qKUDqy&wQXiRJqzZ82z7F4>7aB92gb=AjS#+0PcSvj!y1Y#*Y6md8w^y zi!F}eE4t4a_4ErD+tZp%rqWR+94QfkEU00CduIB{GqyNM*3L!; z^Q^^PVqfQIOjAS_Q%pqXB-tNi_Gz+2HpDm4-||)g6~uUlb6hCu!C@W2V!1HxDl!M^ z>Xwpi>$#B&8e@{WWIDy-pPL3qwZb}4roy=4^&mNg;TB$)!|DYlZmaT(=vQFqHmc6P zs^vhpd$?aSW+QepD+bms6xxEx;^1@p)<;A4Zc0JH4vZjvb64u_9JCc&-ta2=1-5l+ zn`)EeSn|ag)^65rwNO18kT3yE96nxuj)d7H@Y&D?2KuzaChc*#;S=q$m5Ms4vr*m@ zboXK#xGKi=?6H&Ov2&nl4v+(0%hW*d4$UEkwXtQdjf*~638^bQjiIZ)-fDVY&UJIf zOA6{MjGnJNJHm9onbzqoHHxw=m@xy81Re#V>1VTN8qSSseWAd}o#do^yh0AnjpTOR zvZW8|UhF9APm0h7)Ry6N!kB!JV@CvHY`w2v4@`wK(dgb}z+A6RGfvze1fpmu0g^R} z;u9P`Zj^~l95MkeWG$r@8EpX#1dneO7`Mq`+&bffDNcPUHFKbI|JouMQwoe3_1$O# zUfKdJvc%VmZ7m0WQNq4gw65t6Ree#$yj8Sr=?>vkM936Uu@0}Pbvl4#st)3E=pcBO zx(Q$8?V;3#2B;2RdDMh$E$JY1SauN-tE#vQITj-0x5-1sWs-x6(If#8gG&G=ycYtD zxhwb`a!}~GYFP>}gegy1Y>$z-K?^chkOz7uoG2%&5|$29b>wyk4W zSsqOiLR#`_PF)5PS|9M;!isZWThDV1^n@@Mz~3WP0D(J@+z;XBfF!*lj}v3R?hzpUH@$|n4_C903x0lj-OFNl-^^y zhaxIvWQgrpS-jjo4fyxe0Eu9)Gksi&y;xWrvwwW)oB&M^7pyyP7oIa#k`uu_8}4c* zQHX8uP0r6s>Lv*rja($1Rlc9z{^_bWZ_B#tF`-!hBJU3AcM%;Z4r+a30L3X?p9jAO zo^mVQTPf(7_hP^Uj|IOcp61{NnFh@PWnDvup%p2#cue#2sH1qJ)kl>5WM=@Hpq0E8 zPd!K>#aeV%1y}J+4Edds$;7+i4SQ}-HQnV=+6>>;2*(GUSYRev8`BLU+29^5^LNGB z8VuOo?$v>4SvTeP;yhY`uZ0qNdGR=nmPkEry5NRR-;T>T(ahmPA7B* zIit0c%wr8ml45bV{vren5>M+5B`2b;hCK_~bB_zU%?Yo<^Yxk5atxs{{K(PiILwG)L^O(AuBAD4f zmmQjFDAmlxw*8);D82))KOafvS6j>dTV-I1mS}9MBwLJ`tkX)io8@`P?yrc}9PXlK=&X=N}n@1M#*Xtnl3JyI6zKU%143jNg#n{WeM!}y-K-QCQ-u^7b-`RW_Q^4N*Uc`&FW!dm=2Ct>1ed|CcIIpXvfa_qF@h6Zr(|eAJ zuGPEwFW8G&RITJZ*R98pG^nQ4y9PgZY2ed3+xU#`j)CIGGN6P=ZAsyyJKOMiRLtC} zg}1e+@mQJENZlR%y&h%((hjFU*1d8Hv!7F;+F@9w-u`(diLH&U*S38;D_W%B51!!% zJ9;<;N|?xs7ACc=h0oy5=x_FOVK0sqZDIrlrX>BRayKUkY?Q!?6ehDBvts`@d0*)6 z_&+bBiJ0M}xjQznAI*pqCbj*4n1}s?cx}zwQ%d|Xp2x$?PwLJDXl`u7p44FCa7y@= zy;O2r3pvMC>u_pl|L4Pz|FPu1Oq0ULba&)u`$62<3l5b1??&b)wjAiKCy!-B?mNn* zbhiD|XFv7~5!lk8{-5sp$G|i`rn}<+yC1~SK}d+A^iOBLp5_5EjA8lbN@b|qODB^I zyoK0(lm*OK$$&MyQJK0ELY~)*ojbJWV)DG8OIC}szq&(n-7^Fcx|^gidfNf^P-|o} zSLJLfmcZpwW-iu+jl2rrCjGuEd>j;&_clxtoZ^=Qw_Y)jJCl(>yDn|s+J6ZqH_~Uj zsPJ)>>$b63ESVM{?<>YbT${d!GVeG3)wQyawNP@mOpYtq)>XUO)>_gL{ONy{7rgRP zc-zmDT+P^(``2Qz#6Xk)dGuX=!Dee5x?8YDv&?m#9M_Xz@PeY0?|D4Zkvu_RUzr_> zNIe+VgPa#JP;cJ&qyLvz$CB1qIVD-(0Kt4i=ZhXqB&Gl$qP7@uj_Tdh>jWur?V074 zFI@LyKz^b$|G=@wS)gstM-jDQ*c48g2&)Yj-v|)o1Xej=!4%f|=-;k9oJOwUP#7(4 z+Q1g_FAL5i+*I|Qg#pa2h4yH=353)z@uH~ZM`>&3k=e}Q`fS5Xz%v}}Fb8#cg_WE| zR(OrqVQlAg)+qTBUIFr-AC|jh3$y*MN1CYOUWfRPTzFz_;uRd-ZV7nrE|t*MKp@JG zkJ*KF{ZN<()dsghE%q8)ti31CpAh8i;oP6p@v-&K_1?IUUq_P2CH-a1Ty9 z@lEL{&fzJ4*9&AsJ9cWUW+ym~%q=$W`Zb>wIKQnqUR+9cOxC&|xkC;?I#w~}v4mT2 zyL;EvQZRg$1BGzER2rtKL;XG3I?Eb>4={{4*y;C(THtamS}`}9x*4EMQ`n22JTA-! z+7Coxk#_q@x7NN&+ZX8DrNsW$Jh9TXZ|j^JKdgP)6EL2d@bEh%7#HM10-!S|iAp>rb1^97|thixTEG#mxzT8!L7TLz1E7q1a9`@z_46-n)2V$#6pfzfhk3_Zg z&bCat8|ap_;n3QK3o>^^*?q*w9L*bjGSwx(v$XZrWBR^06&ERl*cPi}Qp!Zs*WIH=uaM@~z+U3BVT+`knYX99&_>NYe;AJ|HpRw=t z{<_oidXc#Mx98(6gZ8Ts`s%b5qmyIgY>;MX@0+Lt)%(TQxb@{?Te`9L>ihMjMXBR2 z^v$;m>v9!OhwFX!FRS_`L2FJEB`VJ@k7Pxv6Iv;@uk@ho5=*e8#?oar6EH>Bk_qg{ zgAgvp7e^WnUyTN(Rkl*=F=G{+Q}?MpLh2BF+ibtS^Qz>hoeR1Zl`QrV11)bk!=cu< z?F}Xy)^M-;ikzO;kJufr*RzZr-;c-ZFXbe*)9X*w@0Ys`-jCsxcaJKY>65sN zd{s{;-yle({I-8X9mGAh!Zi=O2bP@h%8f;pK3-P$cX z(sQ>*8h;H}SSYA!-rt)pr`T>dtEtC3zCr)n`=6BlsE9@U@fC&s6P5YbrF1lQax%9u z{nuk`(pq!CW=;0a33~+x-7z)*PndH6S5e2Edt$PdZQV&2DpXVW9aWjX`mi!HrXe)W z_2A?*!WBNA!3Tuq%Ke=Gb+_V6jaI`0cVN=3)5RXY6PBntVA0&2Uc=ML{(5xs#F5## zZuP#T+@n?#!b%1=aC}&^^L66;ar9-yXw~9oeGjQv$znROmXVlo`Sf)0;KbO0k^Fg_ z@pxGabnC%Q^Zxsb(}zv_>7b-zW2NEou6bvg_9XK4X;10bo($|lu=-k z_xE?(D_ho`NtIAxE_UWJS$+>}r#lOFPS0okCfxT4(7}71^h8^NjGmg63DsxQmI1Z_ zd%@Z)HufxtfjfuRcDGflP-D%S=8UZYNh?H3xnCB7u7`K)e_lpzGt1G;V?dtE=;Kz>EG+o?E+vgdcX3mD@)Sc{^ype;BC6va??@Pn`zkl@y!H+*(*g`R9 zMjk(7W<3AiUi&;hd|CMxCw2}Leyqo4jPT|}%sarqbzSy^4c^>*zFpg*Te0P7;buOGt?D+70yE)%K$M$S}-#n#+;_-atPw#vcPxJctI(|KEeZ2MTbf&FF z((=CI<_A`6g_iJsfqA+naS>?vn{%s;gujXT%hp`#*?jTQOMv$94)H2vj{Q*xaMUhH znifkWCz1I3l3Ex==Om?4Wg$^koH|NA&*scjse3KTQK6k{*y$Qw%_m}va+HCn;R>$( z{l+=|KCKW_jvrmJDW6pqb0sQl&2*F@A;H!iP#IN>{96b)30&hG9}f2T@26Q+dA>t# z^iuYC2JE=#R~ET+!RDO!p@?gF;xF2Z61@^HsU~Je2}f}>QgD$-M0OHN5(XTk=maH^ zszic?ER7n@YN+Lm+0!v~xOoEj*EcV#lcrn+Pzi`6aF+JUGxLp8OHm3LjOgyD4i-%a1y31q z5!7;C_}I!<*9hong?2r`g7>qC1uZnbvCIPb@He2L^T8Q1mR0z1OZ38|GHl{Y?|d$? z;X)~9D)l4KKif%NN2nAiFQ67nru5H)-I z=I-6u>n*3uWRG&0bIh>`4QtcSn&A3EPg9d!Kj8Cn@Y= zoRtTTC%otEMk@u6X^yI(3^djagivbps}`MMb6!?6qx_IE*q7G(z;tc}-DEJQ_Q%W% z-kTBU@sXbV!0ZDxaHW_&JXXF<%9((4@HuIvj)?*?F>W>BVbPWhp|bE@JPfJ8KqCR4 zlZ#OT1CV9vM8RAS=$^NX(iWPtZ4rLWy*Y>4eqE_WpG+vhYKfi5w0!a#SsoOcG5#gL zo+U=TZa-^p8~QbvC40=7Vt9DGThW>fIvSf2h(Oj_?028?5L4?Kbl?=*I)~*RTh6r- zS1~<#}d6$?4%%6J@60N|^4oATeSc4}2(^ z`p@2guwDlZA!iW`kK)ly=kcE>*qlx%b^<76=(#|$E6+~R;RMLbYomliD4i9hU^xnE zSy(i|Q`YD^C0yi76a<%#o7uiujOZv|`Ms{*=^OFDX~cur76Sl-NSA0R@nbkl_~v-Ac4^ zXg#qlCuISs55MM9mPH%}Jr=EHqC)*73Wk4k`ni@QL|2+FKw}_&dLC{rlQG5)GCoiW z!(M3uA}T+EyI_Q2mH`iX(zFR_frN(8oYXdaj#F()kS%0f^}UoN@*N6_`Zk-q)AVgy zkRAiyMEs?a@u6b2ygFoXm?CC!0hOB~1xLPP ztw)>!Y6rPuVX!{|7aw*_1&ModeV<^@8hS}aRIvRb!4&_dX!ik!o1ScCkAt}1mK7)s ze}g)9e&_Q1+^1WiZk$Iw5FQA;hJijxuMk3NiLzf^RLq4`U?>j*RzPWoM-&kiUy!ZY zRi%LRI6aeqv%pz3U5rcCQ(9~|jsofM91WH(RaTV++L?@@7oe|VSZ9;5jtGf=KFGwj za{8f6R7W zs=%KM<02~ZriLZPPYRe<3PB%uYj!l41_Eg&bjRlAEk1oLOh+L4fNi519pF{BjG1e`u-{(y#$AfKx#pL0PcQ*~%F@CH^W2 zo8aQa7xDE^nJ|){>I>8Z9ZFI%I4NX6uMF<%9QGQQtH!NS6XU}FE>NphXx$}Dn}+pLuDZ9e2yI9E#(WKn9C#j5gSt3HhjU{ z4-C>Wsc{|!(q=*mUW=$8j0lP^1bsth#k=bV7$V~a@PfI@u}~QR-(HuVUCm}K>8`y6 z63B3+gq(<2k#LS#6_!?&YfL;ka#c{$76n+cXC6k3=?{WKK7OB-PEm;z<7O%*8eeJ@ zM_&)TqXunhbYc}fm;fv#RFu9ZBsWXjYd}ooUqux%kgo{!S}kd09i|_xx4c8HL}kWe ztb{VmOsJfzl%_rf0iYV^f29Paq(U;b9+f=Y8xf~$nUoxD^bR<9T+7A+#(YQ}u7#Bq zAX~{|9C!SSA{-10SS-W^13mB%`HWQE-~L9Ox*nKxnJ&WYAgCmO-)gBCzf`YD+t6ac zpFnDu@Z1Tyg^4Bi{31<@^YAL>C>nsYq@6JwZug*bp1PlP+rT>AevxQ>wvx3UAdorY zRfL#YCZm^lZl#~mCvcyEL3Q}A94I2uu%!?Irbu|^*1K|( zoq!4-5do8&v2H00MJ>49oDr{Z0anpKv{)dfKQZU6yYV?uteBi~7DtSH;>2$9#0!U&IRxCo{Vy|cD zet^+u*m{+Op!X&!q0cpsfPU9Z zDR#*3a2iDehKcES;ko|y)dGH606dIZ0Tji}(R;#^;)^$A^|QW-Ju(4A6+f~owLy~_ zzMsva`-xE2voKk9*{zp~=k6qAX@Rr*G3qxkhZh)XAeL-14luFhgM)}9Poh$tw@{0= zh_g5e)!mCDp~}b-n4b_;NUsGcU?FPO2OQ3w^m@eRK@O1|Px%G02Ht_E{U#DR%O_1D zq`F{k;1njvlbobXk<+OqC=$Ubqb)1#1YaI8MtCk*imR&PAo_jpS2|c+wib6$axBv_ z?j|QGEFUx`BfNuTpv-`Ejx{e2VA)ae~bU^sDstbv+Y6Mu2KZ2B?hxL3%jXUmPV_oGm;oz@$2t*ytl@MU2?5kRA(; ze47xMC?QNHF$_OC6KHWg*D_WOQm%O0Fuw#gA8MB_F>76+)A$RyN|-#NK?*xGQQCNp zBmKh9zaAU-Bs}2PeMzZW-bDH%X1ia4MvN6Nf4@DW_#nE`{-h;`Q{U;J6$)xJth9}De%Gy z5jhtOntJbN;z z!UZ4GNr& zLz=B7?C4kI@IfNJyjUJCsal~OAow#$FCqYp|FZi$@S`tviw4CzY zYC@w|O84vOA%UIyTXai5|%WW7V~(WYd+YQQ-AF=Y98MR{|k_Hju{^V zRAh1%#fe^~6c{TJkZ7)nAe#>~LJjS~;UESx@)dpnxW?cKW`%Y3dGI1;=2TV2$r_ZL ze8`oH5*vUh3dY2n&S%DR!pA{M-QJa9qQ%hfhE_GP+OU7?sZ0eSBkeS zi{{o2Onm&-wGQ`|_SJn>c2Zd0uY{47Z>ax{UKzin4@dmyRt6#dqw)GTdSzm3>tyUe z|Bu{ZNu|SPgAREM>H!ZV2GmMDJP}Nwu=fTEcN46x!8wm&-GGRPZ(ijCaO(|etHJ4X zd50oG<})}UftoYEVt9H{9NGDr{Um!r^7QUJn{*mdQkV_OZ^a4_oNigN*V9UJpG!~YZ)J4SQBdZUrJ;{NaaLC;yW3&LwBK(Z~lYod3QbCpS)qxDtCpHa*NvGjciA;2u%(B!lYmAZnG{l4G zLS=0Ps&uP;g}o*!FXOS9Gk)3r#YO`tHUAAmktDJ?;^)36*Nvr;FrA9()O;e;{KXsW zU$N}066C~{LG07%IF4Nn5eXW$vi0{}!1$9)T}FH%3ADoMvG}xtSaltU6R?kf;~FP_ z<`?+^{;cH;%Izw|$ZZwPXFlbIkl3UbPbrm>8Vm{7GkR~AS@KvX`U%GKYS7W_QPVdS z>1>F1F^<4OKuk4}Oj>TB$@R-4``!0#_*^$09OYCSqteg)1>r2~2@nUM@v~&*&7T5e zFpMqQa)!~!PBnh9r{ z8AG3yYsG%G1N|QO%z7~0C^N(xXG!%EsSLSsY@uZ@8M+M^V~DB@4|^*W+SBdz{`q+y zE2|5q$6Y;hZ8Opgo|sPhaV^7hHw&xdk~zgI_5%L@7V<#-k4neM%-Gua|Hygfs;>uM zexyFc7ytk${|)>X{_iNiRF}5JVukNQJM~q&=&CdNOT<73-psSV?1CsH5rIwdyJ;e< zLn|%`XDi}REthYuaWoGwLdS!A9Zbv*)$GkOvsg?K-#1V2%0gH|=@Oj>UHBq$(3{aK z6Qi3zRkeCMw#+rG4WHWl?MRYjXJ9N2l=xT1*QL*M!9+J1u>_EidO*e(GSv6^awwh_ ze+EN8{ZlUwLPqJCs6ugurKJJHfS8s6h0N|+*e$yF%lJT(Ujfk#)9baTxebGepSlHN0p&|OSzDm-+O$x0}2^9Yjcq2w8Me-s+}#7j(O zNJIzjEKJCff)*mO(Cp&I3*W@Twe-h2JKZm5myxF1w}B@ka6a5VFE=lJv}r^W7HA}S z=8wmrwBPP`Y0u9M*V|lg>(OYWUo$zpzON&yHuzTg>{+TiT%Uhm7gS?=+&&M8z`ZgG z{C{01qC;JC@Z8zdp`#WT7%+|if7zgZLLe*{aQ*_7h)W;Z>mee7^7f7(ci45Q#p&b3 z78(TYWN9-+xDxgv3?DeqLDuXA9zKOVm?pm{Ym1_LCKEr+&Xkqf{2c_V?bsq`aMZ#m z&d(h_VNBJJI+cM;f*8!!H?KIeif%Y^euZc-^yml8j$}pL)iJoiKZudQgQ2#>#JWyG ze`tJ82=Ur%;Al6pp}*L4&cf3eUrPn=9CvMK5qyi8E{5Ep^&~Gf<#$bl(I)m(>}9sk zAs|pJD3!MIs}`On0}FfElGqy#WH9Rqm?PSnIK}AVt}PawG2WWRMwnbidlgrl5b3=R zT`-*RnlzE-1+c+2>4R-o37H>_VHkwsS8?=2a1h+wq_Lg;eLf9mUKb}I?JF# zqzCQv_0Zb)PUL<0r`J~km#RLznKSxi%*NXdP7Rl5EJP7Edy$*&=|PL%Hj4tIJG!! z_6cL>uE{|`e0Drq!cN$g{7rQLorwNEu55$#J$UgTjsmLQ)J8SZO@}XQ$ z14S+X4a*&Ll5tB;OO-~piiWC5(P*7eKPf|6Kvd+J4j~WVWT{L*R&x<7Jyn7q>ALi6g{54MK`@Es6G3Zh&oEQq62iGum?;QNPjIXO z#uwFCye-a}IG=h~!-;`8EPQaYfY|2E;#C;aET37(k*X#TUrWsaChkw92yB848Ahy# z8~Ict77^wAnyTE36ji2d)9YH_c!D(kRu?(j9hg(UEdhC*MOP&dIy~UD>$o}-Fi;IK z6hX$yj)38~@roB&sUkjS_vD&VrQt6 zpnOTb-pCjB_A3g^0DfzpG+}9aon-x@wb#-uP7^3D|8?{9puD%Hw2k0a6z+a@9O&$_ z`@k)OrT$qnm+Hm%WnP_BUfS9|ZunT1&e1G63I_k#+$vwd|Na-^$H@?u`pM+MX8o^B z-j6ok+1l8~>0j+9j<(~*@NF04CmeS7Mn9{#bQ$cg1RIliDNOcD!IA}kF)<-&L~4Na zX67t=L{1k(P6x6wB(keU^Zj*eOtP%@aKo{)*l<2^*)OQA4q!1{h+Ys7IRz;0Fc65% z%gd|FmCMV|(-E}xtWEbNI_56b>4uUtFPTf`$K>S=@)KR|4L0S;6Di5Frlgo{#fjI* z^0e>UaX8&lZ0+EwPK#oabpHs@O; z-rm}l<&uJ1X20#BCw6VU1#QcVe|?TgTz48AXC1dURGoP@fqPf|6;Z95TxhSWTU3s6 z4E&-n>#9*(PhXy^jGSd5YMVMe`sh9V%?Xf&2^^%OP71(|cZD@PN$&MVV!MnDy^EUy z-2_Z`%H2@)NH!3*feBrA8Q{cY1%J|k^W3JNgJSZA1?P^7xd?3xQJBiawvY+OpmA7a z6S@mH=PICV8+p$p*0S5Yq1?EQUh4*&C4e#!M6k364Ki9NX%F@!x9O1DQ__Ahki;-Y`|i+f9MnS-vGfa)-$GF1?XxCf}-QrcEqD95|? zH}x}$pnIP3v?TNhvZMhF@4W9?uWY3T8mEO#tC!AM(!G|?udT);=7m=$U-JNBrD!g# zCuhEp-Uu!a7xTN?HPv*wmfdh>6eDy$(0-TJ%{lldc73ngaRC2HXzDDdr;OqfIOqWW zUPerh8HPQ;AuEes1ks>ezP9c8Hs0}DtXqg#BSJJlyVA5&i!>xU7|f(=*LFCW8) zua&1MUcGj`bASso{Dw(<70_z63dV&=xCKxU_)I!Uh-V$qzK@{rf+v}-b_rImGH(f=UtKsd z_00W{2p%pQf-g-yZ7t8cIPc3-UGG0b`8BMc+742nl9xscgbg?r8bm59Y(R9^#wNh# zEqc9CN1^@v+6N8D23bLh0A!7J!mN6L_zJ7M4D)2^L&D~qwsK}vE%n^p*!HBk>v3vx ziuEzZrqwZ{&o|7Mx^_zm<5Oi?^BgqN`E|y7@rdVsUWke9nJ+b86;q=GI4G1#@!G7a zOwtIw+yT5j7>|BO1I-RxGP~sVv9Rh)pLE!m0$D-EQag*Cp3`tNVr z3SgeP$%bY4yyU&WQ=}IG3a;fmp3QI2Szop36!f~FwL=3uwoYe$f(!cipcvA@Oz0Zr zz7U{qpy&L+ZW1L?Fkf({FFOpRzByMra~&YoAVFR>$I&?{9Otcw&%1ORe|Gwvzq>bX z?<|ecE+5m(ay`Ev$s8YPCS7E7zTG=l{3me{E1h+eXwHF|u%Q&~v^#Q}Az=38)i0fV z%Js^u^(_F0>Wl?&aT7NPz(2+r&<(S9M$qBhc7)COfI+V4=?)zx^GuTi*pHL}I2QBSN#E^Bp!TrkoYd>C--YZt1Q1~=E7j*S=O;jxKc#X*?xRNf_KP>iON zICRg_ktL47oBf zYA9Eo0=l&tIcOxqa9E$-xMWZ2Tak#r)n20? z)ty)lBMtZg$nYNb?ZnBkJj_^H$WBGYK)wko9}JBO-(>0Gs=2cB4@$pmiNMIAyD5eI zl?4?!c&5)YFQy$j;X24jqDWMdpV5{;`?B-lM#rlKs5n+Le<5;N^0AYPz_}-k3>vTl2Skveq3h;o=E&isk(i! z4|lhPQ3p2nkS}-hF%u3j*`C(5b!+Z5hxaaco!XcU*|`38{+I= z#T74VgyglwB7Rcs^duW*2v-OsxG6lF{1K49$P-`cS+rHdQb>x)=P5|@CQte{HVNHu zGlg~epG}G3qHxzmMybMJ;SD;cq#b8NUz#nrWDfyex~t(eEAIc4PnuN2*H4`VuS}xc zY3~bFGBs&Q(2P*I#B5=9-w{HxohD>bA=ffp!yN4X8AaE}j;9Uh(oN-!5~P}TCq~Sr z9~_L>!9_$W;Pv{$+1mUkkhm7x$R9^WwT(tKiJt&J`%;Tc+-yhJ$J+K}?CNO+0F|%l z`HNT7_H(4${tr3Ld*aL`>owPgdt?A&Eu;D#ANC2_vi^_=LcX;F=>&uNG3m+RL~~eu z1T~~py*^ITbbK#E7C?9tb8+9^8eQxJmhN!w+8ObYOfXHqHIdb`NIZ%CZ{jJ1j^Yul z0+@#vU{QxDpZX(d?!rP8t^>S{-d`Nz@a-B26+;@gqY&O=AA28bdggdxyqRN30AE7l z2^igk*>WG3J3S0<_cG8Qdr37QHzUZF0!7oRvCzK1pfFRrVi2GbIc;_kNv28sG{X;! z)DyxyU62Jn>>M-H-00mJKrlkYb886i2@g?mF)VRmy$5w-{CSch(m>wW^7>RQ$dnln zX^Ftz?4~V%UJQc~6;m)pqk9JTGtF4%dT>FAm`3T5R?7kCNe%Lh{$8$maBA#0G1wOr z^@-X~y4Bawwc#rY#9%0zk1DtE_|lCT?r^cf^T-;JwzHxPj7fsSA3A;3mwZ#I!Gg9! zi??Z2LK}1uA{Spmj+jh_314;)4+g-5+K>K83MKnhIVt%Vr8Tof8aZbCv{VcRN@XV< z%H||F-f$=Znw`>%B1W~qg#+l^Nqhv5fUplwPXMQ~i^ZjSP#6{Bj(r!^;P{@>gVQTQ zN`8YF8S|@co=ekAtVuy+L~vH#oMoxIsM*H_!h`g1!;wV1lJVmsFMhH%joE6l*+y+V z!~@-f6vYZ21j0zN>2;uXhU`?maiKi(+ComI_$rxEy|-VQ2^7*FllA(z6kymS5iqzX z%8`JOgPg1X9!Qs5rG9IMX9%tyJG0Tj&JFfjna5=hp;{hEqV`_TMv!QnkU^^N#AFR5 zL=tIr2fAbFXKi)}iiau=VAzXXG_V)5CR4fySml&)JBVYmBjJ40+Ke&wuYrmV;1k}A zxy(&;$OdiJsR;ue*Mq}&DE#Vmdv(lflo{QkRtom$(kT=Gn-lr;Y8X{)fyNS|w{ME0 zqgD^nLJt~6U*BwWl00j5sU!O|>0Zm3#iWBGVRTb3X0b5E_9wIu?L$C`1;>tLM0D_n zVj%kyQ8eCI6whE<*iO`|T#esbP_%~wN>u5gWjanOU@YQX@ zry;=p{g=^0**u%5IQ-qJYXy@xJowIDM38z|mQn?uxtt_kAI;EEaUPe(%dy2h&6df+ z;TYJI=cbim4oCqc;mKcdJG7rUNF1_mNg0bEa`?dRj}G|Ky}u4~KnC6CX^Zb8-D7TNoEH<0l){|0;;oaV!b=fOZT zy2laE2y;2JI0ShbU1TeS!2*sjcGA!(7y*=BpGS*|$So>xyR)dkV7tk9x&GK&F1Roq z{w_?1;!}?oO#4%-+r6hL;1+BO`0n+d!nusRwcZAW8qoQitqlv=O>i%=)#czhOCeco z({8m1$F_CvX$e?+ea9ygXnlUd;Wo$f&vt-<=e6mPwzxbnB4!a?eVn2GGe?oAW4IKc z{E|4xc*Q9%;Y&dsf6l;a?z$as?}sPu_h(zY5^*CbV2sH9H6|cU&|k*w9?*8cJh^@@ zd_pq25?cNmtEow{Y05%SOS^!C7BOdow0ay_${E&d3}b1s1ue9(S3YOy;3J|G>c~lJ zK>_G?R?TndAVswR(;f&ikAKtbjG*hBx4pM~UYPBczY4$$Hdb=`hwKwpa3GhXdiL*E zo>O#7W<^0*K18uT=fIn-xJ9+>qCJG;^i}CJ(#Q6Z)iVhr6?e@AG})yP=AB+B|71H^ zRc5Y|qSW6N!yPo#Y&Ya|wluo>dOnYt9>5QED#vvaK;kY>mxHq7-?}a{MCB>R2SsY^ zl8CTE$mTLEK*+zO<corYFzk=4FQJg zWt=B+)Q6o>hLWRBE-h8STm3m2+?b}I=3nh10!LIwgS6{E-9Y>co(o!=f8Mrk#}sa^u+sH}2mSya%ltH8ui+|V8X3NZ@z z4LM1X;i^!l6STk#lyLQ7b%L%>w^CamWU?F9=JXo?5RwI@$b&BdX!>NvQ29)V5$=FA z4$w1j4>ZL8Kq{A*)8WJf@|Xq)NW45!>JQu~x)dtVx=?ta^llQ$`-W(nmW|Uh$J=*b z*KRm+VK}Hx5HNGr=TaK!G}EmBlYLp-4FN-0sKU8$9SwM;^;=oss!nhPve|1~K4G>_ z2Xr!?zXgS{@FY`&aGL_89HdVw?^#4@*;q8kgaQgJS+!fe1UVmqD(0VbEyB=S>~KPp zTtpD$FK7r+;z(eR{NEA?MBbgteaWy*>M$|ufwP3NOPu_GK5XfT0-u)W?KZu*7Ai?{ z@oo;U`OAt^4!GyThIs{hRg2`VxtX+fZU@XFYV5ud10!3zRBcu0H}e#zyt67EShE8! zpeO6@VWyeINOYfOR-uti=!_UYI*1c&L`F5XiU>qgry2V*uJ-rXPg&dxo^Gpat6-*_ z@!lsqZ;Be~Sc=Ggw<6ZT{GntFt8ex6jakJ3va<@BaFps+AX|wHlPX9b!3S`A) zBkR}hfoW^7Bj4-;hlBgN+uIh6lXyS7dSVg5&m!8hz(Hz`OIR#))^1TcKv`9?DD5gv zXSADxI0#1Nbw&+ouZHH35wG|fJ|}_qD+S`#G^nMs8gMNeXO-s=Vc zNAC?L0^gEceX~5(JvCvYB^H7?0jhhsK%cG^WR6)u;QMW>7{PPX;-=QZbf*?2|U;u#KpIpXI1nNKgl1*%FoRstptp45G z-<7;$vrdORd`)(VlfT(gCx}l$S>?w(Z{t$u{QvFNR!+7xN6S*$jpP!-ch4%@S^h#U z;nlpfsn@pO*m(B-B!vmL*tRwa|32~Wr}h1hKc9-vt2PhGRC7IkeEEs*D^5I_&{=r= zf5qH+D*KjuE48UiZz}s^dG+7Zqp!oCZ~o@d6;y2y|HACN)xRY=-DLtVa-1wLF5k3( zDXwqHqa`i#vt$Yu+4*-*_W9H_CFej<*tuq4-*~^rV!o3~?#k0Hnj6h7((VGk-y(Yc(}4zZkYY>#Qune&uO`i7A)%}m*1*(Prp}vvU3A7m(r4D636aL*z`R`-_8HT!zBW?%2qkC^E@?W6Rf8Idz)FTN=e z=kt}Jw8lb6q?oqT%TZzlE%AMT@^~5sP8@6~(n)QN@ zE#N~OkD$+?dieeO->)C>MC@^iy%Ee)y={$bo7*M-$91=Adl>DVW4}BNF{3p>_K?oy0YP-n4$Sh!uo8Zda+1KP9q_^q?-n8p4=hS%buE)r0+Ve;` z_E5>g-0234pWhUB{fzFHBO?X&?rN7SmX<~b&^60Zrr8nO$yY1h3 z<>V?WzK>irPeLEf@_FznxclH1zVg*Z3Vl0+Wvi#|IAlGmp*UyZ-E)HPOgS&GSp0d` z%f)xW=-#Cxi&|fF|HnN;$Og<(@kOaQ=qH>oDk;hT1zyQzE}VF$hrBQoc?x!>MzG zZcln+9*|h6bN*+nA^R2^`HY%BAvPr`pW4pY2pzLMU)Sh|9 zi#sIYbFJ8dGsSYk$uGcQ)Bu)bGC&%c^DlUzGt%z8wj+#Z{62?qgvPc@4_i3 zcD6XJJ6g+dHSXrJO)6Vv2koy7bq->0s{ZI|ush>f^31pIsy961R{nZVQ)811%dT7I zd$UFNgs(3@uh6kId&^fo(H@Tt+WGn0@-s}A`(OFm=u%X;WI-~Yeo)ZehYK`6GsfPM zkY_*Zc`S@Aw*HmaQ?>K+Q|44VR6f+?>usvYkaG-4_Bi>!x;pun)c1XMd@p`@wV2#1 zTxzeQ7AzZ`!umXLnulXtdqsqB)8)c6hRIVdN9!2gS${HNPkPU1?LV)M{y97AXUmzD zNnhLxX6ejb5Fy&=KKoRS9+U4c5qEXU(k9K^_W%3WeB;9(Pt8i=G|YUjWv20a4TJjLOL<`%ufGg_KTVXgHTX~kyJ)m? z(&LLyj~49Wo4^(IHt6WHj)#4pRh}ofYSl8hD{t)&Q`mb;RUr!!!b;|cof0r9!X6Sy%z9wYnd*ATqWpgjDNaNJJ_;uT| zJF3wOW2-}VW#!vs?dl2sm{xc3cN}}XOW8$tkBSxxi{BDfB1In@>zG`$^#AU4m|YXW zc%AK^^MaGM9qzx5Gv?2GF7GUSS*h}~zichALS|$VVL+UIgdRP>7-C>#Pymu`?pPxW zVgUBDMnDA+1b_}wdJ5bs2FpLFmZBF(AUzOEIbC6Tz}W|%WuPOSAOK_;2p}EsglZr9 z5lyLipt1}CKw9+OPzo$`$D)^QAdQfaia^zfQPQECgg(uPFiBh=>I7sn z(6ysC6%pDeIYPCgG#t_Oqp$cv=;v00>xZxZLf4JH+YzDL7g&a2?0rPnj()ffLc1(5 z0wLPrN9{l~6BBobHK3YdD}Yc_Ir014Al)efENEu&}n zi57-3204^1p^*-Z9ZO$7)=V3ch`0rsN}IS7awb?O2%V?_9#)n4tVKZU72I9OFADs6 zV_+vv+8PmdRKv6W<`|k;5gn7){@7i1uK%X_LqXLK!NSF!6+4e6qI3{YHTP#^Wtpb7nwE_!8Nd$7VVibNl*N7B2#rj}SE4i2`!M753`=N$SQvMqJ^1 zTJyuD=gr^7+uvXPG=u%T-`MZHctfO-&)Z*t7Y^o+ev>KI+-VcQItz5y=V>9X?_2-A zzCeK#{)Z9&QuPD>{BGI(w$UHoMy&5-YU9j6|IhjV8t?zX7W>~`y*f!&8k7k!>?-Js zXsU;MgPM3@Q%~er*5m_NnE5R*3n8hZ^=peVivCYaI6jN#(FBX|a#j!C63rN^hx$Mx zrC`J27HnOhLU@2mT6@M%GXY-1%9;v7yJ@uYL&Rs)R{IUXyPg&9Nx3+lz-|n; zuxaAqzXYb^i{)WPV@iQHuT1GEN>HL=p!h$va_sJ(nk_WP6A-NkJhzTWm?)Zgj-pB< z39^0?z-89mW=}tG+TPPgwtZC}vE0>!B*$y^f&M3R@!ZU?WIzN0k}L)SLi(N~cY7xj z1`~T@SKDvL_m9Ur*V2vO7)A4CnEN6;-aKrRfLVj1l!}4_3pC_D5zZ6auO80WN8Gn) z$s$Amj>5FHvI$rgTO<}RE_Tq$7YjglMdCQg)2soMeTL3BNSp@$3EPv>qFUmMnB1NE z#qyNf;mn!+bBpKZ?>ZAK3FHf;>n^!|o#3`mE8q#?^lIyBYwolK3UnKS{&rXJ16Azd zCxZWH(@!y398F<_*LE?&_i|2{>fl!(K>mbdB3l4{gq>F$S|JqPZWj72hl|U;MgmU3 z+@Xlx4&W;YQIj!B!k_#)UQk7Tr#jim!VOBSm)|2ySuwz5y zu3D2!DgX>wusjUmArLk?ZHGoNrdH5^X7ZY>V|LOa^@yQf0msa6z0d?EhrAgKVPgZY z28^i8#qar6pkUw#<^pArc3dj5VD5)f8`S$ccBCzsdB%)S6(ED_#P`y3>T}d4|U)>_6Qa_2tO8iFo z6E?!xeKQ~-hpdRCpE8>EP-49FWY)-~C04iMQdy+IO;<@#-Bc0e+tX3&*HEy!GI{lV z?ddymnEIEy%IViu_@KyZBV6J?n2tp!*nEu=pP_}Lun3LFH5Ev;(z8_JKn##b60mtC zh@r5!iAEGJEf4YbNp*4s=Iy?8Zu8nVJHMt+8zjYL$4j6ZeP`l*DkFmPySG=IV z4UlJo3?o3}iBx2M<>`v&llW0Are&n`T)|9#l09iN>{lxl!RP3+2LVNFBLd&fC2I6O zM3C#x|9QGQf{~}o^YZ?%C_jGnJP%l9sK&>U(34MEJ&o!lt<#Vv851K(UZoVd%=WgW z7%W)CG155S`$PXU@rMNF2A4UUtErW_=-G-0BlOoMCZtoerEoGIcljbP^c_0dLAR); zres-qK8LW&uiA>SQHIak(=++8JYKJd^DHca+KAa#Sn-a}rvrjI8LxTTwH-#j_k@u9 zr-IOJVEp&vBD5Dnls_jz=wpV1L{NrcL&h5X)zhCBa~|;eJwD8Q-VJiPwi1f0CF~QE zE7{o#b1~j_PLi4TfAtYLk_yg(Xh&t_K$*$kNOyI+Et1UWk`nt9YPKjPXy(s{Ls2PS zck=0nBO>MY97l)p^ip&^LTG+o62&B{cX%G(LoRW|yVRLHR#O_5NhpnmrO#LVSCfK*u2{3=|GFosbyE5#%#+})LMX-fG|{wj!@@KrF5)I zim|A7KnWd0YgkAnkxe@-0(4l_GfkRAp{5W|o|$r9UtG+owUxk%N>1={QV$!+AO_E^ zfC;vL=s>bigtzT9=cbA=uNPv;XqE^L8TFm$BEy5JMmaZiI0%G$FaY_%{EB&Bb;$8k zkjd%BiJ~9xXIP*QyXv(x4yN&NVR;)!cCcBj{&zR=w2C|I5YlL9dV?(zrzK z_DP0}qN=D}Hmqf(&e~aHo4TqNUFFuJ83P$%inoJKI(pDdW)ZqJ)!mBBC2cLe4BJa~ z=c4;Jyv_<{gL0n3jQ4G6Bu_tX*3bFoIco)Bwi1k1R!J&?dIBj8J+&|rPIO+aNAdOx zsh*v>IDYo);{-w9uSY}Ze$Yx8JDuDoiK@9PiInb|3)E2e%4v||*G1SevZcb7_*9jI z4=4!#*QY$oLak7%+uGxL=Ft&EqzF?)Jb&Msg*!B;o#JVd(yPOAF|~WL4qy_bRby*$PRqx9pr(-FUNT@t&vN!ghQA zj2ETxGK{6nl4emQh7>)wh(>3C7{okxDqT;)XFeSY7En|;1?+3M9-OOgVE`$$-RmgLDpsF#;Qbz1cO zq_~SRdyAU)XOZui!W2BglLB#J8=0U*^v!A;Q(;-mRY*$ps**@#qOR$J(k>p1FvIUW zhg|lTKS~|1_r98=0Q=cda|U$z!cZkNml_#rJx}|}sw^w%H43sbb%7;iTM^)!lTEgs z7&b6TyYZTu&E&5W%77e<%6uTNLJo$219_QFOl~Q~m-^0$SQf?-guHL()4dk&$Lk3Npot=tN4L4A`F)h<#(CrX z{OJDm=)UgD>vQvH1*1nbG(9%09mjmYePdCdxBGd_N^bLa)E}j#M|m@AVJl0#rRBP$JTyP z4fT^owO9V(p{uGTX}gn%slqz((QqAdrNfq2iM!FBN`VM%G~XDM%NF!^lo%EvDTKwk z0UF#!e1Y7C{Kt>36*r;1QcJyaR>@=pN2iOw-j|$5o--X|D-#OyG%U>=dtPd8PJ?*U z3aB*>titA_e4{leb`F^CHv79(`MX4GO))Ia4)}3qhjbf`59P7<%;swrtje9#EHZvP zHC_YrT@ef%=KEqStT?$h^p(YnQLVeT2^LdsKRjvm9(_m$tF2ATZo_o(X>Ir@j;hz3ilA-5HYK8zW?u?K`{VZE zRyb1ermuro>3Rwb z!+OXi|FJS*%mf=HQ^X=H`bsqP+ya?;#9%!p%^!dQI*yS`V@#b(u+T(Qu?33#3=jKp z1UK1wzUC(+u0(}4sZ3mQvvh1g6?UX)mY|e_=+bWP4TZdqsHa*o)99_{@iTN&`)F80 zi&Uge;DHi*VfYVY>Z~RuB78@lkhL3pD%idUQA%f;F(gRp4p#42KQ&Y&DwxGDRSz-9 zaG5fudbM`l1%nIf@zw*s&(q(Rld6!t_Tq`E+vqx)d#H73j%mY zq_Mm)>~c|QDAdLva-|k>G377ARxAY}v5G2i$pY07>=D2dV*w>(`-CJvRW+SDT`EE| z5)@*?QP5JCPgXAi0uPj%-YY7Tq@qjZi^B%?Ml$HFNt-Y;dQnRAV$xx?8vT?~W~Hlt zOI;}X&4MX7K`k9GXKRv?#DQx5DIZ!EHl*0~QPSO#45$IW^WcIJh=%V!>nsK(S1Xo8 z{N&^auAK7EU^@e}_EM+}+LT?p*H=w; zA=!M%@W4HXV|L(S_F)E|LEK*K!QN|?65l58R3P?}0E3eF@2%O#_NTnoYp>PdoQSNp z+GmDsgRAY2H_e-whl`q@n<0TZMPA38u-*E-N^Ii}(IW&}7^JEQFsB!2{uWWYgObf^ zABLQPsM+zApCZPr`e&-6oM~ti!S*MpZwOSM8FDj3Vok`ZM+B zjvLLXEn+NUmSF=x!#gE_ffHt!vExpB|5t_wE%nnyTL_sGDUtrRr(^86*9Q+WU#$16 zKAXO-HD*9D10g&V_bkD3ycZr)QRlKI4u?P)rR)I$V8{;uoe2S}a11Q(5=0?XY-j(` z+jV1eG}8AO-4**nDz2QJU(&ur@)YHQk|81o+`Gg*C(P*3kI}cPwUVYVgG=1@K@%X#l;$$wfIqNU8zV^LB8~ zs@rRv^AzES4D-jnYd--qr@Nyw6Ug+M>J`BCF`(`Ud%maKjI7 z(yHLcT%{Agyz_t!wq(CsfdtN+%bm_Qjs+hVrc&&!748s5&sZU^CPF! z64SdNLxPLB*a@aT=Q-i8UChz`yj6YS^rj3yOf*jiG(Gp-OtIuo6-x0wY;fxMTGBY**F^Bn`#-b1!`E4&-N^XV&UT;Bu5bIcIBSiRM zP++|27m@q$;Ggr{-(uRicTLJ7^tXs~36x1Ru~WOV-Qy7@KloV2EygDRZs;NYtQbmG zCuhyU2`v1XiO)MsI>?QD+1bJ0OY{CodcFdZl!hOwl^Za)evw8jfJ;%*#XPB`Xv0i% z?0vWesxN$TB2fYnHk4mRV|Vxfm9@1iw3Y9h%1syo8^0Xf5 zoX)?u(>#$VGW8rS$N&Yib%vfnjbTo@QM&X(3`G-zHK;`dKyp-SW0*j$Mv~84k%~{c zrufq*<)F(ZfFa3bqUCI$k!03F8M^dm>hx?G(kGziw3B96GIawuVMgRyi|C;7cpy`1 z69}4Jy1~`>ooCop0t!^5RnOUAm4+{*tDct<w&mnh)YnA|k#54_;5CxMNUHC}<(Kl^0Am zKph7^tl#~a>Gr<@#Q#6;%Wqvul=hAJ;`{&tLjLaYFI6+Mw|B9#cQJMT2g#~V+i+TE z{D%Fw7u~O)bH^ct`ccM73oiCsEeQk?!Iy`*Vn`Xgebq=p+z(~-Ka~?Qn;Lc9`+vRi{d&u7&?x3e52F7dVf!39JxhNhUX!p4ZT{oY zk4R31s`>h>g<5btA;!tZj)O!CyQAT!h!g2g95G7jVmU?B5JAt9X3{^H8rN9SyzG9V zB;kh5DgcmdJclTWu$GeWG$cK^4$&X1SHXoygdRhb=S6!}iY)so4+4vdgbGU}n{gyL zo*io(N`ELeV@XDQ7kqFl(&f7Ic9ax>lW{6ITOF#}B8)$Jl~I6bY}RllfANB_WGrD$ z4ZlH&?kpjCWb4Vc3+t4!#xG_Pr+>;t7vJWwe#&_{-PV0#BV;0Iqo-*TdewI{wAA4v zcO}1RCE=9~rYQ<%9wLfU$&9Kj;yr6%%b2m5_)`IS=dR46QR8Y@eOcL_EwVTF6Wvzz z0A3_tOpP#MS7pO3c)}!}y{EOH!(r_(@X<2m9EJj?%OFH}`(x$;38FKZ>M$dkmo7ML z3^bRr7i&4-twC|%&jSfYT!6@1EZxw^Dgja146PhPrIIe<#Ve7WwhrQ3k%{YmwTONe z9m;gEzHyHWt;2&ka9i$FpOV61IQ9tZZ3U69ids2y_2?JmJ%7RSnVJbMD}vYH0P zC%MjaADn9)My37fKM0}n3U`?7WUM;}y8gPE;p%o3Xkyn~Dq03BrW(`TRhtlpni{FM zUaZ952D6+381?G(@bpOs-sk+XPHlEDIx> zZg`k2huFw!9JGovP@$-1`xj0Xq+&WuISj^B2^9d9&SHydx;*F?FLD_PM}y0IUsMu? zx^o_gBEn*X%iSDvY&DL$StyEuiU2f#GOCEd){D(1tfvaeiUkIuinri`c``UO9hSI9 zZ^;+KdYObiB$4BSya}eBDXH<7k|ZLy&ny~@$)1}Rq@Fyk?>4)Ogz=_&6p?-#f)b=I zjBxa1DTEW5+Vq8^hRO=-GDe2_OA&BYLP7C$y5LdYz1>>BNoNF^uC4x-$=AT$QHQn( zO|FZ@W}*S_sIp+D^K(-Wwq(FaP56-j+<@WswO2@-SNcM~#@3fB41HDH&()2XpXw_E za~Hqt1SwXW0NVdblLjea;9@jb$Qk`_x%piMup=a6QT5Sep&2bTM4_##H~f{R8rzWz zb?(qczZkFgjyIDzP*x{vR}}J!qv%#TM-tKoX(vVFnTRaTU&ZVZ344BZDE^rBleAHO zac?_qqh0=g>9DKb{-d*z9&=%VGE63qeF^hE8>FZLKCp?0LT&&7k>YzvcB8Q6lR4fq zK1%I+U1h$+Uq#RXW?5Lr-ysIKFPu@o-&mjJkoz8CN1qL2Z;W0s)6_i7Iqh@Q`LAH~ zJx*p#BOLGPMiBs`&1N`_lbdT%WjOq-+C@uv)V7SLPSq-U$TF!eI+wq5KW_DSdh_x4 zee>jrectq2^i^&KoSU7yUjL)ZNB8T4;P`I2h6Mup&MW+{b=cI2>7P}&IIY9(FC(JB z8_)}+peayRl20|A#|op*Kq$(PczRfAI}Q0BaFVyLK3JGCv6Bm*c zjQjsEp|jY$Ba5S7SVWFGE4cOBiYQgn=~iPJnvcV;i+jr|`~d}{i5Vofs$#Li;H<;W zztAJRt`uB95%)53?D~*UOlCb6U$;tnd`-kY7|sHxM?<@Iq-7gJ*LwhStmc_u=Q^aMhZyoZy&-J2Y{+RJ2hNq_MdOeV>Y~ zC~r2X;rruyX*|!*uG~9`w&*sR(WUv9iX&g2BRoN5tcmdSvX!GU zbAnoicsqUOXKeGl$f$x^bXr@m(YQhQff8a%#7?ri*){@yf4`51gEx{YgTpY#)O6+E z)`F{^zAhKVZcm~ZJ-vAOTCf_yH|{sg3Yhw(qW|nC?p1y-+J6VtTv*?};=ioS#lqCq zl;L0Jf0^33rgk*WPgFmKd;SPddz-6QWQLnCUHv5XF3E8_rCSdkl3B{-m>ANlQF}5^ zT2!gUq;Lo+{a1x`2xN0EB(iAtHhjDvQuk zrYR_G^(m)g%XJK`*B++Kt$wmagyD?FjeT?&wrEu?yB~hS1^hPEX`8QcKXdkn05U8$ z%XDsNXxTipD`Owg%I`kD*|cEoGRE)uUcUr4uWi?~)hsuPOZig?q zdQA)JCF7PdP_j+}sjw6CASe`CEnLbyr=T~fTroaGE2GATr!r+)=6!@jNOp_~&9e!Z zl`(3<%B-K)$2l}t$J71(RvpFDRo>sX5o1@Z#?@A@hoST@o>$n9kNqxngx*I$XzbVB z(QMw=O)3GU?M}2k{@26(O?0?^_xnvCWbaUc{Sbm=6nJM;{5)J*WuzxWzwf6RdN?%V zh7mwfxJm>ff4bOG`#q#x^(cESyEMxoG*xaTh8XuzCc&Z_mca0T(nXb_|FltGDS?f z0WHx3b6CpyIB!B^{Qf{lxLkjz%C9&k({da`A|LjZ=ivfxQRoQ%i#L~~P6_&nx$wWB zqc$eta2wFYBn;+BWbBW|Oe)f-bFSn)q#0epF1iQ6jj1QSqV>s_i%*ZTB{`qqh2Eoo z+sGK5p8z57KsZMw;3IO9Zk0YqB-QfmsVcqCkBR!4v&AM?4ttv{(Ly~iZIrXNqa;p` zOC6wqb1pTUK~P_YnX8c(e}Y58-UO7Wr;vI3f>MkJ zm7)sFq8C;Fl=3|n4oD1VM$_S6?PUdqz3*LAUgtUt<1XaskVvh$K+H;pPwWc;cL z6vro)3iXs}DtsgW`Ir=`$z)MFgQJXd$#r_ubX&)HLKr|hgNUy6sk z?Bpz|G07MR#lT+2xiU>$0?&&VWr`hpcSXFSC4$}@Xl4h8SH;_=sca{N*%B1k`Bq`X zrSuuHESvAR3?sw|cki#5hJ?`wN<3j$N|Wa=MS2*Kq*CL`4aZ8;uF8(>6=$BJ)8z9= zY>w}ibYl=8+)-FkUfKIMvh9g(pmT6E>Ru2TuZR!t4ksT()mp^`h=h2bClhIRd5^xZ zolt$T=J@?o)kZPD2&|MMitdo}Z_1HNwI^n2bd%HB;>5jiPH`KbtNhOeyflki4uSiM zla+XP_i^oNm`!($gN2@Q*Xdu&HC$v{p91yeXu+I+Sd9@{3YSV+M}Gve{q?b|(_g9ZU5kF!&5SJ}SU`6N+FqDxpkH8l#)2-)^jG zTq9dvD6b@6!=CD!ozPk>_OOr`#Y8Nx=D|YxdFf{__PFBj)u+Yh#ck&vJ^i{C`Yxrz zgT2x;?bG1*alThZ@CIwTI1dVbwp+-%=(n&)Zm$R~veq-n;;;nYnVGW2i?T82NvR zK=0DaE!un!v|W*xSLV^9GuxQ9bMDCtbO4{Km{?7d&c&LNAq@{G3tPxL!} z_V_o(*}cGqg%9gtAJzf8-n{Mi0?j|a>f}oshWy&G+z6U2G9BNIMb;1&H|y{{nzcXi zYdD1%Fw{2;y_+YJe^;By>vw-oz|a!%zJM#f;A=emAK9;<$i*-CbimutMkN5Zdn=_(vVA9d&%JjE)VjrbHb$zs-W183-`$O8 z*6!)20rR#t#2>%$Vf6S?w2VifYyaugmV0ppU%NjGaElFx?>{$Ng=bN4$JVUhb8F&} zXYA;wqrEShAA_!IC}DGZNWU2CW3*Aa8@pW$muo}t_PO0?0C;__#cxmDoowE*=E3s3 zo}O5R$Hw?JeViO9;tx4#%#KQ*+j1Vh@#5}nF5R5kN56a?j!#HxF^uhAWQ4C}Z6d$s zlqxs@U8V8cg^vWbjNycrZMHY8)y*}~W8v0|zBfrj2-&sILADV9w>Td|H?8o@vcZflr`pg@G zr(T^L->iVM{`P9j8lHZ&j-aos0MLKXhJ8H49QLl-ZQ(upxS)R3x)vDv4-GjqU{iB@ zC;xo=FnhT8xPbHc_#&L3AlO**VR`dhy~L;ISKD1O;{}gG7#e%KV*m2!^|{+ipWa)# z%iH$(0`RNx|G{`&I=$-aeKqyFi`W1BynH+2-}L{Qls{d%>#I`l^KrjBeTg1<@aOk- z(|Rd-NPwE**Lg?V+V74*?2)37lgXTe6ahn$-ivTn(rk$6UA00{x@pvm(KymxJ< zd#{OXPJqn32`$xWjJ*afXWG*G855(2qYNdFcHjN=(B4z+|PuLiq;2tJi=W z)slW(X3t?~@>I};iaJHC*)5acs!+|aNs+68-yahiv=;Ei z;`m>Rw%Ai4QUflQI3?>Ya1%_GbVl_EQ#9Ho&DXTd1C4zK8|;*k2D1r!TtE9Bi6ReN5AhFEQdxF155OrgyrqGibs42Kc-BH-^P*NO&B)P%sWX*k~ zBQ!&;e14A)Q`RY8D5;b}RzRNoNOnUXkm}5{NtTaV6ABAE9xqP#q0}|%k&~E!GuG{I z_Zug3XI8-1J11`>29_!Lx{dYDVZ5 zwJ@oTvV3PEH3p>9oHAUvO0E$ea3h_S38u>s1=S@R{_p(v_aloG^JAyckz`1!C{1OA zLVvqqJ10moYD+Xm2z4ayprAEzLPw`3E@3j05V;4%PQaf)+!;AlmcUNdna<2t47Ml# zh*ChGZ^+_UgBA{Q$}zQURLRgWXj0uRh?H4JqwoFEDmT3)_N|-^BHFETEV2~n7$#>* zQfap1^vz3uu)QzW8#M|Q%q=rWL^~T}?4<_LoeIYHX;62|lSa8l_Sh3Fek>}I(IrWg z+K*c*EU{S9lmy*PNui#irNUGIQ;1+J`wy8Y&kwp)!kl_7YYM>B$Qo;w1yO{XF;%ir z@9RafQEz6J<_ck%?oR)bK?)>G5)JdPpqg|~saO~sKm^0;wM)C1hCp~TGtRzbX1c1w zg~=D`01z8BQG9B3(DvJj1y0u6q;*l&wYa$Ob4qjxdUHWJL$yRL!f}tdn&vrc^Gf zh$q%qPZq}fR%TgefoYsUL|8m4%!;mtQ5`|e0xPO9`4M7?retbe@gbwhN(>~r^M#f? zi^_yr6{A9@$KEMtJI_8_UF`O!tXeqQX0pQsQ@rcgVJ#*|FQhh+c!>)yQtwO{R4&Pt zH42ML6TL=Mvb9M{M;gnuz!>qorH&Lwq?AaL>awJkZb;;L{2@ac3b9z-q0{vm=jw0 zMIpWy(479FsJr)v!vq^-miQ!#n>1cq9^30J6pQzKdCR3b{ zWN6ATcC2DDe*GG()TYowKgY0G8U=PTml)GTpb29{t#V?aL}?NFuS(+&MPuQ41@It_ zKW}kMnWL&#tY>#b^j@OgLZcgTdl5I&B<}N5@gRcG!+TUwxMi{iuZP+Px*#Y~;w_UL z*qH)MBOFoLVne!2V5(VCGNqElHchnH5=v=3lS~tah-Wofs70MoFcRItgBZ4u;O|bG(NJTwGla$8U?D@s&7-%z`qF};iPf7jdIOU zkfA=)fd2s|wL}HpD?P-up@v#jNd9UjdPm;)z~*^5dx>Iw?OY4Vz{z zk;#stqNUKKALy3Nj@5egowDK`t2T_HIICD#);36yIROH>{;B*I(zQ4$V@{I zK-EkV)lhq2n7_ARHN*3%sFuq6ZA|TVY4_^Nd|^014TBAh-(7$P81>#P0-1h6Kn*~a zMh>9aQrQwgsbo!I5B=F+uqlfe;8Wy=LqiH)l0mOvCO3YI?9`l;!&Zr}U|p_%Ezv@z@*#tgB@k+ZiJ*`yL&1Ty7t>6eyI!&G8aty_co}<>zeJv8`nsHn zk^9hXo417~L4IKe(?}|&-3Ax=6QDgShkm;46Dp1MZghy%h)s%FHGu~X{s|562h7&0bJXk z(f?X6kfd0>?y8{sOVb`v;vr4cJUnP&jvjbeO~yDi#Cbq+jG9D(i*mZK>2C4F+zoyK zoXTJ%rj;-eqCQ#u+g52Iy7EJ2rlJFnYf-(k_7VM?4c)kMfD?n3FzMyOGiVpvG;n>W z7TZh;X;X@>$F)RS<(#m7QHZ|pr(=Or6{Hy+0d&;6(Mc^p9Zo6r0~3x~(a*0T z7B)KS=52(Kmv??6?TM#t5{B3JG5wrAN^3Fl8%w`5DOFKV(JyJrQQKg zimMp5wB*LbFVg>Exc+Sy12=jzaycHlqbPB z`M;= zdu!H)ou&8d@zm+%zx8kZt0$Ld7grayu>ruySFby0iaxlXZpaS1xUuH5*~azL=~1JQ z!DDnChUX7kYu4oP?eu6bn|b2%lFPd~3HLtqndSN0bmaZGo6EiJyx5cVw&B>NQ@zd8 z_3Xg8*|$ZTp5+dB-++8?(iSJjP+~td>Es)=a@gR0@grad_4O)y`EP;s{p-e(VL%6-FU4-ek{H!-u<6v0g^1f5N{x@ z;Z?~GqGkIPK`D=*Hu2YADRxE9Vm$2R0D|oiz-pr>t+0Z!eJ2^(=aWh2QD5rq^w)Q3 z%zwa{6mYFGzVmJUsQ<0*!Oqpz$kgc@Y5FJQHkCGQ2Vh4Wy8?g2gWW_qoouA5Zd%nb9Z*eh`GEOu~`_bqoC&GDUxAlJgh!~w@9|1Om#TXKW zAlm50Toa8+lxh-U>^f~p?3`-<;F{!|V&BF}beu4W`ciwe?jJgZQi$rnXVftEyTWmz zfq*Xc8E6IqvygO1DH-r<7cOjS9)_-q&>sw{ckZdP+<=i5*IwEoU8bSW1-JS zhc#~BT{7CSIA2;Tj>I(%rhIZ9FOk9}4jvd4}G`Uo|Uh97!A>a>ZR{>Yq+sz1)x zI`vH_C!rM7SVc%wvR#`p&H_;{S+Ym${p=(LM6=D*TOo83B^e4%YyXYpUo2nkp-1vd z@zl(=ymxI5cb4SIxHJK(k}E%wtkuJqvd5y&SGpzjTaDD&gA0xzpjl|T%%Z%B{3@V=Fjm%WT_W?-W;sK%%7*QG`;Ig{)YbLY z6~6?tkp=z@o~l&;fM_ei>7-e4<;4k(ZGbDh4KBUOZA;EdVk*?$Bl(Lty|C@?XLsZ; zm8mJ#+TwXr#R`gc$TEGu4lRr$88$N0T6c(Lqi9Wgw#$d1h2^L!vtH^sugt)AAGNs*}%|bSADbi6fO&uWnW_IKPZoK&x30xJ_VQcwJgCUv%!1EpqW4 zgN#Z_cp8PxhnRwoG~7d+<%%R}`w9Q09P4EBNxxL`I_OYzs&Qz3nLDc}z>Fw*@BG%` z{(NtL`9e`4g)~}XklBl)vtZ=-D`L23$4*b?6(Ilg`;OvLr+Hszf#8EutD-H(Vz5C!aTPMXzXpKy1v7Ky_4 zm*vuT8d>xJUR(nlphw|XQP1_E85&&517zoNj=FCFMjfZwSC~c)A zDymYh#69eml^r`JCNWEor+L#+CuTX0$SQn?T@YyWucHr)uW|kpX-^#&!+ZSr(1_5d zlaQ(8Mns0YCY>IYx_y2MTAJvcS9+>J4nADnVJd_?WiLD)Q>xu9H{bN6LLO=(Cyv*{ ztG>@y{=7)z#iHutPZy2;A)GxK=n49lHwFnOj>5GX^CR2Gs*@UkvZDpAc(%-~_L2CY zgD_jmtNK}gwWq4DRYe=mtp{$d`bj{aG)26ohiK7VQlBHoI%?S-WF9Zqq;c9^f<7*H zndLiU9C4;)-ejqxNS?gqV|D)g-g7twv(-{y!Zge0)676GDj`)NB!e&)3THrHR$@xt ziwY*`-eO<1ZQCCxS6?5g$Z_uh^mQW~+XfO^n3|{C;=7VsfOcaS`Q=t-`2TMtOMfq5#(!7Mt{eovQnN%L%Um1 zPjE=5(PQS?YLDCtIjgK764WJyWDaJF6O-Py93fGTSn(Mo8zAe?IP3LvvL~A{SPY(x z2Z$gYd4e4_XCJkGv|Z0;%UR4+d7dsxHYjN4Byki8vdfR9esQw7i_!NqSfG32Ph}pH z`LbTh9v-NWwyy?9mxZWLU&&{Kb=2jNUZ{}6=mSbEaz|z7d1A8)JK{G)b;y~Kv`QWUA(1tzM@_k7=~%nU#ojP# zUFri^6BDL#W{U#n)2_xXsYL)(_ju8t1EKNN+X>BNwO!u0cT5pY9dFmI7QG-7LR&P*#KUNSG-tjyOsrj>$vBVqMe}GW;u#$VW zddtdP@{!BCGJlcNa8=&<=$sns)FORg2;Nu;#X-F0e&q0qk|TOFz|Vuf?5DBV?Kr|k z%*q9`lJse$hunfDTe?>Sf9_Xp2f#aHpX>^QG=3y3fJGL3DHQ9_QCM|Dm--M8Z*lC6 zai0Qy2nSZSe>c#bf}`#PPU(5Z6KF`Zdj%F|8oCHwjBpbvEfO0pEl8LB_Pa9FSzlGP z9T0*ldJY&=&pN8=Vw-jM-=v`$F@~O`xEtOES{AS;(E#m%Ba%L}RC_*e*!MiI-+#HR z6Hia%LGad2dTQc{>y9Kc>`h5v)Mu8+V1Of?ssg%PX=TfJBeR1$^egEKdZ5D%8}NDg zRVIysJ(Zp(nZdxH%&6~2ZrJ-SGwAcOHuDi6NA6>JVIMW0(CZ^7{F-Iam{iJ=mi#`7 zaw{mr5E(A}6y=uI6#0C~Iayg(=_L>aw>=Cn>Kc4Oe&NLPw$3zou}Kg2RZSv|DRBD$ znPhIYIvhzUy#)W%6cXYxl@z(lE#Ct@F+G7cUEnuSutptOZqEI_(jMi099@{#9_^}%#rP4Ec92^_#&h&(H94}^Vd`mM z2|eq%v7i)YKY1$`f8d*>@5(hOnD@n6k~i=I|Jq&7bjf3zN5Yo&{Y#X&BheZK=(s@z zozZ~P)sdLBEqafs#|%nlWyW2TQjM`xta%Ir`IBf3nP=;X=+MWOFt+TSAx;+EV23@v zy~*b4{DIErnqsrGX|AqcNXwQpG4(UEV5XtYvMt2&lS#4z943&~ z0ZAmy1WC9=rV>sr8ZH?~%T)+0Ab917f$%Efp^;dDFe(OolnO-P|GpF<07&kLb>D%fl(_2zT^vpqW;5kDG+^&a@!asoG;|9lP~l}6bM5l41%Wg?}z+* zz`r{o{_lcTcAK0ame1j1l+XD|QGzeM-0?hvs=Jj1!mvYHpCx63k zLRPv;+V{b(9JhiB z-Oz|{4ozQ1U?=_ifa6zPs!JyzJ%7nw^#5t+Ox&Sr-#BgwCDM>xo0l=!$G(oJWFN*p zhKwy_8CfF~nPd^OP zp67m^`#Z^PMlxDba>R$X!dEcQB!JWT<=Y;2_58Wvg|_N)?l?-%9qfzHw(V^2Z5gsA zUpr;d4-_&B+s}Ymk1L4YJ6@*xU{NX1kiL7`}5~U!^Kb z2{UXD)7$H3ShBE`roquJ;Q-$FZVUZ2Y%wJGa8DQ;vR%mx%sY|V#VA~Ud8sa0E$I?oQS zCjfP@OTEHbW8)_XLgwk{BRRbh!YcN6SOvu|)5fr+pjBycR>i#$cYbJIIxILB1z$`l zPE)>+6FZXUYdUYoOck5skF!zCpLyCGZdv3q;*E}!dVIT#b^kWL*=$%F zv7@N3HzH^7M9FU%zysLg;Oxq|DDSN*@265~W=bC8{}wl+Xxa>@U{Zj-HHJL~&Fq76 z=t7O9^)>Zu=ImgGV$AjD6w(rly!tpYEA$oKs+QioQj?J65SYZDu;K=*l21#4-FAg@bmsJU!UB3+Ee)HIH+)rO_ z)Bz7-6iVu7B(G?xwCXc9c86v+3njSZHmAy?+n|#&trK&So0#j?z8ihcgKx)h5MA2( z?#!i@F;LOH#pNoux=lCY8w`vUa!9R zxKq`xJMB!apJr`fXEAw!7nxCR^os{)I9eG>K59omw+jm`8!YD3(Ik-@0!>7rMxD1Xtc@sZWgyYQI zXGtrqI}d#G^)O-P&RbfCewyiDih%e2yykscrHqLMd(YWe=!&T>< zUQd50qs3ZrMhxTNb*m5u$W5Q?x=hbG8F|ejBi~a*F((WbWxoekC)d%+GDCyw!ah@Z zdI(|nB^biFf_V^`K2y~)9Qu-{CfYc0zPU%)!%EwJ*_Qt4=syI?0Vz$T9}69<4#)DrD)l- zr+2lljEQIt-Wnpm*N_fSMKmIVUM3HbW;X;aV*ULKpRBDJH5~rZ;og1)$oLXYm`+`D={r|P42s{PmDzG<&(V#3Fs3`W8N`qn zx*(vl-Z(jh`LYHAAoz|?yNX+QIb^_R{%Y2d;-<+;YB_el#k~w)D!)|my2TR2sR{z-9WfJmT@t^ff+f{KMRz0mir2u!B@r%y6hO7Q1Y?6$ zmXzHy6BGg`Q;n#(=|=(^^;lU?X>1^REZ&owchY`*NpeX;VuS_Rh%&c{x-{XGI3|C; ziMFE$Ye%A&Gf~XYm{%p!h)B~3(HrE#I;qkwx|kS9S$KW5sSCRNg+^t$SHKGuL&`jw z|82Zk4Bym%;U0*x=QElIT&1z`yCcK9{!qkJdRz%W=WPgLA6l$+^mWK!3D)IeydXSv zv4(~xxXZ!hY8MP6lB65fBU7n_WwMJk4H0~5nKdnFKIiiYK)1f>)ZiR8yQG{ycCP}E z2c}${eMAlCb-M6ZYdP@7{1fxwB}SOsz_TGLFli#BIABkS7h0i|Hs%4oNg=&ssPom_ ziZZeXCG5y5?b9Co>Z@AEin8CZ@AkI^4B)PaFKvO$1beGf%o+?HE{B>7V9$fB%TV9< ze_{JkRSvXTFN}*F)tjXCPX&P}-F4lL*;!MmSyQu->55EsrR()3@UGECx4z9wri*R8 zp>&onT2v|-#;ehAd2tAOY$T%0v89q}*REb$A@NE^(Wg~uUTd_7Ol+^WI&&688w_wr zz!_-F3mIy3;#f8n#;7vh!oblF1A!s$=Kbwc>@)E~f6RtO)00M96JorS5X}HW;V7Y6 zRQskg%2mkH`R0#6CV091S1n37b+@smHv)xEp_iz3=&(MTIYk1B0y|F)`A$s_44A5D z4GA-FyJn!HxlD>au)fZZN_etP)<6*HBkGwIK2|z)$|H&;jl${swk4Dn9i_7r+up{$EALg z$AtV0K%|M9gP|QfOkHmyoRSJ#R(yXu9>;Jr{23X=pfSf)Fr?r_XrbX*H#}=rnyeU# zaiRY12NUT#6(fR!+^6R@97tMKPq1cA?FpTyC7MMa18NzmKM_=@6oz!++At} zo@c6Fjy|%20`2PDe~M-O#$HlQ^L^&|4Rkf&l^s8Vg zACPS6S`l4v?KM?@nc1k9lPg(?sr{bJ*aE{C@G~=l&p?&Ju|Aji{V+Qf;0Rh*4H(;G zrtPMF?VDYr;n+l?P~Wey|Ai*uv=JVOupb_om4B_!=`7~< z7!)6MG<{|eOfHmlLEdB?Sb%b9lL-DM&rWtem|c3I-MhJnp?bzp9=uD!{e zo?tO2fJWR^Kb?Cq@wQ_ZP(mn#yME)I!Lx)-Md2mJybs;}SE8ey)NCS>aQP_Ux8c`$OK>Xq8C?&koPmA+!O&xjJ4bJrC~>vfUOZiGqJVG zEHA1g;USl2SA7HmF)!5KPh?ExJf@O>kQFzbnYz(A+c1j;-;;I3*HYwHpS!NutGGGc z_Ti4XP*9x!MJ*qalWga_`8-^RA7Ai{vntkWIep08_;%PX@T&S5cl&iSmBM^@PSbq2 zOg;}27Nf1ft^eS)xC zpA_Ot2-j{xxDs4#4_!*#UEQ1=|BKik!TRH=7;6fB{rzI9xl5KNa7xI3kt+5Z`{ktAxZj3i1r$1Y_d( zzG|JAn^shTT<%mXe;{Lj|Fl*4^9k1EXV*D6zS&xyc6eU5YU0zjc)m|ec~7`7H)$bZ z#EAsiNr!k>*wmG4w}*+?vz9*w)O>>9b2W#&_1I*a31uFYbMa~Ij@tGsNA^jFNb=FY zpT$$BbJ+`FXM1=bsIr-r6g`eFSC$UnRPcY>A} zCLZe^z(~!XFww}DSb=yncc4(G^;6-Ou^lo0YajZ6CLzJ-kdXY=qbA0G?dBZDdGrq9 pKRZ3d^sjfF!*svFA=>iadyuv|1>w*2y+?JD=jD*aHllE%eGMi!{ z5@e3ZIG!8*X#30*_&lUGN{(Ox`hZtk*M;6;gyqU4;Wn*^Z|~DlVRQ30W;2cd#uw#8 zEg>uI1E;ZPqcF7{B-y_Zk<9cP%=eTNKwXX0kM$|A=l8(Di-7QtpQ16!1|q&^vrF@L zmM=lHwX9Qh3o`evg*gXN7K(8v+vm&HI^ukD;eLehF3n6oh^Z;Uf$=~f5E3XHNo7mi zG{_9o3c3Qr0w^v$3rePKVt#O;(o+{k9cf`-D4~x$_P|~X+o1Q72ud^0baXH9O66S7 zVpI*NKP+J@;3KMJ5s^@c&qHb~E1DifZXdP1B$D~#%52M|QLH{Y^ZRyTcWj4aLurGdzW!kmfAQiyvllMCHFk5>AH>3vL6S3+Z4Y6Ud@>7@+E5vMYLDqbC$I zlHob3@G)E}6D@84BhYLwnKe*G!d}2B6z#kAQ=OhznVWT4zzfA~gAv>k3^Ib-UrBNl z5a=6J44we!G#+)?ZpB|MWqIwHX3<}``gCHiTUpw^d*(L35Qn>%!6z+AP@)h7qcD1A zI?SNmknShmd}ypw{*a~Qa7EY#qAZ}tVK=(6nQ>B>eNTAj3=Ra{Uu6w3-B7fC42@wd z?0*hU9I`Y;py~P+bLO;u>MwFN9Ww}nYCXnS$e0Vnb$S0iHtjUZDP7bY*2DyD-3VVX z7Fws$?{7OFae5C-`)6Dbi5kh{*P)qIJUI`{4hb(_TPN2ljma?8mtIcw_8yjnBtq4z zx2|z4IB~j?%8jfZS@&J)utYguwbs>sTo9~xBm_`g3i8BQ4ocNZ{5;g4vkxUOpUR6I zMcDy*|3ri{eXlk=m26I8kx#zy&XiOtsO1v1ps6;;P;Cx$7&;B!{wZ@kM1s;4;AQqQ zU%P$LW8-}2@q8M^jow0JSYRxDsWFDHDU(hOL*l`B$g9djY+M^N=T$l90HhQ>1sG+n zMl5Y!5{ViB_B%2!58+RGEc}?%?{&i&3w42njITGG_d&bnsYhu?vMHRSx_c8Jh;7ST zglx+>2dvy!Y2^1lbzQwM(IWgd&fzp2vVUUCE?zv=3Y-%IUPiltM+wu@(q*b`UCyDf z?#Ja?+VU!v>Lo6cBwP)5omry1QQ_YVg@u|-YIann|2A{VD@V$FwmD3q0)dvDOJm>{ zT-okbA94JEFE-d{-t%E?HJp^bDCj6F#-xL3y(9TWj$(|P>QC8{f;mZt|BZLSG1%_a z$eASDFL;tDDVnd|o7QnMOTdBv=B24wluTlVSwA(~p8guclX|JKgR3z}@Ceg+g>tJ% zY(V#!TIES9`)~MtyVyXqPJ~G$`xX!==0Udt>N&L+1by*!!2qq~*295X7_Z(`hazvP zX-v?H2?`tt7f+tSKk90-7Ce}5j{H%o9|tcijGhSBsGtYmrX*#PA|xXNl0=H z@qRI)VH1cW(6Ff+YfZb9gY_bSYbBP&#y&VB)a4Dx?_m#k8C9{YTqFf@4sK0KCzQVZ zz|TwjZtGLDGZNZ@b=MZu>t~4BK?oO5>4j7%5f2Z8rN+&a+Y9NvP%ev>y@c20qU;Ob zx6{I)R%Eg`8}#Na9sV1#I`j2fkgHwhAUi5ZmgM-OrFZkJrK5zpBX%%x{bmCXbgUs# zk2ACtkGWShQTFfJj`=W9-cu8KG_0pG>B-j$&e09_<@TE}BT;wuqPvDZTQr z7fG2>^kP{j43*k@!pZ%0M=zXmu6XaU{@IP-X{>cEijD4INJ*;vvl3bj0*^B#&%yfN zy0-K_cE;6C(vpQvi;?LW*Vlf-f3gUwYwRO}m0=8|OeFYOL8j6`_MNl$kl!nh7dL&` zNojh$_ZlnC?T1{2JO(lk>q?jMla2S0rYqUa~-hC?nL-&+&`z-5S1Pm|Qoqc_*SeLFa1l zAYHzIv_M_qgoeua>)r>^*VBtGZ@}06urq8i>z=tlvNZE6U$ZLwpsFdIUIU0 z40gX&HeI>^KY0DBw9Tqk$KfKw9S(rQEwI^D{aMar!}bwi3XA&rVulW&lFgren(*!cds>o+rT2PMSN+0CNX{TH-vd8M~+6;yLWRSMw~ zs{#SNFeBBq+8nG4A$E+9BH@Tyg$%{C^WHQ_A;T}UFIny z54!uKE{ARX&9IBqt=>=I!0N$ia^!0DZQ$uLbchi3;2ifQPC#(jrMp)`2jVRs*)M#Dsuv#`{P_1^B5*qy`mS2Z{!ClHJ_0UGs{!4 zC+;rdk7lRg=<}xa>l>D*0?Q&FG#YQ>d*yyDWjN07!=Jp~UhKNtRId62m8J=2FS4|j z987@?vFGnar2F<>Y_E{-a{U%uf>Kco*-&USZAA1Tn@oC2^|w}a@K8oHDFD|Db*9 zk0XnJ)=2sCC(hzdK7&J)K$6{EWb~0I=KH=SXM{q|Xm;`CtystZFDCHcpfO&SZIC6k zPY#-I>+*Y-MP_cr(zy_R-tpI$yZl+d0NcpErbl4t);>Tw8jAgyE$x4~q`1SjrblD@ z=EeJHfuv#OjygJ`%bzZbjro6OOWwSOT&dym{g>w)Ys1!@aa*z0b?|nE9d&HY2X2u9 zPWZKWXXeB?yb;a+L|=iBXL$+1a|_T@cq5ik%~_{x|3 zC`Nu;6RY!B+YUk1CZJzpS21JG|CN^(dhw7gwbl!M-r77dN3z;xCAz%Log}y zzmi|c==k|~nT2?4yABI`CCJ>}rRcXhY%GI%-YHu~r7aCR#fwzRtP9Ka3$s}?P((9Y z@Jcv6Ts`lKJaoi|1IEUDE{Ie#g#i%AXIwszSQntb}t;gV1Q|s;59x??J%T|X02+qL2=MRW2-A}zIYaqd zBB84p{$Hn~MOe)_*yf-oMxluQ4dPip#)^~q z_~3KYDLl05T2sio#cUA-EpMU!_2hTCPx-Av9=l3H$sH6_$uy+NIny5DBNED!MC;Cg z()YCuhg*(BbhkZ?7I-iqFlM`gwQnzqIdZHyf1<7Vimh3bEbKtl{(ew{scu@99;Xt2 zu;{^=bi65gBlc*(erJ9!6dG7v>R$m5;-2 zrI$Qs#G#TXO36X6yWcScuc za7Nn4CPBU?ct`bG20N%lQy4WB6%7??w&?;YC)(^tzC8{p9V&5!S$u>z?8J?>_-Gxd z2jc?NS1S1U(iThtyth4fK4EnsUU|!eTP6oZ$r{PRoeW5JR9zBSbI84VNd8o1H>rto z0}7C3;Sz`{0}%7v17|g$XR(9VYSC4PzMQx*t&M#{)A|@^l|P3LsAFZ~|LW0ZI{d(F zvZqJ`6gfZ>JYASmz{g99uFjPAnj<+<;bU@iQw9YzPkK9R`c4HxU~hgCLC_ddQq{Ap zLNpC8{sL-GiJcVw^E zNpBMv5}d&Pl()WNwM;{61_yfinz(9?6LTf9&f}3U%m;>%gO6g^=%_uv3T{kW8C#N}pCsoqx;C4? zIgrV0RT?(p7dNl}l~p*(0mHc1#g*%7W{J2m0vZ-h2F!;}3$5CJH!pZlnkCHYv$^Q< zvL~?zgzSFsgc&j3#EyAA;uqxAwn2&m`hztw#78BmDa^J-KcnK{g7rg;pN}_lxotiX z@EEM96Xjopm44|BnAgMnxmA6>A(6x~6S#K)cAZaw$wk?J@xz%vBX$}^_7@`)@H`jU z2P|{0&HV69$fdF-f)~Fy$26qFZ!37k;396T3%>7*oOptJ{TK21+3O^J>}iO9zH5H- z!a?xH_FC$9o*44bCB$!-*jVM?7cP4PcS^^ObmhnEE}38@Qi2_U__2mv^~@QKuHVe( zJMKR?k(E>|*aTHHILI58tB6^`2MPKkoB^~CwAaIEUGVz))*j(I?SqbVJL(P}bxb|= zY+P|4;C0;84J*w^=c@L`;Ddc?_OW-l7+vIace$Mn$Z{!s*%t0FN$o+tju%|G2gRqI zBlr3}uDp$NlNT|en~0NTIcFiBrZ}!ONE$vROu|NM^=G@CUqdi#xZl;7x`am+PyoZD z?p%MduHGxT6w6+9I_B9tzaL> zkDBS>Pi7a@ydYmBKCP2&A>PiQU(fFxRdTpwH5ygz80hX4UL1|fc>2n%SARVVnD4JC zY7|I+OlJG2B`YRRAa*v?w!iK9TjXv{v&IB6o7Su~GmYj?FZHd6Td|^=NLzVbZ=~Z{ zXIGlP!D_MIB;`1)x*D)*)@HpvI;sKOD^hAme%VOPozgQ&wp>+})F+iMdhm32K$!WO zs0|rOGc8C`>zux6#r&+V>#Alxav9~S97U7SyzeftXR5H4@K5^wc|_+YbM-sD%qcDR zvQMjAr1g$DykoJuVGxrANN(VCR((~Kz5DoDSUqzu`%k?QNG9O3W!l2#Za zF_LV^g|`Ze7==nDo6<2`hAWhJc^c;cM5?3Qq-~@wC-AL)TCgHNrN&oAr>*EGE~8#$ zdHC9lS#-ytEiO+wpLm^6dzUFHy z_Zhc0m@csEH+*;8%lCPggN>P%9vd@QQF-f|#59%(AOot0+wWhH?!2Oq6t#_Af69!JMMZ~p>UeeyFZ7;Y-+CCk%dKJiwf@5}a-fz$Sikkaoh|IJ zCj~;_Hu=?UUl1z@tSFx*^nY^ zGf4c#)#jmq*1YpZRmO~-N9*2}8kWKmW}P8^l)TFst=zGzS$Iz^d0!vPkG@*=Cib@$yCP zNr8q|n`RCrZM3yY86J^CbPo?mW=2Z=DS|p|$q|X!gfnav{0Ap1POq2Dt)++)pH&Lb zv7#bBnJpHm;e{G;%pph_ZF<|meR8eJU;KQWDI!fwm1AasYw^fc#gyuTvkydkin8~| zu%BLO$D4sAyZtwz_l|v(AOnZKIGrHe+E>bxx)tRn`Z(h|#fiU5?LKB9HI~dj!lBO@ zBAM3UTvj}K<|b2x22*A2sh##tkpVyIb)E$4t-*RWIcjAt-Bf)D+w#N7@$Y9uh5mY2 zv5-Y=T*C}|^2wk!*MUfn~m z&QMmUSNT?hRxu4eD}B;lf~=MNuYuZHBhFOEb-$IaTXo6p1`7oiofn2E;|LN9ry>b(J{C)~Ip`7*S~ zk2hxajWPYo51%qCiZcxzY}}bYy2>h7_Ga%7XU|Nb8^IS*7W2JCthgPSfVNKV-y_O; ztWo>JOq=R)q=j835&Q&P$?|#ztU^4(lwk)+rb_8@2j6STAF`XU(G`phW+3#X9B>=& z5b|a26jE8pKwchk{10I@^XU_B-odXiU&JAM&G1GyxD(RP=q3<#X<*aRhxEbX3=8Va zY7m2xKIde6?n7R4EUWX584{Ojg)vLtZO;v>JX`g`D!fp}c`5)Ee6TK@@r^}ADe)5~pe%gj-Tt1PuF}P&NzhPi)Qm%qwfnAD zahzh?2c>gNT+Uf0?wsha4)S+d0!5G9(~kQqg=7S>!fU+Ui(cj&i{8!f=DsnP0lPYnOYhC@GdC{+X>BZ5owIShS%R-EdC|kLqQOG<7}|0WDgySlRmf%a&p6@6hB@ z2wlJaYJIAwaAmt_A84j z;ji&sen^@!QxK#S_TD&hNt{1IKS+ydLEO~>d|gm~C138P=J<8Gp%tQ3<7NnY9Q{{X zm4CMg0#BrkcpL0p1b4;LQI(@o=eA^4r3;n z*N`l)=$1^^pFZfk@Q0l?jW+hvHem=Ri-CVqm7#Rx{x7!iEp_EOxhN5fJ__FP4JaZ5 z45inT_oSJXrvGQkKBP5kaIyqpo>w!kY13Yd&GoOK^HK6kc)mmeGB+;sD4;Z%6_2(U zX}|_INkUkDS+t`Cl_xrf^@H4c7p1r`)#gPCT&*OBBxLZt3^nYX=e+Sog+g9mcc^gI zcKsj<>AIu}x>U6Lc;m@DpIbA2n)N%fOAZCT#Sl#gqEs^Q)Gtp}o1<#h!|>e^qHEEw zmwKSu+f6Yu>JiXD?joK72zdGmdJ2*%00&l&rR+!TC%uca+7JTTSK3~mrwS3};=6>r z9%tqH9?*>Bt7fhh5~Zfj5yG^ND9fkT(96g?C2j6+QhuBa+>wXg&(Oo2q!AZS>kVTS zZ!zE9z67WL>`Yk)@AVvG9tAaduD4e_LmL*9`a?L26jfvy%K&Hd5*P66hT_^L8kFzIyFTsR`p+aB?o zv(zHoL?Kx36U{?406)lu##62T5%;V+dcFuIw|q46eil}mO?yHn77h;FQy6C+jzUB>M$7W@x+4%+m2^jOr9U=6bhcNjhQoDvfy-j`=9;FGhmi)!GtFJQn<2 zSP!s+KRC~QS))761e}Q<3l+c|J^PSSVHz)VHe&);4W}+-fE_MX%xjaWfW{>|xR;PN z5{(gmdPUC{e{a>q4;2Rt8V7r0rq|7AsJ#Lct1&(4?F{gkzkb}u zJk{=d#pqf6v4*)BF@AE#AecLm67A-f)qv@P`#x1}1{ewUb`zGVe$a8 zx_+Nos?RKX#ficGp;HA(XE*IrskBDb)p5O#G%g`|WRWC}D;1Y^_Iv z=rmFU7LNRRg44Mb`PuwUEDlp1xb=m{3AB#+L6c(pyoTjfR(d3a=)P)MUY0;(ZZzF| zD>))}74e)S8Dj{}CX&*s$@72S#sBjs9V7gWD0HI^!K8%)fi_T~CoIH3>blbs7v9fv z##8cwm6kdwDrT0dK)z`wk2?3ICS-)~gC17l+!SWIKQcYqJP#<$j&f~M{rsozdU?czkJvw%=Hz}vS*MP8Y&&WD;wTPh;$x$^~%Ym>nc^G38PC3^7!|D z?qzrISa-kSRz6C@m&^13;GYnBDPoKEz&e0PzMm?s&x19IE7~dwdE9Fz3o%A$2jZ4P(q1zy`Y zN(h2$h)b7z&n16sxWK`S$Ki4jl=N3JcUTs!AVGqzxaWqSMx4JAu00!13~S=1PxoMZ^--}?80kZ#;U-3y4C!mog}^qP1HO0 zy{202nh(;eFUK1wiNPS0CUncx)j(3myun(8eJ6wS2Oj~bF37W0`gFI&C1C^;bn)wu zm<68eh8l-)d@YXZ_bqZ?8I0qc3`#t5=G^SuVE_5~)A1IXUWc^tf+m`8^LO$v*=g17 zfF=JJ7%?g1n_aDU6*1O->}U`G!3GB|8)EWeWR7sH$Wkns#+z7oN8w;5(Xj_{9YQ%= zA9w^1(I6ENgB397WE%fNwpeD?J@(njp6-NfGgPEN)rDW}yDWCOW7Z!^andFZ^+nNm zPh_TZISv?fzL+gq<36`d$22aO>l4?=C$W~-vjCBQ|4=;Cr3w*w(cm>n|K>jMip+Ws z?rGDU+|I~$x6O`J2w_~J`0Z$KWh!l4X-4-pVt7_EaZ|;$X_EV~)xLKN5hB?~8c1)rQJ)z<`e@)|cb^6O&eHKFNS4k|!4c6= z3O1j#t=b!yo;}tEe}^fS=SC!faH`zdAHsy{rv=BCK;ey_pvW$eOL%h|yfvlyD1hWf zH^^9|r`-Nl%TH;k_eIQFGDANbP+CUQ()+(od)>J=jy%a%zHgJBP15=Qv(4oYqh190x|&6&slxwmsDW{@fF|Op3E5uk5~r1-YlKCig;yn*e0Su2 ze+Wu@ym8wHsi{LFknFqs4e%DYg(jF(aui80}0r@0*`bLN%>XT_CAC zS56e*Oe=mC#hSI2wLpet-Ub1GEk!95e2_@PkghOvo8XWO z4*OPm9MSZ;R2FFyO$-HJI?s_P_z$18u=?W!Lb-EnY48%qoqXFlFukUnC%-`(t!vC2 z*T%Te=tbNdpY4IeI{Fr(=Vr@)_NGYf%w&FyL2*T++RRGB=^;S?J8K>^h% zEvh?MFLnU$LiOd5V6n<75!~JeZf&nkHTu;S6K}=VpwWQU$?W#v2>~l%=&OHt)?nbh z8Y))WrbL4tj`|@Pd;7DobtlAnD;ASBh@#Ht`f7Tfs)bIg3mGWABK+&dp#f|pHC}Kn zFeo3>F#SkS0RVZZAOZonPH)UO7b|hedkh$wbS8qt0@pU+o3(U<*X`S5{*i34 zEKdNI#X+19G2=Bq&xaT`@DNqf*+}rf<&J0p_Q;m?Bg=Qq$71O_A7UB?LT7Bqv!{=X zg99(U(XOdl{*@<66(NdHVyf=$alCVrCUSQ2hdKNsrq=!8cSnTSG0tP$ik`@vgWNh0 z>XJ!H1`<3+tpI-TGU^pk$ed@1-r!eO^mw&L{*fHT+)1JjpRpHM!azF0bvt)mjwY(l zRe^ycn3y+UbUqAB8-ipz4GoP1t;W8^FDnHE6}|js#l_~x{-J9!oQ&1Fl7tKv9P3tf z%LX({?H`iOxvb7EJ8m`Ob2z^_-pq>t%gSQ#Zf&?!=I_^9wBp-&ftWny;WhLf=) zY2#+#XVmqmPG-$0p)qSSE;jr%x`8J+78~xMd_38Hr}Twzy!zRew(~f<{rN#i=v6)Q z%wmONhpS>Bt>e*VF>dy2Y7J*p=w`5TW-1w+i&pQ0sf!CL3M#^G)F&AuLa$%-q(6|S+U^vAleaDE&{Rewhpz2`z(BWLk@6E&;p)12AxGGU~Mbw(j z7w80TB1rhD5Td$+M;g2wD_R}jTFtX-nWQX%Z8#nuQ7nz@?UE@`cgH`29H5R zluk3yg#{gWLAA=c?ek}4N_3b%iRa$wRU9y33|LsBqlBG%-u@VEK<6-a)?ve5pVl@N z4z{y*eUxu#(t+_B@+$X|&C>OFccq*^nQCtxaBsYMMTPl;>#&Lf04p1saKNI?;)8vh zFY^#s$U@#7c3^3W0hFUNKJSxYFATp87MKjU=ALYpILv?qN|Kz&n@F^)`Pz!a*pxc>`Wrp>N{zJ zIfs<&Tg9z<+DdyjI9bE@w2p&52HmO;?ZJh=eNi^fpQ8JXv#}TW;=%szTcYgOOOF1}q7bU?dm+@+=`e*GBYg=qH`Y!YGQ5c%Umz8fyln^A=pb5FknLhR_n*q6819zr}p$@~{Co zdQSn#z4vBGrM?NZq;;#+8vgNM;5%{9LB7uQ;k>+}wSmP8S4c|jP>rf``K~ypQJut+ z7;80zgWUyD94*K(-f&eD_c=*uf+ncxOHfRy^&cG~tT{HYlcL0D6BW@Zu=?!XM!=s6 zL-qt?VQt*!xSyf|yN6qE`*<`L^-R2pRfA33+FAWg zTy`h4S9VjDhIrF2-Ey$3nCdhX?${y~4K8tLX3cb>&2*Vx(Ol}3KToO$p+(Y-OK0Yz z(D~-04C;v!7dOMh@37J0gZ-co|ME}{Uaeazm+I!ZLsR^csc+Vah8XHp=EwzKI3`id z)regL%9jO2S{5uV;4&H3>&{HC%BP05_41&7Es~%}_h?0e3zEN#7-s%`5w-1tn?A4;RajtNyT{B?(+uDI5Ps=Nz`(%PJltJ2suO7*TW ziy2TX^g2t!H#ia+XDgJlV$8%RySSS%dH06{Qyg2pyvuy%Xy_boFoXAH{{-(5G0Fxf zt6O_}oSv>N|EkL1F5CCLfjdp*T~FXi#Ztvp)!oTn)_b7#qtp(S+1Y6Q@ipu`*!#~7 zZ_S>aKP31e2u%zd+pwg-_NxEy(o(0jilKfPT8T~tUR3)r--LeE@3d6=W8VtGl{83;$)Td! z8YkX@sjGG`V2WuyfF0G&P>;GyU~i*kQ#V7iuE`YTVbYY*M=H0=u&zmIan+B*6ZuzC z>#vmEb~H^_I9Jk00eW2l=ie=+(6F?kkL%Ku?pKn6$*y?z43TAl^?jrx#wD3dS2F!h zM!lpXd;g`UN_>1fn%W81o&iO&wMv)Mwuqzd<6l$h{IlW;SCTkQkz7v8k$D~_S~mE# zjO&^NI%iNbbbfFR>id5*=ltWSRiWHpVWPjz{qOPqQA^`QV9yX&<3Sa%+Dj@Ih;7f1 ztUzj|VEZ56Ik0WiH&$KsZO6(tt^n6@PMUQ*#58k=yjBpL)4w5Mk(n!T0pvHkGG1~r ziz>@~5Z4t6o2Jv247T3BonE~CdNr4dWIq4?G^&C{&@pSZ(~kFXHxYSPRsl)TtkLli z)6dnAX^RHUffp~o*T3uyUG3Lh#ln6<&(qSuqcD%^rzd{(3pf^#x*j%S%RusgN2|M# zDviO#>zij2SDQ-MKBYewLZyrST|K)nTM%&h^Gf+m@}`_Y88|ScgiqJA^nTO6dAb>j zZBwM2s;%9TwP)t+(Gb_9|F~?sIh7Q!7w;+1Gpn|5$0-~IR4FZ|diM0=oRfHjF<8%3iu>>?Ix)@|1YZZ{RqXVAj*!z9d z>)rW&OKksn1pg##j!GXg(KnbXy?T3jx)1_C41hbHPYybs|I7%zAzq|Su4sCyhG$0$ z6sb@+dRnkvRxW?ZXw>vBk}NhI48H z4}Sl*Q@UZJAUs}^kh|&M28oD-Y|N(DNx115-p%xmp+Y2X5X$(8H%dd)Oovpm)E6<=^EeIiM|I{JbLd5y zRTf|DCac0}o<-^=_S)DZzkJk!+@#@j3bz9dmOekwxGkpWjJnAzrMxeKQ|@iF$F##3wiyflM_&n=VIP^fdu0>2-w-A< z2yH?AH0L?tRUO`Xj>#^ZifNg2+)K*ty0u*^FTroivP)PT#faq-`;;gK%Jcv@B;9aM z`I-wo3eI}i0H^P3(A8l(oFvXR@Jmi?e(xPepe#bDlBn&(12-ej=0VLUJb#du!R1Lae~u6|i2xEob$TUfE@ zpugsf5PiYMOlWQXOpF^FMNb&Nu%_&XvlgYy-7S}#!hZOd72Speo5LvTi8S0yg|j<{ z!FVD1ZrwpE|Gf6cuZ9B*to5u0#a*xtwbUKwTmM+bQrIwM%U7VAh}YGqQbdJ^dBGK41uqY@)(L_s}J9j>ILDEpkf6iK_G~ z33>64KptI{O}YhsJ%J5q!b6nU29=H<8W5sCir`h1fY;U<68;AG419MqDz&w6JoLMk zVP2xhmgXLjcq<+MyDNO>g+iFZZV7izi1jstTTDdrn&slny7g!b*psPyOWnm)cG-qN zapItm<@y^pnM5IrBR83N9&XB?+=UDMjLI@X%oaHBx5jPW+U5;Xi5?GL{(dwjskI^@ zE7aey7Tnq2y=vA+e^X=;gwXAqcxUj_J!$_sAjU0gWjdzm^T|(IHX+!Xrdl~8`Qcnz zK@`+WwMsoY;MO{J1Rnl;&6hjx-Gm;(i=uFJJfoPjHlgO*OUYzqi|?kWr>w8HSkd4v zXbw9=aqpnVM3^PF*~u+zR03Y2BMfP~KJ;-rqPJo9N#N$CB6JQi!KcE=9r6oRo$}LO zJpUn{UTn^-q+flv*M=X#yJux&uj?fR$t7;-V)2OkoxSN68MP8kRIUqPFpozc=BsbAF4@0b-6L%M#(5dHY`{1$Zo1`|tCQ;WBah`PN( zy+nrz0I=pjb4WqpvqIy>uI` zsXFw^@v}-7$L-n|14KEetViZkUHy2Rk6&`zi@*EDGWe~=IFAb)xStCgtP>hEt5uYp z(uWowFMA6%w9s~TSY zW=+&wnnF7Zl3gx0HP6^Se))NXE)mpR?~=!)wf}8xQNK*Czb~`@BV8L%>$pH$wM>96 zeS6LL=63Wu_(vHJI`19_a!0i!$*xb6J&|u4a&dC2mJ6NXLZcNOhhz&^y280zo>{Cfot?l?e&=XjJ6~0V5LNKqAyUiShmpinai{pWzeUy zQn#s3?_y4|wI#27_1L87bL>wIie%CItQC9k+~wse2x;Vg58HC47p9|M*Ou}?@-1$F z=J3lRDd)7bNp>;Ib}n;G>dPq?VUQgt^%09H$`jSL@0N!Ywm;HGX3f)UgQQt+Y& z1=rdpFF@Rmqu(`BCkLIRj?AfU^XLlEA|;8-V@Xkd)(gbhylhzs6+G%~jkfx(gJRy< zw6WRDFS)pSSi$^dyI?XfJKMKDoR)n-au0=e=AFICuCwA>Tg6a{PKv_3`Pc(xYtRN^ zXn1VhX;km*bI5w{7nDGo~7o%=!!LqIhSdn;Gw+Qm#0Q ze@OshSX^{ntSap@J2PBq{uO!+a7Z~dPq=C}=H+*RU4SRilPg@wS=Gi@5n_#mWRo^b zZuUjT-;eeK-tS|Q$F!N>aavbMdp}~FV;JoxdC3%etl}hUpQ#Uh-AfuPL+GK`EN&bLN2UUh`b(ygT36Y3%q&j18g#Zxlw@#<$B&o^#G6Ss4BIf>c@EM-J3${ri zD}m2xhiKYd1V-Tdty8bE)qVqjL=wEw5S5&$kI;VwOI|s*;KnkWSgKKJJMbl@Z>4xP z-gYW66A0qt1fckbZRzFmw03<*S`7)!?|M%PH?+Ef*@%7~gEqI#6iJ~^6L5S}>KP-|3(FS+gXb2lCy zGbWvR3anm!FCN|sZciID47(EzFX3d_hU|l%i_c;9U=LjsxA6BJHZZsRHCZ}yxUm%g zY7QWUl*)2g+xx%tj9V8CjuN1;F@$h*iAtC^bvZminOE*VP@|(=gTrxxVQ~nCHDNiW z3=|-foq67Qnjb+5go}nm^QlOl{VIkjg|e{5@T|J3EE$1Dt=h+;>WS>LyeU8 zsx|2dW%4C?LE^cBhze+Tfm`!s17#-{AeT^0ItWd(vhlw&e&k|7;Zi^|3wQxmsAg%_xPzJ%b{0r&UCnE968H(Rjt*^ zfzTf*kg5_>&ad0-7K_6a3@aGXE$`Pm(H-!&Yx{*j+?mbEV1Mo>zaf}$CNGtMFl6%3 zv7fjRGU?JT{6&+SHfYI+jACOh3IRAg{TNT(vi1+Os>a`&v?Qx5CDcR_?6eB=eDHd6 zEz>)ME7^u;%&1ZGV?H`5#d&{;;}eZ~U)9PmHQp-iyjP9&iH@M!f#O*ED}+W^v)xqe zV!UZH6J-Xg1sqUIu*<#tW7SQzK~-qzk%Aa62!;)XD_bd_o$fR9T@dwSouJ2L^F3F_ zp8Iv)+xi~{{yxl;b`f*UoSLRshe1P@R;V9qX3Do_YSYLj8=i5s6cBueWb9jAs{SML6>U zihXwC6Y#|=PB9EGjFsU!Cp3mCPPLANl!bcP9qfOqSS=-UvUBnl(~mn?DJ~YI)H#XV z5Ua~175QLOnvyzOLha4)z*TlMw=gO?8&DH7wG(vUE*L%IKP%cjyI3Tif~ahclY_W# z3k>1L;cFZJ`Ds_UZ<6w0NXYti`Ge2W@>_0V8Ya#uF2NOBlV4isgCXv}EC^Od661iI zqR|JY2s8OGSGdmW%U=%u9NJ|hMM3DjI(Kr8Iul*ayOw?q>x^AbELh;Ou!n~PE48|S z!#lcjL5rn>jtp|J%QJ@&>|T^rQ@HFV%#Ja*0x-a@@=<$^7Nq?|BRiF<*)4Kv+oR~Mi)Y8h(-M<#gzQd&f4radO8FZSYOC}^1pRfKh5~uw=UmF8v>8X*n z+o5;SG$9XFjTqmg3|omYn289;)f9xXY@z~m1;u3fXS+O~wv2aySSk=x^DD~)pTWN$ z#57AG7Qr5BSk<0Ch(OJZUAjbTW7(4w=txL;TtihF&EFE`s%(y_<)8Hjjdin?>AL+&VId#=kqB2*xg9##UH~)?;&=5Z?jdtIH4|y{W(0h1N7&^(w*J`>iYL&${jk%vL3v zY-V1Xmn4T~CvwQ#CwM_8{~`?cphn#+`bvrT<&*cxp zDg{Z^18Wbn8Dj|(+ znt`W?t*06G%rNJap@QX+ey%se)Q=RApWzK3I^-iQ$p^HQHt}&-u*uqCKTV<;WMmRO z=VosDH%Hz0Qdv%P5s8a-@6mRH(wJyL!NDmi-b-u&ic8&Ye$u`*-_EF-02}gjghXmg zQ0%Nn^J4oX&5bDV{#okL?t{5!yZF1MC536`si>z!DrW1obUTosl!IX8Cill&3XL?LJj)rT z3B^xc3Q>5=UBftV`E9*Xdxt5YfOX^}4*1h9!a^O2BH0Cw4dDum^Tlu$Uz>3y&!8#& zBqba;KW1-qR^?o~(c~*Y2f>a`#Rqy7-nP9RC}qwDNJqhKDTz~?BM2hVG9`Tcl`!&? z6mew>Xnrh0y%4l{il5f&i6zgYR28mm|hT@eBw;6d(CHpADD464xojMtC@~O zOsuy%5W7$c&Jgd>#UsCayVgpfgB^v}_I^?y@&_5p!8MNOGJO4Ur!u*gP5ry&iIh3D zhdF@qQZ0@iQk6A?Q``LWgy0p0lxI7)-kss8FfVY+kQuj}S3gV`%21HWizl_LI97^U z=SrjB{%=M8FV>jyRBP)42LPaA0021u4{J2Hw{uZ5GPW`M7ueYLb1+P83);-*5 zqaP(8zo-^=S-wRR%*FkFf?Pzcy1k{Yb#)hVvTFl3T|C z+ZEwkDFohdA3u5k5fCqkOAqg4efvN)L*Y0GV$ZrAz0cbm;zOpoy!QxIP z&KCIy0QX=~W^IrsAUjsaU_sC=&VKw=~m~I$(;TTWQLX(8h zT8$<*Lc085_0S$fl_?X<<{i4>z}!SM%tDVojM$1MPm5@BGeNo|d1_xW*g#*7IYEF_!!Z+JkfdO{2&EjSc zHs?4L7w?n(1CJZ^#gdiPJyvMcgrj|#9N$jvCe~uYF0#9rtR{&7B&Y~KqrE14GDy-q z`^-OW-Gqr)FEV*le;EMk8*$mtNP1w5DKVn`axv9Qgw2&vnyXE0td+~~_dd;W+H<%| z`v&g-OXgRT7x-?L=wb(cXHtolo0dl%W-IIi!m;`YyDyhXDo_~o%DO_}&62A}52Cpb@z|K)m%hs$Uk@-<$CY6iy z_bKyV{0ohV3mz8lGgN|A2-cqo8p_HFlMiiTRsW~C35vtUi}3H(8WlD*7(HkKn=lLl z^ni^OW*ADs&JBCb3=Lo=|D-Gj1B(av-*%k8kN-b-+P@18f8Rd<20-z5_JwA$Q8t#69Y}*;D%|0PI1s7 J7P9_}{Xg_~J`Ml? diff --git a/xinnengyuan/ruoyi-admin/src/test/java/org/dromara/test/DemoTest.java b/xinnengyuan/ruoyi-admin/src/test/java/org/dromara/test/DemoTest.java index fae75919..67feee62 100644 --- a/xinnengyuan/ruoyi-admin/src/test/java/org/dromara/test/DemoTest.java +++ b/xinnengyuan/ruoyi-admin/src/test/java/org/dromara/test/DemoTest.java @@ -4,7 +4,10 @@ import cn.hutool.core.io.FileUtil; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.dromara.design.service.IDesTechnicalStandardService; +import org.dromara.facility.domain.FacMatrix; +import org.dromara.facility.service.IFacMatrixService; import org.dromara.facility.service.IFacPhotovoltaicPanelPartsService; +import org.dromara.progress.service.IPgsProgressCategoryService; import org.dromara.project.service.IBusProjectService; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; @@ -23,6 +26,12 @@ public class DemoTest { @Resource private IFacPhotovoltaicPanelPartsService photovoltaicPanelPartsService; + @Resource + private IPgsProgressCategoryService progressCategoryService; + + @Resource + private IFacMatrixService matrixService; + @Resource private IBusProjectService projectService; @@ -62,4 +71,12 @@ public class DemoTest { String suffix = FileUtil.getSuffix(originalFilename); System.out.println(suffix); } + + @Test + void testTemple() { + List matrixList = matrixService.lambdaQuery() + .eq(FacMatrix::getProjectId, 1906557369562726402L) + .list(); + Boolean result = progressCategoryService.insertByTemplate(1906557369562726402L, matrixList, null); + } } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/pom.xml b/xinnengyuan/ruoyi-modules/ruoyi-system/pom.xml index 032c128b..d2e4c00b 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/pom.xml +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/pom.xml @@ -62,6 +62,12 @@ 2.0.29 + + com.deepoove + poi-tl + 1.12.2 + + org.dromara diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/common/utils/JSTUtil.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/common/utils/JSTUtil.java index ce4f53c8..2e78c5b9 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/common/utils/JSTUtil.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/common/utils/JSTUtil.java @@ -246,6 +246,9 @@ public class JSTUtil { FacFeatureByPlane nearestPolygon = null; double minDistance = Double.MAX_VALUE; for (FacFeatureByPlane polygonFeature : polygons) { + if (polygonFeature == null || polygonFeature.getGeometry() == null) { + continue; // 跳过空对象 + } List> polyCoords = polygonFeature.getGeometry().getCoordinates().getFirst(); Coordinate[] polygonCoords = polyCoords.stream() .map(c -> new Coordinate(c.getFirst(), c.get(1))) diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/common/utils/documentOperations/WordToPdfToImg.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/common/utils/documentOperations/WordToPdfToImg.java index ba262a3a..a0891668 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/common/utils/documentOperations/WordToPdfToImg.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/common/utils/documentOperations/WordToPdfToImg.java @@ -1,17 +1,13 @@ package org.dromara.common.utils.documentOperations; -import io.swagger.v3.oas.annotations.security.OAuthFlow; import jakarta.annotation.Resource; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.rendering.PDFRenderer; import org.docx4j.Docx4J; import org.docx4j.openpackaging.exceptions.Docx4JException; import org.docx4j.openpackaging.packages.WordprocessingMLPackage; - -import org.apache.pdfbox.pdmodel.PDDocument; -import org.apache.pdfbox.rendering.PDFRenderer; -import org.dromara.common.oss.core.OssClient; import org.dromara.system.domain.vo.SysOssUploadVo; import org.dromara.system.service.ISysOssService; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mock.web.MockMultipartFile; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; @@ -19,19 +15,24 @@ import org.springframework.web.multipart.MultipartFile; import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; -import java.io.*; -import java.util.*; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; import java.util.List; import static org.dromara.common.constant.MinioPathConstant.ContactNotice; @Component public class WordToPdfToImg { - @Autowired + + @Resource private ISysOssService ossService; /** * wordToImg 根据file生成缩略图(路径) + * * @param file 文件 */ public String wordToImg(MultipartFile file) throws Docx4JException, IOException { @@ -75,6 +76,7 @@ public class WordToPdfToImg { /** * convertWordToImage 根据MultipartFile转成缩略图 并上传至minio + * * @param wordFile 文件 */ public SysOssUploadVo convertWordToImage(MultipartFile wordFile) throws Exception { @@ -119,7 +121,7 @@ public class WordToPdfToImg { "image/png", // ContentType new ByteArrayInputStream(imageOut.toByteArray()) // 文件内容 ); - return ossService.uploadWithNoSave(image,ossService.minioFileName(ContactNotice,image)); + return ossService.uploadWithNoSave(image, ossService.minioFileName(ContactNotice, image)); } // public static void main(String[] args) throws Exception { diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/cory/service/impl/BusContactnoticeServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/cory/service/impl/BusContactnoticeServiceImpl.java index bbc1ce71..0919dcb9 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/cory/service/impl/BusContactnoticeServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/cory/service/impl/BusContactnoticeServiceImpl.java @@ -1,23 +1,23 @@ package org.dromara.cory.service.impl; -import org.dromara.common.core.utils.MapstructUtils; -import org.dromara.common.core.utils.StringUtils; -import org.dromara.common.mybatis.core.page.TableDataInfo; -import org.dromara.common.mybatis.core.page.PageQuery; -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; +import org.dromara.common.core.utils.MapstructUtils; +import org.dromara.common.core.utils.ObjectUtils; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.cory.domain.BusContactnotice; import org.dromara.cory.domain.bo.BusContactnoticeBo; import org.dromara.cory.domain.vo.BusContactnoticeVo; -import org.dromara.cory.domain.BusContactnotice; import org.dromara.cory.mapper.BusContactnoticeMapper; import org.dromara.cory.service.IBusContactnoticeService; +import org.springframework.stereotype.Service; +import java.util.Collection; import java.util.List; import java.util.Map; -import java.util.Collection; /** * 联系单Service业务层处理 @@ -38,7 +38,7 @@ public class BusContactnoticeServiceImpl implements IBusContactnoticeService { * @return 联系单 */ @Override - public BusContactnoticeVo queryById(Long id){ + public BusContactnoticeVo queryById(Long id) { return baseMapper.selectVoById(id); } @@ -73,6 +73,7 @@ public class BusContactnoticeServiceImpl implements IBusContactnoticeService { LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); lqw.orderByAsc(BusContactnotice::getId); lqw.eq(bo.getProjectId() != null, BusContactnotice::getProjectId, bo.getProjectId()); + lqw.eq(ObjectUtils.isNotEmpty(bo.getType()), BusContactnotice::getType, bo.getType()); lqw.in(bo.getTypes() != null, BusContactnotice::getType, bo.getTypes()); return lqw; } @@ -87,7 +88,7 @@ public class BusContactnoticeServiceImpl implements IBusContactnoticeService { public Boolean insertByBo(BusContactnoticeBo bo) { BusContactnotice add = MapstructUtils.convert(bo, BusContactnotice.class); validEntityBeforeSave(add); - return baseMapper.insert(add) > 0; + return baseMapper.insert(add) > 0; } /** @@ -106,7 +107,7 @@ public class BusContactnoticeServiceImpl implements IBusContactnoticeService { /** * 保存前的数据校验 */ - private void validEntityBeforeSave(BusContactnotice entity){ + private void validEntityBeforeSave(BusContactnotice entity) { //TODO 做一些数据校验,如唯一约束 } @@ -119,7 +120,7 @@ public class BusContactnoticeServiceImpl implements IBusContactnoticeService { */ @Override public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { - if(isValid){ + if (isValid) { //TODO 做一些业务上的校验,判断是否需要校验 } return baseMapper.deleteByIds(ids) > 0; diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/design/constant/DesDrawingConstant.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/design/constant/DesDrawingConstant.java deleted file mode 100644 index 1c7134e2..00000000 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/design/constant/DesDrawingConstant.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.dromara.design.constant; - -/** - * @author lcj - * @date 2025/7/2 19:59 - */ -public interface DesDrawingConstant { - - /** - * 对象存储前缀 - */ - String OSS_PREFIX = "doc/design/drawing/"; - - /** - * 获取项目对象存储前缀 - * - * @param projectId 项目id - * @return 项目对象存储前缀 - */ - static String getProjectOssPrefix(Long projectId) { - return String.format("%s%s/", OSS_PREFIX, projectId); - } -} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/design/constant/DesSpecialSchemeConstant.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/design/constant/DesSpecialSchemeConstant.java deleted file mode 100644 index 64d8ecf2..00000000 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/design/constant/DesSpecialSchemeConstant.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.dromara.design.constant; - -/** - * @author lcj - * @date 2025/7/3 11:35 - */ -public interface DesSpecialSchemeConstant { - - /** - * 对象存储前缀 - */ - String OSS_PREFIX = "doc/design/special/scheme/"; - - /** - * 获取项目对象存储前缀 - * - * @param projectId 项目id - * @return 项目对象存储前缀 - */ - static String getProjectOssPrefix(Long projectId) { - return String.format("%s%s/", OSS_PREFIX, projectId); - } - -} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/design/controller/DesDesignChangeController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/design/controller/DesDesignChangeController.java index 8816b300..f667e3c4 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/design/controller/DesDesignChangeController.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/design/controller/DesDesignChangeController.java @@ -48,7 +48,7 @@ public class DesDesignChangeController extends BaseController { } /** - * 根据主键设计变更单 + * 根据主键导出设计变更单 */ @SaCheckPermission("design:designChange:export") @Log(title = "设计变更管理", businessType = BusinessType.EXPORT) diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/design/service/impl/DesDesignChangeServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/design/service/impl/DesDesignChangeServiceImpl.java index 66a7c77c..2c4bdd1c 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/design/service/impl/DesDesignChangeServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/design/service/impl/DesDesignChangeServiceImpl.java @@ -364,8 +364,19 @@ public class DesDesignChangeServiceImpl extends ServiceImpl designChangeVoList = designChangeList.stream().map(this::getVo).toList(); + Set ossIdList = designChangeList.stream().map(DesDesignChange::getFileId).map(Long::parseLong).collect(Collectors.toSet()); + List ossVoList = ossService.listByIds(ossIdList); + Map ossVoMap = ossVoList.stream().collect(Collectors.toMap(SysOssVo::getOssId, Function.identity(), (a, b) -> a)); + List designChangeVoList = designChangeList.stream().map(designChange -> { + DesDesignChangeVo designChangeVo = new DesDesignChangeVo(); + BeanUtils.copyProperties(designChange, designChangeVo); + String fileId = designChange.getFileId(); + if (StringUtils.isNotBlank(fileId)) { + SysOssVo file = ossVoMap.get(Long.valueOf(fileId)); + designChangeVo.setFile(file); + } + return designChangeVo; + }).toList(); designChangeVoPage.setRecords(designChangeVoList); return designChangeVoPage; } @@ -394,7 +405,7 @@ public class DesDesignChangeServiceImpl extends ServiceImpl> future = executorService.submit(() -> { + FacProperties nameProperties = nameFeature.getProperties(); + String name = nameProperties.getText(); + // ① 获取名称 + if (StringUtils.isBlank(name)) return Collections.emptyList(); + if (!name.startsWith("G")) return Collections.emptyList(); List panelList = new ArrayList<>(); - // ① 找到该点对应的 polygon(优先包含,否则最近) + // ② 找到该点对应的 polygon(优先包含,否则最近) FacFeatureByPlane matchedPolygon = JSTUtil.findNearestOrContainingPolygon(nameFeature, locationFeatures); if (matchedPolygon == null) return Collections.emptyList(); - // ② 获取 geometry 坐标 + // ③ 获取 geometry 坐标 List> coordinates = matchedPolygon.getGeometry().getCoordinates().getFirst(); - // ③ 判断所属方阵 + // ④ 判断所属方阵 FacMatrix matrix = matrixService.getMatrixIdBy2Coordinates(matrixList, coordinates); if (matrix == null) return Collections.emptyList(); Long matrixId = matrix.getId(); - // ④ 获取进度类别 + // ⑤ 获取进度类别 List progressCategoryListByMatrix = progressCategoryMap.get(matrixId); if (CollUtil.isEmpty(progressCategoryListByMatrix)) return Collections.emptyList(); - // ⑤ 获取名称 - String name = nameFeature.getProperties() != null ? nameFeature.getProperties().getText() : null; - if (StringUtils.isBlank(name)) return Collections.emptyList(); + // ⑥ 构建面板数据 for (PgsProgressCategory progressCategory : progressCategoryListByMatrix) { FacPhotovoltaicPanel panel = new FacPhotovoltaicPanel(); diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/constants/MatMaterialsConstant.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/constants/MatMaterialsConstant.java new file mode 100644 index 00000000..d9bf74ad --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/constants/MatMaterialsConstant.java @@ -0,0 +1,67 @@ +package org.dromara.materials.constants; + +import org.dromara.common.core.utils.DateUtils; +import org.dromara.materials.domain.MatMaterialIssue; +import org.dromara.materials.domain.MatMaterialReceive; + +import java.text.SimpleDateFormat; + +/** + * @author lcj + * @date 2025/7/4 18:26 + */ +public interface MatMaterialsConstant { + + /** + * 物料领料单文件路径 + */ + String MATERIALS_ISSUE_FILE_URL = "docs/materials/issue/"; + + /** + * 物料接收单文件路径 + */ + String MATERIALS_RECEIVE_FILE_URL = "docs/materials/receive/"; + + /** + * 物料领料单模版路径 + */ + String MATERIALS_ISSUE_TEMPLATE_PATH = "template/物料领料单模版.docx"; + + /** + * 物料接收单模版路径 + */ + String MATERIALS_RECEIVE_TEMPLATE_PATH = "template/物料接收单模版.docx"; + + /** + * 获取物料领料单文件名 + */ + static String getMatMaterialIssueFileUrl(MatMaterialIssue materialIssue) { + String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(materialIssue.getUpdateTime()); + return String.format("%s%s/%s", MATERIALS_ISSUE_FILE_URL, materialIssue.getId(), timestamp); + } + + /** + * 获取物料领料单文件名 + */ + static String getMatMaterialIssueFileName(MatMaterialIssue materialIssue) { + String createDate = DateUtils.formatDate(materialIssue.getCreateTime()); + return String.format("物料领料单(%s).docx", createDate); + } + + /** + * 获取物料接收单文件名 + */ + static String getMatMaterialReceiveFileUrl(MatMaterialReceive materialReceive) { + String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(materialReceive.getUpdateTime()); + return String.format("%s%s/%s", MATERIALS_ISSUE_FILE_URL, materialReceive.getId(), timestamp); + } + + /** + * 获取物料接收单文件名 + */ + static String getMatMaterialReceiveFileName(MatMaterialReceive materialReceive) { + String createDate = DateUtils.formatDate(materialReceive.getCreateTime()); + return String.format("物料接收单(%s).docx", createDate); + } + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/controller/MatMaterialIssueController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/controller/MatMaterialIssueController.java new file mode 100644 index 00000000..776ee2a1 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/controller/MatMaterialIssueController.java @@ -0,0 +1,105 @@ +package org.dromara.materials.controller; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import org.dromara.common.core.domain.R; +import org.dromara.common.idempotent.annotation.RepeatSubmit; +import org.dromara.common.log.annotation.Log; +import org.dromara.common.log.enums.BusinessType; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.web.core.BaseController; +import org.dromara.materials.domain.dto.materialissue.MatMaterialIssueCreateReq; +import org.dromara.materials.domain.dto.materialissue.MatMaterialIssueQueryReq; +import org.dromara.materials.domain.dto.materialissue.MatMaterialIssueUpdateReq; +import org.dromara.materials.domain.vo.materialissue.MatMaterialIssueVo; +import org.dromara.materials.service.IMatMaterialIssueService; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 物料领料单 + * + * @author lcj + * @date 2025-07-04 + */ +@Validated +@RestController +@RequestMapping("/materials/materialIssue") +public class MatMaterialIssueController extends BaseController { + + @Resource + private IMatMaterialIssueService matMaterialIssueService; + + /** + * 查询物料领料单列表 + */ + @SaCheckPermission("materials:materialIssue:list") + @GetMapping("/list") + public TableDataInfo list(MatMaterialIssueQueryReq req, PageQuery pageQuery) { + return matMaterialIssueService.queryPageList(req, pageQuery); + } + + /** + * 根据主键导出物料领料单详细信息 + */ + @SaCheckPermission("materials:materialIssue:export") + @Log(title = "物料领料单", businessType = BusinessType.EXPORT) + @PostMapping("/export/word") + public void exportWordById(@NotNull(message = "主键不能为空") Long id, + HttpServletResponse response) { + matMaterialIssueService.exportWordById(id, response); + } + + /** + * 获取物料领料单详细信息 + * + * @param id 主键 + */ + @SaCheckPermission("materials:materialIssue:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(matMaterialIssueService.queryById(id)); + } + + /** + * 新增物料领料单 + */ + @SaCheckPermission("materials:materialIssue:add") + @Log(title = "物料领料单", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated @RequestBody MatMaterialIssueCreateReq req) { + return toAjax(matMaterialIssueService.insertByBo(req)); + } + + /** + * 修改物料领料单 + */ + @SaCheckPermission("materials:materialIssue:edit") + @Log(title = "物料领料单", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated @RequestBody MatMaterialIssueUpdateReq req) { + return toAjax(matMaterialIssueService.updateByBo(req)); + } + + /** + * 删除物料领料单 + * + * @param ids 主键串 + */ + @SaCheckPermission("materials:materialIssue:remove") + @Log(title = "物料领料单", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] ids) { + return toAjax(matMaterialIssueService.deleteByIds(List.of(ids))); + } +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/controller/MatMaterialReceiveController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/controller/MatMaterialReceiveController.java new file mode 100644 index 00000000..d08efa88 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/controller/MatMaterialReceiveController.java @@ -0,0 +1,105 @@ +package org.dromara.materials.controller; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import org.dromara.common.core.domain.R; +import org.dromara.common.idempotent.annotation.RepeatSubmit; +import org.dromara.common.log.annotation.Log; +import org.dromara.common.log.enums.BusinessType; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.web.core.BaseController; +import org.dromara.materials.domain.dto.materialreceive.MatMaterialReceiveCreateReq; +import org.dromara.materials.domain.dto.materialreceive.MatMaterialReceiveQueryReq; +import org.dromara.materials.domain.dto.materialreceive.MatMaterialReceiveUpdateReq; +import org.dromara.materials.domain.vo.materialreceive.MatMaterialReceiveVo; +import org.dromara.materials.service.IMatMaterialReceiveService; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 物料接收单 + * + * @author lcj + * @date 2025-07-04 + */ +@Validated +@RestController +@RequestMapping("/materials/materialReceive") +public class MatMaterialReceiveController extends BaseController { + + @Resource + private IMatMaterialReceiveService matMaterialReceiveService; + + /** + * 查询物料接收单列表 + */ + @SaCheckPermission("materials:materialReceive:list") + @GetMapping("/list") + public TableDataInfo list(MatMaterialReceiveQueryReq req, PageQuery pageQuery) { + return matMaterialReceiveService.queryPageList(req, pageQuery); + } + + /** + * 根据主键导出物料接收单详细信息 + */ + @SaCheckPermission("materials:materialReceive:export") + @Log(title = "物料接收单", businessType = BusinessType.EXPORT) + @PostMapping("/export/word") + public void exportWordById(@NotNull(message = "主键不能为空") Long id, + HttpServletResponse response) { + matMaterialReceiveService.exportWordById(id, response); + } + + /** + * 获取物料接收单详细信息 + * + * @param id 主键 + */ + @SaCheckPermission("materials:materialReceive:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(matMaterialReceiveService.queryById(id)); + } + + /** + * 新增物料接收单 + */ + @SaCheckPermission("materials:materialReceive:add") + @Log(title = "物料接收单", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated @RequestBody MatMaterialReceiveCreateReq req) { + return toAjax(matMaterialReceiveService.insertByBo(req)); + } + + /** + * 修改物料接收单 + */ + @SaCheckPermission("materials:materialReceive:edit") + @Log(title = "物料接收单", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated @RequestBody MatMaterialReceiveUpdateReq req) { + return toAjax(matMaterialReceiveService.updateByBo(req)); + } + + /** + * 删除物料接收单 + * + * @param ids 主键串 + */ + @SaCheckPermission("materials:materialReceive:remove") + @Log(title = "物料接收单", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] ids) { + return toAjax(matMaterialReceiveService.deleteByIds(List.of(ids))); + } +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/MatMaterialIssue.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/MatMaterialIssue.java new file mode 100644 index 00000000..698ce888 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/MatMaterialIssue.java @@ -0,0 +1,126 @@ +package org.dromara.materials.domain; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.dromara.common.mybatis.core.domain.BaseEntity; + +import java.io.Serial; + +/** + * 物料领料单对象 mat_material_issue + * + * @author lcj + * @date 2025-07-04 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("mat_material_issue") +public class MatMaterialIssue extends BaseEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @TableId(value = "id") + private Long id; + + /** + * 项目id + */ + private Long projectId; + + /** + * 材料来源(1甲供 2乙供) + */ + private String materialSource; + + /** + * 表单编号 + */ + private String formCode; + + /** + * 工程名称 + */ + private String projectName; + + /** + * 设备材料名称 + */ + private String materialName; + + /** + * 订货单位 + */ + private String orderingUnit; + + /** + * 供货单位 + */ + private String supplierUnit; + + /** + * 领料单位 + */ + private String issueUnit; + + /** + * 保管单位 + */ + private String storageUnit; + + /** + * 缺陷情况(承包单位填写) + */ + private String defectDescription; + + /** + * 合格证份数 + */ + private Integer certCount; + + /** + * 合格证文件 + */ + private String certCountFileId; + + /** + * 出厂报告份数 + */ + private Integer reportCount; + + /** + * 出厂报告文件 + */ + private String reportCountFileId; + + /** + * 技术资料份数 + */ + private Integer techDocCount; + + /** + * 技术资料文件 + */ + private String techDocCountFileId; + + /** + * 厂家资质文件份数 + */ + private Integer licenseCount; + + /** + * 厂家资质文件 + */ + private String licenseCountFileId; + + /** + * 备注 + */ + private String remark; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/MatMaterialIssueItem.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/MatMaterialIssueItem.java new file mode 100644 index 00000000..b7c7ae78 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/MatMaterialIssueItem.java @@ -0,0 +1,77 @@ +package org.dromara.materials.domain; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.dromara.common.mybatis.core.domain.BaseEntity; + +import java.io.Serial; +import java.math.BigDecimal; + +/** + * 物料领料单明细项对象 mat_material_issue_item + * + * @author lcj + * @date 2025-07-04 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("mat_material_issue_item") +public class MatMaterialIssueItem extends BaseEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @TableId(value = "id") + private Long id; + + /** + * 项目id + */ + private Long projectId; + + /** + * 领料单id + */ + private Long issueId; + + /** + * 名称 + */ + private String name; + + /** + * 规格 + */ + private String specification; + + /** + * 单位 + */ + private String unit; + + /** + * 库存 + */ + private BigDecimal stockQuantity; + + /** + * 领取 + */ + private BigDecimal issuedQuantity; + + /** + * 剩余 + */ + private BigDecimal remainingQuantity; + + /** + * 备注 + */ + private String remark; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/MatMaterialReceive.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/MatMaterialReceive.java new file mode 100644 index 00000000..048b5f36 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/MatMaterialReceive.java @@ -0,0 +1,126 @@ +package org.dromara.materials.domain; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.dromara.common.mybatis.core.domain.BaseEntity; + +import java.io.Serial; + +/** + * 物料接收单对象 mat_material_receive + * + * @author lcj + * @date 2025-07-04 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("mat_material_receive") +public class MatMaterialReceive extends BaseEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @TableId(value = "id") + private Long id; + + /** + * 项目id + */ + private Long projectId; + + /** + * 材料来源(1甲供 2乙供) + */ + private String materialSource; + + /** + * 表单编号 + */ + private String formCode; + + /** + * 工程名称 + */ + private String projectName; + + /** + * 设备材料名称 + */ + private String materialName; + + /** + * 合同名称 + */ + private String contractName; + + /** + * 订货单位 + */ + private String orderingUnit; + + /** + * 供货单位 + */ + private String supplierUnit; + + /** + * 缺陷情况(承包单位填写) + */ + private String defectDescription; + + /** + * 合格证份数 + */ + private Integer certCount; + + /** + * 合格证文件 + */ + private String certCountFileId; + + /** + * 出厂报告份数 + */ + private Integer reportCount; + + /** + * 出厂报告文件 + */ + private String reportCountFileId; + + /** + * 技术资料份数 + */ + private Integer techDocCount; + + /** + * 技术资料文件 + */ + private String techDocCountFileId; + + /** + * 厂家资质文件份数 + */ + private Integer licenseCount; + + /** + * 厂家资质文件 + */ + private String licenseCountFileId; + + /** + * 设备材料入库/移交 + */ + private String storageType; + + /** + * 备注 + */ + private String remark; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/MatMaterialReceiveItem.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/MatMaterialReceiveItem.java new file mode 100644 index 00000000..b84995a6 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/MatMaterialReceiveItem.java @@ -0,0 +1,77 @@ +package org.dromara.materials.domain; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.dromara.common.mybatis.core.domain.BaseEntity; + +import java.io.Serial; +import java.math.BigDecimal; + +/** + * 物料接收单明细项对象 mat_material_receive_item + * + * @author lcj + * @date 2025-07-04 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("mat_material_receive_item") +public class MatMaterialReceiveItem extends BaseEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @TableId(value = "id") + private Long id; + + /** + * 项目id + */ + private Long projectId; + + /** + * 接收单id + */ + private Long receiveId; + + /** + * 名称 + */ + private String name; + + /** + * 规格 + */ + private String specification; + + /** + * 单位 + */ + private String unit; + + /** + * 数量 + */ + private BigDecimal quantity; + + /** + * 验收 + */ + private BigDecimal acceptedQuantity; + + /** + * 缺件 + */ + private BigDecimal shortageQuantity; + + /** + * 备注 + */ + private String remark; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialissue/MatMaterialIssueCreateReq.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialissue/MatMaterialIssueCreateReq.java new file mode 100644 index 00000000..8fef6583 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialissue/MatMaterialIssueCreateReq.java @@ -0,0 +1,105 @@ +package org.dromara.materials.domain.dto.materialissue; + +import lombok.Data; +import org.dromara.materials.domain.dto.materialissueitem.MatMaterialIssueItemDto; + +import java.io.Serial; +import java.io.Serializable; +import java.util.List; + +/** + * @author lcj + * @date 2025/7/4 15:02 + */ +@Data +public class MatMaterialIssueCreateReq implements Serializable { + + @Serial + private static final long serialVersionUID = 2742974667799153892L; + + /** + * 主键id + */ + private Long id; + + /** + * 项目id + */ + private Long projectId; + + /** + * 材料来源(1甲供 2乙供) + */ + private String materialSource; + + /** + * 表单编号 + */ + private String formCode; + + /** + * 工程名称 + */ + private String projectName; + + /** + * 设备材料名称 + */ + private String materialName; + + /** + * 订货单位 + */ + private String orderingUnit; + + /** + * 供货单位 + */ + private String supplierUnit; + + /** + * 领料单位 + */ + private String issueUnit; + + /** + * 保管单位 + */ + private String storageUnit; + + /** + * 缺陷情况(承包单位填写) + */ + private String defectDescription; + + /** + * 明细项 + */ + private List itemList; + + /** + * 合格证文件 + */ + private String certCountFileId; + + /** + * 出厂报告文件 + */ + private String reportCountFileId; + + /** + * 技术资料文件 + */ + private String techDocCountFileId; + + /** + * 厂家资质文件 + */ + private String licenseCountFileId; + + /** + * 备注 + */ + private String remark; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialissue/MatMaterialIssueQueryReq.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialissue/MatMaterialIssueQueryReq.java new file mode 100644 index 00000000..6f563e98 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialissue/MatMaterialIssueQueryReq.java @@ -0,0 +1,63 @@ +package org.dromara.materials.domain.dto.materialissue; + +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * @author lcj + * @date 2025/7/4 15:02 + */ +@Data +public class MatMaterialIssueQueryReq implements Serializable { + + @Serial + private static final long serialVersionUID = -4011015750160760763L; + + /** + * 项目id + */ + private Long projectId; + + /** + * 材料来源(1甲供 2乙供) + */ + private String materialSource; + + /** + * 表单编号 + */ + private String formCode; + + /** + * 工程名称 + */ + private String projectName; + + /** + * 设备材料名称 + */ + private String materialName; + + /** + * 订货单位 + */ + private String orderingUnit; + + /** + * 供货单位 + */ + private String supplierUnit; + + /** + * 领料单位 + */ + private String issueUnit; + + /** + * 保管单位 + */ + private String storageUnit; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialissue/MatMaterialIssueUpdateReq.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialissue/MatMaterialIssueUpdateReq.java new file mode 100644 index 00000000..3898a21d --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialissue/MatMaterialIssueUpdateReq.java @@ -0,0 +1,100 @@ +package org.dromara.materials.domain.dto.materialissue; + +import lombok.Data; +import org.dromara.materials.domain.dto.materialissueitem.MatMaterialIssueItemDto; + +import java.io.Serial; +import java.io.Serializable; +import java.util.List; + +/** + * @author lcj + * @date 2025/7/4 15:02 + */ +@Data +public class MatMaterialIssueUpdateReq implements Serializable { + + @Serial + private static final long serialVersionUID = 2053113999402012882L; + + /** + * 主键id + */ + private Long id; + + /** + * 项目id + */ + private Long projectId; + + /** + * 表单编号 + */ + private String formCode; + + /** + * 工程名称 + */ + private String projectName; + + /** + * 设备材料名称 + */ + private String materialName; + + /** + * 订货单位 + */ + private String orderingUnit; + + /** + * 供货单位 + */ + private String supplierUnit; + + /** + * 领料单位 + */ + private String issueUnit; + + /** + * 保管单位 + */ + private String storageUnit; + + /** + * 缺陷情况(承包单位填写) + */ + private String defectDescription; + + /** + * 明细项 + */ + private List itemList; + + /** + * 合格证文件 + */ + private String certCountFileId; + + /** + * 出厂报告文件 + */ + private String reportCountFileId; + + /** + * 技术资料文件 + */ + private String techDocCountFileId; + + /** + * 厂家资质文件 + */ + private String licenseCountFileId; + + /** + * 备注 + */ + private String remark; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialissue/MatMaterialIssueWordDto.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialissue/MatMaterialIssueWordDto.java new file mode 100644 index 00000000..a3ed7be4 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialissue/MatMaterialIssueWordDto.java @@ -0,0 +1,39 @@ +package org.dromara.materials.domain.dto.materialissue; + +import lombok.Data; +import org.dromara.materials.domain.dto.materialissueitem.MatMaterialIssueItemWordDto; + +import java.util.List; + +@Data +public class MatMaterialIssueWordDto { + + // 顶部信息 + private String projectName; + private String formCode; + private String materialName; + private String supplierUnit; + private String orderingUnit; + private String issueUnit; + private String storageUnit; + + // 表格数据 - 这是一个列表! + private List items; + + // 合计行数据 + private Integer totalStockQuantity; + private Integer totalIssuedQuantity; + private Integer totalRemainingQuantity; + + // 缺陷情况及附件 + private String defectDescription; + private String isCertCount; + private Integer certCount; + private String isReportCount; + private Integer reportCount; + private String isTechDocCount; + private Integer techDocCount; + private String isLicenseCount; + private Integer licenseCount; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialissueitem/MatMaterialIssueItemDto.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialissueitem/MatMaterialIssueItemDto.java new file mode 100644 index 00000000..a65e9ecb --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialissueitem/MatMaterialIssueItemDto.java @@ -0,0 +1,58 @@ +package org.dromara.materials.domain.dto.materialissueitem; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; + +/** + * @author lcj + * @date 2025/7/4 15:21 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class MatMaterialIssueItemDto { + + /** + * 主键id + */ + private Long id; + + /** + * 名称 + */ + private String name; + + /** + * 规格 + */ + private String specification; + + /** + * 单位 + */ + private String unit; + + /** + * 库存 + */ + private BigDecimal stockQuantity; + + /** + * 领取 + */ + private BigDecimal issuedQuantity; + + /** + * 剩余 + */ + private BigDecimal remainingQuantity; + + /** + * 备注 + */ + private String remark; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialissueitem/MatMaterialIssueItemWordDto.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialissueitem/MatMaterialIssueItemWordDto.java new file mode 100644 index 00000000..d47d7602 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialissueitem/MatMaterialIssueItemWordDto.java @@ -0,0 +1,21 @@ +package org.dromara.materials.domain.dto.materialissueitem; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class MatMaterialIssueItemWordDto { + + private Integer no; // 序号 + private String name; // 名称 + private String specification; // 规格 + private String unit; // 单位 + private Integer stockQuantity; // 库存数量 + private Integer issuedQuantity; // 领取数量 + private Integer remainingQuantity;// 剩余数量 + private String remark; // 备注 + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialreceive/MatMaterialReceiveCreateReq.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialreceive/MatMaterialReceiveCreateReq.java new file mode 100644 index 00000000..bdf649e3 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialreceive/MatMaterialReceiveCreateReq.java @@ -0,0 +1,100 @@ +package org.dromara.materials.domain.dto.materialreceive; + +import lombok.Data; +import org.dromara.materials.domain.dto.materialreceiveitem.MatMaterialReceiveItemDto; + +import java.io.Serial; +import java.io.Serializable; +import java.util.List; + +/** + * @author lcj + * @date 2025/7/4 15:03 + */ +@Data +public class MatMaterialReceiveCreateReq implements Serializable { + + @Serial + private static final long serialVersionUID = 1826521942178676812L; + + /** + * 项目id + */ + private Long projectId; + + /** + * 材料来源(1甲供 2乙供) + */ + private String materialSource; + + /** + * 表单编号 + */ + private String formCode; + + /** + * 工程名称 + */ + private String projectName; + + /** + * 设备材料名称 + */ + private String materialName; + + /** + * 合同名称 + */ + private String contractName; + + /** + * 订货单位 + */ + private String orderingUnit; + + /** + * 供货单位 + */ + private String supplierUnit; + + /** + * 缺陷情况(承包单位填写) + */ + private String defectDescription; + + /** + * 明细项 + */ + private List itemList; + + /** + * 合格证文件 + */ + private String certCountFileId; + + /** + * 出厂报告文件 + */ + private String reportCountFileId; + + /** + * 技术资料文件 + */ + private String techDocCountFileId; + + /** + * 厂家资质文件 + */ + private String licenseCountFileId; + + /** + * 设备材料入库/移交 + */ + private String storageType; + + /** + * 备注 + */ + private String remark; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialreceive/MatMaterialReceiveQueryReq.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialreceive/MatMaterialReceiveQueryReq.java new file mode 100644 index 00000000..242d4690 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialreceive/MatMaterialReceiveQueryReq.java @@ -0,0 +1,63 @@ +package org.dromara.materials.domain.dto.materialreceive; + +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * @author lcj + * @date 2025/7/4 15:03 + */ +@Data +public class MatMaterialReceiveQueryReq implements Serializable { + + @Serial + private static final long serialVersionUID = 5772774919127572167L; + + /** + * 项目id + */ + private Long projectId; + + /** + * 材料来源(1甲供 2乙供) + */ + private String materialSource; + + /** + * 表单编号 + */ + private String formCode; + + /** + * 工程名称 + */ + private String projectName; + + /** + * 设备材料名称 + */ + private String materialName; + + /** + * 合同名称 + */ + private String contractName; + + /** + * 订货单位 + */ + private String orderingUnit; + + /** + * 供货单位 + */ + private String supplierUnit; + + /** + * 设备材料入库/移交 + */ + private String storageType; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialreceive/MatMaterialReceiveUpdateReq.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialreceive/MatMaterialReceiveUpdateReq.java new file mode 100644 index 00000000..792c9742 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialreceive/MatMaterialReceiveUpdateReq.java @@ -0,0 +1,100 @@ +package org.dromara.materials.domain.dto.materialreceive; + +import lombok.Data; +import org.dromara.materials.domain.dto.materialreceiveitem.MatMaterialReceiveItemDto; + +import java.io.Serial; +import java.io.Serializable; +import java.util.List; + +/** + * @author lcj + * @date 2025/7/4 15:03 + */ +@Data +public class MatMaterialReceiveUpdateReq implements Serializable { + + @Serial + private static final long serialVersionUID = 5686357336524453994L; + + /** + * 主键id + */ + private Long id; + + /** + * 项目id + */ + private Long projectId; + + /** + * 表单编号 + */ + private String formCode; + + /** + * 工程名称 + */ + private String projectName; + + /** + * 设备材料名称 + */ + private String materialName; + + /** + * 合同名称 + */ + private String contractName; + + /** + * 订货单位 + */ + private String orderingUnit; + + /** + * 供货单位 + */ + private String supplierUnit; + + /** + * 缺陷情况(承包单位填写) + */ + private String defectDescription; + + /** + * 明细项 + */ + private List itemList; + + /** + * 合格证文件 + */ + private String certCountFileId; + + /** + * 出厂报告文件 + */ + private String reportCountFileId; + + /** + * 技术资料文件 + */ + private String techDocCountFileId; + + /** + * 厂家资质文件 + */ + private String licenseCountFileId; + + /** + * 设备材料入库/移交 + */ + private String storageType; + + /** + * 备注 + */ + private String remark; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialreceive/MatMaterialReceiveWordDto.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialreceive/MatMaterialReceiveWordDto.java new file mode 100644 index 00000000..f276b36c --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialreceive/MatMaterialReceiveWordDto.java @@ -0,0 +1,48 @@ +package org.dromara.materials.domain.dto.materialreceive; + +import lombok.Data; +import org.dromara.materials.domain.dto.materialreceiveitem.MatMaterialReceiveItemWordDto; + +import java.util.List; + +/** + * @author lcj + * @date 2025/7/6 13:56 + */ +@Data +public class MatMaterialReceiveWordDto { + + // 顶部信息 + private String formCode; + private String projectName; + private String materialName; + private String contractName; + private String orderingUnit; + private String supplierUnit; + + // 表格数据 - 这是一个列表! + private List items; + + // 合计行数据 + private Integer totalQuantity; + private Integer totalAcceptedQuantity; + private Integer totalShortageQuantity; + + // 缺陷情况及附件 + private String defectDescription; + private String isCertCount; + private Integer certCount; + private String isReportCount; + private Integer reportCount; + private String isTechDocCount; + private Integer techDocCount; + private String isLicenseCount; + private Integer licenseCount; + + + // 设备材料入库/移交 + private String storageType1; + private String storageType2; + private String storageType3; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialreceiveitem/MatMaterialReceiveItemDto.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialreceiveitem/MatMaterialReceiveItemDto.java new file mode 100644 index 00000000..3aec0b7b --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialreceiveitem/MatMaterialReceiveItemDto.java @@ -0,0 +1,58 @@ +package org.dromara.materials.domain.dto.materialreceiveitem; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; + +/** + * @author lcj + * @date 2025/7/4 15:24 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class MatMaterialReceiveItemDto { + + /** + * 主键id + */ + private Long id; + + /** + * 名称 + */ + private String name; + + /** + * 规格 + */ + private String specification; + + /** + * 单位 + */ + private String unit; + + /** + * 数量 + */ + private BigDecimal quantity; + + /** + * 验收 + */ + private BigDecimal acceptedQuantity; + + /** + * 缺件 + */ + private BigDecimal shortageQuantity; + + /** + * 备注 + */ + private String remark; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialreceiveitem/MatMaterialReceiveItemWordDto.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialreceiveitem/MatMaterialReceiveItemWordDto.java new file mode 100644 index 00000000..e9d7800c --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/dto/materialreceiveitem/MatMaterialReceiveItemWordDto.java @@ -0,0 +1,56 @@ +package org.dromara.materials.domain.dto.materialreceiveitem; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author lcj + * @date 2025/7/6 14:04 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class MatMaterialReceiveItemWordDto { + + /** + * 序号 + */ + private Integer no; + + /** + * 名称 + */ + private String name; + + /** + * 规格 + */ + private String specification; + + /** + * 单位 + */ + private String unit; + + /** + * 数量 + */ + private Integer quantity; + + /** + * 验收 + */ + private Integer acceptedQuantity; + + /** + * 缺件 + */ + private Integer shortageQuantity; + + /** + * 备注 + */ + private String remark; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/vo/materialissue/MatMaterialIssueVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/vo/materialissue/MatMaterialIssueVo.java new file mode 100644 index 00000000..0b3411d8 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/vo/materialissue/MatMaterialIssueVo.java @@ -0,0 +1,152 @@ +package org.dromara.materials.domain.vo.materialissue; + +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import org.dromara.materials.domain.MatMaterialIssue; +import org.dromara.materials.domain.vo.materialissueitem.MatMaterialIssueItemVo; +import org.dromara.system.domain.vo.SysOssVo; + +import java.io.Serial; +import java.io.Serializable; +import java.util.List; + + +/** + * 物料领料单视图对象 mat_material_issue + * + * @author lcj + * @date 2025-07-04 + */ +@Data +@AutoMapper(target = MatMaterialIssue.class) +public class MatMaterialIssueVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + private Long id; + + /** + * 项目id + */ + private Long projectId; + + /** + * 材料来源(1甲供 2乙供) + */ + private String materialSource; + + /** + * 表单编号 + */ + private String formCode; + + /** + * 工程名称 + */ + private String projectName; + + /** + * 设备材料名称 + */ + private String materialName; + + /** + * 订货单位 + */ + private String orderingUnit; + + /** + * 供货单位 + */ + private String supplierUnit; + + /** + * 领料单位 + */ + private String issueUnit; + + /** + * 保管单位 + */ + private String storageUnit; + + /** + * 缺陷情况(承包单位填写) + */ + private String defectDescription; + + /** + * 合格证份数 + */ + private Integer certCount; + + /** + * 合格证文件 + */ + private String certCountFileId; + + /** + * 合格证文件 + */ + private List certCountFile; + + /** + * 出厂报告份数 + */ + private Integer reportCount; + + /** + * 出厂报告文件 + */ + private String reportCountFileId; + + /** + * 出厂报告文件 + */ + private List reportCountFile; + + /** + * 技术资料份数 + */ + private Integer techDocCount; + + /** + * 技术资料文件 + */ + private String techDocCountFileId; + + /** + * 技术资料文件 + */ + private List techDocCountFile; + + /** + * 厂家资质文件份数 + */ + private Integer licenseCount; + + /** + * 厂家资质文件 + */ + private String licenseCountFileId; + + /** + * 厂家资质文件 + */ + private List licenseCountFile; + + /** + * 备注 + */ + private String remark; + + /** + * 明细项列表 + */ + private List itemList; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/vo/materialissueitem/MatMaterialIssueItemVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/vo/materialissueitem/MatMaterialIssueItemVo.java new file mode 100644 index 00000000..a816f264 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/vo/materialissueitem/MatMaterialIssueItemVo.java @@ -0,0 +1,75 @@ +package org.dromara.materials.domain.vo.materialissueitem; + +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import org.dromara.materials.domain.MatMaterialIssueItem; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; + + +/** + * 物料领料单明细项视图对象 mat_material_issue_item + * + * @author lcj + * @date 2025-07-04 + */ +@Data +@AutoMapper(target = MatMaterialIssueItem.class) +public class MatMaterialIssueItemVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + private Long id; + + /** + * 项目id + */ + private Long projectId; + + /** + * 领料单id + */ + private Long issueId; + + /** + * 名称 + */ + private String name; + + /** + * 规格 + */ + private String specification; + + /** + * 单位 + */ + private String unit; + + /** + * 库存 + */ + private BigDecimal stockQuantity; + + /** + * 领取 + */ + private BigDecimal issuedQuantity; + + /** + * 剩余 + */ + private BigDecimal remainingQuantity; + + /** + * 备注 + */ + private String remark; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/vo/materialreceive/MatMaterialReceiveVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/vo/materialreceive/MatMaterialReceiveVo.java new file mode 100644 index 00000000..10bb48b4 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/vo/materialreceive/MatMaterialReceiveVo.java @@ -0,0 +1,152 @@ +package org.dromara.materials.domain.vo.materialreceive; + +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import org.dromara.materials.domain.MatMaterialReceive; +import org.dromara.materials.domain.vo.materialreceiveitem.MatMaterialReceiveItemVo; +import org.dromara.system.domain.vo.SysOssVo; + +import java.io.Serial; +import java.io.Serializable; +import java.util.List; + + +/** + * 物料接收单视图对象 mat_material_receive + * + * @author lcj + * @date 2025-07-04 + */ +@Data +@AutoMapper(target = MatMaterialReceive.class) +public class MatMaterialReceiveVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + private Long id; + + /** + * 项目id + */ + private Long projectId; + + /** + * 材料来源(1甲供 2乙供) + */ + private String materialSource; + + /** + * 表单编号 + */ + private String formCode; + + /** + * 工程名称 + */ + private String projectName; + + /** + * 设备材料名称 + */ + private String materialName; + + /** + * 合同名称 + */ + private String contractName; + + /** + * 订货单位 + */ + private String orderingUnit; + + /** + * 供货单位 + */ + private String supplierUnit; + + /** + * 缺陷情况(承包单位填写) + */ + private String defectDescription; + + /** + * 合格证份数 + */ + private Integer certCount; + + /** + * 合格证文件 + */ + private String certCountFileId; + + /** + * 合格证文件 + */ + private List certCountFile; + + /** + * 出厂报告份数 + */ + private Integer reportCount; + + /** + * 出厂报告文件 + */ + private String reportCountFileId; + + /** + * 出厂报告文件 + */ + private List reportCountFile; + + /** + * 技术资料份数 + */ + private Integer techDocCount; + + /** + * 技术资料文件 + */ + private String techDocCountFileId; + + /** + * 技术资料文件 + */ + private List techDocCountFile; + + /** + * 厂家资质文件份数 + */ + private Integer licenseCount; + + /** + * 厂家资质文件 + */ + private String licenseCountFileId; + + /** + * 厂家资质文件 + */ + private List licenseCountFile; + + /** + * 设备材料入库/移交 + */ + private String storageType; + + /** + * 备注 + */ + private String remark; + + /** + * 明细项列表 + */ + private List itemList; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/vo/materialreceiveitem/MatMaterialReceiveItemVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/vo/materialreceiveitem/MatMaterialReceiveItemVo.java new file mode 100644 index 00000000..ad28588f --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/domain/vo/materialreceiveitem/MatMaterialReceiveItemVo.java @@ -0,0 +1,75 @@ +package org.dromara.materials.domain.vo.materialreceiveitem; + +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import org.dromara.materials.domain.MatMaterialReceiveItem; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; + + +/** + * 物料接收单明细项视图对象 mat_material_receive_item + * + * @author lcj + * @date 2025-07-04 + */ +@Data +@AutoMapper(target = MatMaterialReceiveItem.class) +public class MatMaterialReceiveItemVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + private Long id; + + /** + * 项目id + */ + private Long projectId; + + /** + * 接收单id + */ + private Long receiveId; + + /** + * 名称 + */ + private String name; + + /** + * 规格 + */ + private String specification; + + /** + * 单位 + */ + private String unit; + + /** + * 数量 + */ + private BigDecimal quantity; + + /** + * 验收 + */ + private BigDecimal acceptedQuantity; + + /** + * 缺件 + */ + private BigDecimal shortageQuantity; + + /** + * 备注 + */ + private String remark; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/mapper/MatMaterialIssueItemMapper.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/mapper/MatMaterialIssueItemMapper.java new file mode 100644 index 00000000..65c0baa4 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/mapper/MatMaterialIssueItemMapper.java @@ -0,0 +1,15 @@ +package org.dromara.materials.mapper; + +import org.dromara.materials.domain.MatMaterialIssueItem; +import org.dromara.materials.domain.vo.materialissueitem.MatMaterialIssueItemVo; +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; + +/** + * 物料领料单明细项Mapper接口 + * + * @author lcj + * @date 2025-07-04 + */ +public interface MatMaterialIssueItemMapper extends BaseMapperPlus { + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/mapper/MatMaterialIssueMapper.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/mapper/MatMaterialIssueMapper.java new file mode 100644 index 00000000..63033f01 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/mapper/MatMaterialIssueMapper.java @@ -0,0 +1,15 @@ +package org.dromara.materials.mapper; + +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; +import org.dromara.materials.domain.MatMaterialIssue; +import org.dromara.materials.domain.vo.materialissue.MatMaterialIssueVo; + +/** + * 物料领料单Mapper接口 + * + * @author lcj + * @date 2025-07-04 + */ +public interface MatMaterialIssueMapper extends BaseMapperPlus { + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/mapper/MatMaterialReceiveItemMapper.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/mapper/MatMaterialReceiveItemMapper.java new file mode 100644 index 00000000..333779ab --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/mapper/MatMaterialReceiveItemMapper.java @@ -0,0 +1,15 @@ +package org.dromara.materials.mapper; + +import org.dromara.materials.domain.MatMaterialReceiveItem; +import org.dromara.materials.domain.vo.materialreceiveitem.MatMaterialReceiveItemVo; +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; + +/** + * 物料接收单明细项Mapper接口 + * + * @author lcj + * @date 2025-07-04 + */ +public interface MatMaterialReceiveItemMapper extends BaseMapperPlus { + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/mapper/MatMaterialReceiveMapper.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/mapper/MatMaterialReceiveMapper.java new file mode 100644 index 00000000..13bf8246 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/mapper/MatMaterialReceiveMapper.java @@ -0,0 +1,15 @@ +package org.dromara.materials.mapper; + +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; +import org.dromara.materials.domain.MatMaterialReceive; +import org.dromara.materials.domain.vo.materialreceive.MatMaterialReceiveVo; + +/** + * 物料接收单Mapper接口 + * + * @author lcj + * @date 2025-07-04 + */ +public interface MatMaterialReceiveMapper extends BaseMapperPlus { + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/service/IMatMaterialIssueItemService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/service/IMatMaterialIssueItemService.java new file mode 100644 index 00000000..a999c41d --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/service/IMatMaterialIssueItemService.java @@ -0,0 +1,41 @@ +package org.dromara.materials.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import org.dromara.materials.domain.MatMaterialIssueItem; +import org.dromara.materials.domain.vo.materialissueitem.MatMaterialIssueItemVo; + +import java.util.List; + +/** + * 物料领料单明细项Service接口 + * + * @author lcj + * @date 2025-07-04 + */ +public interface IMatMaterialIssueItemService extends IService { + + /** + * 查询物料领料单明细项列表 + * + * @param issueId 领料单id + * @return 物料领料单明细项列表 + */ + List queryListByIssueId(Long issueId); + + /** + * 获取物料领料单明细项视图对象 + * + * @param matMaterialIssueItem 物料领料单明细项对象 + * @return 物料领料单明细项视图对象 + */ + MatMaterialIssueItemVo getVo(MatMaterialIssueItem matMaterialIssueItem); + + /** + * 获取物料领料单明细项视图对象列表 + * + * @param matMaterialIssueItemList 物料领料单明细项对象列表 + * @return 物料领料单明细项视图对象列表 + */ + List getVoList(List matMaterialIssueItemList); + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/service/IMatMaterialIssueService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/service/IMatMaterialIssueService.java new file mode 100644 index 00000000..dd96b015 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/service/IMatMaterialIssueService.java @@ -0,0 +1,106 @@ +package org.dromara.materials.service; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import jakarta.servlet.http.HttpServletResponse; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.materials.domain.MatMaterialIssue; +import org.dromara.materials.domain.dto.materialissue.MatMaterialIssueCreateReq; +import org.dromara.materials.domain.dto.materialissue.MatMaterialIssueQueryReq; +import org.dromara.materials.domain.dto.materialissue.MatMaterialIssueUpdateReq; +import org.dromara.materials.domain.vo.materialissue.MatMaterialIssueVo; + +import java.util.Collection; +import java.util.List; + +/** + * 物料领料单Service接口 + * + * @author lcj + * @date 2025-07-04 + */ +public interface IMatMaterialIssueService extends IService { + + /** + * 查询物料领料单 + * + * @param id 主键 + * @return 物料领料单 + */ + MatMaterialIssueVo queryById(Long id); + + /** + * 分页查询物料领料单列表 + * + * @param req 查询条件 + * @param pageQuery 分页参数 + * @return 物料领料单分页列表 + */ + TableDataInfo queryPageList(MatMaterialIssueQueryReq req, PageQuery pageQuery); + + /** + * 查询符合条件的物料领料单列表 + * + * @param req 查询条件 + * @return 物料领料单列表 + */ + List queryList(MatMaterialIssueQueryReq req); + + /** + * 根据id导出word + * + * @param id 主键 + * @param response 响应 + */ + void exportWordById(Long id, HttpServletResponse response); + + /** + * 新增物料领料单 + * + * @param req 物料领料单 + * @return 是否新增成功 + */ + Boolean insertByBo(MatMaterialIssueCreateReq req); + + /** + * 修改物料领料单 + * + * @param req 物料领料单 + * @return 是否修改成功 + */ + Boolean updateByBo(MatMaterialIssueUpdateReq req); + + /** + * 批量删除物料领料单信息 + * + * @param ids 待删除的主键集合 + * @return 是否删除成功 + */ + Boolean deleteByIds(Collection ids); + + /** + * 获取物料领料单视图对象 + * + * @param materialIssue 物料领料单对象 + * @return 物料领料单视图对象 + */ + MatMaterialIssueVo getVo(MatMaterialIssue materialIssue); + + /** + * 构建查询条件封装 + * + * @param req 查询条件 + * @return 查询条件封装 + */ + LambdaQueryWrapper buildQueryWrapper(MatMaterialIssueQueryReq req); + + /** + * 获取物料领料单分页对象视图 + * + * @param materialIssuePage 物料领料单分页对象 + * @return 物料领料单分页对象视图 + */ + Page getVoPage(Page materialIssuePage); +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/service/IMatMaterialReceiveItemService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/service/IMatMaterialReceiveItemService.java new file mode 100644 index 00000000..92740874 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/service/IMatMaterialReceiveItemService.java @@ -0,0 +1,41 @@ +package org.dromara.materials.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import org.dromara.materials.domain.MatMaterialReceiveItem; +import org.dromara.materials.domain.vo.materialreceiveitem.MatMaterialReceiveItemVo; + +import java.util.List; + +/** + * 物料接收单明细项Service接口 + * + * @author lcj + * @date 2025-07-04 + */ +public interface IMatMaterialReceiveItemService extends IService { + + /** + * 查询物料接收单明细项列表 + * + * @param issueId 接收单id + * @return 物料接收单明细项列表 + */ + List queryListByReceiveId(Long issueId); + + /** + * 获取物料接收单明细项视图对象 + * + * @param matMaterialReceiveItem 物料接收单明细项对象 + * @return 物料接收单明细项视图对象 + */ + MatMaterialReceiveItemVo getVo(MatMaterialReceiveItem matMaterialReceiveItem); + + /** + * 获取物料接收单明细项视图对象列表 + * + * @param matMaterialReceiveItemList 物料接收单明细项对象列表 + * @return 物料接收单明细项视图对象列表 + */ + List getVoList(List matMaterialReceiveItemList); + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/service/IMatMaterialReceiveService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/service/IMatMaterialReceiveService.java new file mode 100644 index 00000000..d50e4aed --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/service/IMatMaterialReceiveService.java @@ -0,0 +1,106 @@ +package org.dromara.materials.service; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import jakarta.servlet.http.HttpServletResponse; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.materials.domain.MatMaterialReceive; +import org.dromara.materials.domain.dto.materialreceive.MatMaterialReceiveCreateReq; +import org.dromara.materials.domain.dto.materialreceive.MatMaterialReceiveQueryReq; +import org.dromara.materials.domain.dto.materialreceive.MatMaterialReceiveUpdateReq; +import org.dromara.materials.domain.vo.materialreceive.MatMaterialReceiveVo; + +import java.util.Collection; +import java.util.List; + +/** + * 物料接收单Service接口 + * + * @author lcj + * @date 2025-07-04 + */ +public interface IMatMaterialReceiveService extends IService { + + /** + * 查询物料接收单 + * + * @param id 主键 + * @return 物料接收单 + */ + MatMaterialReceiveVo queryById(Long id); + + /** + * 分页查询物料接收单列表 + * + * @param req 查询条件 + * @param pageQuery 分页参数 + * @return 物料接收单分页列表 + */ + TableDataInfo queryPageList(MatMaterialReceiveQueryReq req, PageQuery pageQuery); + + /** + * 查询符合条件的物料接收单列表 + * + * @param req 查询条件 + * @return 物料接收单列表 + */ + List queryList(MatMaterialReceiveQueryReq req); + + /** + * 根据id导出word + * + * @param id 主键 + * @param response 响应 + */ + void exportWordById(Long id, HttpServletResponse response); + + /** + * 新增物料接收单 + * + * @param req 物料接收单 + * @return 是否新增成功 + */ + Boolean insertByBo(MatMaterialReceiveCreateReq req); + + /** + * 修改物料接收单 + * + * @param req 物料接收单 + * @return 是否修改成功 + */ + Boolean updateByBo(MatMaterialReceiveUpdateReq req); + + /** + * 批量删除物料接收单信息 + * + * @param ids 待删除的主键集合 + * @return 是否删除成功 + */ + Boolean deleteByIds(Collection ids); + + /** + * 获取物料接收单视图对象 + * + * @param materialReceive 物料接收单对象 + * @return 物料接收单视图对象 + */ + MatMaterialReceiveVo getVo(MatMaterialReceive materialReceive); + + /** + * 构建查询条件封装 + * + * @param req 查询条件 + * @return 查询条件封装 + */ + LambdaQueryWrapper buildQueryWrapper(MatMaterialReceiveQueryReq req); + + /** + * 获取物料接收单分页对象视图 + * + * @param materialReceivePage 物料接收单分页对象 + * @return 物料接收单分页对象视图 + */ + Page getVoPage(Page materialReceivePage); +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/service/impl/MatMaterialIssueItemServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/service/impl/MatMaterialIssueItemServiceImpl.java new file mode 100644 index 00000000..a76d0de3 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/service/impl/MatMaterialIssueItemServiceImpl.java @@ -0,0 +1,59 @@ +package org.dromara.materials.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.dromara.materials.domain.MatMaterialIssueItem; +import org.dromara.materials.domain.vo.materialissueitem.MatMaterialIssueItemVo; +import org.dromara.materials.mapper.MatMaterialIssueItemMapper; +import org.dromara.materials.service.IMatMaterialIssueItemService; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 物料领料单明细项Service业务层处理 + * + * @author lcj + * @date 2025-07-04 + */ +@Service +public class MatMaterialIssueItemServiceImpl extends ServiceImpl + implements IMatMaterialIssueItemService { + + /** + * 查询物料领料单明细项列表 + * + * @param issueId 领料单id + * @return 物料领料单明细项列表 + */ + @Override + public List queryListByIssueId(Long issueId) { + return this.lambdaQuery() + .eq(MatMaterialIssueItem::getIssueId, issueId) + .list(); + } + + /** + * 获取物料领料单明细项视图对象 + * + * @param matMaterialIssueItem 物料领料单明细项对象 + * @return 物料领料单明细项视图对象 + */ + @Override + public MatMaterialIssueItemVo getVo(MatMaterialIssueItem matMaterialIssueItem) { + MatMaterialIssueItemVo vo = new MatMaterialIssueItemVo(); + BeanUtils.copyProperties(matMaterialIssueItem, vo); + return vo; + } + + /** + * 获取物料领料单明细项视图对象列表 + * + * @param matMaterialIssueItemList 物料领料单明细项对象列表 + * @return 物料领料单明细项视图对象列表 + */ + @Override + public List getVoList(List matMaterialIssueItemList) { + return matMaterialIssueItemList.stream().map(this::getVo).toList(); + } +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/service/impl/MatMaterialIssueServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/service/impl/MatMaterialIssueServiceImpl.java new file mode 100644 index 00000000..a9d044f1 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/service/impl/MatMaterialIssueServiceImpl.java @@ -0,0 +1,529 @@ +package org.dromara.materials.service.impl; + +import cn.hutool.core.collection.CollUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.deepoove.poi.XWPFTemplate; +import com.deepoove.poi.config.Configure; +import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; +import org.dromara.common.core.constant.HttpStatus; +import org.dromara.common.core.exception.ServiceException; +import org.dromara.common.core.utils.ObjectUtils; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.core.utils.file.FileUtils; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.oss.core.OssClient; +import org.dromara.common.oss.exception.OssException; +import org.dromara.common.oss.factory.OssFactory; +import org.dromara.common.utils.DocumentUtil; +import org.dromara.materials.constants.MatMaterialsConstant; +import org.dromara.materials.domain.MatMaterialIssue; +import org.dromara.materials.domain.MatMaterialIssueItem; +import org.dromara.materials.domain.dto.materialissue.MatMaterialIssueCreateReq; +import org.dromara.materials.domain.dto.materialissue.MatMaterialIssueQueryReq; +import org.dromara.materials.domain.dto.materialissue.MatMaterialIssueUpdateReq; +import org.dromara.materials.domain.dto.materialissue.MatMaterialIssueWordDto; +import org.dromara.materials.domain.dto.materialissueitem.MatMaterialIssueItemDto; +import org.dromara.materials.domain.dto.materialissueitem.MatMaterialIssueItemWordDto; +import org.dromara.materials.domain.vo.materialissue.MatMaterialIssueVo; +import org.dromara.materials.mapper.MatMaterialIssueMapper; +import org.dromara.materials.service.IMatMaterialIssueItemService; +import org.dromara.materials.service.IMatMaterialIssueService; +import org.dromara.project.service.IBusProjectService; +import org.dromara.system.domain.vo.SysOssVo; +import org.dromara.system.service.ISysOssService; +import org.springframework.beans.BeanUtils; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.math.BigDecimal; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.*; +import java.util.zip.ZipOutputStream; + +/** + * 物料领料单Service业务层处理 + * + * @author lcj + * @date 2025-07-04 + */ +@Slf4j +@Service +public class MatMaterialIssueServiceImpl extends ServiceImpl + implements IMatMaterialIssueService { + + @Resource + private ISysOssService ossService; + + @Resource + private IBusProjectService projectService; + + @Resource + private IMatMaterialIssueItemService materialIssueItemService; + + /** + * 查询物料领料单 + * + * @param id 主键 + * @return 物料领料单 + */ + @Override + public MatMaterialIssueVo queryById(Long id) { + MatMaterialIssue materialIssue = this.getById(id); + if (materialIssue == null) { + throw new ServiceException("物料领料单信息不存在", HttpStatus.NOT_FOUND); + } + return this.getVo(materialIssue); + } + + /** + * 分页查询物料领料单列表 + * + * @param req 查询条件 + * @param pageQuery 分页参数 + * @return 物料领料单分页列表 + */ + @Override + public TableDataInfo queryPageList(MatMaterialIssueQueryReq req, PageQuery pageQuery) { + Page issuePage = this.page(pageQuery.build(), this.buildQueryWrapper(req)); + return TableDataInfo.build(this.getVoPage(issuePage)); + } + + /** + * 查询符合条件的物料领料单列表 + * + * @param req 查询条件 + * @return 物料领料单列表 + */ + @Override + public List queryList(MatMaterialIssueQueryReq req) { + return this.list(this.buildQueryWrapper(req)).stream().map(this::getVo).toList(); + } + + /** + * 根据id导出word + * + * @param id 主键 + * @param response 响应 + */ + @Override + public void exportWordById(Long id, HttpServletResponse response) { + MatMaterialIssue materialIssue = this.getById(id); + if (materialIssue == null) { + throw new ServiceException("物料领料单不存在"); + } + Path targetDir = Paths.get(MatMaterialsConstant.getMatMaterialIssueFileUrl(materialIssue)); + // 如果存在目录则直接返回,不存在则生成文件并返回 + if (!Files.exists(targetDir)) { + // 清理旧文件 + String baseUrl = MatMaterialsConstant.MATERIALS_ISSUE_FILE_URL + materialIssue.getId(); + try { + Path dirPath = Paths.get(baseUrl); + if (Files.exists(dirPath)) { + FileUtils.deleteDirectory(dirPath); + } + } catch (IOException e) { + log.error("文件目录:{},清理失败", baseUrl, e); + } + // 准备数据 + List itemList = materialIssueItemService.queryListByIssueId(id); + MatMaterialIssueWordDto data = this.getReplacementDto(materialIssue, itemList); + // 生成文件 + try (InputStream is = getClass().getClassLoader().getResourceAsStream(MatMaterialsConstant.MATERIALS_ISSUE_TEMPLATE_PATH)) { + if (is == null) { + throw new ServiceException("模板文件不存在"); + } + LoopRowTableRenderPolicy hackLoopTableRenderPolicy = new LoopRowTableRenderPolicy(); + Configure config = Configure.builder().bind("items", hackLoopTableRenderPolicy).build(); + XWPFTemplate template = XWPFTemplate.compile(is, config); + template.render(data); + // 创建目标目录 + if (!Files.exists(targetDir)) { + Files.createDirectories(targetDir); + } + // 组合目标文件名 + String fileName = MatMaterialsConstant.getMatMaterialIssueFileName(materialIssue); + // 保存修改后的文件 + try (FileOutputStream fos = new FileOutputStream(targetDir.resolve(fileName).toFile())) { + template.write(fos); + } + template.close(); + // 获取附件 + String certCountFileId = materialIssue.getCertCountFileId(); + String reportCountFileId = materialIssue.getReportCountFileId(); + String techDocCountFileId = materialIssue.getTechDocCountFileId(); + String licenseCountFileId = materialIssue.getLicenseCountFileId(); + if (StringUtils.isNotBlank(certCountFileId)) { + List ossIdList = Arrays.stream(certCountFileId.split(",")).map(Long::parseLong).toList(); + List ossVoList = ossService.listByIds(ossIdList); + String baseFile = MatMaterialsConstant.getMatMaterialIssueFileUrl(materialIssue) + "/合格证"; + for (SysOssVo ossVo : ossVoList) { + OssClient storage = OssFactory.instance(ossVo.getService()); + storage.fileDownload(ossVo.getUrl(), ossVo.getOriginalName(), baseFile); + } + } + if (StringUtils.isNotBlank(reportCountFileId)) { + List ossIdList = Arrays.stream(reportCountFileId.split(",")).map(Long::parseLong).toList(); + List ossVoList = ossService.listByIds(ossIdList); + String baseFile = MatMaterialsConstant.getMatMaterialIssueFileUrl(materialIssue) + "/出厂报告"; + for (SysOssVo ossVo : ossVoList) { + OssClient storage = OssFactory.instance(ossVo.getService()); + storage.fileDownload(ossVo.getUrl(), ossVo.getOriginalName(), baseFile); + } + } + if (StringUtils.isNotBlank(techDocCountFileId)) { + List ossIdList = Arrays.stream(techDocCountFileId.split(",")).map(Long::parseLong).toList(); + List ossVoList = ossService.listByIds(ossIdList); + String baseFile = MatMaterialsConstant.getMatMaterialIssueFileUrl(materialIssue) + "/技术资料"; + for (SysOssVo ossVo : ossVoList) { + OssClient storage = OssFactory.instance(ossVo.getService()); + storage.fileDownload(ossVo.getUrl(), ossVo.getOriginalName(), baseFile); + } + } + if (StringUtils.isNotBlank(licenseCountFileId)) { + List ossIdList = Arrays.stream(licenseCountFileId.split(",")).map(Long::parseLong).toList(); + List ossVoList = ossService.listByIds(ossIdList); + String baseFile = MatMaterialsConstant.getMatMaterialIssueFileUrl(materialIssue) + "/厂家资质文件"; + for (SysOssVo ossVo : ossVoList) { + OssClient storage = OssFactory.instance(ossVo.getService()); + storage.fileDownload(ossVo.getUrl(), ossVo.getOriginalName(), baseFile); + } + } + + } catch (IOException e) { + throw new OssException("生成Word文件失败,错误信息: " + e.getMessage()); + } + } + // 设置响应头,返回ZIP文件 + response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE + "; charset=UTF-8"); + try (ZipOutputStream zos = new ZipOutputStream(response.getOutputStream())) { + DocumentUtil.zipDirectory(targetDir, targetDir, zos); + zos.flush(); + } catch (Exception e) { + throw new OssException("生成ZIP文件失败,错误信息: " + e.getMessage()); + } + } + + /** + * 新增物料领料单 + * + * @param req 物料领料单 + * @return 是否新增成功 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean insertByBo(MatMaterialIssueCreateReq req) { + MatMaterialIssue materialIssue = new MatMaterialIssue(); + BeanUtils.copyProperties(req, materialIssue); + validEntityBeforeSave(materialIssue, true); + getFileSize(materialIssue, + req.getLicenseCountFileId(), + req.getReportCountFileId(), + req.getTechDocCountFileId(), + req.getCertCountFileId()); + boolean save = this.save(materialIssue); + if (!save) { + throw new ServiceException("物料领料单新增失败", HttpStatus.ERROR); + } + List itemList = req.getItemList(); + if (CollUtil.isNotEmpty(itemList)) { + List materialIssueItemList = itemList.stream().map(item -> { + MatMaterialIssueItem materialIssueItem = new MatMaterialIssueItem(); + BeanUtils.copyProperties(item, materialIssueItem); + materialIssueItem.setIssueId(materialIssue.getId()); + materialIssueItem.setProjectId(materialIssue.getProjectId()); + return materialIssueItem; + }).toList(); + boolean result = materialIssueItemService.saveBatch(materialIssueItemList); + if (!result) { + throw new ServiceException("物料领料单明细项新增失败", HttpStatus.ERROR); + } + } + return true; + } + + /** + * 修改物料领料单 + * + * @param req 物料领料单 + * @return 是否修改成功 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean updateByBo(MatMaterialIssueUpdateReq req) { + Long id = req.getId(); + MatMaterialIssue oldMaterialIssue = this.getById(id); + if (oldMaterialIssue == null) { + throw new ServiceException("修改物料收货单失败,数据不存在", HttpStatus.NOT_FOUND); + } + MatMaterialIssue materialIssue = new MatMaterialIssue(); + BeanUtils.copyProperties(req, materialIssue); + validEntityBeforeSave(materialIssue, false); + getFileSize(materialIssue, + req.getLicenseCountFileId(), + req.getReportCountFileId(), + req.getTechDocCountFileId(), + req.getCertCountFileId()); + boolean update = this.updateById(materialIssue); + if (!update) { + throw new ServiceException("物料领料单修改失败", HttpStatus.ERROR); + } + // 删除旧的 + List oldMaterialIssueItemList = materialIssueItemService.queryListByIssueId(id); + if (CollUtil.isNotEmpty(oldMaterialIssueItemList)) { + boolean result = materialIssueItemService.removeBatchByIds(oldMaterialIssueItemList); + if (!result) { + throw new ServiceException("物料领料单明细项删除失败", HttpStatus.ERROR); + } + } + // 重新添加 + List itemList = req.getItemList(); + if (CollUtil.isNotEmpty(itemList)) { + List materialIssueItemList = itemList.stream().map(item -> { + MatMaterialIssueItem materialIssueItem = new MatMaterialIssueItem(); + BeanUtils.copyProperties(item, materialIssueItem); + materialIssueItem.setIssueId(id); + materialIssueItem.setProjectId(materialIssue.getProjectId()); + return materialIssueItem; + }).toList(); + boolean result = materialIssueItemService.saveBatch(materialIssueItemList); + if (!result) { + throw new ServiceException("物料领料单明细项新增失败", HttpStatus.ERROR); + } + } + return true; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(MatMaterialIssue entity, Boolean create) { + // 做一些数据校验,如唯一约束 + Long projectId = entity.getProjectId(); + String materialSource = entity.getMaterialSource(); + if (create) { + if (projectId == null) { + throw new ServiceException("项目 id 不能为空", HttpStatus.BAD_REQUEST); + } + if (StringUtils.isEmpty(materialSource)) { + throw new ServiceException("物料来源不能为空", HttpStatus.BAD_REQUEST); + } + } + // 查询项目是否存在 + if (projectId != null && projectService.getById(projectId) == null) { + throw new ServiceException("对应项目不存在", HttpStatus.NOT_FOUND); + } + } + + /** + * 批量删除物料领料单信息 + * + * @param ids 待删除的主键集合 + * @return 是否删除成功 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean deleteByIds(Collection ids) { + List itemList = materialIssueItemService.lambdaQuery() + .in(MatMaterialIssueItem::getIssueId, ids) + .list(); + if (CollUtil.isNotEmpty(itemList)) { + materialIssueItemService.removeBatchByIds(itemList); + } + return this.removeBatchByIds(ids); + } + + /** + * 获取物料领料单视图对象 + * + * @param materialIssue 物料领料单对象 + * @return 物料领料单视图对象 + */ + @Override + public MatMaterialIssueVo getVo(MatMaterialIssue materialIssue) { + MatMaterialIssueVo vo = new MatMaterialIssueVo(); + BeanUtils.copyProperties(materialIssue, vo); + List itemList = materialIssueItemService.queryListByIssueId(materialIssue.getId()); + if (CollUtil.isNotEmpty(itemList)) { + vo.setItemList(materialIssueItemService.getVoList(itemList)); + } + String licenseCountFileId = materialIssue.getLicenseCountFileId(); + if (StringUtils.isNotBlank(licenseCountFileId)) { + List ossIdList = Arrays.stream(licenseCountFileId.split(",")).map(Long::parseLong).toList(); + List ossVoList = ossService.listByIds(ossIdList); + vo.setLicenseCountFile(ossVoList); + } + String reportCountFileId = materialIssue.getReportCountFileId(); + if (StringUtils.isNotBlank(reportCountFileId)) { + List ossIdList = Arrays.stream(reportCountFileId.split(",")).map(Long::parseLong).toList(); + List ossVoList = ossService.listByIds(ossIdList); + vo.setReportCountFile(ossVoList); + } + String techDocCountFileId = materialIssue.getTechDocCountFileId(); + if (StringUtils.isNotBlank(techDocCountFileId)) { + List ossIdList = Arrays.stream(techDocCountFileId.split(",")).map(Long::parseLong).toList(); + List ossVoList = ossService.listByIds(ossIdList); + vo.setTechDocCountFile(ossVoList); + } + String certCountFileId = materialIssue.getCertCountFileId(); + if (StringUtils.isNotBlank(certCountFileId)) { + List ossIdList = Arrays.stream(certCountFileId.split(",")).map(Long::parseLong).toList(); + List ossVoList = ossService.listByIds(ossIdList); + vo.setCertCountFile(ossVoList); + } + return vo; + } + + /** + * 构建查询条件封装 + * + * @param req 查询条件 + * @return 查询条件封装 + */ + @Override + public LambdaQueryWrapper buildQueryWrapper(MatMaterialIssueQueryReq req) { + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + if (req == null) { + return lqw; + } + Long projectId = req.getProjectId(); + String materialSource = req.getMaterialSource(); + String formCode = req.getFormCode(); + String projectName = req.getProjectName(); + String materialName = req.getMaterialName(); + String orderingUnit = req.getOrderingUnit(); + String supplierUnit = req.getSupplierUnit(); + String issueUnit = req.getIssueUnit(); + String storageUnit = req.getStorageUnit(); + lqw.like(StringUtils.isNotBlank(projectName), MatMaterialIssue::getProjectName, projectName); + lqw.like(StringUtils.isNotBlank(materialName), MatMaterialIssue::getMaterialName, materialName); + lqw.like(StringUtils.isNotBlank(orderingUnit), MatMaterialIssue::getOrderingUnit, orderingUnit); + lqw.like(StringUtils.isNotBlank(supplierUnit), MatMaterialIssue::getSupplierUnit, supplierUnit); + lqw.like(StringUtils.isNotBlank(issueUnit), MatMaterialIssue::getIssueUnit, issueUnit); + lqw.like(StringUtils.isNotBlank(storageUnit), MatMaterialIssue::getStorageUnit, storageUnit); + lqw.like(StringUtils.isNotBlank(formCode), MatMaterialIssue::getFormCode, formCode); + lqw.eq(ObjectUtils.isNotEmpty(projectId), MatMaterialIssue::getProjectId, projectId); + lqw.eq(StringUtils.isNotBlank(materialSource), MatMaterialIssue::getMaterialSource, materialSource); + return lqw; + } + + /** + * 获取物料领料单分页对象视图 + * + * @param materialIssuePage 物料领料单分页对象 + * @return 物料领料单分页对象视图 + */ + @Override + public Page getVoPage(Page materialIssuePage) { + List materialIssueList = materialIssuePage.getRecords(); + Page materialIssueVoPage = new Page<>( + materialIssuePage.getCurrent(), + materialIssuePage.getSize(), + materialIssuePage.getTotal()); + if (CollUtil.isEmpty(materialIssueList)) { + return materialIssueVoPage; + } + // 对象列表 => 封装对象列表 + List materialIssueVoList = materialIssueList.stream().map(materialIssue -> { + MatMaterialIssueVo materialIssueVo = new MatMaterialIssueVo(); + BeanUtils.copyProperties(materialIssue, materialIssueVo); + return materialIssueVo; + }).toList(); + materialIssueVoPage.setRecords(materialIssueVoList); + return materialIssueVoPage; + } + + /** + * 获取文件数量 + * + * @param materialIssue 物料领料单对象 + * @param licenseCountFileId 证书文件id + * @param reportCountFileId 报表文件id + * @param techDocCountFileId 技术文档文件id + * @param certCountFileId 证书文件id + */ + private void getFileSize(MatMaterialIssue materialIssue, String licenseCountFileId, + String reportCountFileId, String techDocCountFileId, String certCountFileId) { + if (StringUtils.isNotBlank(licenseCountFileId)) { + int size = Arrays.stream(licenseCountFileId.split(",")).map(Long::parseLong).toList().size(); + materialIssue.setLicenseCount(size); + } + if (StringUtils.isNotBlank(reportCountFileId)) { + int size = Arrays.stream(reportCountFileId.split(",")).map(Long::parseLong).toList().size(); + materialIssue.setReportCount(size); + } + if (StringUtils.isNotBlank(techDocCountFileId)) { + int size = Arrays.stream(techDocCountFileId.split(",")).map(Long::parseLong).toList().size(); + materialIssue.setTechDocCount(size); + } + if (StringUtils.isNotBlank(certCountFileId)) { + int size = Arrays.stream(certCountFileId.split(",")).map(Long::parseLong).toList().size(); + materialIssue.setLicenseCount(size); + } + } + + /** + * 根据实体获取替换数据 + * + * @param materialIssue 物料领料单对象 + * @param items 物料领料单明细列表 + * @return 替换 Word 数据 + */ + private MatMaterialIssueWordDto getReplacementDto(MatMaterialIssue materialIssue, List items) { + MatMaterialIssueWordDto dto = new MatMaterialIssueWordDto(); + BeanUtils.copyProperties(materialIssue, dto); + // 领料总数量 + int issuedQuantity = items.stream() + .map(MatMaterialIssueItem::getIssuedQuantity) + .filter(Objects::nonNull) + .reduce(BigDecimal.ZERO, BigDecimal::add) + .intValue(); + dto.setTotalIssuedQuantity(issuedQuantity); + int stockQuantity = items.stream() + .map(MatMaterialIssueItem::getStockQuantity) + .filter(Objects::nonNull) + .reduce(BigDecimal.ZERO, BigDecimal::add) + .intValue(); + dto.setTotalStockQuantity(stockQuantity); + int remainingQuantity = items.stream() + .map(MatMaterialIssueItem::getRemainingQuantity) + .filter(Objects::nonNull) + .reduce(BigDecimal.ZERO, BigDecimal::add) + .intValue(); + dto.setTotalRemainingQuantity(remainingQuantity); + Integer certCount = materialIssue.getCertCount(); + dto.setIsCertCount(certCount > 0 ? "☑" : "□"); + Integer licenseCount = materialIssue.getLicenseCount(); + dto.setIsLicenseCount(licenseCount > 0 ? "☑" : "□"); + Integer reportCount = materialIssue.getReportCount(); + dto.setIsReportCount(reportCount > 0 ? "☑" : "□"); + Integer techDocCount = materialIssue.getTechDocCount(); + dto.setIsTechDocCount(techDocCount > 0 ? "☑" : "□"); + // 明细项信息 + List dtoItems = new ArrayList<>(); + for (int i = 1; i <= items.size(); i++) { + MatMaterialIssueItem item = items.get(i - 1); + MatMaterialIssueItemWordDto itemDto = new MatMaterialIssueItemWordDto(); + BeanUtils.copyProperties(item, itemDto); + itemDto.setNo(i); + itemDto.setIssuedQuantity(item.getIssuedQuantity().intValue()); + itemDto.setRemainingQuantity(item.getRemainingQuantity().intValue()); + itemDto.setStockQuantity(item.getStockQuantity().intValue()); + dtoItems.add(itemDto); + } + dto.setItems(dtoItems); + return dto; + } + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/service/impl/MatMaterialReceiveItemServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/service/impl/MatMaterialReceiveItemServiceImpl.java new file mode 100644 index 00000000..e7de6ead --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/service/impl/MatMaterialReceiveItemServiceImpl.java @@ -0,0 +1,59 @@ +package org.dromara.materials.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.dromara.materials.domain.MatMaterialReceiveItem; +import org.dromara.materials.domain.vo.materialreceiveitem.MatMaterialReceiveItemVo; +import org.dromara.materials.mapper.MatMaterialReceiveItemMapper; +import org.dromara.materials.service.IMatMaterialReceiveItemService; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 物料接收单明细项Service业务层处理 + * + * @author lcj + * @date 2025-07-04 + */ +@Service +public class MatMaterialReceiveItemServiceImpl extends ServiceImpl + implements IMatMaterialReceiveItemService { + + /** + * 查询物料接收单明细项列表 + * + * @param issueId 接收单id + * @return 物料接收单明细项列表 + */ + @Override + public List queryListByReceiveId(Long issueId) { + return this.lambdaQuery() + .eq(MatMaterialReceiveItem::getReceiveId, issueId) + .list(); + } + + /** + * 获取物料接收单明细项视图对象 + * + * @param matMaterialReceiveItem 物料接收单明细项对象 + * @return 物料接收单明细项视图对象 + */ + @Override + public MatMaterialReceiveItemVo getVo(MatMaterialReceiveItem matMaterialReceiveItem) { + MatMaterialReceiveItemVo vo = new MatMaterialReceiveItemVo(); + BeanUtils.copyProperties(matMaterialReceiveItem, vo); + return vo; + } + + /** + * 获取物料接收单明细项视图对象列表 + * + * @param matMaterialReceiveItemList 物料接收单明细项对象列表 + * @return 物料接收单明细项视图对象列表 + */ + @Override + public List getVoList(List matMaterialReceiveItemList) { + return matMaterialReceiveItemList.stream().map(this::getVo).toList(); + } +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/service/impl/MatMaterialReceiveServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/service/impl/MatMaterialReceiveServiceImpl.java new file mode 100644 index 00000000..c2122d67 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/service/impl/MatMaterialReceiveServiceImpl.java @@ -0,0 +1,546 @@ +package org.dromara.materials.service.impl; + +import cn.hutool.core.collection.CollUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.deepoove.poi.XWPFTemplate; +import com.deepoove.poi.config.Configure; +import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; +import org.dromara.common.core.constant.HttpStatus; +import org.dromara.common.core.exception.ServiceException; +import org.dromara.common.core.utils.ObjectUtils; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.core.utils.file.FileUtils; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.oss.core.OssClient; +import org.dromara.common.oss.exception.OssException; +import org.dromara.common.oss.factory.OssFactory; +import org.dromara.common.utils.DocumentUtil; +import org.dromara.materials.constants.MatMaterialsConstant; +import org.dromara.materials.domain.MatMaterialReceive; +import org.dromara.materials.domain.MatMaterialReceiveItem; +import org.dromara.materials.domain.dto.materialreceive.MatMaterialReceiveCreateReq; +import org.dromara.materials.domain.dto.materialreceive.MatMaterialReceiveQueryReq; +import org.dromara.materials.domain.dto.materialreceive.MatMaterialReceiveUpdateReq; +import org.dromara.materials.domain.dto.materialreceive.MatMaterialReceiveWordDto; +import org.dromara.materials.domain.dto.materialreceiveitem.MatMaterialReceiveItemDto; +import org.dromara.materials.domain.dto.materialreceiveitem.MatMaterialReceiveItemWordDto; +import org.dromara.materials.domain.vo.materialreceive.MatMaterialReceiveVo; +import org.dromara.materials.mapper.MatMaterialReceiveMapper; +import org.dromara.materials.service.IMatMaterialReceiveItemService; +import org.dromara.materials.service.IMatMaterialReceiveService; +import org.dromara.project.service.IBusProjectService; +import org.dromara.system.domain.vo.SysOssVo; +import org.dromara.system.service.ISysOssService; +import org.springframework.beans.BeanUtils; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.math.BigDecimal; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.*; +import java.util.zip.ZipOutputStream; + +/** + * 物料接收单Service业务层处理 + * + * @author lcj + * @date 2025-07-04 + */ +@Slf4j +@Service +public class MatMaterialReceiveServiceImpl extends ServiceImpl + implements IMatMaterialReceiveService { + + @Resource + private ISysOssService ossService; + + @Resource + private IBusProjectService projectService; + + @Resource + private IMatMaterialReceiveItemService materialReceiveItemService; + + /** + * 查询物料接收单 + * + * @param id 主键 + * @return 物料接收单 + */ + @Override + public MatMaterialReceiveVo queryById(Long id) { + MatMaterialReceive materialReceive = this.getById(id); + if (materialReceive == null) { + throw new ServiceException("物料接收单信息不存在", HttpStatus.NOT_FOUND); + } + return this.getVo(materialReceive); + } + + /** + * 分页查询物料接收单列表 + * + * @param req 查询条件 + * @param pageQuery 分页参数 + * @return 物料接收单分页列表 + */ + @Override + public TableDataInfo queryPageList(MatMaterialReceiveQueryReq req, PageQuery pageQuery) { + Page receivePage = this.page(pageQuery.build(), this.buildQueryWrapper(req)); + return TableDataInfo.build(this.getVoPage(receivePage)); + } + + /** + * 查询符合条件的物料接收单列表 + * + * @param req 查询条件 + * @return 物料接收单列表 + */ + @Override + public List queryList(MatMaterialReceiveQueryReq req) { + return this.list(this.buildQueryWrapper(req)).stream().map(this::getVo).toList(); + } + + /** + * 根据id导出word + * + * @param id 主键 + * @param response 响应 + */ + @Override + public void exportWordById(Long id, HttpServletResponse response) { + MatMaterialReceive materialReceive = this.getById(id); + if (materialReceive == null) { + throw new ServiceException("物料接收单不存在"); + } + Path targetDir = Paths.get(MatMaterialsConstant.getMatMaterialReceiveFileUrl(materialReceive)); + // 如果存在目录则直接返回,不存在则生成文件并返回 + if (!Files.exists(targetDir)) { + // 清理旧文件 + String baseUrl = MatMaterialsConstant.MATERIALS_RECEIVE_FILE_URL + materialReceive.getId(); + try { + Path dirPath = Paths.get(baseUrl); + if (Files.exists(dirPath)) { + FileUtils.deleteDirectory(dirPath); + } + } catch (IOException e) { + log.error("文件目录:{},清理失败", baseUrl, e); + } + // 准备数据 + List itemList = materialReceiveItemService.queryListByReceiveId(id); + MatMaterialReceiveWordDto data = this.getReplacementDto(materialReceive, itemList); + // 生成文件 + try (InputStream is = getClass().getClassLoader().getResourceAsStream(MatMaterialsConstant.MATERIALS_RECEIVE_TEMPLATE_PATH)) { + if (is == null) { + throw new ServiceException("模板文件不存在"); + } + LoopRowTableRenderPolicy hackLoopTableRenderPolicy = new LoopRowTableRenderPolicy(); + Configure config = Configure.builder().bind("items", hackLoopTableRenderPolicy).build(); + XWPFTemplate template = XWPFTemplate.compile(is, config); + template.render(data); + // 创建目标目录 + if (!Files.exists(targetDir)) { + Files.createDirectories(targetDir); + } + // 组合目标文件名 + String fileName = MatMaterialsConstant.getMatMaterialReceiveFileName(materialReceive); + // 保存修改后的文件 + try (FileOutputStream fos = new FileOutputStream(targetDir.resolve(fileName).toFile())) { + template.write(fos); + } + template.close(); + // 获取附件 + String certCountFileId = materialReceive.getCertCountFileId(); + String reportCountFileId = materialReceive.getReportCountFileId(); + String techDocCountFileId = materialReceive.getTechDocCountFileId(); + String licenseCountFileId = materialReceive.getLicenseCountFileId(); + if (StringUtils.isNotBlank(certCountFileId)) { + List ossIdList = Arrays.stream(certCountFileId.split(",")).map(Long::parseLong).toList(); + List ossVoList = ossService.listByIds(ossIdList); + String baseFile = MatMaterialsConstant.getMatMaterialReceiveFileUrl(materialReceive) + "/合格证"; + for (SysOssVo ossVo : ossVoList) { + OssClient storage = OssFactory.instance(ossVo.getService()); + storage.fileDownload(ossVo.getUrl(), ossVo.getOriginalName(), baseFile); + } + } + if (StringUtils.isNotBlank(reportCountFileId)) { + List ossIdList = Arrays.stream(reportCountFileId.split(",")).map(Long::parseLong).toList(); + List ossVoList = ossService.listByIds(ossIdList); + String baseFile = MatMaterialsConstant.getMatMaterialReceiveFileUrl(materialReceive) + "/出厂报告"; + for (SysOssVo ossVo : ossVoList) { + OssClient storage = OssFactory.instance(ossVo.getService()); + storage.fileDownload(ossVo.getUrl(), ossVo.getOriginalName(), baseFile); + } + } + if (StringUtils.isNotBlank(techDocCountFileId)) { + List ossIdList = Arrays.stream(techDocCountFileId.split(",")).map(Long::parseLong).toList(); + List ossVoList = ossService.listByIds(ossIdList); + String baseFile = MatMaterialsConstant.getMatMaterialReceiveFileUrl(materialReceive) + "/技术资料"; + for (SysOssVo ossVo : ossVoList) { + OssClient storage = OssFactory.instance(ossVo.getService()); + storage.fileDownload(ossVo.getUrl(), ossVo.getOriginalName(), baseFile); + } + } + if (StringUtils.isNotBlank(licenseCountFileId)) { + List ossIdList = Arrays.stream(licenseCountFileId.split(",")).map(Long::parseLong).toList(); + List ossVoList = ossService.listByIds(ossIdList); + String baseFile = MatMaterialsConstant.getMatMaterialReceiveFileUrl(materialReceive) + "/厂家资质文件"; + for (SysOssVo ossVo : ossVoList) { + OssClient storage = OssFactory.instance(ossVo.getService()); + storage.fileDownload(ossVo.getUrl(), ossVo.getOriginalName(), baseFile); + } + } + + } catch (IOException e) { + throw new OssException("生成Word文件失败,错误信息: " + e.getMessage()); + } + } + // 设置响应头,返回ZIP文件 + response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE + "; charset=UTF-8"); + try (ZipOutputStream zos = new ZipOutputStream(response.getOutputStream())) { + DocumentUtil.zipDirectory(targetDir, targetDir, zos); + zos.flush(); + } catch (Exception e) { + throw new OssException("生成ZIP文件失败,错误信息: " + e.getMessage()); + } + } + + /** + * 新增物料接收单 + * + * @param req 物料接收单 + * @return 是否新增成功 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean insertByBo(MatMaterialReceiveCreateReq req) { + MatMaterialReceive materialReceive = new MatMaterialReceive(); + BeanUtils.copyProperties(req, materialReceive); + validEntityBeforeSave(materialReceive, true); + getFileSize(materialReceive, + req.getLicenseCountFileId(), + req.getReportCountFileId(), + req.getTechDocCountFileId(), + req.getCertCountFileId()); + boolean save = this.save(materialReceive); + if (!save) { + throw new ServiceException("物料接收单新增失败", HttpStatus.ERROR); + } + List itemList = req.getItemList(); + if (CollUtil.isNotEmpty(itemList)) { + List materialReceiveItemList = itemList.stream().map(item -> { + MatMaterialReceiveItem materialReceiveItem = new MatMaterialReceiveItem(); + BeanUtils.copyProperties(item, materialReceiveItem); + materialReceiveItem.setReceiveId(materialReceive.getId()); + materialReceiveItem.setProjectId(materialReceive.getProjectId()); + return materialReceiveItem; + }).toList(); + boolean result = materialReceiveItemService.saveBatch(materialReceiveItemList); + if (!result) { + throw new RuntimeException("物料接收单明细项新增失败"); + } + } + return true; + } + + /** + * 修改物料接收单 + * + * @param req 物料接收单 + * @return 是否修改成功 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean updateByBo(MatMaterialReceiveUpdateReq req) { + Long id = req.getId(); + MatMaterialReceive oldMaterialReceive = this.getById(id); + if (oldMaterialReceive == null) { + throw new ServiceException("修改物料收货单失败,数据不存在", HttpStatus.NOT_FOUND); + } + MatMaterialReceive materialReceive = new MatMaterialReceive(); + BeanUtils.copyProperties(req, materialReceive); + validEntityBeforeSave(materialReceive, false); + getFileSize(materialReceive, + req.getLicenseCountFileId(), + req.getReportCountFileId(), + req.getTechDocCountFileId(), + req.getCertCountFileId()); + boolean update = this.updateById(materialReceive); + if (!update) { + throw new ServiceException("物料接收单修改失败", HttpStatus.ERROR); + } + List oldMaterialReceiveItemList = materialReceiveItemService.queryListByReceiveId(id); + if (CollUtil.isNotEmpty(oldMaterialReceiveItemList)) { + boolean result = materialReceiveItemService.removeByIds(oldMaterialReceiveItemList); + if (!result) { + throw new ServiceException("物料接收单明细项删除失败", HttpStatus.ERROR); + } + } + List itemList = req.getItemList(); + if (CollUtil.isNotEmpty(itemList)) { + List materialReceiveItemList = itemList.stream().map(item -> { + MatMaterialReceiveItem materialReceiveItem = new MatMaterialReceiveItem(); + BeanUtils.copyProperties(item, materialReceiveItem); + materialReceiveItem.setReceiveId(materialReceive.getId()); + materialReceiveItem.setProjectId(materialReceive.getProjectId()); + return materialReceiveItem; + }).toList(); + boolean result = materialReceiveItemService.saveOrUpdateBatch(materialReceiveItemList); + if (!result) { + throw new ServiceException("物料接收单明细项新增失败", HttpStatus.ERROR); + } + } + return true; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(MatMaterialReceive entity, Boolean create) { + // 做一些数据校验,如唯一约束 + Long projectId = entity.getProjectId(); + String materialSource = entity.getMaterialSource(); + if (create) { + if (projectId == null) { + throw new ServiceException("项目 id 不能为空", HttpStatus.BAD_REQUEST); + } + if (StringUtils.isEmpty(materialSource)) { + throw new ServiceException("物料来源不能为空", HttpStatus.BAD_REQUEST); + } + } + // 查询项目是否存在 + if (projectId != null && projectService.getById(projectId) == null) { + throw new ServiceException("对应项目不存在", HttpStatus.NOT_FOUND); + } + } + + /** + * 批量删除物料接收单信息 + * + * @param ids 待删除的主键集合 + * @return 是否删除成功 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean deleteByIds(Collection ids) { + List itemList = materialReceiveItemService.lambdaQuery() + .in(MatMaterialReceiveItem::getReceiveId, ids) + .list(); + if (CollUtil.isNotEmpty(itemList)) { + materialReceiveItemService.removeBatchByIds(itemList); + } + return this.removeBatchByIds(ids); + } + + /** + * 获取物料接收单视图对象 + * + * @param materialReceive 物料接收单对象 + * @return 物料接收单视图对象 + */ + @Override + public MatMaterialReceiveVo getVo(MatMaterialReceive materialReceive) { + MatMaterialReceiveVo vo = new MatMaterialReceiveVo(); + BeanUtils.copyProperties(materialReceive, vo); + List itemList = materialReceiveItemService.queryListByReceiveId(materialReceive.getId()); + if (CollUtil.isNotEmpty(itemList)) { + vo.setItemList(materialReceiveItemService.getVoList(itemList)); + } + String certCountFileId = materialReceive.getCertCountFileId(); + if (StringUtils.isNotBlank(certCountFileId)) { + List ossIdList = Arrays.stream(certCountFileId.split(",")).map(Long::parseLong).toList(); + List ossVoList = ossService.listByIds(ossIdList); + vo.setCertCountFile(ossVoList); + } + String reportCountFileId = materialReceive.getReportCountFileId(); + if (StringUtils.isNotBlank(reportCountFileId)) { + List ossIdList = Arrays.stream(reportCountFileId.split(",")).map(Long::parseLong).toList(); + List ossVoList = ossService.listByIds(ossIdList); + vo.setReportCountFile(ossVoList); + } + String techDocCountFileId = materialReceive.getTechDocCountFileId(); + if (StringUtils.isNotBlank(techDocCountFileId)) { + List ossIdList = Arrays.stream(techDocCountFileId.split(",")).map(Long::parseLong).toList(); + List ossVoList = ossService.listByIds(ossIdList); + vo.setTechDocCountFile(ossVoList); + } + String licenseCountFileId = materialReceive.getLicenseCountFileId(); + if (StringUtils.isNotBlank(licenseCountFileId)) { + List ossIdList = Arrays.stream(licenseCountFileId.split(",")).map(Long::parseLong).toList(); + List ossVoList = ossService.listByIds(ossIdList); + vo.setLicenseCountFile(ossVoList); + } + return vo; + } + + /** + * 构建查询条件封装 + * + * @param req 查询条件 + * @return 查询条件封装 + */ + @Override + public LambdaQueryWrapper buildQueryWrapper(MatMaterialReceiveQueryReq req) { + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + if (req == null) { + return lqw; + } + Long projectId = req.getProjectId(); + String materialSource = req.getMaterialSource(); + String formCode = req.getFormCode(); + String projectName = req.getProjectName(); + String materialName = req.getMaterialName(); + String contractName = req.getContractName(); + String orderingUnit = req.getOrderingUnit(); + String supplierUnit = req.getSupplierUnit(); + String storageType = req.getStorageType(); + lqw.like(StringUtils.isNotBlank(projectName), MatMaterialReceive::getProjectName, projectName); + lqw.like(StringUtils.isNotBlank(materialName), MatMaterialReceive::getMaterialName, materialName); + lqw.like(StringUtils.isNotBlank(contractName), MatMaterialReceive::getContractName, contractName); + lqw.like(StringUtils.isNotBlank(orderingUnit), MatMaterialReceive::getOrderingUnit, orderingUnit); + lqw.like(StringUtils.isNotBlank(supplierUnit), MatMaterialReceive::getSupplierUnit, supplierUnit); + lqw.like(StringUtils.isNotBlank(formCode), MatMaterialReceive::getFormCode, formCode); + lqw.like(StringUtils.isNotBlank(storageType), MatMaterialReceive::getStorageType, storageType); + lqw.eq(ObjectUtils.isNotEmpty(projectId), MatMaterialReceive::getProjectId, projectId); + lqw.eq(StringUtils.isNotBlank(materialSource), MatMaterialReceive::getMaterialSource, materialSource); + return lqw; + } + + /** + * 获取物料接收单分页对象视图 + * + * @param materialReceivePage 物料接收单分页对象 + * @return 物料接收单分页对象视图 + */ + @Override + public Page getVoPage(Page materialReceivePage) { + List materialReceiveList = materialReceivePage.getRecords(); + Page materialReceiveVoPage = new Page<>( + materialReceivePage.getCurrent(), + materialReceivePage.getSize(), + materialReceivePage.getTotal()); + if (CollUtil.isEmpty(materialReceiveList)) { + return materialReceiveVoPage; + } + // 对象列表 => 封装对象列表 + List materialReceiveVoList = materialReceiveList.stream().map(materialReceive -> { + MatMaterialReceiveVo materialReceiveVo = new MatMaterialReceiveVo(); + BeanUtils.copyProperties(materialReceive, materialReceiveVo); + return materialReceiveVo; + }).toList(); + materialReceiveVoPage.setRecords(materialReceiveVoList); + return materialReceiveVoPage; + } + + /** + * 获取文件数量 + * + * @param materialReceive 物料接收单对象 + * @param licenseCountFileId 证书文件id + * @param reportCountFileId 报表文件id + * @param techDocCountFileId 技术文档文件id + * @param certCountFileId 证书文件id + */ + private void getFileSize(MatMaterialReceive materialReceive, String licenseCountFileId, + String reportCountFileId, String techDocCountFileId, String certCountFileId) { + if (StringUtils.isNotBlank(licenseCountFileId)) { + int size = Arrays.stream(licenseCountFileId.split(",")).map(Long::parseLong).toList().size(); + materialReceive.setLicenseCount(size); + } + if (StringUtils.isNotBlank(reportCountFileId)) { + int size = Arrays.stream(reportCountFileId.split(",")).map(Long::parseLong).toList().size(); + materialReceive.setReportCount(size); + } + if (StringUtils.isNotBlank(techDocCountFileId)) { + int size = Arrays.stream(techDocCountFileId.split(",")).map(Long::parseLong).toList().size(); + materialReceive.setTechDocCount(size); + } + if (StringUtils.isNotBlank(certCountFileId)) { + int size = Arrays.stream(certCountFileId.split(",")).map(Long::parseLong).toList().size(); + materialReceive.setLicenseCount(size); + } + } + + /** + * 根据实体获取替换数据 + * + * @param materialReceive 物料接收单对象 + * @param items 物料接收单明细列表 + * @return 替换 Word 数据 + */ + private MatMaterialReceiveWordDto getReplacementDto(MatMaterialReceive materialReceive, List items) { + MatMaterialReceiveWordDto dto = new MatMaterialReceiveWordDto(); + BeanUtils.copyProperties(materialReceive, dto); + // 接收总数量 + int quantity = items.stream() + .map(MatMaterialReceiveItem::getQuantity) + .filter(Objects::nonNull) + .reduce(BigDecimal.ZERO, BigDecimal::add) + .intValue(); + dto.setTotalQuantity(quantity); + int shortageQuantity = items.stream() + .map(MatMaterialReceiveItem::getShortageQuantity) + .filter(Objects::nonNull) + .reduce(BigDecimal.ZERO, BigDecimal::add) + .intValue(); + dto.setTotalShortageQuantity(shortageQuantity); + int acceptedQuantity = items.stream() + .map(MatMaterialReceiveItem::getAcceptedQuantity) + .filter(Objects::nonNull) + .reduce(BigDecimal.ZERO, BigDecimal::add) + .intValue(); + dto.setTotalAcceptedQuantity(acceptedQuantity); + Integer certCount = materialReceive.getCertCount(); + dto.setIsCertCount(certCount > 0 ? "☑" : "□"); + Integer licenseCount = materialReceive.getLicenseCount(); + dto.setIsLicenseCount(licenseCount > 0 ? "☑" : "□"); + Integer reportCount = materialReceive.getReportCount(); + dto.setIsReportCount(reportCount > 0 ? "☑" : "□"); + Integer techDocCount = materialReceive.getTechDocCount(); + dto.setIsTechDocCount(techDocCount > 0 ? "☑" : "□"); + // 明细项信息 + List dtoItems = new ArrayList<>(); + for (int i = 1; i <= items.size(); i++) { + MatMaterialReceiveItem item = items.get(i - 1); + MatMaterialReceiveItemWordDto itemDto = new MatMaterialReceiveItemWordDto(); + BeanUtils.copyProperties(item, itemDto); + itemDto.setNo(i); + itemDto.setQuantity(item.getQuantity().intValue()); + itemDto.setShortageQuantity(item.getShortageQuantity().intValue()); + itemDto.setAcceptedQuantity(item.getAcceptedQuantity().intValue()); + dtoItems.add(itemDto); + } + dto.setItems(dtoItems); + // 设备材料入库/移交 + String storageType = materialReceive.getStorageType(); + dto.setStorageType1("□"); + dto.setStorageType2("□"); + dto.setStorageType3("□"); + if (StringUtils.isNotBlank(storageType)) { + List storageTypeList = Arrays.stream(storageType.split(",")).map(Integer::parseInt).toList(); + for (Integer type : storageTypeList) { + if (type == 1) { + dto.setStorageType1("☑"); + } + if (type == 2) { + dto.setStorageType2("☑"); + } + if (type == 3) { + dto.setStorageType3("☑"); + } + } + } + // 封装数据 + return dto; + } +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/service/impl/PgsProgressCategoryServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/service/impl/PgsProgressCategoryServiceImpl.java index a568db31..511a4d36 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/service/impl/PgsProgressCategoryServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/service/impl/PgsProgressCategoryServiceImpl.java @@ -12,6 +12,8 @@ import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.utils.DateUtils; import org.dromara.common.core.utils.ObjectUtils; import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.utils.BigDecimalUtil; +import org.dromara.common.utils.JsonDimensionUtil; import org.dromara.facility.domain.*; import org.dromara.facility.service.*; import org.dromara.progress.constant.PgsProgressCategoryConstant; @@ -35,8 +37,6 @@ import org.dromara.progress.service.IPgsProgressPlanDetailService; import org.dromara.progress.service.IPgsProgressPlanService; import org.dromara.project.domain.BusProject; import org.dromara.project.service.IBusProjectService; -import org.dromara.common.utils.BigDecimalUtil; -import org.dromara.common.utils.JsonDimensionUtil; import org.springframework.beans.BeanUtils; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; @@ -338,7 +338,6 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl matrixList, List oldMatrixList) { - List oldMatrixIdList = oldMatrixList.stream().map(FacMatrix::getId).toList(); // 获取模板进度类别 List categoryTemplateList = pgsProgressCategoryTemplateService.lambdaQuery() .in(PgsProgressCategoryTemplate::getProjectId, projectId, PgsProgressCategoryConstant.PUBLIC_PROJECT_ID) @@ -351,7 +350,9 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl> oldPercentageCategoryMap = new HashMap<>(); Map> oldPlanMap = new HashMap<>(); Map> oldPlanDetailMap = new HashMap<>(); + List oldMatrixIdList = new ArrayList<>(); if (CollUtil.isNotEmpty(oldMatrixList)) { + oldMatrixIdList = oldMatrixList.stream().map(FacMatrix::getId).toList(); List oldPercentageCategoryList = this.lambdaQuery() .in(PgsProgressCategory::getMatrixId, oldMatrixIdList) .ne(PgsProgressCategory::getPid, PgsProgressCategoryConstant.TOP_PARENT_ID) @@ -473,7 +474,9 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl percentageFacilityLqw = new LambdaQueryWrapper<>(); - percentageFacilityLqw.eq(FacPercentageFacility::getMatrixId, oldMatrixIdList); + if (CollUtil.isNotEmpty(oldMatrixIdList)) { + percentageFacilityLqw.eq(FacPercentageFacility::getMatrixId, oldMatrixIdList); + } long count = percentageFacilityService.count(percentageFacilityLqw); if (count > 0) { boolean remove = percentageFacilityService.remove(percentageFacilityLqw); diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/materials/MatMaterialIssueItemMapper.xml b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/materials/MatMaterialIssueItemMapper.xml new file mode 100644 index 00000000..58eaffb1 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/materials/MatMaterialIssueItemMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/materials/MatMaterialIssueMapper.xml b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/materials/MatMaterialIssueMapper.xml new file mode 100644 index 00000000..ec3b6c40 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/materials/MatMaterialIssueMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/materials/MatMaterialReceiveItemMapper.xml b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/materials/MatMaterialReceiveItemMapper.xml new file mode 100644 index 00000000..3ce551d7 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/materials/MatMaterialReceiveItemMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/materials/MatMaterialReceiveMapper.xml b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/materials/MatMaterialReceiveMapper.xml new file mode 100644 index 00000000..9fa02c79 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/materials/MatMaterialReceiveMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/xinnengyuan/script/sql/menuInitValue.sql b/xinnengyuan/script/sql/menuInitValue.sql index 231b4791..039f6d25 100644 --- a/xinnengyuan/script/sql/menuInitValue.sql +++ b/xinnengyuan/script/sql/menuInitValue.sql @@ -947,3 +947,163 @@ values(1940723160391405573, '设计变更管理删除', 1940723160391405569, '4' insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) values(1940723160391405574, '设计变更管理导出', 1940723160391405569, '5', '#', '', 1, 0, 'F', '0', '0', 'design:designChange:export', '#', 103, 1, sysdate(), null, null, ''); + +-- 菜单 SQL +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941027796600016898, '物料领料单', '1940386534691717121', '1', 'materialIssue', 'materials/materialIssue/index', 1, 0, 'C', '0', '0', 'materials:materialIssue:list', '#', 103, 1, sysdate(), null, null, '物料领料单菜单'); + +-- 按钮 SQL +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941027796600016899, '物料领料单查询', 1941027796600016898, '1', '#', '', 1, 0, 'F', '0', '0', 'materials:materialIssue:query', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941027796600016900, '物料领料单新增', 1941027796600016898, '2', '#', '', 1, 0, 'F', '0', '0', 'materials:materialIssue:add', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941027796600016901, '物料领料单修改', 1941027796600016898, '3', '#', '', 1, 0, 'F', '0', '0', 'materials:materialIssue:edit', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941027796600016902, '物料领料单删除', 1941027796600016898, '4', '#', '', 1, 0, 'F', '0', '0', 'materials:materialIssue:remove', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941027796600016903, '物料领料单导出', 1941027796600016898, '5', '#', '', 1, 0, 'F', '0', '0', 'materials:materialIssue:export', '#', 103, 1, sysdate(), null, null, ''); + +-- 菜单 SQL +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941027798210629634, '物料接收单', '1940386534691717121', '1', 'materialReceive', 'materials/materialReceive/index', 1, 0, 'C', '0', '0', 'materials:materialReceive:list', '#', 103, 1, sysdate(), null, null, '物料接收单菜单'); + +-- 按钮 SQL +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941027798210629635, '物料接收单查询', 1941027798210629634, '1', '#', '', 1, 0, 'F', '0', '0', 'materials:materialReceive:query', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941027798210629636, '物料接收单新增', 1941027798210629634, '2', '#', '', 1, 0, 'F', '0', '0', 'materials:materialReceive:add', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941027798210629637, '物料接收单修改', 1941027798210629634, '3', '#', '', 1, 0, 'F', '0', '0', 'materials:materialReceive:edit', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941027798210629638, '物料接收单删除', 1941027798210629634, '4', '#', '', 1, 0, 'F', '0', '0', 'materials:materialReceive:remove', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941027798210629639, '物料接收单导出', 1941027798210629634, '5', '#', '', 1, 0, 'F', '0', '0', 'materials:materialReceive:export', '#', 103, 1, sysdate(), null, null, ''); + +-- 菜单 SQL +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941028782785744898, '物料领料单', '1940389874213339138', '1', 'materialIssue', 'materials/materialIssue/index', 1, 0, 'C', '0', '0', 'materials:materialIssue:list', '#', 103, 1, sysdate(), null, null, '物料领料单菜单'); + +-- 按钮 SQL +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941028782785744899, '物料领料单查询', 1941028782785744898, '1', '#', '', 1, 0, 'F', '0', '0', 'materials:materialIssue:query', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941028782785744900, '物料领料单新增', 1941028782785744898, '2', '#', '', 1, 0, 'F', '0', '0', 'materials:materialIssue:add', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941028782785744901, '物料领料单修改', 1941028782785744898, '3', '#', '', 1, 0, 'F', '0', '0', 'materials:materialIssue:edit', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941028782785744902, '物料领料单删除', 1941028782785744898, '4', '#', '', 1, 0, 'F', '0', '0', 'materials:materialIssue:remove', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941028782785744903, '物料领料单导出', 1941028782785744898, '5', '#', '', 1, 0, 'F', '0', '0', 'materials:materialIssue:export', '#', 103, 1, sysdate(), null, null, ''); + +-- 菜单 SQL +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941028820853248002, '物料接收单', '1940389874213339138', '1', 'materialReceive', 'materials/materialReceive/index', 1, 0, 'C', '0', '0', 'materials:materialReceive:list', '#', 103, 1, sysdate(), null, null, '物料接收单菜单'); + +-- 按钮 SQL +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941028820853248003, '物料接收单查询', 1941028820853248002, '1', '#', '', 1, 0, 'F', '0', '0', 'materials:materialReceive:query', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941028820853248004, '物料接收单新增', 1941028820853248002, '2', '#', '', 1, 0, 'F', '0', '0', 'materials:materialReceive:add', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941028820853248005, '物料接收单修改', 1941028820853248002, '3', '#', '', 1, 0, 'F', '0', '0', 'materials:materialReceive:edit', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941028820853248006, '物料接收单删除', 1941028820853248002, '4', '#', '', 1, 0, 'F', '0', '0', 'materials:materialReceive:remove', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941028820853248007, '物料接收单导出', 1941028820853248002, '5', '#', '', 1, 0, 'F', '0', '0', 'materials:materialReceive:export', '#', 103, 1, sysdate(), null, null, ''); + +-- 菜单 SQL +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941030734919684097, '物料领料单明细项', '1941027796600016898', '1', 'materialIssueItem', 'materials/materialIssueItem/index', 1, 0, 'C', '0', '0', 'materials:materialIssueItem:list', '#', 103, 1, sysdate(), null, null, '物料领料单明细项菜单'); + +-- 按钮 SQL +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941030734919684098, '物料领料单明细项查询', 1941030734919684097, '1', '#', '', 1, 0, 'F', '0', '0', 'materials:materialIssueItem:query', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941030734919684099, '物料领料单明细项新增', 1941030734919684097, '2', '#', '', 1, 0, 'F', '0', '0', 'materials:materialIssueItem:add', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941030734919684100, '物料领料单明细项修改', 1941030734919684097, '3', '#', '', 1, 0, 'F', '0', '0', 'materials:materialIssueItem:edit', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941030734919684101, '物料领料单明细项删除', 1941030734919684097, '4', '#', '', 1, 0, 'F', '0', '0', 'materials:materialIssueItem:remove', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941030734919684102, '物料领料单明细项导出', 1941030734919684097, '5', '#', '', 1, 0, 'F', '0', '0', 'materials:materialIssueItem:export', '#', 103, 1, sysdate(), null, null, ''); + +-- 菜单 SQL +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941030735251034113, '物料接收单明细项', '1941027798210629634', '1', 'materialReceiveItem', 'materials/materialReceiveItem/index', 1, 0, 'C', '0', '0', 'materials:materialReceiveItem:list', '#', 103, 1, sysdate(), null, null, '物料接收单明细项菜单'); + +-- 按钮 SQL +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941030735251034114, '物料接收单明细项查询', 1941030735251034113, '1', '#', '', 1, 0, 'F', '0', '0', 'materials:materialReceiveItem:query', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941030735251034115, '物料接收单明细项新增', 1941030735251034113, '2', '#', '', 1, 0, 'F', '0', '0', 'materials:materialReceiveItem:add', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941030735251034116, '物料接收单明细项修改', 1941030735251034113, '3', '#', '', 1, 0, 'F', '0', '0', 'materials:materialReceiveItem:edit', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941030735251034117, '物料接收单明细项删除', 1941030735251034113, '4', '#', '', 1, 0, 'F', '0', '0', 'materials:materialReceiveItem:remove', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941030735251034118, '物料接收单明细项导出', 1941030735251034113, '5', '#', '', 1, 0, 'F', '0', '0', 'materials:materialReceiveItem:export', '#', 103, 1, sysdate(), null, null, ''); + +-- 菜单 SQL +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941032197632929794, '物料接收单明细项', '1941028820853248002', '1', 'materialReceiveItem', 'materials/materialReceiveItem/index', 1, 0, 'C', '0', '0', 'materials:materialReceiveItem:list', '#', 103, 1, sysdate(), null, null, '物料接收单明细项菜单'); + +-- 按钮 SQL +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941032197632929795, '物料接收单明细项查询', 1941032197632929794, '1', '#', '', 1, 0, 'F', '0', '0', 'materials:materialReceiveItem:query', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941032197632929796, '物料接收单明细项新增', 1941032197632929794, '2', '#', '', 1, 0, 'F', '0', '0', 'materials:materialReceiveItem:add', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941032197632929797, '物料接收单明细项修改', 1941032197632929794, '3', '#', '', 1, 0, 'F', '0', '0', 'materials:materialReceiveItem:edit', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941032197632929798, '物料接收单明细项删除', 1941032197632929794, '4', '#', '', 1, 0, 'F', '0', '0', 'materials:materialReceiveItem:remove', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941032197632929799, '物料接收单明细项导出', 1941032197632929794, '5', '#', '', 1, 0, 'F', '0', '0', 'materials:materialReceiveItem:export', '#', 103, 1, sysdate(), null, null, ''); + +-- 菜单 SQL +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941032233947213826, '物料领料单明细项', '1941028782785744898', '1', 'materialIssueItem', 'materials/materialIssueItem/index', 1, 0, 'C', '0', '0', 'materials:materialIssueItem:list', '#', 103, 1, sysdate(), null, null, '物料领料单明细项菜单'); + +-- 按钮 SQL +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941032233947213827, '物料领料单明细项查询', 1941032233947213826, '1', '#', '', 1, 0, 'F', '0', '0', 'materials:materialIssueItem:query', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941032233947213828, '物料领料单明细项新增', 1941032233947213826, '2', '#', '', 1, 0, 'F', '0', '0', 'materials:materialIssueItem:add', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941032233947213829, '物料领料单明细项修改', 1941032233947213826, '3', '#', '', 1, 0, 'F', '0', '0', 'materials:materialIssueItem:edit', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941032233947213830, '物料领料单明细项删除', 1941032233947213826, '4', '#', '', 1, 0, 'F', '0', '0', 'materials:materialIssueItem:remove', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1941032233947213831, '物料领料单明细项导出', 1941032233947213826, '5', '#', '', 1, 0, 'F', '0', '0', 'materials:materialIssueItem:export', '#', 103, 1, sysdate(), null, null, ''); diff --git a/xinnengyuan/script/sql/xinnengyuan.sql b/xinnengyuan/script/sql/xinnengyuan.sql index fc5132c7..555dfdb0 100644 --- a/xinnengyuan/script/sql/xinnengyuan.sql +++ b/xinnengyuan/script/sql/xinnengyuan.sql @@ -1437,3 +1437,111 @@ CREATE TABLE `des_design_change` index `idx_project_id` (`project_id` asc) using btree comment '项目id' ) comment '设计变更管理' collate = utf8mb4_unicode_ci; +DROP TABLE IF EXISTS `mat_material_receive`; +CREATE TABLE `mat_material_receive` +( + `id` bigint not null auto_increment comment '主键id', + `project_id` bigint not null comment '项目id', + `material_source` char(1) not null comment '材料来源(1甲供 2乙供)', + `form_code` varchar(50) null comment '表单编号', + `project_name` varchar(255) null comment '工程名称', + `material_name` varchar(255) null comment '设备材料名称', + `contract_name` varchar(255) null comment '合同名称', + `ordering_unit` varchar(255) null comment '订货单位', + `supplier_unit` varchar(255) null comment '供货单位', + `defect_description` text null comment '缺陷情况(承包单位填写)', + `cert_count` int default 0 null comment '合格证份数', + `cert_count_file_id` varchar(1024) null comment '合格证文件', + `report_count` int default 0 null comment '出厂报告份数', + `report_count_file_id` varchar(1024) null comment '出厂报告文件', + `tech_doc_count` int default 0 null comment '技术资料份数', + `tech_doc_count_file_id` varchar(1024) null comment '技术资料文件', + `license_count` int default 0 null comment '厂家资质文件份数', + `license_count_file_id` varchar(1024) null comment '厂家资质文件', + `storage_type` char(1) null comment '设备材料入库/移交', + `remark` text null comment '备注', + `create_by` bigint null comment '创建者', + `update_by` bigint null comment '更新者', + `create_time` datetime default CURRENT_TIMESTAMP null comment '创建时间', + `update_time` datetime default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP comment '更新时间', + primary key (`id`) using btree, + index `idx_project_id` (`project_id` asc) using btree comment '项目id', + index `idx_material_source` (`material_source` asc) using btree comment '材料来源' +) comment '物料接收单' collate = utf8mb4_unicode_ci; + +DROP TABLE IF EXISTS `mat_material_receive_item`; +CREATE TABLE `mat_material_receive_item` +( + `id` bigint not null auto_increment comment '主键id', + `project_id` bigint not null comment '项目id', + `receive_id` bigint not null comment '接收单id', + `name` varchar(255) null comment '名称', + `specification` varchar(255) null comment '规格', + `unit` varchar(255) null comment '单位', + `quantity` decimal(10, 2) null comment '数量', + `accepted_quantity` decimal(10, 2) null comment '验收', + `shortage_quantity` decimal(10, 2) null comment '缺件', + `remark` text null comment '备注', + `create_by` bigint null comment '创建者', + `update_by` bigint null comment '更新者', + `create_time` datetime default CURRENT_TIMESTAMP null comment '创建时间', + `update_time` datetime default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP comment '更新时间', + primary key (`id`) using btree, + index `idx_project_id` (`project_id` asc) using btree comment '项目id', + index `idx_receive_id` (`receive_id` asc) using btree comment '接收单id' +) comment '物料接收单明细项' collate = utf8mb4_unicode_ci; + +DROP TABLE IF EXISTS `mat_material_issue`; +CREATE TABLE `mat_material_issue` +( + `id` bigint not null auto_increment comment '主键id', + `project_id` bigint not null comment '项目id', + `material_source` char(1) not null comment '材料来源(1甲供 2乙供)', + `form_code` varchar(50) null comment '表单编号', + `project_name` varchar(255) null comment '工程名称', + `material_name` varchar(255) null comment '设备材料名称', + `ordering_unit` varchar(255) null comment '订货单位', + `supplier_unit` varchar(255) null comment '供货单位', + `issue_unit` varchar(255) null comment '领料单位', + `storage_unit` varchar(255) null comment '保管单位', + `defect_description` text null comment '缺陷情况(承包单位填写)', + `cert_count` int default 0 null comment '合格证份数', + `cert_count_file_id` varchar(1024) null comment '合格证文件', + `report_count` int default 0 null comment '出厂报告份数', + `report_count_file_id` varchar(1024) null comment '出厂报告文件', + `tech_doc_count` int default 0 null comment '技术资料份数', + `tech_doc_count_file_id` varchar(1024) null comment '技术资料文件', + `license_count` int default 0 null comment '厂家资质文件份数', + `license_count_file_id` varchar(1024) null comment '厂家资质文件', + `remark` text null comment '备注', + `create_by` bigint null comment '创建者', + `update_by` bigint null comment '更新者', + `create_time` datetime default CURRENT_TIMESTAMP null comment '创建时间', + `update_time` datetime default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP comment '更新时间', + primary key (`id`) using btree, + index `idx_project_id` (`project_id` asc) using btree comment '项目id', + index `idx_material_source` (`material_source` asc) using btree comment '材料来源' +) comment '物料领料单' collate = utf8mb4_unicode_ci; + +DROP TABLE IF EXISTS `mat_material_issue_item`; +CREATE TABLE `mat_material_issue_item` +( + `id` bigint not null auto_increment comment '主键id', + `project_id` bigint not null comment '项目id', + `issue_id` bigint not null comment '接收单id', + `name` varchar(255) null comment '名称', + `specification` varchar(255) null comment '规格', + `unit` varchar(255) null comment '单位', + `stock_quantity` decimal(10, 2) null comment '库存', + `issued_quantity` decimal(10, 2) null comment '领取', + `remaining_quantity` decimal(10, 2) null comment '剩余', + `remark` text null comment '备注', + `create_by` bigint null comment '创建者', + `update_by` bigint null comment '更新者', + `create_time` datetime default CURRENT_TIMESTAMP null comment '创建时间', + `update_time` datetime default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP comment '更新时间', + primary key (`id`) using btree, + index `idx_project_id` (`project_id` asc) using btree comment '项目id', + index `idx_issue_id` (`issue_id` asc) using btree comment '领料单id' +) comment '物料领料单明细项' collate = utf8mb4_unicode_ci; +