用友U8的二次开发,有一个重要的功能就是调用U8的API,生成或者审核U8的业务单据.当然这些单据可以直接通过写数据库的方式,直接插入或者更新数据表也能达到预期.但除非非常熟悉用友数据表的逻辑,否则这种直接写数据库的方式,有诸多风险,比如数据逻辑错误,关联错误等等.

本文提供一以一种通用的API调用方式,避免受客户端环境(比如是否安装用友,用友的版本约束等)影响.估计有反应快的同学已经猜到,通过在服务器部署WebService或者WebAPI接口的方式,提供给客户端调用就可以实现这个方案.

做过用友U8二次API开发的同学们都知道,调用用友API的首先的先决条件是登录系统,获得U8Login对象,这个对象是通过登录用友后获得的.主要的参数可以参考U8发布出来的通用文档.这个地方就不多说.(注意:在u816以后,API调用的方式将被限制,不购买OpenAPI授权下,是不能调用API方式写入单据.直接写数据库的方式请参考我后续发布的文章)

1.打开 VS2019,创建一个WebService,或者AspMVC程序都行,反正能提供给客户端调用的接口的程序类型都行

2.要创建U8Login对象,需要在项目中引用以下dll

UFIDA.U8.MomServiceCommon.dll

UFIDA.U8.Portal.Common.dll

UFIDA.U8.Portal.Framework.dll

UFIDA.U8.Portal.Proxy.dll

UFIDA.U8.U8APIFramework.dll

UFIDA.U8.U8MOMAPIFramework.dll

UFSoft.U8.Framework.Login.UI.dll

生成U8Login对象的的代码如下具体

/第一步:构造u8login对象并登陆(引用U8API类库中的Interop.U8Login.dll)//如果当前环境中有login对象则可以省去第一步U8Login.clsLogin u8Login = new U8Login.clsLogin();String sSubId = "AS";String sAccID = ConfigurationManager.AppSettings["sAccID"].ToString();String sYear = DateTime.Today.Year.ToString();String sUserID = ConfigurationManager.AppSettings["sUserID"].ToString();String sPassword = ConfigurationManager.AppSettings["sPassword"].ToString();String sDate = DateTime.Today.ToString("yyyy-MM-dd");String sServer = ConfigurationManager.AppSettings["sServer"].ToString();String sSerial = "";if (!u8Login.Login(ref sSubId, ref sAccID, ref sYear, ref sUserID, ref sPassword, ref sDate, ref sServer, ref sSerial)){resp.resp = "fail";resp.msg = "登陆失败,原因:" + u8Login.ShareString;result = "{\"resp\":\"" + resp.resp + "\",\"msg\":\"" + resp.msg + "\",\"retcode\":\"" + dmlist.cDLCode + "\"}";return false;}

U8Login对象可以在调用的时候建立,或者在Web应用程序初始化的建立,作为全局对象保存,需要的时候直接使用.另外,透露一个U8的秘密,对于从IIS进程,JAVA进程发起的Login请求,U8是不校验U8Login对象是否是调试版的U8Login.

3.拿到U8Login对应以后,就可以调用U8API了.具体API的声明以及参数使用,参考用友的API资源管理器中的范例,此处用一个范例说明(销售发货单)

//第二步:构造环境上下文对象,传入login,并按需设置其它上下文参数U8EnvContext envContext = new U8EnvContext();envContext.U8Login = u8Login;//销售所有接口均支持内部独立事务和外部事务,默认内部事务//如果是外部事务,则需要传递ADO.Connection对象,并将IsIndependenceTransaction属性设置为false//envContext.BizDbConnection = new ADO.Connection();//envContext.IsIndependenceTransaction = false;//设置上下文参数envContext.SetApiContext("VoucherType", VoucherType); //上下文数据类型:int,含义:单据类型//第三步:设置API地址标识(Url)//当前API:新增或修改的地址标识为:U8API/Consignment/SaveU8ApiAddress myApiAddress = new U8ApiAddress(cAds);//第四步:构造APIBrokerU8ApiBroker broker = new U8ApiBroker(myApiAddress, envContext);//第五步:API参数赋值//给BO表头参数domHead赋值,此BO参数的业务类型为发货单,属表头参数。BO参数均按引用传递//提示:给BO表头参数domHead赋值有两种方法//方法一是直接传入MSXML2.DOMDocumentClass对象//broker.AssignNormalValue("domHead", new MSXML2.DOMDocumentClass())ADODB.Connection conn = new ADODB.ConnectionClass();ADODB.Recordset rs = new ADODB.RecordsetClass();MSXML2.DOMDocument domhead = new MSXML2.DOMDocumentClass();string strConn = string.Format("Provider=SQLOLEDB;Initial Catalog={0};Data Source={1};", ConfigurationManager.AppSettings["sDBname"].ToString(), u8Login.dbServerName);conn.Open(strConn, "sa", u8Login.SysPassword, 0);string sql = "select * from Sales_FHD_T where 1=0";rs.Open(sql, conn, ADODB.CursorTypeEnum.adOpenForwardOnly, ADODB.LockTypeEnum.adLockOptimistic, -1);rs.Save(domhead, ADODB.PersistFormatEnum.adPersistXML);U8APIHelper.FormatDom(ref domhead, "A");broker.AssignNormalValue("DomHead", domhead);domhead.selectSingleNode("//rs:data/z:row").attributes.getNamedItem("cdlcode").nodeValue = dmlist.cDLCode;domhead.selectSingleNode("//rs:data/z:row").attributes.getNamedItem("ddate").nodeValue = dmlist.dDate;domhead.selectSingleNode("//rs:data/z:row").attributes.getNamedItem("cbustype").nodeValue = dmlist.cSTCode == "03" ? "委托代销" : dmlist.cBusType;domhead.selectSingleNode("//rs:data/z:row").attributes.getNamedItem("cstname").nodeValue = GetSTNameByCode(dmlist.cSTCode);domhead.selectSingleNode("//rs:data/z:row").attributes.getNamedItem("ccusabbname").nodeValue = GetCusAbbNameByCode(dmlist.cCusCode);domhead.selectSingleNode("//rs:data/z:row").attributes.getNamedItem("cdepname").nodeValue = GetDepNameByCode(dmlist.cDepCode);domhead.selectSingleNode("//rs:data/z:row").attributes.getNamedItem("cstcode").nodeValue = dmlist.cSTCode;domhead.selectSingleNode("//rs:data/z:row").attributes.getNamedItem("ivtid").nodeValue = U8APIHelper.GetVTIDByCardNum(u8Login, cCardNum);domhead.selectSingleNode("//rs:data/z:row").attributes.getNamedItem("ccusname").nodeValue = GetCusNameByCode(dmlist.cCusCode);domhead.selectSingleNode("//rs:data/z:row").attributes.getNamedItem("ccuscode").nodeValue = dmlist.cCusCode;domhead.selectSingleNode("//rs:data/z:row").attributes.getNamedItem("cmaker").nodeValue = u8Login.cUserName;domhead.selectSingleNode("//rs:data/z:row").attributes.getNamedItem("cexch_name").nodeValue = dmlist.cExch_Name;domhead.selectSingleNode("//rs:data/z:row").attributes.getNamedItem("iexchrate").nodeValue = exRate.ToString();// dmlist.cSTCode == "02" ? "6.8" : "1";domhead.selectSingleNode("//rs:data/z:row").attributes.getNamedItem("itaxrate").nodeValue = dmlist.iTaxRate;domhead.selectSingleNode("//rs:data/z:row").attributes.getNamedItem("cdepcode").nodeValue = dmlist.cDepCode;domhead.selectSingleNode("//rs:data/z:row").attributes.getNamedItem("breturnflag").nodeValue = dmlist.cFlag;domhead.selectSingleNode("//rs:data/z:row").attributes.getNamedItem("cvouchname").nodeValue = VType;domhead.selectSingleNode("//rs:data/z:row").attributes.getNamedItem("cvouchtype").nodeValue = dmlist.cSTCode == "03" ? "06" : "05";domhead.selectSingleNode("//rs:data/z:row").attributes.getNamedItem("cpersonname").nodeValue = GetPerNameByCode(dmlist.cPerCode);domhead.selectSingleNode("//rs:data/z:row").attributes.getNamedItem("cpersoncode").nodeValue = dmlist.cPerCode;domhead.selectSingleNode("//rs:data/z:row").attributes.getNamedItem("cmemo").nodeValue = dmlist.cMemo;domhead.selectSingleNode("//rs:data/z:row").attributes.getNamedItem("bneedbill").nodeValue = "1";domhead.selectSingleNode("//rs:data/z:row").attributes.getNamedItem("isale").nodeValue = "0";domhead.selectSingleNode("//rs:data/z:row").attributes.getNamedItem("iflowid").nodeValue = "0";domhead.selectSingleNode("//rs:data/z:row").attributes.getNamedItem("iverifystate").nodeValue = "0";domhead.selectSingleNode("//rs:data/z:row").attributes.getNamedItem("ireturncount").nodeValue = "0";domhead.selectSingleNode("//rs:data/z:row").attributes.getNamedItem("iswfcontrolled").nodeValue = "0";//收付款协议string AgrCode = GetCusSAProtocol(dmlist.cCusCode);AgrCode = "SA10";if (AgrCode != ""){domhead.selectSingleNode("//rs:data/z:row").attributes.getNamedItem("cgatheringplan").nodeValue = AgrCode;domhead.selectSingleNode("//rs:data/z:row").attributes.getNamedItem("cgatheringplanname").nodeValue = GetAgrName(AgrCode);domhead.selectSingleNode("//rs:data/z:row").attributes.getNamedItem("dcreditstart").nodeValue = dmlist.dDate;domhead.selectSingleNode("//rs:data/z:row").attributes.getNamedItem("dgatheringdate").nodeValue = Convert.ToDateTime(dmlist.dDate).AddDays(GetAgrNum(AgrCode)).ToString("yyyy-MM-dd");domhead.selectSingleNode("//rs:data/z:row").attributes.getNamedItem("icreditdays").nodeValue = GetAgrNum(AgrCode).ToString();//domhead.selectSingleNode("//rs:data/z:row").attributes.getNamedItem("bcredit").nodeValue = "1";}//固定值// domhead.selectSingleNode("//rs:data/z:row").attributes.getNamedItem("cgatheringplan").nodeValue = "S10";domhead.selectSingleNode("//rs:data/z:row").attributes.getNamedItem("bcredit").nodeValue = "0";List<FHDetails> ddlst = dmlist.cDetails;MSXML2.DOMDocument domBody = new MSXML2.DOMDocumentClass();ADODB.Connection conn1 = new ADODB.ConnectionClass();ADODB.Recordset rs1 = new ADODB.RecordsetClass();string strConn1 = string.Format("Provider=SQLOLEDB;Initial Catalog={0};Data Source={1};", ConfigurationManager.AppSettings["sDBname"].ToString(), u8Login.dbServerName);conn1.Open(strConn, "sa", u8Login.SysPassword, 0);sql = "select * from Sales_FHD_W where 1=0";rs1.Open(sql, conn, ADODB.CursorTypeEnum.adOpenForwardOnly, ADODB.LockTypeEnum.adLockOptimistic, -1);rs1.Save(domBody, ADODB.PersistFormatEnum.adPersistXML);U8APIHelper.FormatDom(ref domBody, ddlst.Count, "A");broker.AssignNormalValue("domBody", domBody);for (int i = 0; i < ddlst.Count; i++){DataTable dtinv = GetInvInfo(ddlst[i].cInvCode);string _iquantity = ddlst[i].xnflag == "1" ? "0" : ddlst[i].iQuantity;if (dtinv.Rows.Count == 0){resp.resp = "fail";resp.msg = "存货编码[" + ddlst[i].cInvCode + "]不存在!";result = "{\"resp\":\"" + resp.resp + "\",\"msg\":\"" + resp.msg + "\",\"retcode\":\"" + dmlist.cDLCode + "\"}";u8Login.ShutDown();broker.Release();return false;}//LogException.WriteTxt(dmlist.cDLCode + ":" + ddlst[i].cInvCode + ":" + _iquantity, "AAAADISJSON");domBody.selectNodes("//rs:data/z:row")[i].attributes.getNamedItem("cwhcode").nodeValue = ddlst[i].cWhCode;domBody.selectNodes("//rs:data/z:row")[i].attributes.getNamedItem("cinvcode").nodeValue = ddlst[i].cInvCode;domBody.selectNodes("//rs:data/z:row")[i].attributes.getNamedItem("iquantity").nodeValue = _iquantity;domBody.selectNodes("//rs:data/z:row")[i].attributes.getNamedItem("itaxunitprice").nodeValue = ddlst[i].iTaxUnitPrice;domBody.selectNodes("//rs:data/z:row")[i].attributes.getNamedItem("irowno").nodeValue = i + 1;domBody.selectNodes("//rs:data/z:row")[i].attributes.getNamedItem("cwhname").nodeValue = GetWhNameByCode(ddlst[i].cWhCode);domBody.selectNodes("//rs:data/z:row")[i].attributes.getNamedItem("cinvstd").nodeValue = dtinv.Rows[0]["cinvstd"];double iNatsum = 0, iNatunitprice = 0, iNatmoney = 0, itax = 0;double isum = 0, iunitPrice = 0, imoney = 0, inattax = 0;// if (dmlist.cSTCode == "02")if(exRate!=1){iNatsum = Convert.ToDouble(ddlst[i].iQuantity) * Convert.ToDouble(ddlst[i].iTaxUnitPrice) * (double)exRate;isum = Convert.ToDouble(ddlst[i].iQuantity) * Convert.ToDouble(ddlst[i].iTaxUnitPrice);iunitPrice = Convert.ToDouble(ddlst[i].iTaxUnitPrice);iNatunitprice = Convert.ToDouble(ddlst[i].iTaxUnitPrice) * (double)exRate;iNatmoney = Convert.ToDouble(ddlst[i].iQuantity) * iNatunitprice;imoney = Convert.ToDouble(ddlst[i].iQuantity) * iunitPrice;itax = isum - imoney;inattax = iNatsum - iNatmoney;}else{iNatsum = Convert.ToDouble(ddlst[i].iQuantity) * Convert.ToDouble(ddlst[i].iTaxUnitPrice);isum = iNatsum;iNatunitprice = Convert.ToDouble(ddlst[i].iTaxUnitPrice) / (1 + Convert.ToDouble(dmlist.iTaxRate) / 100);iunitPrice = iNatunitprice;iNatmoney = Convert.ToDouble(ddlst[i].iQuantity) * iNatunitprice;imoney = iNatmoney;itax = isum - imoney;inattax = iNatsum - iNatmoney;}domBody.selectNodes("//rs:data/z:row")[i].attributes.getNamedItem("iquotedprice").nodeValue = 0;domBody.selectNodes("//rs:data/z:row")[i].attributes.getNamedItem("iunitprice").nodeValue = iunitPrice.ToString("F2");domBody.selectNodes("//rs:data/z:row")[i].attributes.getNamedItem("imoney").nodeValue = imoney.ToString("F2");domBody.selectNodes("//rs:data/z:row")[i].attributes.getNamedItem("itax").nodeValue = itax.ToString("F2");domBody.selectNodes("//rs:data/z:row")[i].attributes.getNamedItem("isum").nodeValue = isum.ToString("F2");domBody.selectNodes("//rs:data/z:row")[i].attributes.getNamedItem("idiscount").nodeValue = 0;domBody.selectNodes("//rs:data/z:row")[i].attributes.getNamedItem("inatunitprice").nodeValue = iNatunitprice.ToString("F2");domBody.selectNodes("//rs:data/z:row")[i].attributes.getNamedItem("inatmoney").nodeValue = iNatmoney.ToString("F2");domBody.selectNodes("//rs:data/z:row")[i].attributes.getNamedItem("inattax").nodeValue = inattax.ToString("F2");domBody.selectNodes("//rs:data/z:row")[i].attributes.getNamedItem("inatsum").nodeValue = iNatsum.ToString("F2");domBody.selectNodes("//rs:data/z:row")[i].attributes.getNamedItem("inatdiscount").nodeValue = 0;domBody.selectNodes("//rs:data/z:row")[i].attributes.getNamedItem("itaxrate").nodeValue = dmlist.iTaxRate;domBody.selectNodes("//rs:data/z:row")[i].attributes.getNamedItem("kl2").nodeValue = 100;domBody.selectNodes("//rs:data/z:row")[i].attributes.getNamedItem("kl").nodeValue = 100;domBody.selectNodes("//rs:data/z:row")[i].attributes.getNamedItem("ccomunitcode").nodeValue = dtinv.Rows[0]["ccomunitcode"];domBody.selectNodes("//rs:data/z:row")[i].attributes.getNamedItem("cinvm_unit").nodeValue = dtinv.Rows[0]["ccomunitname"];domBody.selectNodes("//rs:data/z:row")[i].attributes.getNamedItem("igrouptype").nodeValue = dtinv.Rows[0]["igrouptype"];domBody.selectNodes("//rs:data/z:row")[i].attributes.getNamedItem("cgroupcode").nodeValue = dtinv.Rows[0]["cgroupcode"];if (Convert.ToBoolean(dtinv.Rows[0]["bfree1"]))domBody.selectNodes("//rs:data/z:row")[i].attributes.getNamedItem("cfree1").nodeValue = ddlst[i].cFree1;if (Convert.ToBoolean(dtinv.Rows[0]["bfree2"]))domBody.selectNodes("//rs:data/z:row")[i].attributes.getNamedItem("cfree2").nodeValue = ddlst[i].cFree2;}//给普通参数VoucherState赋值。此参数的数据类型为int,此参数按值传递,表示状态:0增加;1修改broker.AssignNormalValue("VoucherState", 0);//该参数vNewID为INOUT型普通参数。此参数的数据类型为string,此参数按值传递。在API调用返回时,可以通过GetResult("vNewID")获取其值broker.AssignNormalValue("vNewID", "");//给普通参数DomConfig赋值。此参数的数据类型为MSXML2.IXMLDOMDocument2,此参数按引用传递,表示ATO,PTO选配MSXML2.IXMLDOMDocument2 domMsg = new MSXML2.DOMDocumentClass();broker.AssignNormalValue("DomConfig", domMsg);//第六步:调用APIif (!broker.Invoke()){//错误处理Exception apiEx = broker.GetException();if (apiEx != null){if (apiEx is MomSysException){MomSysException sysEx = apiEx as MomSysException;resp.resp = "fail";resp.msg = "系统异常:" + sysEx.Message;result = "{\"resp\":\"" + resp.resp + "\",\"msg\":\"" + resp.msg + "\",\"retcode\":\"" + dmlist.cDLCode + "\"}";//todo:异常处理}else if (apiEx is MomBizException){MomBizException bizEx = apiEx as MomBizException;resp.resp = "fail";resp.msg = "API异常:" + bizEx.Message;result = "{\"resp\":\"" + resp.resp + "\",\"msg\":\"" + resp.msg + "\",\"retcode\":\"" + dmlist.cDLCode + "\"}";//todo:异常处理}//异常原因String exReason = broker.GetExceptionString();if (exReason.Length != 0){resp.resp = "fail";resp.msg = "异常原因:" + exReason;result = "{\"resp\":\"" + resp.resp + "\",\"msg\":\"" + resp.msg + "\",\"retcode\":\"" + dmlist.cDLCode + "\"}";}}u8Login.ShutDown();//结束本次调用,释放API资源broker.Release();return false;}//第七步:获取返回结果//获取返回值//获取普通返回值。此返回值数据类型为System.String,此参数按值传递,表示成功返回空串System.String res = broker.GetReturnValue() as System.String;//获取out/inout参数值//获取普通INOUT参数vNewID。此返回值数据类型为string,在使用该参数之前,请判断是否为空string vNewIDRet = broker.GetResult("vNewID") as string;if (string.IsNullOrEmpty(res) && vNewIDRet != ""){resp.resp = "succ";resp.msg = VType + "[" + dmlist.cDLCode + "]创建成功!";result = "{\"resp\":\"" + resp.resp + "\",\"msg\":\"" + resp.msg + "\",\"retcode\":\"" + dmlist.cDLCode + "\"}";bool isExistDispCode = CheckIsExistsDispCode(dmlist.cDLCode);if (!isExistDispCode){resp.resp = "fail";resp.msg = VType + "[" + dmlist.cDLCode + "] 用友对应单据不存在!";result = "{\"resp\":\"" + resp.resp + "\",\"msg\":\"" + resp.msg + "\",\"retcode\":\"" + dmlist.cDLCode + "\"}";u8Login.ShutDown();broker.Release();return false;}//VerifyDispatchlist(u8Login, VoucherType, vNewIDRet);审核销售出库单//string ckid = U8APIHelper.GetChildIDByFatherID(u8Login, "ID", "rdrecord32", "cDLCode", vNewIDRet);//VerifyRd32(u8Login, ckid);}else{resp.resp = "fail";resp.msg = VType + "[" + dmlist.cDLCode + "]创建失败!" + res;result = "{\"resp\":\"" + resp.resp + "\",\"msg\":\"" + resp.msg + "\",\"retcode\":\"" + dmlist.cDLCode + "\"}";u8Login.ShutDown();broker.Release();return false;}u8Login.ShutDown();//结束本次调用,释放API资源broker.Release();

代码中,分别用:销售发货单(退回单) 调拨单 采购入库单 材料出库单等API的调用,展示了用友API的调用过程

JSON范例请参考完整代码的

销售发货单JSON:
{"cFlag":"0","cDLCode":"PFD-A-026384","dDate":"2018-09-21","cSTCode":"01","cBusType":"普通销售","cDepCode":"1402","cExch_Name":"人民币","cCusCode":"A0457","iTaxRate":"16","cDetails":[{"cWhCode":"042","cinvcode":"0108020743","cFree1":"","cFree2":"","iQuantity":"1.0000","iTaxUnitPrice":"1888.0000000"}]}调拨单JSON:
{"cFlag":"0","cTVCode":"TBM-A-008699","dTVDate":"2018-10-16","cIWhCode":"044","cOWhCode":"017","cIRdCode":"120","cORdCode":"220","cDetails":[{"cInvCode":"0402011632","cFree1":"","cFree2":"","iTVQuantity":"1.0000","iTVACost":"0"}]}

完整代码:https://download.csdn.net/download/daniel_qsy/85686892https://download.csdn.net/download/daniel_qsy/85686892

用友U8二次开发调用API通用解决方案相关推荐

  1. 用友U8二次开发之登录

    首先引用U8的登录DLL: 然后是调用U8的登录UI: UFSoft.U8.Framework.Login.UI.clsLogin U_Login = new UFSoft.U8.Framework. ...

  2. 记录用友ERP二次开发全过程(转载)

    记录用友ERP二次开发全过程 以此为备忘录. 最好在机器上装好U8. 下一步把自定义权限及模块加入U8里,以方便外部程序调用,识别! function erpLogin:boolean; var lo ...

  3. nx二次开发c语言,NX二次开发-UFUN API函数编程基础

    1.NXOpen C 的函数 函数名称的约定 NX Open C 共有2类名称约定:一个是标准的NX Open C 的函数名称约定:另一个是以前版本的原有的名称约定. 1.标准名称约定 [格式]UF_ ...

  4. 微信开发sdk_二次开发微信API更新日志

    微信开发sdk_二次开发微信API更新日志 微信开发sdk_二次开发微信API更新日志 2.6.35 清粉优化 小于1k的图片发送失败的问题 联系人资料新增电话号码和描述 发布2.6.31->2 ...

  5. 通达信二次开发接口api如何操作?

    通达信二次开发接口api如何操作,步骤如下: 1.调用LoadLibrary加载MetaTrade.dll实例: 2.调用GetProcAddress获取API函数地址: 3.调用Init接口进行AP ...

  6. 金蝶、用友的二次开发通常是指做什么?(问答形式)

    问: 1.金蝶.用友的二次开发做什么?2.就是开发点报表.修改或设计点业务流程吗?3.会不会涉及到修改数据库或者源代码?4.金蝶.用友应该不可能开放源代码吧? 答: 二次开发的工作分两个部分.一部分是 ...

  7. 用友NC二次开发问题汇总【转】

    一.供应链采购订单问题 在采购订单参照请购单时,若选择了10行请购单的记录,采购订单的表体也就显示了10条记录,如何才能实现还可以再弹出请购单的参照,追加一条记录,而不需要取消单据后重现选择请购单. ...

  8. [转] 用友NC二次开发问题汇总【转】

    原文: http://blog.csdn.net/softwave/article/details/8739799 1. nc57 字段颜色 getDealArrivalUI().getBillCar ...

  9. dz发帖html模式,discuz二次开发调用编辑器发帖显示html何解?

    discuz的开发文档很少,在二次开发的时候用discuz的编辑器,显示的是html代码,查看源码和各种莫名其妙的问题着实令人摸不着头脑.而discuz帖子存储在数据库的却是自定义的bbcode而不是 ...

最新文章

  1. 「SAP技术」A项目关联公司间退货STO流程
  2. Java JPanel的使用
  3. 一篇文章搞定面试中的二叉树题目(java实现)
  4. 监听某个区域滚动_监听页面滚动及滚动到指定位置
  5. selinum-操作表单元素-0223
  6. ASP .NET Controller返回类型
  7. 这个应用魔方厉害了,让软件开发者效率提升10倍
  8. 华为鸿蒙OS发布!余承东:如果安卓不可用,随时启用鸿蒙
  9. 品牌就是复购,运营就是零售
  10. 普通开发人员与软件工程师的区别
  11. 团队作业 -- beta版本
  12. ASM 转自三思笔记
  13. SPSS数据分析常见问题(差异性研究)
  14. DP接口与HDMI接口的区别?
  15. 【easyui】easyui datagrid deleteRow报错修复
  16. Arduino 串口读写函数快慢/时间花费
  17. 自定义View之指南针(反编译别人的代码实现)
  18. 逻辑运算符和逻辑表达式(逻辑或、逻辑与、逻辑非)
  19. 国产服务器Kylin(aarch64)安装mysql8.0.27
  20. docker一个镜像启动多个容器的操作

热门文章

  1. ssm杏坛女子学院系统毕业设计源码
  2. 解决动易SiteWeaver6.8后台编辑器支持IE9/IE10/IE11浏览器的方法
  3. 关于RF框架的一些整理
  4. HP存储2000FC基础操作方法
  5. C语言分数参与运算的表达式
  6. 佳能Canon PIXMA iP1600 打印机驱动
  7. uoj#58./bzoj3052 【WC2013】糖果公园 //树上带修改莫队
  8. 写代码python用什么笔记本好_写代码对电脑有要求吗?什么电脑适合写代码?
  9. 学习单片机的准备工作
  10. 暴风影音使用的小技巧