From f076ee1b83c71afdee5544ec7028510081caf52c Mon Sep 17 00:00:00 2001 From: alvarsanmartin Date: Mon, 16 Mar 2026 16:08:13 +0100 Subject: [PATCH] Errores por pantalla + logs en archivo --- electron.vite.config.ts | 14 +-- resources/icon.png | Bin 35949 -> 54294 bytes src/config/base.json | 4 + src/main/LogService.ts | 74 +++++++++++++++ src/main/handlers.ts | 115 +++++++++++++++++++++++ src/main/index.ts | 73 +++----------- src/preload/index.d.ts | 10 +- src/preload/index.ts | 7 ++ src/renderer/index.html | 2 +- src/renderer/src/assets/main.css | 5 + src/renderer/src/components/MainView.vue | 97 +++++++++++++------ src/services/NfcService.ts | 19 ++++ src/types/Result.ts | 27 ++++++ tsconfig.node.json | 2 + 14 files changed, 351 insertions(+), 98 deletions(-) create mode 100644 src/config/base.json create mode 100644 src/main/LogService.ts create mode 100644 src/main/handlers.ts create mode 100644 src/types/Result.ts diff --git a/electron.vite.config.ts b/electron.vite.config.ts index 65d4397..69207f3 100644 --- a/electron.vite.config.ts +++ b/electron.vite.config.ts @@ -11,12 +11,14 @@ export default defineConfig({ "@renderer": resolve("src/renderer/src"), }, }, - plugins: [vue({ - template: { - compilerOptions: { - isCustomElement: tag => tag === "nfc-reader", + plugins: [ + vue({ + template: { + compilerOptions: { + isCustomElement: (tag) => tag === "nfc-reader", + }, }, - }, - })], + }), + ], }, }); diff --git a/resources/icon.png b/resources/icon.png index cf9e8b2c87b5c18ac0b26913af6fd3ed00ec3bfb..2367ff28cdc00b9af0f43c798af0d2ea72bd073b 100644 GIT binary patch literal 54294 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 R;GqBj002ovPDHLkV1gWJflL4Z literal 35949 zcmY&<1yq#Z7ws?%!qAO$cb9^IfOH5*hcrreOAR0(-6bO3($YwXw4~B05=u)q@AA|C zTkoyKTDsQEcjw%DPwcbL{=(H%;{AmV&&rIs^g*|Aj)(?ty=fyuM#RAT$sK zX-Q2lqwP!-H_cv>o_4HG!-y6lc{FVfFK16rRu$GHXu)>_ef{}`1ET&dtp>R9bkS7yxbLD_(`?Yv1@6*RG zRru5;zWy@~N3!QRfI%9--U(!cV9Dkt%+<;ZopDyOQEXe2Rb z=Qru__u_Mn&Oep1VCJLQ=@1qKCOR9*Wx<-Hw)okLYFXXd&u0B*fr4d3eNdX}APmL7 zRz@*94MN{leRiSH-hxMFt$D%dRL%^3QsH12T=t#qwhq!0Aml47O-wpz&dyUC^y%3; z&HB-43Oo%xVnXliYJK1FLbtq^lek^$jo0~Hj+97OtN#}=)IJzQ;>5RGUD})U*}P3% z3PcSq@hF;tmHEH@^E?c6g=p(>q&%&>x_&@C)3O%P)aCB)_BaCqTg4u>kCwo~P{Zs9 z8X&v!Y*uBz8)T`a|9irR z_*G_{9J-s1)m&Iu3;zABfn?cG?v4;r1V#G`ky0YA$+e6Wmc#EnuW>iL`MAe zAaXy$cYk^ETd2>&K&eV4$c=Bq(zuxFCL&mg#g$L$>!3!7 z5Q`Dg=kp^t2jT4@MT?eE8Gr5g0^>--#|!M2!w$83;G8s&Ra^gL}BgTY;hRHVGi+=vyF?xs9iIn;8e!20g zL~9_|*dg{?8}Pgbeo&gM3(l&eh7R=}0tBDz-yd9JG6`}2L^NsiG7F2x9lF2Ka+8I` zaIiBMp7+;P_IaQUrZSHFl~_D4pm9wmonB+_&-#n}EA~&TMBe{M_%Fb&vJl&ZUR3=Q4_&Hp!~jC|~bI{`nh-aR_W^i%InnHqOFHSWLZ&tyw9IMy_I6 zl~cQ~YiY@vzR>)yS@=$3fvMUUuc)!HNPk^a(C>{2z$GNq_HiMGL(ov?|E)%VhKYrP zasCDFFW4d=1I5K96vdE`8XBwpU*vmH1DeoFej@YlE2S`wst@9X_2nN*7oTMg-koZv zxv7kS9P&$_eaIma5BK|Zn09Qb#GC_Il-i??>{g?i{_>eGo_Q57_EMq%= z!zE&}m#H}=s4a0`-~3CL9R_H+f&O7#PuiT;z23crToH!?cdgc<$>Ha$fC#1mCD%}C$Ekem621q&vaTLk5LXx}a_!LS5YRli0 zyZ;i}^1jtuB}^E8?&UjrXOAsHfPU}Ej)R&^xzZ@+D_9q3zWU8Zv)_r)B#2oQ*O zoz$H{&a$YA0sk|l7WTo4+@HsyHU8&A0i-@EO_oaPD~nC>_;|^2l7Bls6AGNed&Ao639{hHL>{a4t(+qq!?zJL9rY9~|+U4Y|X5N*Y_s{h}rGE8d{ zxE3j8I(I?(V<8TKaV`onLxh8Z!t@cbb#6~M|6NiX;t+V9De$^xo8OWe&^Ug}u_!!$yh~FV zQO-;?rGGBLuq+KFoY$_$-Xn42- zb>a9l9=XzQ$oQG47TWADU!8BKdn3QJ0C%E~_8nxKc;t)iw=Uq!`MsJaf|xwS)Ip9n zA%j{UuF6cBb;r>eczjVwnm$=>I6J>)ZnKP~`Z2a+P;aq3UHDX})`xl5u*vMLGY>8} zNkJ$v`%8*P_s2D5%99|g16o28N@Z(kh{nIxI8g`M6+D)17WIy2ZA4rB)@Ia#`wC)t zy4#s<*y41(3jgFV4ffwr2ctSO_%I_S)nHsRRjz)Q2IuiQ0K~LRyIBnT9=Mf#YG}sit|y9{;F^&mi>fa^iKmGG)G&)}-N%>Ewfy?KCrh+Z1+r9_+i{l`0 zVx)Plis#oGn7jl@pmGR$-a5{;TV1kjk>_qz@~K#xciv9U?E|G7{|Bwcxv-j4u1KM9 zg00QH?=d^N^9`{T^>&~-nTUcTVZ6TO1EYyg{JPKLDgc(!lsdwC+<;(i=UB!M5fX|Q)n9X1R1 z{hfSD`W|`vKye8|`ml*6EO}=tdSN3+c_|2f( zHLR&jTPJ>2;2nyZtPCw&C{u#)OE>{>{fRiUw+yHxeOf}X-8M5DN5#_sWpo(8trkui zE>dq)#EOexPvLv%qG>ko7CtF4^&x^(E3Q{ zNr-(NmpF;Q+QT$)d~y&nEb^S~SGz?E&s}&_*GAeUPR3s(tvsr=WhOrPU7lY6e4!&8 z_Th~0%A^km#JE~~38F5Ypex4~pC-@~mu0dU3;ls6`xSlIpS~Q?iYmgHn!G=6o(&jc zRp??@8nvoTYJf{$#)PI=|1h0<%g%U*ljh1LXf0n$W&tZs;C)2_=_qQ|YfAx<<{7J_ zDpP4GhXC2`hS&P&s(uyJ3H=l&u?pkph>|4oKKWG`nxj*_82i2yusO6!p0 ze@X9uu&U@Es#PAfp-RPW9gUl8H-$v~y}W33UW^apBDBhj7TB_LClQr#r^DK zG5JFW-}6(h8-C;tGKfkm)a@x09cI=O8Kx4M!p0Kl7fJHtG`=hOqii^S!P7|X#6q^F zL_*j{9P&^ z6HOv7$HoA%c4jENGm^Z%u@}2*JIU(q?XgG2@#{D}A%zZXX9LfRv^!yQ`o=zWDIK!< zRZqbDHDeI!E0MiNqx|sJM2Rax*8Q;~J;kI4(d3Z}hZG`5awU1~;VTRZK_{;3?1C-s zyBrqG9l_)ela2_1Lkfi5beEbnJxvh8-i zow)eX9NCBSy7q)gmS^M2>0@@=UN1Zk_Lo|$kWRRsLu{pAyNIBJK#QU`34hb){A)CZ zeoqUjFuwqYZ# zoWHT7h0qZIQ`r(UHHVO!S~MOXwfHCgRSr7)a&TZ&BHG8dqD0~2`C12$>m|iR8-F*m zo~Tob&>ELNQmmF?dQ@%CUa#^FVX!gs`=m1z`0Fg1bcgzx{B(T)$NdXc0K9dJ^Cw33 zaO^8em;eMwK%^v|YMxT>0;i9I-5L-(}I1ew1v9J8ly;_Vi%&Mt&@@zrsj|8 z->nW`J2!f-M^&8Ml>%I0K%KPm%Xb8$F$}&XdMXz^LFha^K%^_;m0kFNZG~#fuz~Ar zaiUCD#0oOJGgpRBCJ4?L9hk@>k^36ZxP$tU0M^9nTF`UF2U?=?BSYQjD@x$7StkXOYdpi~NXk7H_5-I%hc z&LtpmhD#Ja3Bl7WU|VgW%2=$Xte_N+VIbwpmAJmw_pI;()x&_g89~c>dqW5yBqYR< zh9SQ!ds7&eA3$GOA}zwMjynC`&D3GY-JVevc}N?r@~f-#g^kkP!>}v~PQz=o+pL&j-xJE0d1K1lt8*sT>KoqcxwrD? zQ;XN1BUUp;d4%pC0-9Ivgs_p@U5?P!J@!IVN3yPabuN6VrxOsTd@sirM*a+CRBg97 zx;0pWqj~|3%J+QJb(>060w0{xS1Z0jo`R>gqOI z1m{6=Vs-G4g$~oIwJeR)dmg{67G7vxS?T0?`lF9MFoE(Bt-{68+u2Wew~t+5C!9vb zWt`;k2<|(UEm9}b{6rDjRH`X6qdG4_#5HlTe)21Z`E+;FjH8!Q=RCJ^w-zPEcY=gj zs{Z$8Mznm#6dDiGejWSppI3r`Q79NWE?I4Fs6^@qdr6ypNhh%=x1HLn@tLHD_WUIx zwuRl!$N4X_%jh4_A>lB0z&g6PX}XvL0|)>dWRIvjN8>BlMfdr$8eYy5`z-n1(wBLY zQQUm&fdX4J4RM=ja!Zvhn?YHIWp;2TX9LOWLVht46{Qn2kz4rr%D+EWD}}T#9ImhQ z{MJzUo#$|iB%jKi^>V3UIIAnjNbJvYkNc4Q3?K(X?gFf7oT5k-KhEBR`g@t95-jTD z;Ex~ms@Kf*4!q;``E8|s*PJ!P>=jK}u9qjKzo-2ET=f(DeLV2)@x}p)yb*#osT}F{ zkHns;;i_+Z4S8LnVQY4<*^Mz*dJ}1y(};U=(ZXJ?8K%;w(-O1JrN<)A&-Y-T_RbA{ znYjY@3YBQJ=#S@6B4$udCWEUNJb5ywWAo(=If*Bi;pc_HRHuz`nfXr)OWZ%6{6cEz zVxMWFe_X7g<4R$`{PatV9=||?IWqpf$6W|sqr3VtEX%-3{m%s#xu2;YzWH0xJ!~C% z?=dV7-TCz4#M-oc2L@b#>=Bd|87dIHebG;lcB+RX?`;MuS%)oH$cq`UHC}{)#k^+O zYx%5iQU%fr8}+z!3AiHs5MblfjeQh!a4+&efN*oV&lIZ8&aKJbQc!b*-^C$O=$yZk#(rolnUAz35xnu0&+PAGy;Q zcOQR_9H5OyRN~3MKlb~6{Q{EP8=fb6#4Z?Ezr|;vpXJ^rt$B=CnxE zOt_j&=mYMTngoGy)*6`N-D(;T!bAX2KorsYdOQW-ngdA>mjwe^>*?d`K@P;%d!zr4 z&nF;A2;LC0r|f7+fSi&n=gnt9ZXtHJ*XTPRX<4D*hI8WEk!}pGcHQMv<%|(ZpC=jo3>_r%HkSfn75sf(X!0w+ z7>XBztg-qpAr?#k+q6AFz!8Xg#k&G0sIO#-q{_ zTR|OS80+Rg)1JM($WDWa-W`N$i&<1ENYea)r+gODT{&H}Awink6N9N~GbP9sS&vHS zib7$c3E-Qtt#+7z5|LmJ{QUH7j(lXwzz}wYQOMH0o6-+OasU5nBuKYbV|KNW{u&D{ z2k{~wo#&Vs8h7CLy)-x&W<$;%MS%Zs|7*&Vx!W{PobA5Ja@-pEA?4JVqbqd4?h@-V z9S;oDpeelKb188PHcj28u5Q1}Wzb&@yaM0RxXW%y?A=1(5HM+JZ~_#dnmgOO3%dK> zs#?PC49mQCarL#pEE`l&S-jCl7*#b(I6?=P_wt&HsPTDFzzr5QVqyjXP@fF@I1GLM zm?B1x+SB93o9#&0I~8E)H@sS8U;#fqc$mfj`ofkb8rFK3p&XkMC;)ARV1nvfB5}PA zHQO!9vf2zb!{^}#tG;Y|6a@mVqvUQ?Cpm-$H)>`}8hDHZ`Ltj+x981WfYNJ!e*FfI z85XkUyiQ{PwotdqBX+eh#a-rCJXGI1`>)SGniHucUQo;2H&=!!ny`qymGQ zXWOj_|7;RD7&jtBNVuolZf}=1{v358hxyi4@7=|f$kc3Hylf;XMt{vqzw2a1_5{nJ zh}R|G?yt-#tLz$n3ff{;oy87razEj4crOw;w=t5zD&1p-i&S0eS*mq8nQAQPEa~ja`-QmZ;{%3fWhN#g0JL>(g=V*N{)Zk zTP9(QpwgjQTJOKUZ1lbmaL5#ij705nGMm$Gef8(_&)#k%NS*%`oD_pt{mGy0F?wa& zse7jtMq1R0NGP454zW1>FIb>F~3rD=OrKu&+iKVRjq@R8M;4UrrUDH$g&F3q` z{|LUSM{V~lp~~5`W!W=q3d*dtq_dk)G$wDJihg(*R`9Gz)p*U>K7)^R&Qe)pGP25~ zs|R$E(S;9&@s(EC6t=f4meV+C<8;gfmgqn%H&mP&$Ys#HV6$LRTdoXi8~7}e>+_Vx zVwUi=a)u&>!+%|@I?BD-m&N!63c+6e2|vG9WD2#t;E%D>tz^wz|H-ucDJnf_cD~6C z{%y9tC(?2x>4>gW+=*v=b)fu%XWjnU`qQ{d^Nfd`WOzR|cW1K5L6|uqyVbgpGArQE z<*@J_vljBT2azw@`1gaQyW; zRbAh8%&WHC)z)6hu`XknMdW-2YMbwX&b8Z(=j*L7tnR=UN=d~%3I|mBQCV;9JO5<+ z%^gDhdAq_e=_6f2c|hloKFih+jVNi&PNl{2+Tq4av~b@0@*t`Md4{$XZ;IC{v=>f@ zn4R(Y!#3lqd6As1YWkV4+|D0MT=<^bEfM6)|E~JhlFDuRq?T#GU(xgCzPHVH%}MU- zb#_3+$>=S)tXRwu>#6eV?a@`HMW{kTuMXKDyu!J3%?l;zDLia^XpGZfOek=I7Mh0=8 zuTkT6SL2#9YXsGhW=rjzy*@r9yr8FHiQY9nSJ6}~;NX6uzCc%(K||7!qjW$ejHTAK zzEa59(0|Vc{ld}gd_kdl=~3?2_7#{9IdckZ?Ow ziNyId!MFWrqwA(^r=|9URtZWI-m&$XX3RKT@@kdUt9wko^q2M9c z`kq(*CiaU2Ha~tMo0Bo}(}w?P0Z^wtd@cw^rQGbzAY)d@q9R4_OBoL;oZh=xzHsNb z%6-TnIbm~dGbK}kO_`kW)NbsncIuMy%d+@5je6zvkAA5-n8Oc*os?|MURUU@Z&&7{^>*m&T zWn|gHyeTZos9GP7tq27p>biG4q`W_Sb!^(5x2?9*#Z?uyxSkDA2-7G8wuZ*lg*-GOZ;9_$T*2R&-I}GgA30B7Xt6W!U&Se&L{T~MJ=}Qz zRDvo(FM?2JJ-0hIS7QVt2W7nEFK zP_gs+<#K{xkX5%yd#M6;_to2QTQ<4f!Edf>Nj~wni1#n*g(Fn1urTu9Z`)cC2+{4e z9B!O|3Durqiu%@|X5ZB}J2~9OvX!!_eJ?+A5d&L}MTi@-cmpGXk(9tZd zwMX;mZL=$MsZf%O)D=h6LF`Nhh6gZ?kQ&j!t?$l$HC`$mPz z^{D}Lg6zQ>H;$h$&)U&2rN?DqhbLOvi-_CFbJs>(vWUnW zR3}zZ3LJ;$p64>7>TNpzLFNYCi0zs9hL`qz3gNQTO`m-JTo&Wi|NLmZeuqyfraB!6 z5B5``jBt&j`ZB-N<^F4*`k%J3cGDe-M%eL3Z9Tj1R~j<)sL3KQOi}G{{DpHT7no|P z_%O0<^dqrLF5HV$UcwG0KD=Nb*)Hzy3YhU+;)6R8=1cCRL+-=I(;ZfSEZH6D8W4%f zZ7;u_m=^P_|FNe?86IxGpd_(L*+;B?o{;>bqMp1+_0vrfHL=Yl7rb;vc@n9Z%Ofch zaxgqc{?vo4KT2Z!YdR$vRU#y8pL8}2j>r*;_GH2d5SI9Ymssx8vN0U^Zd-;P382Kw zhdBNdxpJ~`iLUD-+cVLwJ}1+Ue=Gf9sm-AH!47CnWg8^p8S^SlUl)Q>aPI7Opj6NpR4p$*9@_o?`kiC4Z6m)Vy%BUscX2Zro;=Bh^KXM4gIUbo)k7kqBM={yjQcCDSkFahG}#fH;<^%L*@|`HQNz=PGF}zkTzKl{lKN z##5_+LI;xNYB==XVM`FFyq~Yf0zAmYSFxf3rVh}KSGkW%7a610y3=f>40!C^(`)@O zfz4qMbli1R={-J6eGHNh!2*iL`T;P`>4ZO^p! z?^aU7 z+TUUS9-Mr+iOC?JtO)P?I!x)bR(u&r%8FuJCGUvubUN^2t_%UNJShd&0!A6+VOuwK{NWAK&)tR5!WJD?^?~h#U+bOq50gCfGK{LOHnE%PaBQ&D&0I z6J+5u#$rXS1@>~SFb>owl#5kVMfG9D5B{)bZkHAxbf+qsr%2Vm3^=Gxm^6@im5BHU z1RcA<*cJe;!vgs(tE;ds*&F2L(ZH(Pl?Lesjg!8=Bq&qVp43&EV?ITptFc^ zM^w#`*8ZRtYgTX2n5*xJ{#KOyagl925hmK^Lvr|dD<;Eo*o&Q5BPtS($lwnCkT#@M z_qLEFCE%7b#(uWA1grbKOa~E;zxVW@lrhy!0&Mg<+V_h;%*ER3^8yZ-9wQlL>(h~1 zpOqS|dG%atR&DEMh&laBuEhbQcW5QIsBGWn)V>y=&8axA6UV*=7Cfu9wZwPo4mK`4 z1=Zr)wZIMxP(V10bDnB8UJgq}U-wEpVh{;ZIK)KOi})cKHX_WX&P$Jl>daeEV`t}c z_>r7`9<$EY2%-x*KmMYiv_){SQw&~`ilGg;}DLDN3Eum7J<}H#RK!xYqMw4 zoCmO(>a8~U>+rWFOAZgYeZeQMhMx$gR3t6^FYD#FiqUPY5~zb~H*m_Pll@;!l7 zzl6)<^0RkK8|yv=bl4w^7FbSYVeVV3(R6^`>V$poHt{spd4n`#c`cT*sF< zRcSy!xvcVho+|J9acoOl^kh7Wk){%|s)dN4)UPG8y?2#McMOlFpwV3ashZR~pa*%O z`8GruB0$ey7?{$$a)rVZ+CrjUZWnJ6DKhpA zBU!!q+C$;Hjxe^9&1gi;T5`G*u>@%{6Dc3eN1uIe;{p2@p$QWk9OsvNdHsF7iqU&U&9C7@6Af2v!pG3~6g>p! z%gyvJV_QwWuaiOnonagqDiunvWsILrx~l2vvPx|Jb+F$K zM(kr1zekXu_Ju?1Npc087&HP>(%_^MVXAQf`m6i;=7Y#N-A8e`MIIWR`@LSM^N?nhqSHoPiN+N2q+;m(96yL|2 zvyEocMl@KLec8XMv%Npn7zl=mmwl$bw)ASPg9jg{~~ zo`2-2t*829?vDHXu`u@HH@b8z<(xz82-V{+eY1kNe>Rg1IZ-N@X$&sVAK1N_4#y{- zYH*8#Y69g1;0rmKxOT%QICS^i) zN$6a#@r^v`i&%%H8nLrePQBM8s_*ZwrTEWF(AWY>^Q2Bc`4N{{A6~r` z1s#HM5M!V}w11g#a2iYe)b+BD3=j<6^&PPW7nq&aip(+wb+S3KHpw^Zev_0Nr+W|A zgyu<;Qrsa*?dRwRJ~FORVENuN*1DKX9=u0ijf?Y>GxQxC-fqG32Qx-a_Ej_a`{ITf z)8_;|u}55ZUKciH=JzL)AERPxqq`iQRo7nzov7YT9Y(Ewp)qp&9bkx(NWh6LAr#%K zx|bGuHMzg7>hic>;GA8UN>OaZl?&qS#}Y4`ET<~^%T5nkj#Sz1+RagWpFbSBgiA*f zVNi1$lnAI%*^>)1m6VUYe5+sZy=!aAbYkQ>$xGwN1NsihsdE7o3mzN)+dOsExk8nm zli%NxJ`xJ6(3p2VsSj)a&hYT_>Z+_aNZ0{y9r3Kh-0$HR)&y{Md}7z(X)EFFFMNm> z1GHt$T*d_g`L?~W=C67^6!jy(H6By-Y1NSdm{&-MycNQ3>Y__1rb0pJF#ffw-0$74 z=UIYRYjCMw`{zr>3GJfTVl7J5y`|GLUUD&r0)zpt$`aJx?ol?Po&Gad5ttD2a*#p3 zRirk{cWL{rkrnQCL{e~paI8d%SvT%{zVPB;QvVMXp@lu3CzZ}>+5S?5xAOK#dqIn0 z&K@HUm831tkmGeA2W%4EjYMi8<1K>95DH7HDX9=DF+5#KPJ_&`Cgch#F`Fr7lv(%} z#WdW`r*COJkI81q<;H`)U5A<+kulf2`MArCoYYh6J`USXD>!L0=+8-gV}X~=aZi(% z3Bs0?1`$%}m&DQEd>(77NqwqE(<8ZZYtI$N)1MTO`_Y>6Wazhl7~ZRbV8E2+9Ig~7 zn*Vgj>f`NKL7#b+W2OwzWC4KeT|zJw5b}_ML9FHhU*i+K)>r51Ah!IV&WTJiPTyYk z>5cu-xD;A&%xb7)fBcr0{7)itL!@M>M2x-WQpNBT4B$nd?sN1Gl-4>9?1T``nvRfl zp+Jfk17Ki4{3c5@q-$6u)K04JW65)HUJ832YS$TiaRpYq1(GqP1{eVMJsZD>cmqe+ zRtkWS+2>mNgzCcfo?N`p-w?p@Zz#{a9ZA%ODy8R6&axfE!cfnz`psV}X9j`6hRAj# zc59YIPR~=dk1uQs0=X_$T;DA=Nhxfx(=kCRK8*w8I$HjX{M1!HIG4ZvU7ibI)il-3 z?}K&suXrYxKRMh5fUGZJ;L6Z#p_$3j9JNYwr!f zI`k}V*Bj&yQ|it5*&dWBF+YFoqAQ~~)Q;BI?{}~tODf(bWw&a0TW_sVm9eHzx$-MA z`bCjK?|EcWsK3pn2gglK>>Ut@4#k!mKuEN7`Q5C-foR7^rT z6Zg-E(iIap%rk!iopXV_rvYeGMX z>Q5AVVk2$|&F<-^P2QHQoG+?Oz)68>f3_e%(JHmOT;+b@M_COBnpvuw)XzA=E1~uZ z9kO?W3fM#29BFgeBJ9RjQ6cTH6pHri{?etS#)U_o*og*ZyxK0m^1$VBHSX(UBhUVY z>03d?q74|gzsBrwZbY%Qk81VH(c-&OUn-wIzaKU41_N9gu2$QbI%~y5`;i)HC+Ub2s#Dyz7551W5 zT6^C~b%^V``PL}zXov+Y-3DNRIWfLg`<4FhT#DzP(A%-Dw7|6xKpK{iDc8B5Y`=!@ z^mKM}#?xO^nOm;9J0;&CsJ+t1wi$h zX)a^*#iw8v%+)NldHo32`mmU&=*PhFtubNAnsK3$&YISQW6L|{2K(;9KR=x|R!~R` zojraI!ahqtKh^*$>Hg>;7keuGre>3kz!hyR$0(SEH$e& z>njn^ad9<^1hMHz0vRIPaZhq5Li0E=EC7g9lG0?D63U+(RNR6&ARt|6;lF6(TJ+tM z&d&%63a|VEqDy*T)m<=yX-(%DQ*_d_`jG?R`<}an<$uLP$acxH9ItP&2iGO3_>+%z zkx$N1-QYMLm@pP(#L!8>^M?{q0l3d!{WcY_gp%NUkV*<65&^oW6#w%2A@%MoZreMQ zu&LzEUgA<<*4E4?^lEz=NE3tylC(MrOPE$B*yoGfU|GP|ZU$ot7vN+k}$Z!^|~z*b}UHBUwzCZG4^KJZzOWDib!Ibi2=R)qdB0Jm@M zOhKmZ>CfJk&w4-0trCEPuh5e#AGl5T6|p5M9wMmfTPuU93l`N(#bU z@pLT-5W|(W)DDJqRr^n?Js0hpUPo5*{~6tCinfpE4@ zFDF<13wdu$&-?S|%VjVn$uBSoq=a~UVPf4FRPE|y@#{DAi4M zsld8)+!ea~I~etqVHM?_;uR25V{RX3(+L2N%Fsblew<_tq~OuxqZ|ISST1oSL-&Dq zM*S$>W;EzmFCIT-XS^PZ4lwD)Sz@&olRPr&QI0#!-Fxx1SY+PN^`+?{tS)iV&GU08 zg9#)M!2G-}(YiWTzH9DEB;TQr?~>Tyw~ew``=BTqcddT>!-wQVHrq$ps~88NBq^pe z`vZF3s0y84b|YjU-3fUlejFBX^sD)eLAmx^(aq@Epj(|KJ-!oaAk~&XDhF|kq48ti z`?ZgEEp#^Qp?dVRwv3v}FK_OeQ=kHs0hSX=lCqW^e&d$U5^qmXa`eKA`v>X9z32%R z0L`!!hI6N}ce^x^x?A^u)v3kb>F2$k2OliK!a+S@wOY%x(GR>98#qHkcjs(gvaK)}&D{cFsq zN~ecRV~gb5ZFBpbn)HA~jcgY%0!=q^;YklbcDHZE)JQ!mraYK(%wF9a&k0Vu?(bF9 z=YO+_L$N*jpdIjMl8To=aq|rhz$~GR{zrAPP;Me*MUZcgQL&z_&|x56To_M6$D;10 zs=Dt778wqcF?A>Y>5a+;778^Cj|lY;2a#>7Wo<%rVqfh4)S3gSro=FMvRYfOr6QMK z$^Ez#($C*SJk7>P77dBCe&2Hr0*H(tyR_L(zz(Lqj;5AC{g24WcMt31RwQ)0eHt*9 z8`j`p)~{pyMCB+i9?^h1n(*sVkvAJCuky|t!$G_7^f%w_11kvjMMo2hA`d1pFA~rF zVq#Bk+wVX-(840<4a9puItLeKo3yml1otTDnxs&G@1661v<|hRg2{{g}oBuO?v9j4%T_%xR!U zOqkTlz3;q|dx(GC?X9vi?T~TOAS>O-W^p0~<)R0V_`2QIYH?$hdxV@XmFJ3X&sf!2 zc;SZCm|LNk+T-f^nV`|y`HE@(tkj%&wMmUy}M$j6>c}c?vxwc^- zC*mjxEwH)k>VVYkS+dAel84snA2S4X8g6&K6`9U`?{A)~rG>`rxFNA7#y zLDQCxsb+BMc6`SB_1Cl!c>CcIfRCf_;l7vZOgaN=rPI|Qr8H&Wpee@jG0rMyl;At$ zlkNVVh>pP$i$kPzw{_WScGrgCh&d&lNDcod4$bp#oJmn2sB%rYY3Dzo&kcej;JZk| zRJt*6?K;xTM~(J%zAJ7(e7Zt7p>~^>czS&&J9HQcWmvX`+1!lcq@xpQqx(Gn8QK^y zx5~oIKC4*k}y<6F1<#PSK0Oy?@pkUf6NfCd^vd3UP}27 zDS?&mW_)fz{LOlx8+i7yK);*kw-3;^2r*iQ{IaIKE_i zrED8#Or2d)6`(D_3d8&+BA{%03#>Y7Qx$9utjbZv8?D*%>z^`SS*Xw_t6r>hG zdS>3ENjCLwW(>+K#od5|*FUtL3*hk8QgyAFjn9uiIlr7zdGU$L6d=)2t7&<$r}p+t z4Gw_@8(vA34hXwnf52d^B2u055nHtRG50lI+hogdD~`h?#hvmY+E{w=5k@X%N5~UU zZ(rM2mgT4O-?4geHO*`upi$=7oRgC&RibAUF;GpfC@U9uJNf~>Yt)wCB1V2Ee?#Li zMk0E=RUnY`ue>LHd{3j8@EF;GMEav{b<$_|wXcQh5=LBRP?H*r=gmqwt0hKK!lf^k z{G)#wJYe6_3gP|PEmb6=q_uWC7HzLf4MvYs|DCb{ngy3Sp<$Ck6)a&ogYMOD?O&l@!7n&;(SUqM!JEYe{TFE0!D|=4{sJw5`QVg;j`8!- z8}T3e&2^#OV>aWO42l`rsp5`Y7P%N`4QnJ z>2v^k#I5cHJ^sEnRQ;ar08&}nHY6?+^4>w;_J(@l3{|_a>2paD{}h2Z0YvQk^U*@k z-S!z*wz;SRt~^M}_K3Qlol@)e!oY%6`+3tyI|gbB`w+pkTf8~FBQvg8KCvy)|Fi%e zc5ZsjPps3_ktMV{eQLTRvO4Pbxg|?A2fET0cFdnY@=^m_{hc!Ie%F{2ca5j^OQh9C zLn4s|NAC60?Hsyj%{+IEm8DF~GHuckYVpa1hrk^g2+rJg?&)4#ZDVVcLKFohRO|8W z=V${y-5ZcXGpNJ2Ma2SVY()XUY)`eoyhimTb&g4wtfIg1`TtJ<7STcW4uTS1mVvg%%J{t-#?adaU&EdfVXUKh)OI}&8){=Y{h`#u3?OJYMt z2~W!O+0H*|wD*y#xvjS!OC_Gx&O{_h8sJVG-aRUqefwiEv!0T-= zM!y!AA>Rk(VpU(fA9hQtHL8NO@`WjoU_oYrPEm}MJs*2#y#bNJ31CkE=WzKUbm;? z)t-N1-QyQYymI<%)AAMh5aQ+|-W??bW+zqwrW0lFKgCzrLjRgv!2 z1D5Hk>UICRVLq!}1QsS^T#1_L_p44pxzd3f`r>p^@h-oxA-iF z&N{0Vg&qSNznber%~}dlq+%9ve|#2qz4ibBGuMD7$y*<5=9u1gM13 z$IN@34RD{c;|pKpmh0!KXnmS8YK-LnRP`26 zQGVa|@XRoD2m%7qAg!Q)bPV0yASqIUC?YKkN(o3vNq0BWAfQNhcS?6i*Z<oJIsuPY(_81ePR9@1=I9-A8v*SdELjEX6+J`2-wrO-b>deljRzgZ z7Lan%?CXkthvaBX|5VHH*1lDsHhs8MjUqMuMZWpxhaK5m#-S~B_`0Ar=Zrw zm{$CcEtOA-s!8uzU^%+oyXv^t>YDt%Q|l(H`ok_BNQ}{+J&3|TDu9XB0HDa@Dl^dC zMp2PQs&dOp$Sg9KPN+f{9@KdGQ}am;*Vl5_gS1(}kU!V%wr^|SwX}TPQGxtbUThrAo)l)%69G0Nqf~tOX7Y@2vr`BH7NfTC0`RCp@SypoWxKZBZbO zEQ)xIb(&l-wAvRcAbOSN2(@@WjTv)?T6<7HA;WSY`B&MCMfg^N@Q|MAK=F^;z>hOb zxntvTg2IVTGBA8pw%hOnNTIkZQpfAz51?U^O%MNzZqJMKFrCW=%Fs-t+m5TdZ~Z3Gcg^a+_z{GS=U!- zl4`HK+*a|XJiX$a37D_d42W{(`nf;Gji<5fJX_k#oFr@OU8AOi>s?U}-QT0JoJ$@e$h16c zc%>gJ`zw=dMHE85^6)2#Qq$dy_IDUhS{k<4PVD_L9A{V z!ayM<(rU^Gv!}!+YX5ToIYVK38aUn0r>}qGuF>O~C!x^)rmsOB*dqt7&tI&Np$4dV z_W}5*7IM1y<71`D4Pf8{()KGLUP5MVr-t19g8o5>)GC}1qz6C;`YPSWQa1A-tb(ZM zag7eZYYL`EW_=I$+pO-nsH0gp08UDTaSHE3CJsi)`*YCHf<>mjM8zJ+AT{)Eq?wD! z%oS9D#(07H5i1B=pTE^P(|XM4_cV+*3B${;O`RWf0&||g^Gf}mh*-$#QOl^AbUzkb z?m`@o)^)~(#s>gVWBJq!U`0KtuzOi2fF%BY%cC`{M@DY&+oh$ z)LI)L^d@GNo_uvP$T0qR`g>3}_nmfs@&|pr6e3s%Is7u*7~$apm;@^No?1+47;9|e^Zey>9Bl&Yiv*U6zzPT@6A-G%)ODR zvS+IzNR=lpN%y)8Ar|#4?%)8S9$!$6&Hx(c=sJuoohw}j6#p2;b<$cpL$wYwBEGh$ z<(6eu&blM=$L4-F&x}yo3kIfaEn-5d9hL$Xt_D-xf$6^H@T&XXCiew?O9iOU=-9HE z!}#-XQ0_0jp<(clxflk7$8!8sSThQsvchfPkbMAA|MUkWNaMm@RP5AvI^h~9&KEZe1|jc^L_L_Po;AL5Np@WOmvqgNi4ABM zs^x^A|7?67&tnGCa2u+q=w|s}XFo>r_okYRpPn?Mfs6(asFw1cX*tuq{;R<*$9LEu zS0abugK|{SqjibwxGbqm~ZRFgpl9C(aqX*5*7~0xpg(HUVVM*WgMIxNbfGx=5gkuX5_Q zI+e}nPHNuSTS^G&C>*(mJ^4-=iaCDE68lvp3;5vS#ZHFH7?cx-9Lad`A%jM&F1u-{ zr_YHt8`z8=5MpIw1aF;!!x`!W{%YrCtR1785AHhbzZVJ(7=yIoS@Q0I z^1G>wshS$Azg9QU?Z~~BSZbGCD`=_j2oFER;{Ry#z${ODU2GG z^{8W2U&bypUg-Wsj6bveq^yP5ZdJf*i*!E&dE_`Hb>DVLPyh@CfVV*K@!27Y&KJ zoQ@&QOCWB3-Ggau9r43DqcuWo_hXC^m7An5G6fvP8z$d5*2K@{qxWtv)6&+?mxk-y z4Ity75_qJa$IYYX+IWyn9aT;gj!Xwv;gj#5Kem3mD)t@vG4lJy%&}!L%E(WK@H4&X zsynxsWHI)20^H*RG8)DCr*`2lP;>G4fQ`QX&-Shf#43s##6}kxBGcoBzO#XvB+F(6 z2HVljVe(I!yzQ9xC%Awmm%$3!`P4@PTC`rjZ8u-${TM4Tid$@0?E_k6 zpKb}h%~g((X&-U&J)j4t%#aPEGB_Fvy3$f8x#Ea2|%Tc3}T%iw9Ue%Jqb3J}do!fF7v8XGFAhLt#F z9rakv9RK$C>+LwKw9alAp6!Oqz#Fa=}H7denIA9MDAQZIT+5#B^ny8w0m}-ufjqaSf6yePoJ6bZ>wPK z|Oyhc{7u*dcsFftc;cixS*gnSkXMSM3# zr?X3{cR~pTi4Hivm*%H~<`B1<7UnMkS0J|t0Gu|>SKt3^a=ZbGwin;IeDy^pE(P&& zpD`2TSU;HGhA$l@QS7|vqnfS`DaGBKir8O$U_uHW#V>VuRrYAe+ojQMi`2rAb4)Fj z*!@TvF>z3f=C#~z+PytM2^57xBS}DBPKe?7wF**7$WTeXF_JFxB>gQqh&!@P%wYcq z)8#g+oL`>Nx^HRO0m13`HZFpX^O2oOZbR z(lY+o>}%O9YX`ZkY* zOHqozI<*ijN#7$4dN(FfW18=-EZ)4ji#Zvbwg!fvzikB`6MAbxy{-5h ztJP)y>68H6E8B!|J3}cs%`)KhL0jU1ni&l|&@X`bMwMIOcjQA{8B)fk_10wVyKQA) z;RIn8SPVA7w?0ue?!HGwavkK&-6>90Q`xIGPssiog})b_Cfbh83d zzGlz^F{EU?G@mG&KH@4pRgxPnyM3q4#?TDS2E> z(p$ANEolWm=3n%A7!Uo4!m_9x{bi$oSYRYL1QD6Fh8B0VL|mKz-p7Eb=h$ESNrc;6 zof2~1duYz<1NziF*B$9}dPfw748MIWIgJ4wfQ*HM7|L+8aV>hA4KWnzNdad4*;S}) zEIqbZBjuw6Y))9*y^uIe}y_LqjiUEzDex-2;S*8}x zK-K1NC#(9D6SQW68SESo*(pa1lQ=z7RAt-Ot$53Z`oFy&=;>B) zBO&Jsct46Z14P9}4Vr`QaXE;Oe$2DdcJ9Mdtrnx-2!yuv9~-UWxBqJa^5yW~nT6S! zg$|m2yX^uqJ|r*gHik0Nw=pwARhX~xxx<_TGGyg}^L@9Ak3WX4Q~Z-UU1s6zw@ip% z^YH@{W^Vv6rfK?z$ctDyZ+}prQeD@ueoW+w16&Gwy(VY_B@tUR6Y2KsU-*{W>`1%q zjr6C@FkEQ!qSpV-*`BE_1=rn!L}{1>?Vf2{Z@WQ$r8?hp^3mqomO8i5Q|;C)q||?? zoKXpfe-oENWq4d+M?TH>US4i)MF?s3U8>%T6_>UIM%p5u9eGVw2WGOo#OwLEV*t;fb(G9>6&#elydF?!ogUOQAuq39!W`mQYwsjd0SB=nYp7Mf_ikM zQhM6~C6?WgKvW8AMn`5gyHgPvsh$;%%*SkJ@`{D3J{g6mrb>S10?YIoZA8{%C0~m? zQ@}}k!%pia`So~n*9|M~AIdaI>!CEo7?m&{6)OK{zKZc5Km!HJTY5%HRMQ26eA-5g zG27FN_e-z04C-b7ddUCw%G^T!UtWo$UgoTaHFUlXc`6g+2TDw|I$CX`5(!gv=myz} zKcnb{v{cv8GTKdH`goUdbDLc4!t(S`om;awMYGo6-Fc>B){D*O0|5CP{u#Ly9ez%iA|7tuMJ}ZZKhYksau6$m) zt^GYih=TSnYh~s&>MFNfrZ2^fnuF(YvV5J2h~B^`iu>p3f>n0kpboVlWl0bN-)$Os z4nmj)x}^^y`GLu84qg{PLGnu}j%eGWN6Uez(gAf8k18kQNGn`ZCql9bRK5N2+pUA9 zvJ}lwdHk8n_8T#+CZPBY$GipC%a-B~pj9AX%)_?yuW7cv@>3cxsW^yfCe29QDuB`q z(I0euX-V}4I_v>pB97^kv`TpIT3bcL5M6kXB-k2Zm5()g2fPV2hEeL6!b->^LtSP1 zZiY_>V<6xa+A-3kJaavgwpZ)qDG1Be*!#19;{SfY+n%t$48^2F=lvT_^LTrd-)l3s znjq}{?5>zQ?=J4BZde0i$^KBz-Q1fXksO1*Xbe6ZP!ni9CL4O~amXlRSo;0W-%FSU zSyaE>|8Qq$v47^)Hn7)T@{>H1hbXX^#PPt?ALm$gjovz8gJ#*`)UKF`yWXJq&kqQg z9-+vMXk#kalKY9@gfzecP<14;asWT3aCj(^r|?!n#_&k$<^kxNDiBy{<9lag_$}$@ z0^D(t_X2puI)aTq7Vy@a*f0RMAH`6oK>L1I&o|2_nMw-aTeqFl{+Y+&aLy+H^=fZe zYbM6Ic$^dg%3V8Vd+ARpgGzB=eU#D<^2=ZF%!3vOco%6XyG%4ktoL!K^0@l}Y3KQ} ziYO34&_OM4R|qHX=0Fd~BZywkNatolU&ynpGlK)kEpf{#e-zX~f0$}Il!QHimPtiO z!*=Ot3^YYGg${p*s?nD^55Qmy(5l<6C9prJPL|*LvY@*whx8On3RM0ygWM^q1ZRGH4FCv0}1MQwxsvFjv8lEj!FOo)!QCQ zueX0;Hea59px4XL%8*h3bo8mPg`HT@JA$j-KO@{vaQ0=Gk`xdMKZ;AV0Fff>B<3;% zfboMX9YKH2L{vp6_vf4;H?#b^&H#Ts9KT-H>l_^=f85R@EQdKIe7GX6OpuXF$UL1v zmSGm3FuayC)9`whhnz+b&8k5G5mLy0xX&aHSz6$bLsrEJogR)9;OY@sXMomn6UXP< zpdl0e%y|I^s6sXT;Y{Sv+JLcXI_j%{kXp_Fty}GD8A5;fA|Fcth)UqRc6hnNRz7m5 zVzIc@PM6gLJ8R9&7?HcPDEw?%+JX96H_K0vRk4bPT@s?kg_EEznL6a>3`9J@`Su^{ zM`k4hUvss!RT=4g<9nY+I;}ipSEg!;3<>&PJa5~I<*N^Ad8z60eW0DEXFjV3A2bMg z)I&GY;BkxtCablG|Jxp5b@^Wnc(3AH3AiN;E@+nRsoaCO#dplr!H(`Tb9``gyu6ij zHb`OPbK2#l7kN|)gQADw`K@O+-WE_kxPDdTPQuhhr2Vm+qAlu%OtZtLoc42!sg+_xM;Xy zKo_aJSFm$nrpvtIsN+tZyEAeTb+$QD_5B{`2b)FvQMlZqqHsKjf?M*?2&T^p>Aa$m zLe{r*@0}#RaPH^F@@wgX7 zD9|S8w`KHQnm_#n>kMJy9H}~U8hPAes*(QOP}gyHv8L<*ZfiOWSpwDYH1QnqHHLWc z@Vr0w1TcLPPZBZ3B)?1x3Vsu;J8Ybbv3KQIO>*DaE#kVFcG#)nIL_9%I6gzs5B&p$ zH6gnDl#<277!=6X2HxwCgivOZeSfnMK=q~GN8@BYDN@+^mGH=on!oY&Lzpg32{U4! z8b&GODW3UqAY>xo(Riba^W{Q37w00+v4E< zs#tZHd!I4n?fVuKde9Oqf$3&ZY#JwT%wC@Fhv!?hzrUN|t}}d$7GI(m`(c<#2V`@oYHPUpgXA zDc`(eLo?T!YlfiszMx-P%ymXx!wj26=NGAXToYOoA7+K+4j7VJSC(xney$`gQ9vWY z6UFC)@!6TBi149Cfjsesh|>pEV`>XW^9!CwAFbW=6hFJo7E*~uJ8_(;ITtwPU_j?v znJw`!Qm6hk7tAyRbqe2y|i&&&th}!Iir`c>J7Roy?%&tNn7dL88s$} z$Yg9an(0=6)pH{WQC{JN`R7-?-$hv@qYLN!reZJP^~+hsr`-KUf^{w>RaWQ5;w>GI z_S8k0SK_!@$8hJ4(5_1|Ds@%86O`P3=>B62$a?XCF|p0N9r@1}#}UUR`Hcd^U;!aw!=AK&M?2$T_ z!QPtHdSq_QR%Im@+IXGi7%}THyZx*_Y*hJNUBIGF6A9_(AFLOdd%pOfQzIiF(w}

(|V7O%OOlsc*vU+P^72X!U7K_eX*CG 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 E`T9pxN5i1O>p>VAy6%lIREYyb! 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 Kl11VsAO0U5dJ04U diff --git a/src/config/base.json b/src/config/base.json new file mode 100644 index 0000000..d4171fb --- /dev/null +++ b/src/config/base.json @@ -0,0 +1,4 @@ +{ + "defultServer": "http://localhost:3000", + "defaultPrinter": "192.168.1.254" +} diff --git a/src/main/LogService.ts b/src/main/LogService.ts new file mode 100644 index 0000000..6e899eb --- /dev/null +++ b/src/main/LogService.ts @@ -0,0 +1,74 @@ +import { app } from "electron"; +import * as fs from "fs"; +import * as path from "path"; + +export class LogService { + private static instance: LogService; + private logPath: string; + + private constructor() { + // Create logs directory in userData + const userDataPath = app.getPath("userData"); + const logsDir = path.join(userDataPath, "logs"); + + if (!fs.existsSync(logsDir)) { + fs.mkdirSync(logsDir, { recursive: true }); + } + + // Monthly log file + const now = new Date(); + const year = now.getFullYear(); + const month = String(now.getMonth() + 1).padStart(2, "0"); + const monthString = `${year}-${month}`; // YYYY-MM + this.logPath = path.join(logsDir, `app_${monthString}.log`); + + this.info(`--- Log initialized at ${now.toISOString()} ---`); + console.log(`Log file: ${this.logPath}`); + } + /** + * Garantizar que sea singleton + * @returns + */ + public static getInstance(): LogService { + if (!LogService.instance) { + LogService.instance = new LogService(); + } + return LogService.instance; + } + + public info(message: string): void { + this.write("INFO", message); + } + + public error(message: string, error?: unknown): void { + const errorDetail = error ? ` | Details: ${JSON.stringify(error)}` : ""; + this.write("ERROR", `${message}${errorDetail}`); + } + + public logOperation( + operation: string, + data: unknown, + result?: unknown, + ): void { + const entry = { + operation, + data, + result, + timestamp: new Date().toISOString(), + }; + this.write("OP", JSON.stringify(entry)); + } + + private write(level: string, message: string): void { + const timestamp = new Date().toISOString(); + const logEntry = `[${timestamp}] [${level}] ${message}\n`; + + try { + fs.appendFileSync(this.logPath, logEntry, "utf8"); + } catch (err) { + console.error("Failed to write to log file:", err); + } + } +} + +export const logger = LogService.getInstance(); diff --git a/src/main/handlers.ts b/src/main/handlers.ts new file mode 100644 index 0000000..2e5aae2 --- /dev/null +++ b/src/main/handlers.ts @@ -0,0 +1,115 @@ +import { IpcMainInvokeEvent } from "electron"; +import { Result } from "../types/Result"; +import { CodeRequest, CodeResponse, PrinterRequest } from "../preload/index.d"; +import { createConnection } from "net"; +import { logger } from "./LogService"; + +/** + * LLamada al servidor para obtener la etiqueta + * @param event -- + * @param data + * @returns + */ +export async function labelReqHandler( + event: IpcMainInvokeEvent, + data: CodeRequest, +): Promise> { + logger.logOperation("labelReq", data); + console.log("nfc:labelReq", data); + try { + const endpoint = "/nfc/generate"; + const url = data.serverURL + endpoint; + console.log("fullUrl = ", url); + const response = await fetch(data.serverURL + endpoint, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + card_id: data.card_id, + override: data.override, + }), + }); + console.log("Response", response.status); + const body: CodeResponse = await response.json(); + console.log("Codigos:", body); + logger.info(`labelReq success: ${JSON.stringify(body)}`); + // body puede tener otro error dentro + return >{ + data: body, + }; + } catch (error: unknown) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const err = error as any; + logger.error("labelReq error", err); + console.error("IPC ERROR", err); + let errorStr = ""; + if (String(err.cause).includes("ECONNRESET")) { + errorStr = "Conexión perdida con el servidor"; + } else { + errorStr = "Error de red"; + } + return >{ + error: errorStr, + }; + } +} + +/** + * Llamada principa a la impresora + * TODO: + * - Mejora de control de errores + */ +export async function printReqHandler( + _event: IpcMainInvokeEvent, + data: PrinterRequest, +): Promise { + logger.logOperation("printReq", data); + return new Promise((res, rej) => { + console.log("nfc:printReq", data); + const port = 9100; + let finished = false; + + const socket = createConnection(port, data.printerURL); + socket.setTimeout(3 * 1000); + + socket.on("connect", (e) => { + console.log("Conectado!", e); + logger.info("Printer connected, sending label..."); + socket.write(data.label, "utf-8", () => { + socket.end(); + }); + }); + + socket.on("close", () => { + if (finished) return; + finished = true; + logger.info("Print job sent successfully"); + console.log("Print job sent and connection closed."); + res("ok"); + }); + + socket.on("timeout", (err) => { + if (finished) return; + finished = true; + logger.error("Print timeout", err); + console.error("Timeout", err); + socket.destroy(); + rej(new Error("timeout")); + }); + + socket.on("error", (err) => { + if (finished) return; + finished = true; + logger.error("Printer connection/transmission error", err); + let errorStr = ""; + if (err.message.includes("ETIMEDOUT")) { + errorStr = "Error de conexión con la impresora"; + rej(new Error(errorStr)); + } + console.error("Printer Error:", err.message); + socket.destroy(); + rej(err); + }); + }); +} diff --git a/src/main/index.ts b/src/main/index.ts index e748dda..22456c2 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -3,7 +3,9 @@ import { join } from "path"; import { electronApp, optimizer, is } from "@electron-toolkit/utils"; import icon from "../../resources/icon.png?asset"; import { NfcService } from "../services/NfcService"; -import net, { createConnection } from "net"; +import { labelReqHandler, printReqHandler } from "./handlers"; +import { logger } from "./LogService"; + function createWindow(): void { // Create the browser window. const mainWindow = new BrowserWindow({ @@ -18,12 +20,16 @@ function createWindow(): void { }, }); - new NfcService((event) => { + const nfcService = new NfcService((event) => { if (!mainWindow.isDestroyed()) { mainWindow.webContents.send(`nfc:${event.type}`, event); } }); + ipcMain.handle("nfc:getReaderName", () => { + return nfcService.getReaderName(); + }); + mainWindow.on("ready-to-show", () => { mainWindow.show(); }); @@ -60,64 +66,13 @@ app.whenReady().then(() => { ipcMain.on("ping", () => console.log("pong")); // HANDLE es bidireccionar ON es unidireccional - ipcMain.handle("nfc:labelReq", async (_event, data) => { - console.log("nfc:labelReq", data); - try { - const endpoint = "/nfc/generate"; - const url = data.serverURL + endpoint; - console.log("fullUrl = ", url); - const response = await fetch(data.serverURL + endpoint, { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - card_id: data.card_id, - override: data.override, - }), - }); - console.log("Response", response.status); - const body = await response.json(); - console.log("Codigos:", body); - return body; - } catch (error) { - console.error(error); - return false; - } - return data; - }); + /** + * LLamada principal + * Cli - card_id -> Server - etiqueta/activacion -> Cli + */ + ipcMain.handle("nfc:labelReq", labelReqHandler); - ipcMain.handle("nfc:printReq", async (_event, data) => { - console.log("nfc:printReq", data); - const client = new net.Socket(); - const port = 9100; - const host = data.printerURL + port; - - const socket = createConnection(port, data.printerURL); - socket.setTimeout(10 * 1000); - socket.on("connect", (e) => { - console.log("Conectado!", e); - socket.write(data.label); - socket.end(); - }); - /* - client.connect(data.printerURL + port, () => { - console.log("Connected to ZSim Printer"); - const res = client.write(data.label, (res) => { - console.log("resultado de la impresion", res); - }); - - console.log("Resultado", res); - }); -*/ - socket.on("close", () => - console.log("Print job sent and connection closed."), - ); - socket.on("error", (err) => - console.error("Printer Error:", err.message), - ); - return data; - }); + ipcMain.handle("nfc:printReq", printReqHandler); ipcMain.handle("ping:url", async (_event, url: string) => { try { diff --git a/src/preload/index.d.ts b/src/preload/index.d.ts index 10b064b..cb111f9 100644 --- a/src/preload/index.d.ts +++ b/src/preload/index.d.ts @@ -1,4 +1,5 @@ import { ElectronAPI } from "@electron-toolkit/preload"; +import { Result } from "../types/Result.js"; export type CodeResponse = { error?: string; @@ -13,6 +14,7 @@ export type CodeResponse = { export type CodeRequest = { card_id: string; // UUIDv7 override?: boolean; + serverURL: string; }; export type PrinterRequest = { @@ -23,16 +25,14 @@ export type PrinterRequest = { export type PrinterResponse = unknown; export interface NfcAPI { + getReaderName: () => Promise; + onReader: (callback: (event: { name: string }) => void) => void; onTag: (callback: (event: { uid: string }) => void) => void; onRemoved: (callback: (event: { uid: string }) => void) => void; onError: (callback: (event: { message: string }) => void) => void; ping: (url: string) => Promise; removeAllListeners: () => void; - labelReq: (args: { - serverURL: string; - card_id: string; - override?: boolean; - }) => Promise; + labelReq: (args: CodeRequest) => Promise>; printReq: (args: { printerURL: string; label: string; diff --git a/src/preload/index.ts b/src/preload/index.ts index 256ff96..a772f79 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -5,6 +5,12 @@ import { CodeRequest, PrinterRequest } from "./index.d.js"; // Custom APIs for renderer const api = { nfc: { + getReaderName: (): Promise => { + return ipcRenderer.invoke("nfc:getReaderName"); + }, + onReader: (callback: (event: { name: string }) => void): void => { + ipcRenderer.on("nfc:reader", (_event, value) => callback(value)); + }, onTag: (callback: (event: { uid: string }) => void): void => { ipcRenderer.on("nfc:tag", (_event, value) => callback(value)); }, @@ -24,6 +30,7 @@ const api = { return ipcRenderer.invoke("ping:url", url); }, removeAllListeners: (): void => { + ipcRenderer.removeAllListeners("nfc:reader"); ipcRenderer.removeAllListeners("nfc:tag"); ipcRenderer.removeAllListeners("nfc:removed"); ipcRenderer.removeAllListeners("nfc:error"); diff --git a/src/renderer/index.html b/src/renderer/index.html index e333747..145794d 100644 --- a/src/renderer/index.html +++ b/src/renderer/index.html @@ -2,7 +2,7 @@ - Electron + Lector NFC import { type CodeResponse } from "src/preload/index.d.js"; +import { tryCatch } from "../../../types/Result.js"; import { ref, onMounted, onUnmounted } from "vue"; /** * waiting = esperando a leer una tarjeta (igual es mejor ready) @@ -10,10 +11,18 @@ import { ref, onMounted, onUnmounted } from "vue"; const readerState = ref<"waiting" | "reading" | "success" | "error">("waiting"); const uid = ref(null); const errorMsg = ref(null); -const labelOutput = ref(""); const labelOutputStructured = ref(null); +const readerName = ref("OFFLINE"); +const errors = ref([]); + +onMounted(async () => { + // Get initial reader name + readerName.value = await window.api.nfc.getReaderName(); + + window.api.nfc.onReader((event) => { + readerName.value = event.name; + }); -onMounted(() => { window.api.nfc.onTag((event) => { uid.value = event.uid; readerState.value = "success"; @@ -64,43 +73,62 @@ const mockReadCard = (): void => { const readCard = async (): Promise => { - console.log("test readcard"); + // Reset de los errores anteriores + errors.value = []; + if (readerState.value !== "waiting") return; readerState.value = "reading"; const serverURL = localStorage.getItem("serverUrl") || "http://localhost:3000"; - const printerURL = - localStorage.getItem("printerUrl") || "192.168.1.254"; + const printerURL = localStorage.getItem("printerUrl") || "192.168.1.254"; // TODO: De momento está hardcodeado porque no se puede leer la tarjeta const card_id = "019cdd39-fc08-7417-b16d-a78794a24c01"; const override = false; - try { - const res: CodeResponse = await window.api.nfc.labelReq({ - serverURL, - card_id, - override, - }); - console.log("Res IPC", res); - labelOutput.value = res.data.label; - labelOutputStructured.value = res; - console.log("Imprimiendo", res); + const codePromise = window.api.nfc.labelReq({ + serverURL, + card_id, + override, + }); - const impRes = await window.api.nfc.printReq({ - printerURL, - label: res.data.label, - }); + const res = await tryCatch(codePromise); + console.log("RES IPC:", res); - console.log("Impreso", impRes); + // Error de la llamada -> sin conexion al servidor + if (res.error != undefined) { + errors.value = [...errors.value, String(res.error)]; + delayWaiting(); + return; + } + // Error que viene del servidor + if (res.data?.error != undefined) { + errors.value = [...errors.value, String(res.data.error)]; + delayWaiting(); + return; + } + const labelData = res.data.data.data; + labelOutputStructured.value = res.data.data; + console.log("label data", labelData); - readerState.value = "waiting"; - } catch (e) { - console.error(e); - readerState.value = "error"; + const impPromise = window.api.nfc.printReq({ + printerURL, + label: labelData.label, + }); + + const resPrint = await tryCatch(impPromise); + console.log("print", resPrint); + if (resPrint.error != undefined) { + let errorStr = ""; + if (resPrint.error.message.includes("timeout")) { + errorStr = "Error de conexión con la impresora"; + } + errors.value = [...errors.value, errorStr]; delayWaiting(); } + + delayWaiting(); }; const delayWaiting = (): void => { @@ -125,8 +153,8 @@ const triggerError = (): void => {

- MODULE - NFC_RD_01 + LECTOR + {{ readerName }}
@@ -134,7 +162,7 @@ const triggerError = (): void => {
-

TAP CARD TO INITIALIZE

+

ACERCA UN NFC PARA EMPEZAR

{
+ +
+ + Error: {{ error }} + +
+ + + + {{ JSON.stringify(labelOutputStructured.error) }} + + Código {{ labelOutputStructured.data.code }} Etiqueta {{ labelOutputStructured.data.label }} diff --git a/src/services/NfcService.ts b/src/services/NfcService.ts index f0a18a8..c574bcc 100644 --- a/src/services/NfcService.ts +++ b/src/services/NfcService.ts @@ -1,13 +1,16 @@ import PCSC, { Tag, Reader } from "@tockawa/nfc-pcsc"; +import { logger } from "../main/LogService"; export type NfcEvent = | { type: "tag"; uid: string } | { type: "removed"; uid: string } + | { type: "reader"; name: string } | { type: "error"; message: string }; export class NfcService { private nfc: PCSC; private onEvent?: (event: NfcEvent) => void; + private currentReaderName: string = "OFFLINE"; constructor(onEvent?: (event: NfcEvent) => void) { this.nfc = new PCSC.default(); @@ -15,12 +18,22 @@ export class NfcService { this.init(); } + public getReaderName(): string { + return this.currentReaderName; + } + private init(): void { this.nfc.on("reader", (reader: Reader) => { console.log(`Lector detectado: ${reader.name}`); + logger.info(`NFC Reader detected: ${reader.name}`); + this.currentReaderName = reader.name; + if (this.onEvent) { + this.onEvent({ type: "reader", name: reader.name }); + } reader.on("card", async (card: Tag) => { console.log(`Tarjeta detectada! UID: ${card.uid}`); + logger.info(`NFC Tag detected: ${card.uid}`); if (this.onEvent) { this.onEvent({ type: "tag", uid: card.uid }); } @@ -28,6 +41,7 @@ export class NfcService { reader.on("card.off", async (card: Tag) => { console.log(`Tarjeta retirada: ${card.uid}`); + logger.info(`NFC Tag removed: ${card.uid}`); if (this.onEvent) { this.onEvent({ type: "removed", uid: card.uid }); } @@ -45,6 +59,11 @@ export class NfcService { reader.on("end", () => { console.log(`Lector desconectado: ${reader.name}`); + logger.info(`NFC Reader disconnected: ${reader.name}`); + this.currentReaderName = "OFFLINE"; + if (this.onEvent) { + this.onEvent({ type: "reader", name: "OFFLINE" }); + } }); }); diff --git a/src/types/Result.ts b/src/types/Result.ts new file mode 100644 index 0000000..0e09667 --- /dev/null +++ b/src/types/Result.ts @@ -0,0 +1,27 @@ +export type Success = { + error?: undefined | null; + data: D; +}; + +export type Failure = { + data?: undefined | null; + error: E; +}; + +/** + * Result + */ +export type Result = Failure | Success; + +export async function tryCatch(func: Promise): Promise> { + try { + const res = await func; + return { + data: res, + }; + } catch (e: unknown) { + return { + error: e as Error, + }; + } +} diff --git a/tsconfig.node.json b/tsconfig.node.json index 4deb49e..398b008 100644 --- a/tsconfig.node.json +++ b/tsconfig.node.json @@ -1,6 +1,8 @@ { "extends": "@electron-toolkit/tsconfig/tsconfig.node.json", "include": [ + "src/config/**/*", + "src/types/**/*", "electron.vite.config.*", "src/main/**/*", "src/preload/**/*",