首页 > 编程语言 >【Python插件入门】第10篇(完结篇):插件常用工具类分享

【Python插件入门】第10篇(完结篇):插件常用工具类分享

时间:2024-09-03 17:47:08浏览次数:11  
标签:完结篇 插件 数据包 BOS Kingdee 单据 Context 常用工具

【Python插件入门】第10篇(完结篇):插件常用工具类分享原创 金蝶云·星空-BOS平台 金蝶云·星空-基础架构 金蝶云·星空-学习笔记 金蝶云·星空-协同开发 更多   金蝶云社区-CQ周玉立 CQ周玉立体验师 149人赞赏了该文章 1.8万次浏览 未经作者许可,禁止转载编辑于2022年08月22日 09:02:14 summary-icon摘要由AI智能服务提供

本文是对“Python插件入门”系列文章的第10篇完结篇,主要介绍在Python插件开发中常用的工具类及其使用示例。文章通过演示如何在服务插件中使用这些工具类,包括读取和保存单据的数据包、根据字段查询单据数据包、以及构建新单据数据包并生成单据等功能。示例代码展示了如何使用`MetaDataServiceHelper`、`BusinessDataServiceHelper`和`QueryServiceHelper`等工具类,并详细解释了如何引用相关库、构建查询参数、处理数据结果及执行单据操作。此外,还介绍了如何通过构建空白单据数据包或单据视图来生成新单据,并触发界面服务。

目录

往期回顾:

一、读取单据的数据包

二、保存单据的数据包,调用单据保存、提交、审核等操作

三、插件构建新单据的数据包,生成单据

四、插件中数据库操作执行SQL语句

五、其他工具类介绍

往期回顾:

【Python插件入门】第1篇:Python插件入门讲解

【Python插件入门】第2篇:基本开发过程介绍

【Python插件入门】第3篇:插件中如何进行数据操作

【Python插件入门】第4篇:单据表单插件

【Python插件入门】第5篇:单据列表插件

【Python插件入门】第6篇:操作服务插件

【Python插件入门】第7篇:简单账表服务插件

【Python插件入门】第8篇:账表表单插件

【Python插件入门】第9篇:单据转换插件

 

        前面9篇已经把Python插件常用的插件类型介绍完了,相信大家对Python插件开发以及各种插件的属性成员和事件已经有了一个整体的认识和了解,我们在插件开发中经常还会用到一些通用的工具类,来帮助我们实现功能逻辑,这一篇作为【Python插件入门讲解】的完结篇,分享一些常用工具类的使用代码,供大家参考。

        这里用一个服务插件作为示例,演示一下这些工具类的使用,示例代码已上传附件!

一、读取单据的数据包

  • MetaDataServiceHelper.Load:读取单据的元数据

    需要添加相关引用:

          clr.AddReference('Kingdee.BOS.ServiceHelper')

          from Kingdee.BOS.ServiceHelper import *

     formID="PUR_PurchaseOrder";#单据FormId
     meta = MetaDataServiceHelper.Load(this.Context, formID);#读取单据的元数据

     QTWLMeta=MetaDataServiceHelper.GetFormMetaData(this.Context, formID);#读取单据元数据

 

  • BusinessDataServiceHelper.Load:读取单据的完整数据包

    需要添加相关引用:

          clr.AddReference('Kingdee.BOS.ServiceHelper')

          from Kingdee.BOS.ServiceHelper import *

    pkIds = List[object]();#需要获取的单据ID集合

    pkIds.Add(10001);

    objType=meta.BusinessInfo.GetDynamicObjectType();#获取单据数据包的对象类型

#这里顺带提一下,如果是修改单据数据包中的基础资料/辅助资料字段*******************************************

#读取基础资料字段数据包赋值给基础资料字段时,不能使用meta.BusinessInfo.GetDynamicObjectType()
    baseFld=this.BusinessInfo.GetField("字段标识");
#应该按此方法获取objType,这样获取到的基础资料不是完整的数据包

#而是根据单据字段引用属性加载的字段,这样的数据包赋值给单据中的资料字段才合适
    objType=baseFld.RefFormDynamicObjectType;
#***********************************************************************************************************

    #根据单据内码集合读取多个单据的完整数据包

    billObjs=BusinessDataServiceHelper.Load(this.Context, pkIds.ToArray(),objType);

    #根据单据内码读取一个单据的完整数据包

    obj=BusinessDataServiceHelper.LoadSingle(this.Context, "10001", objType);

 

  • QueryServiceHelper.GetDynamicObjectCollection:根据需要的字段读取单据数据包

    需要添加相关引用:

           clr.AddReference('Kingdee.BOS.Core')

          from Kingdee.BOS.Core.SqlBuilder import *

          from Kingdee.BOS.Core.Metadata import*

    #通过构建QueryBuilderParemeter取数****************************************************************
    queryParam=QueryBuilderParemeter();
    queryParam.FormId=formID;
    queryParam.BusinessInfo=meta.BusinessInfo;
    billId=SelectorItemInfo(meta.BusinessInfo.GetForm().PkFieldName);#单据内码
    queryParam.SelectItems.Add(billId);
    billNo=SelectorItemInfo("FBillNo");#单据编号
    queryParam.SelectItems.Add(billNo);
    supplierId=SelectorItemInfo("FSupplierId");#供应商内码
    queryParam.SelectItems.Add(supplierId);
    supplierName=SelectorRefItemInfo("FSupplierId.FName");#取基础资料属性字段写法不一样,要注意
    supplierName.PropertyName="FSupplierId_FName";#后台是SQL取数,字段名不能有".",要重命名
    queryParam.SelectItems.Add(supplierName);
    
    entity=meta.BusinessInfo.GetEntity("单据体标识");
    queryParam.FilterClauseWihtKey="过滤条件";
    #按单据体ID过滤,关键字要写成"单据体标识_FEntryId"
    queryParam.FilterClauseWihtKey=("{0}_{1}={2}").format(entity.Key,entity.EntryPkFieldName,entryId);
    dataRows=QueryServiceHelper.GetDynamicObjectCollection(this.Context, queryParam);#获取数据结果数据包
    for r in dataRows:#循环获取结果数据包中的字段值
        billNoValue=r["FBillNo"];
    #QueryServiceHelper示例结束***********************************************************************

二、保存单据的数据包,调用单据保存、提交、审核等操作

  • BusinessDataServiceHelper.Save:调用单据保存操作,将单据数据包保存到数据库,会触发操作服务插件

    需要添加相关引用:

           clr.AddReference('Kingdee.BOS')

          from Kingdee.BOS.Orm.DataEntity import *

    ObjList=List[DynamicObject]();#单据的数据包集合
    ObjList.Add(billObjs[0]);
    #注意!调用保存时,传入的必须是完整的单据数据包
    #Q:既然是Save方法,为什么还要传操作代码"Save"呢?
    #A:Save方法调用的是单据操作列表中,"操作类型=保存"的操作,可以为单据添加多个"操作类型=保存"的操作。
    #例如,可以添加一个"OnlySave",这个操作不注册任何服务插件和服务端服务,仅用于保存单据数据到数据库
    saveRslt=BusinessDataServiceHelper.Save(this.Context, meta.BusinessInfo,ObjList.ToArray(), None, "Save");

if(saveRslt.IsShowMessage):#读取保存操作结果数据
            OperationResultExt.MergeValidateErrors(saveRslt);
            msg="";
            for rst in saveRslt.OperateResult:
                msg=("{0}\r\n{1}").format(msg,rst.Message);#拼接提示信息

 

if (saveRslt.SuccessDataEnity<>None):#存在保存成功的数据
        ids=List[object]();#单据内码集合
        for newBillObj in saveResult.SuccessDataEnity:
            newBillId=newBillObj["Id"];
            ids.Add(newBillId);
        subRslt=BusinessDataServiceHelper.Submit(this.Context,meta.BusinessInfo,ids.ToArray(),"Submit",None); 

 

  • BusinessDataServiceHelper.Audit:调用单据审核操作,会触发操作服插件和服务端服务

if (subRslt.IsSuccess == True):
            BusinessDataServiceHelper.Audit(this.Context,meta.BusinessInfo,ids.ToArray(),None);

 

  • BusinessDataServiceHelper.DoNothing:调用单据空操作,会触发操作服插件和服务端服务

#假设单据配置了一个自定义空操作,空操作配置了自动下推服务,就可以调用空操作实简单实现调用单据下推。

    optCode="DoNothing-AutoPush";#自定义空操作代码
    PkIds=List[object]();#执行空操作的单据内码集合
    PkIds.Add("10001");
    BusinessDataServiceHelper.DoNothing(this.Context, meta.BusinessInfo, PkIds.ToArray(), optCode, None);

 

三、插件构建新单据的数据包,生成单据

    看了前面BusinessDataServiceHelper工具类的介绍,我们可以先Load单据数据包,然后修改数据包之后,调用Save方法,实现通过修改单据数据包的方式来修改单据,由于是后台,这种方法的缺点是,不会触发单据界面服务(实体服务规则、值更新事件、表单插件等),当我们修改单个字段,或者可以传入相关的所有字段时,可以使用。

    既然可以通过这种方法来修改单据,那当然也可以用来生成单据,下面介绍插件中生成单据的2种方法。

  • ①构建一个新的空白单据数据包,然后通过数据包操作赋值后,调用Save方法生成单据。不会触发单据界面服务

    formID="FIN_OTHERS";
    QTWLMeta=MetaDataServiceHelper.GetFormMetaData(this.Context, formID);#读取其他往来单位元数据
    QTWLType = QTWLMeta.BusinessInfo.GetDynamicObjectType();
    QTWLBillObj = DynamicObject(QTWLType);
    QTWLBillObj["Number"]="Test001";#编码赋值
    QTWLBillObj["Name"]="测试其他往来单位";#名称赋值
    Orgmeta = MetaDataServiceHelper.Load(this.Context, "ORG_Organizations");#获取组织员数据
    orgId="1";#创建组织和使用组织一致,使用同一个组织ID
    createOrgFld=QTWLMeta.BusinessInfo.GetField("FCreateOrgId");
    useOrgFld=QTWLMeta.BusinessInfo.GetField("FUseOrgId");
    createOrgObj=BusinessDataServiceHelper.LoadSingle(this.Context, orgId, createOrgFld.RefFormDynamicObjectType);
    useOrgObj = BusinessDataServiceHelper.LoadSingle(this.Context, orgId, useOrgFld.RefFormDynamicObjectType);
    QTWLBillObj["CreateOrgId"]=createOrgObj;#创建组织赋值
    QTWLBillObj["CreateOrgId_Id"]=orgId;
    QTWLBillObj["UseOrgId"]=useOrgObj;#使用组织赋值
    QTWLBillObj["UseOrgId_Id"]=orgId;
    QTWLObjList=List[DynamicObject]();
    QTWLObjList.Add(QTWLBillObj)
    saveRslt=BusinessDataServiceHelper.Save(this.Context, QTWLMeta.BusinessInfo,QTWLObjList.ToArray(), None, "Save");

  • ②构建一个单据视图View,通过View操作单据数据包,就可以触发界面服务了,修改单据同样适用! 

    需要添加相关引用:

          clr.AddReference('Kingdee.BOS.Core')

          clr.AddReference('Kingdee.BOS.ServiceHelper')

          from Kingdee.BOS.Core.Metadata import*

          from Kingdee.BOS.ServiceHelper import *

          from Kingdee.BOS.Core.Metadata.FormElement  import*

          from Kingdee.BOS.Core.Bill import *

          from Kingdee.BOS.Core.DynamicForm import *
          from Kingdee.BOS.Core.DynamicForm.PlugIn import *
          from Kingdee.BOS.Core.DynamicForm.PlugIn.Args import *

          from Kingdee.BOS.Core.DependencyRules import *#触发实体服务规则需要添加此引用

#自定义方法:创建单据视图View
def CreateBillView(ctx,formId,billId):
    #读取元数据
    meta = MetaDataServiceHelper.Load(ctx, formId);
    form = meta.BusinessInfo.GetForm();
    #创建用于引入数据的单据view
    tp = Type.GetType("Kingdee.BOS.Web.Import.ImportBillView,Kingdee.BOS.Web");
    billView = Activator.CreateInstance(tp);
    openParam = CreateOpenParameter(meta, ctx,billId);#调用自定义方法获得单据打开参数
    provider = form.GetFormServiceProvider();
    billView.Initialize(openParam, provider);
    return billView;
#自定义方法:构建单据打开参数
def  CreateOpenParameter(meta, ctx,billId):
    form = meta.BusinessInfo.GetForm();
    openParam = BillOpenParameter(form.Id, meta.GetLayoutInfo().Id);
    openParam.Context = ctx;
    openParam.ServiceName = form.FormServiceName;
    openParam.PageId = Guid.NewGuid().ToString();#随机产生一个不重复的PageId,作为视图的标识
    openParam.FormMetaData = meta;
    #单据ID为空是新增,不为空则认为是修改,若是修改方式EDIT打开单据,会触发网控,注意后面要释放
    openParam.Status = OperationStatus.ADDNEW if(billId==None) else OperationStatus.EDIT;
    if(billId<>None):#若传入了具体单据ID,将ID传入单据打开参数
        openParam.PkValue = billId;
    openParam.CreateFrom = CreateFrom.Default;
    openParam.DefaultBillTypeId = "";
    openParam.SetCustomParameter("ShowConfirmDialogWhenChangeOrg", False);#主业务组织改变时,不用弹出提示界面
    plugs = form.CreateFormPlugIns();
    openParam.SetCustomParameter(FormConst.PlugIns, plugs);
    args = PreOpenFormEventArgs(ctx, openParam);
    for plug in plugs:
        plug.PreOpenForm(args);
    if (args.Cancel == True):
        s="不处理";#不理会插件PreOpenForm事件中的诉求,也就是说会强制打开单据
    return openParam;

#自定义方法:演示创建一个二开的单据,通过View构建单据数据包
def CreateBillObj():
    formID="ORA_TestBill";#单据FormId
    meta=MetaDataServiceHelper.GetFormMetaData(this.Context, formID);
    #创建一个新单据View,billId传空,若为修改单据,可传具体单据ID
    billView = CreateBillView(this.Context, formID,None);
    billView.LoadData();
    dynamicFormView =billView;
    dynamicFormView.SetItemValueByID("F_RBSU_OrgId",orgId,0);#给表头组织赋值
    dynamicFormView.UpdateValue("FBillNo",0,"Test001");#给单据编号赋值
    dynamicFormView.UpdateValue("F_RBSU_Remark",0,"测试插件创建");#给表头备注赋值
    #通过View获取单据的完整数据包,相当于表单插件中的this.View.Model.DataObject
    newBilllObj=billView.Model.DataObject;
    entityKey="FEntity";
    En = billView.Model.DataObject[entityKey];#获取单据体数据包
    En.Clear();#先清空单据体
    i=0;#单据体行号游标
    billView.Model.CreateNewEntryRow(entityKey);#为单据体创建一行数据,通常写在循环体内
    dynamicFormView.UpdateValue("F_RBSU_OrderNo",i, "订单号");#为单据体字段赋值
    dynamicFormView.SetItemValueByID("F_RBSU_MaterialId","物料ID",i);#用ID为基础资料字段赋值
    dynamicFormView.SetItemValueByNumber("F_RBSU_StockId","仓库编码",i);#用编码为基础资料字段赋值
    #触发字段值更新事件,否则,不会自动触发,参数说明:字段标识,行号(单据头字段填0)
    dynamicFormView.InvokeFieldUpdateService("F_RBSU_StockId", i);
    #下面2行可以触发实体服务规则
    obj=BOSActionExecuteContext(dynamicFormView);#若是单据体触发,不要循环构建,此行放到循环体外
    dataEntity=En[i];#单据体行数据包,若是单据头触发,则传入单据数据包
    dynamicFormView.RuleContainer.RaiseDataChanged("F_RBSU_MaterialId", dataEntity,obj);
    
    #billView.InvokeFormOperation("Save");#可以通过View直接调用保存,参考下面调用前面讲的Save方法
    billView.InvokeFormOperation(FormOperationEnum.Close);#关闭View
    billView.Close();#关闭View
    billView.CommitNetworkCtrl();#释放网控
    #将数据包构建成集合,最后调用Save方法完成单据创建
    newBillList=List[DynamicObject]();#批量保存单据时使用此方法最佳
    newBillList.Add(newBilllObj);
    saveRslt=BusinessDataServiceHelper.Save(this.Context, meta.BusinessInfo,newBillList.ToArray(), None, "Save");
    return newBilllObj;

四、插件中数据库操作执行SQL语句

多行SQL语句拼接可以参考下面的示例代码。

/*dialect*/为方言标识,前面不能有空格,否则无法起作用。没有方言标识的SQL语句需要满足KSQL语法。

需要添加相关引用:

         clr.AddReference('System.Data')

         clr.AddReference('Kingdee.BOS')

         clr.AddReference('Kingdee.BOS.App')

         from System.Data import *

         from Kingdee.BOS import *

         from Kingdee.BOS.App.Data import *

         

  • DBUtils.ExecuteDataSet:执行查询SQL,返回DataSet

      orgSQL=("""/*dialect*/select org.FNUMBER,orgL.FNAME
from T_ORG_organizations org
inner Join T_ORG_organizations_L  orgL on org.FORGID=orgL.FORGID and orgL.FLocalEId=2052
where OrgId='{0}'  """).format("1");
    ds = DBUtils.ExecuteDataSet(this.Context,orgSQL);
    tab = ds.Tables[0];
    for dr in tab.Rows:
        orgNum=dr["FNUMBER"];
        orgName=dr["FNAME"];

 

  • DBUtils.ExecuteDynamicObject:执行查询SQL,返回DynamicObjectCollection

    dataRows=DBUtils.ExecuteDynamicObject(this.Context,orgSQL);
    for dr in dataRows:
        orgNum=dr["FNUMBER"];
        orgName=dr["FNAME"];

 

  • DBUtils.Execute:执行更新SQL语句,返回受影响的行

     updateSql=("""/*dialect*/update T_ORG_organizations set FNUMBER='testOrg001' where OrgId='{0}'  """).format("1");
    x=DBUtils.Execute(this.Context,updateSql);

 

  • DBUtils.ExecuteBatch:批量执行更新SQL语句

    sqlLList=List[str]();
    sqlLList.Add(updateSql);
    if(sqlLList.Count>0):
        DBUtils.ExecuteBatch(this.Context,sqlLList,sqlLList.Count);

 

  • DBUtils.ExecuteStoreProcedure:执行更存储过程

    #执行存储过程
    ProcName="Proc_SimpleReport_BillA";
    lstParam=List[SqlParam]();#构建存储过程参数
    para=SqlParam("@P1",KDDbType.AnsiString,"AAA");
    lstParam.Add(para);
    para=SqlParam("@P2",KDDbType.AnsiString,"BBB");
    lstParam.Add(para);
    resutParas=DBUtils.ExecuteStoreProcedure(this.Context, ProcName, lstParam);
    for dr in resutParas:
        paraName=dr.Name;
        paraValue=dr.Value;

 

五、其他工具类介绍

  • SystemParameterServiceHelper.GetParamter:读取系统参数

    需要添加相关引用:

          clr.AddReference('Kingdee.BOS.App.Core')

          from Kingdee.BOS.App.Core import *

    #读取系统参数示例
    orgs=List[Int64]();#系统参数需要读取的组织
    orgId=Int64.Parse("1");
    orgs.Add(orgId);
    sysParaFormId="XXX";#系统参数单据FormId
    acctBookId=0;
    paraName="参数字段标识";#使用绑定实体属性标识
    #acctBookId:账簿Id,若读取的参数与账簿无关,传0
    #orgs:组织内码,传入组织ID列表,则会以字典形式一次性返回多个组织的参数,组织ID为key。若参数与组织无关传0
    #paraName:参数名为单个字段,则sysParaObj就是参数值,若为单据体,则sysParaObj是单据体的数据包,DynamicObjectCollection类型
    sysParaObjs=SystemParameterServiceHelper.GetParamter(this.Context, orgs, acctBookId, sysParaFormId, paraName);
    sysParaObj=sysParaObjs[orgId];
    #也可直接传一个组织ID,获取单个组织的参数
    sysParaObj=SystemParameterServiceHelper.GetParamter(this.Context, orgId, acctBookId, sysParaFormId, paraName);

 

  • UserParamterServiceHelper:读取用户单据选项参数

    需要添加相关引用:

          clr.AddReference('Kingdee.BOS.ServiceHelper')

          from Kingdee.BOS.ServiceHelper import *

    #读取用户选项参数
    formID="PUR_PurchaseOrder";#单据FormId
    meta = MetaDataServiceHelper.Load(this.Context, formID);
    paraObjFormId=formMetadata.BusinessInfo.GetForm().ParameterObjectId;#单据的用户参数对象标识
    formMeta = FormMetaDataCache.GetCachedFormMetaData(this.Context, paraObjFormId);
    userId=this.Context.UserId;#用户Id
    #读取到的用户UserParaObj为DynamicObject类型,相当于用户参数单据paraObjFormId对应的数据包,根据绑定实体属性标识即可读取具体参数字段值
    UserParaObj=UserParamterServiceHelper.Load(this.Context, formMeta.BusinessInfo,userId, paraObjFormId, "UserParameter");
    #如果对用户参数数据包UserParaObj进行修改之后,也可以参考如下Save方法保存,对用户参数进行修改
    UserParamterServiceHelper.Save(this.Context, formMeta.BusinessInfo, UserParaObj,paraObjFormId,this.Context.UserId,"UserParameter");

 

  • PermissionServiceHelper:权限检查

    需要添加相关引用:

          clr.AddReference('Kingdee.BOS.ServiceHelper')

          clr.AddReference('Kingdee.BOS.Core')

          from Kingdee.BOS.ServiceHelper import *

          from Kingdee.BOS.Core.Permission import *

    #检查权限
    businessObj=BusinessObject();#业务对象
    formId="PUR_PurchaseOrder";#单据FormId
    businessObj.Id=formId;
    #可从数据库查询权限项ID:select a.FItemID from T_SEC_PermissionItem a where  a.FNumber='BOS_AUDIT'
    permissionItemId="权限项ID";
    iResult = PermissionServiceHelper.FuncPermissionAuth(this.Context,businessObj,permissionItemId);
    if (iResult.Passed==False):
        raise Exception("对不起,您没有权限!") ;

 

更多常用工具类使用参考:web层插件代码常用写法

 

==========================本篇正文结束=====================================

插件示例代码已经上传附件,老规矩,大家按需下载!

【Python插件入门讲解】系列到这里就完结啦,感谢大家的持续关注,后面有Python实践案例,还算是会不定期分享。

标签:完结篇,插件,数据包,BOS,Kingdee,单据,Context,常用工具
From: https://www.cnblogs.com/woshinige/p/18395115

相关文章

  • Python插件入门】第3篇-插件中如何进行数据操作
    Python插件入门】第3篇-插件中如何进行数据操作原创金蝶云·星空-BOS平台金蝶云·星空-基础架构金蝶云·星空-学习笔记金蝶云·星空-协同开发更多 CQ周玉立已关注286人赞赏了该文章 3.2万次浏览 未经作者许可,禁止转载编辑于2022年09月02日10:58:02......
  • 【Python插件入门】第4篇:单据表单插件
    【Python插件入门】第4篇:单据表单插件原创金蝶云·星空-BOS平台金蝶云·星空-基础架构金蝶云·星空-学习笔记金蝶云·星空-协同开发更多 CQ周玉立已关注247人赞赏了该文章 3.4万次浏览 未经作者许可,禁止转载编辑于2022年09月07日15:00:34摘要由A......
  • 【Python插件入门】第5篇:单据列表插件
    【Python插件入门】第5篇:单据列表插件原创金蝶云·星空-BOS平台金蝶云·星空-基础架构金蝶云·星空-学习笔记金蝶云·星空-协同开发更多 CQ周玉立已关注210人赞赏了该文章 2万次浏览 未经作者许可,禁止转载编辑于2022年08月17日10:37:48摘要由AI......
  • 插件机制与开发
    插件实现流程在开始编写DzzOffice插件之前,您应当首先对插件开发流程有一个大致的了解。以下是推荐的插件开发流程:在熟练掌握DzzOffice系统的基础上,对希望完善或补充的个性化功能进行评估,进而提出插件的功能需求。对插件进行概要设计,如:需使用哪些菜单、参数,配置哪些选项、数......
  • sonarqube 项目内maven插件使用
    一般建议保持项目jdk和sonarqube的jdk版本呢一致,sonarqube支持的版本最低的也是jdk11,如果要使用sonarqube,建议项目尽量上jdk17。sonarmaven插件依赖<!--属性配置--><properties><!--sonarqube配置--><sonar.projectKey>TestExample</sonar.p......
  • react-hook-form 搭配 next-intl 国际化插件 处理form 表单错误
    useEffect(()=>{ form.clearErrors() if(state&&state.data){ router.push('/') } //后台错误 if(state&&state.errorMessage){ //showErrorToast(t(state.errorMessage)) showErrorToast(state.errorMessage) } ......
  • 博客园-awescnb插件-geek皮肤优化-表情配置
    ......
  • 用了这款 Notion 汉化插件,我的工作效率提升了300%
    作者:苍何,前大厂高级Java工程师,阿里云专家博主,2023年实力新星,土木转码,现任部门技术leader,专注于互联网技术分享,职场经验分享。大家好,我是苍何。今天给大家分享Notion汉化插件,提高工作效率。Notion,作为一款广受欢迎的笔记和组织工具,已在全球范围内获得了广泛的用户基础。然而......
  • 实现AI带货直播需要开发一个插件!
    在电商行业蓬勃发展的今天,直播带货已成为商家们竞相追逐的新风口,而随着人工智能(AI)技术的日益成熟,将AI融入带货直播,无疑将为这一领域带来革命性的变化。直播带货以其独特的互动性和即时性,迅速赢得了消费者的青睐,然而,传统直播带货模式在商品推荐、互动引导等方面仍存在一定的局限性......
  • 视频号的视频怎么下载?教你用油猴(Tampermonkey)插件来下载视频
     这个视频号的下载方法支持手机和电脑,请看教程一、环境准备  微信文件传输助手网页版 :微信文件传输助手网页版1.edge(电脑端)下载TampermonkeyTampermonkey-MicrosoftEdgeAddons安装后右上角扩展会有一个黑色的图标​​​2.手机端安装浏览器苹果端:亚瑟浏览器......