From 73fbd316c0e5ce6104f72db361683c856892955e Mon Sep 17 00:00:00 2001 From: xueyinfei <1207092115@qq.com> Date: Sun, 2 Mar 2025 22:53:52 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B5=81=E7=A8=8B=E9=85=8D=E7=BD=AE=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=EF=BC=8C=E5=85=83=E6=95=B0=E6=8D=AE=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E5=AE=A1=E6=A0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../module_admin/dao/approval_dao.py | 58 +- .../module_admin/entity/do/approval_do.py | 8 +- .../module_admin/entity/vo/approval_vo.py | 5 +- .../module_admin/service/approval_service.py | 89 ++- .../module_admin/service/meta_service.py | 4 +- .../public/checkbox-circle-line.png | Bin 0 -> 970 bytes .../public/close-circle-line.png | Bin 0 -> 1013 bytes vue-fastapi-frontend/public/x6-user.png | Bin 0 -> 6123 bytes .../src/views/meta/metaInfo/index.vue | 32 +- .../src/views/system/flow/index.vue | 565 ++++++++++++++++-- 10 files changed, 665 insertions(+), 96 deletions(-) create mode 100644 vue-fastapi-frontend/public/checkbox-circle-line.png create mode 100644 vue-fastapi-frontend/public/close-circle-line.png create mode 100644 vue-fastapi-frontend/public/x6-user.png diff --git a/vue-fastapi-backend/module_admin/dao/approval_dao.py b/vue-fastapi-backend/module_admin/dao/approval_dao.py index 0b174ff..71ffb23 100644 --- a/vue-fastapi-backend/module_admin/dao/approval_dao.py +++ b/vue-fastapi-backend/module_admin/dao/approval_dao.py @@ -39,15 +39,27 @@ class ApprovalDao: @classmethod async def get_flow_list(cls, db: AsyncSession, query_param: ApprovalQueryObject, current_user: CurrentUserModel): + roleList = current_user.roles + query = (select(FlowApproval).where( + (FlowApproval.applicant == query_param.applicant) if query_param.applicant else True, + (FlowApproval.businessType == query_param.businessType) if query_param.businessType else True, + or_(*[FlowApproval.nextStepRole.like(f'%{role}%') for role in roleList], + FlowApproval.nextStepUser.like(f'%{current_user.user.user_name}%')), + ).order_by(FlowApproval.applyTime) + .distinct()) + # 注意:这里不执行查询,而是将查询对象传递给 paginate 方法 + result = await PageUtil.paginate(db, query, query_param.page_num, query_param.page_size, True) + return result + + @classmethod + async def get_owner_flow_list(cls, db: AsyncSession, query_param: ApprovalQueryObject, + current_user: CurrentUserModel): query = ( select(FlowApproval) .where( - (FlowApproval.applicant == query_param.status) if query_param.applicant else True, + (FlowApproval.applicant == query_param.applicant) if query_param.applicant else True, (FlowApproval.businessType == query_param.businessType) if query_param.businessType else True, - or_( - FlowApproval.approver == current_user.user.user_name, - FlowApproval.approver.in_(current_user.roles) - ) if current_user.user.user_name != 'admin' else True + FlowApproval.approvalFlow.like(f'%{current_user.user.user_name}%') ) .order_by(FlowApproval.applyTime) .distinct() @@ -57,9 +69,16 @@ class ApprovalDao: return result @classmethod - async def get_waiting_total(cls, db: AsyncSession, current_user: CurrentUserModel): - return (await db.execute(select(func.count()).select_from(FlowApproval) - .where(FlowApproval.approver == current_user.user.user_name))).scalar() + async def get_all_waitingOrPendingFlows(cls, db: AsyncSession): + result = ( + ( + await db.execute(select(FlowApproval).where( + or_(FlowApproval.status == 'waiting', + FlowApproval.status == 'pending') + )) + ).scalars().all() + ) + return result @classmethod async def get_flow_by_idAndUser(cls, db: AsyncSession, flow_id: str, username: str): @@ -99,5 +118,26 @@ class ApprovalDao: async def delete_flow_by_module(cls, module: str, db: AsyncSession): await db.execute(delete(FlowConfig).where(FlowConfig.module == module)) + @classmethod + async def get_nextstep_conf(cls, module: str, db: AsyncSession, step: int): + result = ( + ( + await db.execute(select(FlowConfig).where( + FlowConfig.module == module, + FlowConfig.step == step + )) + ).scalars().all() + ) + return result - + @classmethod + async def get_first_node_conf(cls, module: str, db: AsyncSession): + result = ( + ( + await db.execute(select(FlowConfig).where( + FlowConfig.module == module, + FlowConfig.step == 1 + )) + ).scalars().all() + ) + return result diff --git a/vue-fastapi-backend/module_admin/entity/do/approval_do.py b/vue-fastapi-backend/module_admin/entity/do/approval_do.py index fe5d613..30af726 100644 --- a/vue-fastapi-backend/module_admin/entity/do/approval_do.py +++ b/vue-fastapi-backend/module_admin/entity/do/approval_do.py @@ -14,10 +14,12 @@ class FlowApproval(Base): businessId = Column(String(255), default='', comment='业务id串') applicant = Column(String(50), default=None, comment='申请人') applyTime = Column(String(50), default=None, comment='审批时间') - approver = Column(String(50), default=None, comment='下一步审批人') - nextStep = Column(Integer, default=None, comment="下一步编号") + currentFlowId = Column(String(50), default=None, comment='当前审批节点id') + nextStep = Column(String(255), default=None, comment="下一步编号") + nextStepRole = Column(String(255), default=None, comment="下一步审批角色") + nextStepUser = Column(String(255), default=None, comment="下一步审批人") status = Column(String(10), default=None, comment='状态') - approvalFlow = Column(Text, default=None, comment='审批流') # [{审批人:‘’,审批时间:‘’,'审批结果':‘’,审批意见:''},{}]数组 + approvalFlow = Column(Text, default=None, comment='审批流') # [{审批人:‘’,审批节点id:‘’,审批时间:‘’,'审批结果':‘’,审批意见:''},{}]数组 class FlowConfig(Base): diff --git a/vue-fastapi-backend/module_admin/entity/vo/approval_vo.py b/vue-fastapi-backend/module_admin/entity/vo/approval_vo.py index 8cbca6a..38e39fd 100644 --- a/vue-fastapi-backend/module_admin/entity/vo/approval_vo.py +++ b/vue-fastapi-backend/module_admin/entity/vo/approval_vo.py @@ -24,13 +24,16 @@ class ApprovalQueryObject(BaseModel): page_size: int applicant: Optional[str] = None businessType: Optional[str] = None + status: Optional[str] = None class EditObjectModel(BaseModel): id: Optional[str] = None status: Optional[str] = None - approver: Optional[str] = None + currentNodeId: Optional[str] = None nextStep: Optional[int] = None + nextStepRole: Optional[str] = None + nextStepUser: Optional[str] = None approvalFlow: Optional[str] = None diff --git a/vue-fastapi-backend/module_admin/service/approval_service.py b/vue-fastapi-backend/module_admin/service/approval_service.py index 5c38733..c492eba 100644 --- a/vue-fastapi-backend/module_admin/service/approval_service.py +++ b/vue-fastapi-backend/module_admin/service/approval_service.py @@ -11,6 +11,7 @@ from exceptions.exception import ServiceException, ServiceWarning from datetime import datetime from utils.common_util import CamelCaseUtil from module_admin.dao.approval_dao import ApprovalDao +from module_admin.dao.user_dao import UserDao from module_admin.dao.meta_dao import MetaDao @@ -20,7 +21,7 @@ class ApprovalService: """ @classmethod - async def apply_services(cls, result_db: AsyncSession, apply: ApplyModel): + async def apply_services(cls, result_db: AsyncSession, apply: ApplyModel, module: str): flow_approval = FlowApproval() flow_approval.id = uuid.uuid4() flow_approval.businessType = apply.businessType @@ -28,9 +29,10 @@ class ApprovalService: flow_approval.applicant = apply.applicant flow_approval.applyTime = datetime.now().strftime("%Y-%m-%d %H:%M:%S") flow_approval.status = 'waiting' - # todo 后期进行流程配置,角色 or 人员 下一步审批人 - flow_approval.approver = 'admin' - flow_approval.nextStep = '1' + listConf = await ApprovalDao.get_first_node_conf(module, result_db) + flow_approval.nextStep = json.dumps([item.id for item in listConf]) + flow_approval.nextStepRole = json.dumps([item.code for item in listConf if item.type == 'Role']) + flow_approval.nextStepUser = json.dumps([item.code for item in listConf if item.type == 'User']) await ApprovalDao.add_flow_approval(result_db, flow_approval) await result_db.commit() return CrudResponseModel(is_success=True, message='申请成功') @@ -44,28 +46,49 @@ class ApprovalService: raise ServiceException(message='所操作的流程已结束') if flow_approval.status == 'canceled': raise ServiceException(message='所操作的流程已撤回') + edit = EditObjectModel() + edit.id = flow_approval.id + flowConfList = await ApprovalDao.get_conf_list(result_db, flow_approval.businessType) + nextSteps = json.loads(flow_approval.nextStep) + nextStepFlowList = [item for item in flowConfList if item.id in nextSteps] + nextFlowList = [item for item in nextStepFlowList if item.code in current_user.roles] + confNodeId = nextFlowList[0].id array = [] if flow_approval.approvalFlow is not None: array = json.loads(flow_approval.approvalFlow) + if operate.operateType == 'success': + nextFlow = [] + for flowConf in flowConfList: + parent = json.loads(flowConf.parent) + if confNodeId in parent: + nextFlow.append(flowConf) + if len(nextFlow) > 0: + edit.status = 'pending' # 有下一步执行人,则设置为 pending + edit.nextStep = json.dumps([item.id for item in nextFlow]) + edit.nextStepRole = json.dumps([item.code for item in nextFlow if item.type == 'Role']) + edit.nextStepUser = json.dumps([item.code for item in nextFlow if item.type == 'User']) + edit.currentNodeId = confNodeId + else: + edit.status = 'succeed' + edit.currentNodeId = confNodeId + edit.nextStep = '[]' + edit.nextStepRole = '[]' + edit.nextStepUser = '[]' + if operate.operateType == 'reject': + edit.status = 'rejected' + edit.currentNodeId = confNodeId + edit.nextStep = '[]' + edit.nextStepRole = '[]' + edit.nextStepUser = '[]' array.append({'operator': current_user.user.user_name, + 'confFlowId': confNodeId, 'operateTime': datetime.now().strftime("%Y-%m-%d %H:%M:%S"), 'operate': operate.operateType, 'operateComment': operate.operateComment, }) - edit = EditObjectModel() - edit.id = flow_approval.id edit.approvalFlow = json.dumps(array) - if operate.operateType == 'success': - # todo 增加流程配置,并查询出下一步操作人以及步骤 - edit.status = 'succeed' # 有下一步执行人,则设置为 pending - edit.approver = None - edit.nextStep = -1 - if operate.operateType == 'reject': - edit.status = 'rejected' - edit.approver = None - edit.nextStep = -1 - if flow_approval.businessType == 't_metadata_supp_info': - await cls.syncSuppInfo(result_db, flow_approval.businessId, operate.operateType) + if flow_approval.businessType == 'metaDataInfo': + await cls.syncSuppInfo(result_db, flow_approval.businessId, edit.status) await ApprovalDao.edit_flow_approval(result_db, edit.model_dump(exclude_unset=True)) await result_db.commit() return CrudResponseModel(is_success=True, message='操作成功') @@ -98,13 +121,37 @@ class ApprovalService: @classmethod async def get_flow_list_services(cls, query_db: AsyncSession, query_param: ApprovalQueryObject, current_user: CurrentUserModel): - result = await ApprovalDao.get_flow_list(query_db, query_param, current_user) - return result + if query_param.status == 'waiting': + result = await ApprovalDao.get_flow_list(query_db, query_param, current_user) + return result + if query_param.status == 'over': + result = await ApprovalDao.get_owner_flow_list(query_db, query_param, current_user) + return result + return None @classmethod async def get_waiting_total_services(cls, query_db: AsyncSession, current_user: CurrentUserModel): - result = await ApprovalDao.get_waiting_total(query_db, current_user) - return result + approval_list = await ApprovalDao.get_all_waitingOrPendingFlows(query_db) + count = 0 + for item in approval_list: + nextRoles = json.loads(item.nextStepRole) + nextUsers = json.loads(item.nextStepUser) + if len(nextRoles)>0 and len(nextUsers) > 0: + if current_user.user.user_name in nextUsers: + count = count+1 + break + if any(element in set(current_user.roles) for element in nextRoles): + count = count+1 + break + if len(nextRoles) > 0 and len(nextUsers) == 0: + if any(element in set(current_user.roles) for element in nextRoles): + count = count+1 + break + if len(nextRoles) == 0 and len(nextUsers) > 0: + if current_user.user.user_name in nextUsers: + count = count+1 + break + return count @classmethod async def cancel_apply_services(cls, query_db: AsyncSession, flow_id: str, diff --git a/vue-fastapi-backend/module_admin/service/meta_service.py b/vue-fastapi-backend/module_admin/service/meta_service.py index db5df8d..906e70a 100644 --- a/vue-fastapi-backend/module_admin/service/meta_service.py +++ b/vue-fastapi-backend/module_admin/service/meta_service.py @@ -99,10 +99,10 @@ class MetaService: await MetaDao.insertMetadataFldSuppInfoVett(suppColumnInfo, result_db) await result_db.commit() applyModel = ApplyModel() - applyModel.businessType = "t_metadata_supp_info" + applyModel.businessType = "metaDataInfo" applyModel.businessId = tableOnum applyModel.applicant = current_user.user.user_name - await ApprovalService.apply_services(result_db, applyModel) + await ApprovalService.apply_services(result_db, applyModel, 'metaDataInfo') return CrudResponseModel(is_success=True, message='操作成功') @classmethod diff --git a/vue-fastapi-frontend/public/checkbox-circle-line.png b/vue-fastapi-frontend/public/checkbox-circle-line.png new file mode 100644 index 0000000000000000000000000000000000000000..a1ec9b22a87f95c137a4d9dae86d4d83565dcfc2 GIT binary patch literal 970 zcmV;*12z1KP)Px&gh@m}R7gw3m0M_BWe|YBIcYbI2~p}(tElLMpdpH}>YmM>q%UGqil{^dt0>yt zwGygWFIA}#uXqKkX3q&|!GaV-irN+hY4&XPY#&VVLT#zHq7Ob*ERmSaX3yxq$)>xT z-OxT1=jmt8{PWG3nSVw&%OYplKT86J_N{9zwEuM*A~%6tCFmu90>=gYM%CJ{?bDxl z*G?3h1=>7FGek%>MjA}^NTO><0SW4)r9 z1rE7R&{GeXGM!K;McQ_*9h<)QK>v!?mYE~w9SA&;c7j*Ug;dslT9p^d&Q%|C`|__> z;P(g7mCI)31n}p7L7iU@m;^eCmUO<~n=@w?3ODaekdDgxP}OZ-U;dTqKN~uDedo+f z%Sm9;b%M@%z)|3GRqgir^50i3CacpiuWaOeE}$E(5v+-Fqd561YXAw~{z%|XMIQH@ z+-ud5)fBWr}L?3SNPC#f_rKJsZ8uH72Tz9WOY2~8WzH8hGu8T|z{S9z>jWRy03HdVZBw&i(sYr)eQ77y*~n2dUDCIQ05c|zMgBgwd&j{3 zLJgpt!;F2S2w$A(sMs`SudyrwGb*f5`bYY6rd7+bc-Wn4!;>PqF&)o;-Yn|!up5uw zfieoxF33>Y$-Pr;-*8+f{n&QU=jIIcR}pKsl-O4)PJdTyJtwj}47;R7Z&qbcVDMrk7q3)nDC(wZCjbBd07*qoM6N<$f;XhmIsgCw literal 0 HcmV?d00001 diff --git a/vue-fastapi-frontend/public/close-circle-line.png b/vue-fastapi-frontend/public/close-circle-line.png new file mode 100644 index 0000000000000000000000000000000000000000..797de582d4cb488aad568b4d6899c0e23d572b46 GIT binary patch literal 1013 zcmVPx&uSrBfR7gw3Rb6NtRTTcd$=dABY(irr(pFR~qF_x$sZWJQLD5PPm0FOB6$I0r z8Ipi4h@d0*R3dIWcQ!FT7z%x;4_d5M6hwd_GnL5ZCPtMV>IohXmLHk(&VsfC~W55cnvyxcDx| z$4l)BZ3_@O&chJNfz*etWK$wCkPd=RmkU}JAaoqBQt2zTgkLCfjD~UYa!1Fv+Lwr; zyGZV&$ddqW&^{qwNc;ZltsqMP;=?I&Nyt5>QYZKiElW&1&zR5WcM0$|fE39=)AtWI z1~vhNuDcT=?*o`Gi)`%*g6~%&f}-o*DH1F&9K zp7#BtanQw~p|w5P>}(_0?7n?HYez>f#=fF$4+;4Ofyq>F?-qLAqTZ_mgpQK|5CHhW zRBCffOXxU0MII<865G><4*j8%3WI~!8&Px$#1K<_`eySXLpY~V4J|l1|fb(WD*~gKQQ2Rs2c@4lz0LCq)o^J*C zRV$+7%9TyY(b4nq)kDYGAi(Ff1E)350B#cCMeRyO;496O)MY%3ea7XZGol)9%C zps1B#778g&Ok8f{JEla)+p0+-=Nc)CW9Np4uT7LnGXQ2SrFvQcE&)gvO|$#Dg9r7x zZmR{Daoz5u$efnA83f%;07cuL)D;TQmsaY#x;h31Ha2iR4H4?sttm31=zeo-?6*3d zwtY9q(^@E&Qg<{1IL^^Z(o+KLPb)Q2Z*mx(t&NK*Mp1uNF^R+}0Gl9k!4$cZxm=;v zWZhuh=p&X=&oluPZ2M`FN3>e3-rn2kdF84k9Ve^RB~i4kYi#V#7MY$fmD*pEX`-0V z{|w+pitILn;GHG_86Hj*OQlI2Amp=Y-=B!DzN&}jIIaMPHFXx*N8ev)0;pEzx(`z1 z4CCwSs37}OzOSWPwdICg%;OwH_E%x(lKxX>HS100000NkvXXu0mjfggw=y literal 0 HcmV?d00001 diff --git a/vue-fastapi-frontend/public/x6-user.png b/vue-fastapi-frontend/public/x6-user.png new file mode 100644 index 0000000000000000000000000000000000000000..c5f380f37e14b3dd76de33ee1871c58b91530518 GIT binary patch literal 6123 zcmVPy1rAb6VRCr$PT@7>`)ph>vNV01SO89jt&_dG2v-Oj5vL2ht#ifVH#c z$Do~+Lvg5anjFGO2{_aZv3FM3V7xOj`LO~9T!KkU>;#B0r_f+%i`|6K7Q&Aqgo5PS zlIHfj(aPv&=Djzwvpc)C-#Ixl+57Ij@4h>4-rQfpUO46z`GW%rsv-mdv0{WQH2gXjo|Jw%xeZ<(tz&4Mut=Yf}t8?_?-X<<;^aZuM+-kgs zvxqU9finP11<+EZb@c<-M!*wHSnnNxP2CyltrD%8plwJ6n7fQmY%=gE5M}_F4WOwe z(i%@>5WspcHV%6D>6!)fY)X8@CfhIy&|ctEi80eKa2^Av#$It1Clav5^RR&l4|nHj zOBG2ahPtj5pb<7bY$qB;8R}92GF?22Jj^d2?}=%9iip;;ft79t{bPze1d^^R1=tHW zeyq^zP7&%t0rr87uUkb(RROYHd@K)QF~~pelOAt_@GKZx0c<70cJk2MZ=jb4(96x} z?SCEqCtS-Ew9)`tsTr*;9$MKzD>FU}U>XS1z&H`W!AUa+#!70!Eu{{6DRJDI2vbu4 zv%nSzHvl+VlUEs-*vKb|u!RS)#W3)%t1bGU1n}-bG0)~>JP&_CO*oa={|Y$`Kx+at zUIybYUVsgpKUfG6>( z+2wqeXP}LMHUNiLK;U}EqQ9?Tex#{2QGhG&(tNFQ6SU zanxkmyk&eiH=&Jzxd2X&LzD^K6IyWnU02cTapp&vQ*{L}Z9b>`)K81Tm=DW%5KVBM z4!Sq;+&Y+GcJb#ihztmyjlqt%yo%G{$1&z=PpPT`RB+_40>gFk^fT?1)G?r0;4?wU z0JtIsn^k=!R80ZQA{W8vh`8X5o`)sfo%Be=c?|*HzMRiB3@ieCCzk#obU8W7=}*vy ztcn7dHVc#I1^R5@4JIscbMy}p<}@s5rpVV3`-*Txghf2$STrjFycTHU3SinS-d!hX zQ6BbAsSN&th zqH{H2L%}LmfUM28Gw>xHMwrp#=4p-&?7j+jXbVnkr|iCeQ};?vjh0XBb^c3SQJYE z%H~}yV-0(_$?c@C>#Slw%xDQ@mh;!iz>S)6IX8~kII;o=$4>ul2>Z11d$e9Qzilly zO?neE$ivwn90lMgFpet!TlgGa0pS$@uZVxMfuHO=3>$mqkO=!ubwp5ttt}I9PE-d{ zWCh3++12stG4OTQqMOo^UV9fGK^{H_#+fwaj5#18FYmE%MiG9-2G(_V&>IowCkC#o z1j38x=1BLo;qw4>KN;sJpGjtt_lDdn=dA@@#Lq7B|q3t3A^33=!eN8S7S5_ ze4mb;zyqf1Miyx+K*r{WG{U&Hdmhe9!^o4d*(RVW9<#Aq!$8rs$Wm`vvJk$p$iN1b z#ZZKoxfW?Ta&i>Sts9xh_z7jR@p>gH zMqVe-RH*=d=(gt{{nF^&v>ZF8&Ej$vH3m;a48I^UeanIr8O6r~I7TVh(EvLfi=w!6 zBccxm*K{DgOa`W_Le7;6U>10VM%?}y$D+9LezAq3yZJ+&ImCRV_v@MC$sbfVgs{fIf+sQFl~NNm7vLlg|&|4(X^F+ z)v@U2I2%89j%oAX0{A-_t~7id<;Wu8MwX5BjzytCsi6v>`SfpeEIK<0A?xDMF^Ul3 zvQmz|tBX?yE?eYFnQ@O)2~se7n>PPM6=Ntn1ws`-=jkth@@e@5bcC#enY)6IY#PA7 z0Qkc&SjQsey+%bx_Pc2_OMd^&U^7lxb2YtM35_Uo%Ymli(=gU45GX9or+<}W(Unn{ ztrS-E^fTiVZk{$*N=G(7Q{dBy@bfU3H2fc?&3CCn&cjZDKn2iw`oZ{AE#vkzp8o3` zi@sgW%^${X+Wgl5!XlV!ehQTH4t^Tv6d0!fqAZI+cv6at@t~8Z3u__lVH(m4590|Z zPoJzMKW2d+5BoYu<6>+U_yJW0lE*l0Z0(|P3Xrk+Mgrvidjl8OI$bMc^J4@AZZZRx z#QoHZt2F*6BJlm7`3yYnS~NW_?l|-OG&B!VA4QOdcANraZ59R-Srx9$jzyn{!(`k! z^X}k3_XhEAA@esl7R`){yOMdP%?|@OF9?UxgpaJghW@=0{88tcHjBGSXhNzeTvf72 z)HT>MMk#>K@lSwNvZxr9xk}&_m%lGN7OB34Dsdb9B?D#i;KT5h9h_1HyRYQRPu9w$*nZVy2_LkoXRae_BF6a0n8$w4EBvIp@Tfk zNTV``Y4fjwqI(#)&$a0DNeM3wo{Y`+5)c#s^P*$XhvML@WR9p*!Ui@%a`d!- zd0zo+{u=<{d3q^6Z5f+)5OCPIMKSJj@^n=t0;_bcS>QWC7-tY;;7!+}sBY>?+41LV zILa0|7JX~10;tlv(!6Z_AApGg()pHSkw~*nZJ0KThekX+W5+JXqTfq{G1=v`%+H>* zGXDg)docmPCZuMx&D182Jy$&Z#Qt=6=8zXC*%ZN}yq1PCWl*zlU(!w2qOMDO|v z;0IFzJ(3B1eTU=Vo;kET0w0Nih6R2waJOqwoU$v4@s_c96##W?bav=>bjJiG#^*wVr_!x;yCk#EEJkZ13Wa z8XklKj2|g}H3?=i1-_67_e+-1?^rZ}M1v)dA-=OiN1E0)!Bp1fECZ`U7)&hmOJmPR zfyhF|2$)y0s1y}vQt&b>g< z04@s>P8$AqML^~~jzv+be|f5H^un;4L70JQRj- zW+_MNtl%1~$Sm@FFjh!NecQ36c{($~>n$^$ z5_bTp4ZvWWygEq3+F))Z@?pZ)DCn?NIahXLffT7CIcbTx%&5@{G9D8JnJdN15 zsL4yO5Nsz$`PhW2F!8cwd~|aY!h0tXUKL*fzhg;#-+sa&-_4P5EY#J=*nB?$s?c=N z4SYEpSmt(+C<3KDGF^NWdHxN$6Tl?dLd5r)sE%L!Fj8Izy0q=-cfYc1! z_XZ~R+?0+NP$eggFPLEz!qvTrfPa#;of*;YHq(P!w5K3b`l2RC*TJqi!O;myOyw83ec#p zfRTbUZ5FB9B89t_<7UUAuhx=aR9bqkfCjt-1_?qVq&=$qLgCYh`H#cA)+MmfJ_CaU zQT{X(H+8*w`*EZ>dd_wbmez~GCu})-pMec#2pYNAY=JNF2-lK4m96sa4#B{{7K3qn zDNlhpf>k4|iCE7N)Ig@-;dN(ip3Orw0R!{$H06^d*aiZMC5u$`l#-;W#HD8nR=W)A z#u+45oVED|(PLM+dO3h70{t3*;YuFD5GGo%G*yCE^h7RM6s7-9CFGQIwVXkX;tm$8 zHEkAAL0RR>#{h@|PKJRV57^c;fLFtE8-*QUuo*`hz*Nsen{MZhG2}{)Mf0NaSPghR zcd)$LMco91WNdzd0PVDNVVyI8`*#x_h-=9dpHUMS7ka=&8dk?Wd&t1gU5lzyuQ-CH zXc)?_Ylx6A(`I3?IaF)yjFm93aya)*YmNqxpF8PczDCi^VQgmMQkty&p zBHtMkI>e_K5v-)2c-2CMA}~W#D3?`J0W+4nc?u27QqhU~ySbb{3j?xH{-Ln&vI0nh zLWuCqQjThBYRz`>Y%&hZf2Z$*&^S}jIT)M zzMmMP@g?x6W6@{gFcN1@*5>mV5cPM$pZt`btRRMTPAURsmMl^gbc`dez&WPPB68`| zVF*P)Xvv~$hE9MYUjT;a_#HNSCpP2YTEyOGm-7jpf%OFZaTqg9IN!~YR6!Dxq$Z+F zk!KR)N1;3e|7CcXUFxLZOd?G>I$-lxaLcX%KRL8D6rM24$&qLR0<^o_YP^egWQLF^ zZAf&O41+Ok7Bzmq7%Iq=)6`^Z(@4kqo@3FamB>eDu10&GLGM5u)SaQ;krhJL0SJw1 zsYUWdw#aSFSQ~n55f-G`xJgI&<%U(uBx{&c%8@J;Ux$noMx%=O{f&Dl4$)tcK0hT6q#13Skq>490m6xZosF1j{?Y3*|s_sjW2!~ z>$xAARB@?To!0<>M2kgBt84%b`}FIa0!ddlskm6Q=4(I{lS`~zysSO}1Gl;sEw139 zNPTL?=35B3A%u~{np|j=ix22&lzPJmMN8Uq9g9S(`i32*&F26J?5h-|#j8pHi8YK6 zglgF`#37p+5qc&<&c=?Njzyuh{B+llXv-M?HPFSg$b%}t zvErstif`7sD6^uw2{JfYd7C6`D;jkk5vggE?kP}d+c;VEui;9TNo+vcIAoPrE3GD0 zm9}vaPJxOVN6PFDqJ-J%9KD$K<|RR27Ijr=mQmFjN9vvel{kqcQNFt-HsiorxSx~Q zU=@zCd-mOsis!MTh&7x(g0*<9VMpp8B(p^t#(mdKf1*+IS-n9AG zfu+_M_d0pHxDtWa+g!82KLjDDyU9zAMaM^~wXdiGuM}QZT`X$9<4lnk5kr-M^fDQkUh1HiWV~xNS~d%8flyEhff=*i zJjp`KR4DfUu8=^cz_W;ypXj1mTHeW%w1u1?rKJG=eZXcBKX$%?zwPBuLvgh49|=pK zeK{Xz7!ZM_(lq!e7DjCa(1_&yN)P%hbs62Gaf0RDy0 zX3;d_HWdRR8Pm$SyJ3Rjlt<0+odH zf7ji7CUmE8|Ep$iV+7)`)+EHd?%x*u|^1WcP9Ws%CENn2Yc z;GDazidHc_vI3M}1)(m^u?wiw)VVLKghq(oNb$sSoySsuDE9&XUKkLFurF_{&e|hx zex&#QNcyoAz*mAI7s2SzS#*Or*^xbU8T^^^#(ZiWH!H5(vZ31zOY@T~0ne zvsyG79LOwi5v2D}0eHx-Fzrtn(NPyE|#Wv1r83`9>bXQl0Po z^0en1i*zpHQvFCo0m@1s3Njz0sg2v2v2efHxP0UfnRl0}EPNwm`;KFgx{$TTW+bKn zz7iDpH4vs~(Dgy$IFNL4Hwv7lW9R+lFkW}^6ck?=YsrZ!K=~w4wV@x&=o)5x!_Cw7 zSSx7INo9Zj*FY~33@4@gFk6yEYIiUd=JEywK(8@=e`7j?uo^5_t%ssfaiK$wk%2Qm653*$jF!F4+5UY*6% z8;qZ>HHZvIUPUZ~Z}Dj@HovNwQB_v}u{hyC+TD-abi9Zm!q`l}8d<-edfEIDeTT&5 z?({f(39sIS7F-|Iu@i?@O%!05G2M6q$wGE8&|`S$DRt7OI18@U9FgVZ8E7M*4Zz_Q z(5dQ?KbEhWDu5s^B8x;>b&c>cxeN)LL}@z)p4oXgp6HoV+s1n>FN1NbP5@^Nwv|&-Qvku4A96m3#StoSD;G2Z z;B63|1w&k>wi01GdFbso(8~kp<3;>17R8% zqLRnKQHX27GFDO(Zc&A9YvGCsl&S&@^IXnGo)2Jl%yl%{wDoLYrQ4By2z^~Bz&@l1 zb+hrqGOsHI*ozgR?l!)z6=0Y-QMHT+=NZ6EPN_9q+;v_{h^4~BDFp_D%Z43Lg@WuZ`9|I$$ zP4@tZy8MrV@Mx{OmL##}hE#x&3%`5`A2@IT&ZVIylHz2TD!%NJ5KaJ&egNBidjqhc z`8_;x_aYL79~yQvyaEJCUX)}R@Nm3Am`cD@CQOBg$spfwBmPbz#$+xVatP>SLLV4A x0sn6w4D=CW8w1-s# literal 0 HcmV?d00001 diff --git a/vue-fastapi-frontend/src/views/meta/metaInfo/index.vue b/vue-fastapi-frontend/src/views/meta/metaInfo/index.vue index d1868fd..e3dcc93 100644 --- a/vue-fastapi-frontend/src/views/meta/metaInfo/index.vue +++ b/vue-fastapi-frontend/src/views/meta/metaInfo/index.vue @@ -81,16 +81,16 @@ 重置 - - - 导出 - - + + + + + + + + + + @@ -135,7 +135,7 @@