泛微日常开发

 
【泛微Ecology8.0二次开发指导手册 -  CSDN App】https://blog.csdn.net/qq_41956016/article/details/107017240?sharetype=blogdetail&shareId=107017240&sharerefer=APP&sharesource=qq_29789565&sharefrom=link

一、免登录,免白名单配置

1.配置webservice         weaver_security_common_forbidden_skip_url_xasad72.xml(文件名可新建)

<?xml version="1.0" encoding="utf-8"?>

<root>
    <skip-any-check-list>
        <url>/services/QueryProcessStatusService</url>
    </skip-any-check-list>
</root>

2.配置jsp    weaver_security_custom_rules_not_need_login_240304_11.xml(文件名可新建)

<?xml version="1.0" encoding="UTF-8"?>

<root> 
    <no-login-urls>
        <url>接口1</url>
        <url>接口2</url>
    </no-login-urls>
</root>

        /ecology/WEB-INF/securityXML/目录下,然后用sysadmin登录,访问下/updateRules.jsp,等60s左右再测试功能

二、E8单点登录

      /login/VerifyLogin.jsp

      post     loginid   userpassword   logintype=1   gopage登录跳转链接

三、E8流程提交、退回

       0fc39a98a6954b4090c974ea20da3bf1.png

注意:userid必须为下个节点的审批人,先获取下个节点审批人

bbcada52a65047e2be74e0485ba53426.png

四、sql

ECOLOGY.SequenceIndex表 获取每各表新增的ID,用后记得更新加+1 

抄送批量提交语句
从待办到已办
-脚本说明:
--修改workflow_currentoperator表中的数据, 即可实现从待办到已办
--isremark=2表示已操作
--islasttimes=1表示这条数据是这个人对这个请求最后一次的流转操作
--userid:流程在谁的待办中, 需要改到已办中, 这里就填写谁的userid, 查询userid可以执行select id from hrmresource where lastname='姓名'
--isremark=8表示只修改那些"抄送不需提交"的流程
--workflowid:要更新哪个路径下的流程, 这里就填写哪个workflowid
update workflow_currentoperator set isremark='2',islasttimes='1' where userid='谁的待办需要删除, 这里就填写谁的id' and isremark='8' and workflowid in('哪个路径下的抄送需要更新,这里就填哪个路径的id','哪个路径下的抄送需要更新,这里就填哪个路径的id',...)

 -------------查询表名

 select distinct ba.workflowname ,bi.tablename from workflow_base ba
                inner join workflow_bill bi on ba.formid=bi.id 
                where ba.workflowname='XXXXXX'


 -------------查询字段
              

 select f.fieldname,o.labelname,f.detailtable from workflow_billfield f
                inner join workflow_bill b on  f.billid = b.id
                inner join HtmlLabelInfo o on  f.fieldlabel = o.indexid
                where  o.languageid = 7 and b.tablename = 'formtable_main_397'


-----------

SELECT DISTINCT NODE.NODENAME "当前节点名称",
    BASE.WORKFLOWNAME "工作流名称"  FROM WORKFLOW_BASE BASE  
    INNER JOIN workflow_flownode B ON B.workflowid=BASE.ID
    INNER JOIN WORKFLOW_NODEBASE NODE ON  B.nodeid = NODE.id 
    WHERE
    NODE.NODENAME LIKE '%出纳%' AND BASE.WORKFLOWNAME NOT LIKE '%作废%' AND isvalid=1


----------------查询流程的所有节点

select b.TYPENAME,a.WORKFLOWNAME,d.nodename
from workflow_base a 
inner join workflow_Type b on a.workflowtype=b.id
inner join workflow_flownode c on c.workflowid=a.id
inner join workflow_nodebase d on d.id=c.nodeid
where b.id=81 and isvalid=1 order by WORKFLOWNAME,NODENAME asc

--《工作流单据信息表》 查 对应流程表单 ID

SELECT ID FROM workflow_bill WHERE TABLENAME='formtable_main_303'; --查询流程表单 ID

--《工作流单据字段表》 WHERE billid(单据ID) AND FIELDNAME(字段名) AND DETAILTABLE(明细表)
 

SELECT * FROM workflow_billfield WHERE billid=-303 AND FIELDNAME='sl'
SELECT * FROM workflow_billfield WHERE billid=-303 AND FIELDNAME='sl' AND DETAILTABLE='formtable_main_303_dt1' 

--可修改表中浏览集成按钮绑定

--备份《工作流单据字段表》,保险起见可以备份下表

select * into workflow_billfield_bak20230726 from workflow_billfield

--更新 《工作流单据字段表》 fielddbtype(单据字段数据库类型) fielddbtype decimal(38,2) 改为 decimal(38,4) ,修改后重启服务。

UPDATE workflow_billfield SET fielddbtype = 'decimal(38,4)' WHERE fielddbtype='decimal(38,2)' AND billid=-303 AND FIELDNAME='sl' AND DETAILTABLE='formtable_main_303_dt1'
select a.nodeid,b.NODENAME,a.* from workflow_flownode a inner join workflow_nodebase b on a.NODEID=b.id where workflowid=19011  找出workflowid 对应节点

--------------查询上个节点与下个节点

select a.WORKFLOWID,a.nodeid,b.NODENAME as dqnodename,a.DESTNODEID,c.NODENAME as xgnodename,d.WORKFLOWNAME,d.activeVersionID,CASE WHEN H.VERSION IS NULL OR H.VERSION='' then 1 else H.VERSION end   as  activebb from workflow_nodelink a 
inner join workflow_nodebase b on a.NODEID=b.id
inner join workflow_nodebase c on a.DESTNODEID=c.id
inner join workflow_base d on a.workflowid=d.id
inner join workflow_base H on D.activeVersionID=H.id
where b.NODENAME like '%XXXX%' and c.NODENAME like '%总裁%' and  (a.isreject='' or a.isreject is null)  

--------------------------查询审批人与下个审批人

select distinct a.REQUESTID,a.OPERATOR as dqjeryid,b.OPERATOR as xgjeryid,c.NODENAME,d.WORKFLOWNAME from  WORKFLOW_REQUESTLOG a inner join WORKFLOW_REQUESTLOG b on a.REQUESTID=b.REQUESTID
inner join workflow_nodebase c on a.nodeid=c.id  
inner join workflow_base d on a.workflowid=d.id
inner join HRMRESOURCE e on b.OPERATOR=e.id
where a.DESTNODEID=b.nodeid and b.OPERATOR not in('210','820')  and   a.OPERATOR='820' and e.seclevel>='90'

---------------------------岗位sql-------------

岗位sql调整需要调用JobTitlesComInfo.removeJobTitlesCache();清理缓存生效

<%@ page import="weaver.monitor.cache.CacheFactory" %>
<jsp:useBean id="SubCompanyComInfo" class="weaver.hrm.company.SubCompanyComInfo" scope="page" />
<jsp:useBean id="DepartmentComInfo" class="weaver.hrm.company.DepartmentComInfo" scope="page" />
<jsp:useBean id="JobTitlesComInfo" class="weaver.hrm.job.JobTitlesComInfo" scope="page" />
<jsp:useBean id="ResourceComInfo" class="weaver.hrm.resource.ResourceComInfo" scope="page" />
<%

        SubCompanyComInfo.removeCompanyCache();
        DepartmentComInfo.removeCompanyCache();
        JobTitlesComInfo.removeJobTitlesCache();
        ResourceComInfo.removeResourceCache();
        CacheFactory.getInstance().reset();
%>

----------------------------权限转移脚本-------------操作完没效果,/commcache/cacheMonitor.jsp?isCache=1清理下缓存,代码可采用上诉清理缓存
 ---待办

SELECT COUNT(1) FROM (SELECT DISTINCT a.workflowId, a.requestId FROM Workflow_CurrentOperator a INNER JOIN workflow_base b ON a.workflowid=b.id WHERE b.isvalid IN ('1','3') AND a.userId=15434 AND a.isLastTimes=1 AND a.isRemark IN ('0','1','5','8','9','7') AND a.userType='0' ) temptab
--日程
select count(1) from workplan where status=0 and ','||resourceid||',' like '%,1605,%'
--文档所有者
select count(distinct id) from docdetail where (ishistory=0 or ishistory is null) and ownerid=1605
--已办
SELECT COUNT(1) FROM (SELECT DISTINCT a.workflowId, a.requestId FROM Workflow_CurrentOperator a INNER JOIN workflow_base b ON a.workflowid=b.id WHERE b.isvalid IN ('1','3') AND a.userId=15434 AND a.isLastTimes=1 AND a.isRemark IN ('2','4') AND a.userType='0' AND (a.isComplete=1 OR a.agenttype<>1) ) temptab
--角色
select count(roleid) from (select a.roleid from hrmrolemembers a left join hrmroles b on a.roleid = b.id where resourceid = 1605 and b.type = 0 group by a.roleid) a
--流程节点替换  人力资源
UPDATE Workflow_HrmOperator SET objid='15434' WHERE  objid='1605'
UPDATE workflow_groupdetail SET objid='15434' WHERE type='3' AND objid='1605'
----流程操作节点数
SELECT COUNT(DISTINCT(wfng.id)) AS finishCount FROM workflow_nodegroup wfng INNER JOIN workflow_flownode wffn ON wffn.nodeid=wfng.nodeid WHERE wfng.id IN (SELECT wg.groupid FROM workflow_groupdetail wg WHERE wg.type='3'  and  exists(select 1 from Workflow_HrmOperator t2 where wg.id=t2.groupdetailid and t2.objid='15434'))   and exists(select 1 from workflow_nodebase wfnb where wfnb.id = wfng.nodeid and (wfnb.IsFreeNode is null or wfnb.IsFreeNode!='1') ) 

----流程待审批明细
select r.* from (     select my_table.*, rownum as my_rownum from (    select tableA.*,rownum  as oracle_rownum from (   select  distinct  wfng.id,wfng.groupname AS groupname,wfnb.nodename AS nodename,wfb.workflowname AS workflowname  FROM workflow_nodegroup wfng INNER JOIN workflow_nodebase wfnb ON wfnb.id=wfng.nodeid INNER JOIN workflow_flownode wffn ON wffn.nodeid=wfnb.id LEFT JOIN workflow_base wfb ON wfb.id=wffn.workflowid  WHERE wfng.id IN (SELECT DISTINCT wfgd.groupid FROM workflow_groupdetail wfgd WHERE  wfgd.type='3' AND    exists(select 1 from Workflow_HrmOperator t2 where wfgd.id=t2.groupdetailid and t2.objid='18143'))  and (wfnb.IsFreeNode is null or wfnb.IsFreeNode!='1')  and wfb.isvalid=1  order by wfng.id desc nulls last) tableA  ) my_table) r 
-----流程待审批明细查询出的ID=groupid  转移
UPDATE workflow_groupdetail SET objid='1569' WHERE type='3' AND objid='18143' AND groupid IN(14430)
UPDATE Workflow_HrmOperator SET objid='1569' WHERE  objid='18143' AND groupid IN(14430)
----更新权限转移角色
update hrmrolemembers set resourceid = 243 where resourceid = 15434

----------js增加字段必填编辑JS

//设置字段必填(2)或可编辑(1)
    function setFieldAttr(fieldid, fieldAttr) {
        if (fieldAttr == 2) {
            setFieldReadOnly(fieldid, false, fieldAttr);
            var checkstr_ = $GetEle("needcheck").value + ",";
            if (checkstr_.indexOf("field" + fieldid + ",") < 0) $GetEle("needcheck").value = checkstr_ + "field" + fieldid;
            jQuery("#fieldfield" + fieldid).attr("viewtype", "1");
        } else if (fieldAttr == 1) {
            //去除必填标识
            if (!!$GetEle('field' + fieldid + "spanimg")) {
                $GetEle('field' + fieldid + "spanimg").innerHTML = "";
            }
            if (!!$GetEle('field' + fieldid + "span")) {
                if ($GetEle('field' + fieldid + "span").innerHTML.indexOf("/images/BacoError_wev8.gif") > -1) {
                    $GetEle('field' + fieldid + "span").innerHTML = "";
                }
            }
            try {
                if ($GetEle('field_lable' + fieldid + "span")) {
                    if ($GetEle('field_lable' + fieldid + "span").innerHTML.indexOf("/images/BacoError_wev8.gif") > -1) {
                        $GetEle('field_lable' + fieldid + "span").innerHTML = "";
                    }
                }
            } catch (e) { }

            setFieldReadOnly(fieldid, false, fieldAttr);
            //提交校验必填
            var checkstr__ = $GetEle("needcheck").value + ",";
            document.all("needcheck").value = checkstr__.replace(new RegExp("field" + fieldid + ",", "g"), "");
            jQuery("#fieldfield" + fieldid).attr("viewtype", "0");
        }
    }

setFieldAttr("37603_" + i, 2);

setFieldReadOnly("37475_" + j, true, 1); ===设置只读

================================================

/**
 * 给输入框绑定事件
 * @param {*} fieldId 输入框字段id
 * @param {*} eventFn 检查事件函数
 */
 function bindCheckEventOnInput(fieldId,eventFn){
    var oldCheckinput2 = window.checkinput2;//存放原检查函数
    window.checkinput2 = function(eId, eSpanId, viewType) {
        if(eId==fieldId){//当字段id为指定id,执行自定义事件
            eventFn();
        }
        return oldCheckinput2(eId, eSpanId, viewType);//执行原检查函数
    };
}

bindCheckEventOnInput("field34833_"+i,function(){

           //文本框改变后逻辑

})

cus_setInputFieldValue("field34838_"+i,"赋值value"); ====为文本款赋值

=================================

-----------查询角色用到的流程
select b.rolesmark,f.workflowname as 流程名称,A.nodeid as 节点ID,A.GROUPNAME as 节点名称 from workflow_groupdetail t 
left join workflow_nodegroup A on t.GROUPID = A.ID
left join hrmroles B on t.objid=b.id
left join workflow_nodebase d on d.id=a.nodeid
left join workflow_flownode e on e.nodeid = d.id
left join workflow_base f on f.id = e.workflowid
where t.type=2
----------查询矩阵用的到的流程
select 
g.name  as  矩阵名称,
f.workflowname as 流程名称,
f.version as 版本号,
d.nodename as 节点名称,
(case e.nodetype when '0' then '提交' when '1' then '审批' when '2' then '执行' when '3' then '归档'  end) as  paytype,  
a.groupname as 操作组名称,
t.orders
from workflow_groupdetail t
right join workflow_nodegroup a on a.id=t.groupid
left join workflow_groupdetail_matrix  b on b.groupdetailid=t.id
left join matrixfieldinfo c on c.id = b.value_field
left join workflow_nodebase d on d.id=a.nodeid
left join workflow_flownode e on e.nodeid = d.id
left join workflow_base f on f.id = e.workflowid
left join matrixinfo g on g.id = b.matrix
where 1=1
and f.isvalid= '1'
order by g.id,f.workflowname,f.version desc,d.nodename,t.orders
-----流程流转信息查询
select a.workflowname 流程名称 ,c.nodename 节点名称 ,b.linkname 出口 ,d.nodename 下一节点名称,b.nodeid 当前节点id ,b.destnodeid 目标节点id ,e.rulename, e.condit 
from workflow_base a,workflow_nodelink b,workflow_nodebase c,workflow_nodebase d,rule_base  e
where a.id = b.workflowid and b.nodeid = c.id and b.destnodeid = d.id and b.id = e.linkid order by a.id asc, b.id asc

==================自定义jsp导出Excle出现乱码=================

===注释web.xml中的过滤    

<!--<filter-mapping>
        <filter-name>Compress</filter-name>
        <url-pattern>*.jsp</url-pattern>
    </filter-mapping>-->

============================流程删除按钮重写=================

jQuery(document).ready(function() {
         forbidDelete();

});

/**删除流程*/
function forbidDelete(){
    doDelete=function(){
        try{
            $GetEle("planDoDelete").click();
        }catch(e){
            if(confirm("你确定删除该工作流吗?这是我的自定义删除咯")) {

               删除前逻辑...........................
                $GetEle("frmmain").src.value='delete';
                jQuery($GetEle("flowbody")).attr("onbeforeunload", "");
               var content="正在删除流程,请稍候....";
               showPrompt(content);

                checkuploadcomplet();
            }
        }
    }
}

========================================================================

-----------查询角色用到的流程
select b.rolesmark,f.workflowname as 流程名称,A.nodeid as 节点ID,A.GROUPNAME as 节点名称 from workflow_groupdetail t 
left join workflow_nodegroup A on t.GROUPID = A.ID
left join hrmroles B on t.objid=b.id
left join workflow_nodebase d on d.id=a.nodeid
left join workflow_flownode e on e.nodeid = d.id
left join workflow_base f on f.id = e.workflowid
where t.type=2
----------查询矩阵用的到的流程
select 
g.name  as  矩阵名称,
f.workflowname as 流程名称,
f.version as 版本号,
d.nodename as 节点名称,
(case e.nodetype when '0' then '提交' when '1' then '审批' when '2' then '执行' when '3' then '归档'  end) as  paytype,  
a.groupname as 操作组名称,
t.orders
from workflow_groupdetail t
right join workflow_nodegroup a on a.id=t.groupid
left join workflow_groupdetail_matrix  b on b.groupdetailid=t.id
left join matrixfieldinfo c on c.id = b.value_field
left join workflow_nodebase d on d.id=a.nodeid
left join workflow_flownode e on e.nodeid = d.id
left join workflow_base f on f.id = e.workflowid
left join matrixinfo g on g.id = b.matrix
where 1=1
and f.isvalid= '1'
order by g.id,f.workflowname,f.version desc,d.nodename,t.orders

======================发起https请求==httpClient======================

 public static String send(String address, String timestamp, String nonce,String version,String sign,String signinfo,String param) {

        String result = "";
        HttpClient httpClient = null;
        HttpPost httpPost = null;
        HttpResponse response = null;

        try {
            httpClient = wrapClient();  //这里重点
            httpPost = new HttpPost(address);
            //请求头参数
            httpPost.setHeader("Content-Type", "application/json;charset=utf-8");
            //httpPost.setHeader("appId", appId);
            //httpPost.setHeader("timestamp", timestamp);
            //httpPost.setHeader("nonce", nonce);
            //httpPost.setHeader("version", version);
            //httpPost.setHeader("sign", sign);

            BasicHttpEntity requestBody = new BasicHttpEntity();
            requestBody.setContent(new ByteArrayInputStream(param.toString().getBytes("UTF-8")));
            httpPost.setEntity(requestBody);
            response = httpClient.execute(httpPost);
            HttpEntity entity = response.getEntity();
            result = EntityUtils.toString(entity);
            EntityUtils.consume(entity);
        } catch (Exception var10) {
            result = "";
        }

        return result;
    }

public static HttpClient wrapClient() {
        try {
            SSLContext ctx = SSLContext.getInstance("TLS");
            X509TrustManager tm = new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }

                public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
                }

                public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
                }
            };
            ctx.init((KeyManager[])null, new TrustManager[]{tm}, (SecureRandom)null);
            SSLConnectionSocketFactory ssf = new SSLConnectionSocketFactory(ctx, NoopHostnameVerifier.INSTANCE);
            CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(ssf).build();
            return httpclient;
        } catch (Exception var4) {
            return HttpClients.createDefault();
        }
    }

========================查询操作记录==================

--流程强制收回的操作记录可以在`workflow_requestoperatelog`表中查询
--在这个查询中,`isinvalid=1`代表强制收回操作,`invalidid`是收回操作人ID,`invaliddate`和----`invalidtime`是收回操作的日期和时间。请将问号`?`替换为具体的流程请求ID进行查询。
select a.id, a.operatorid, a.nodeid, b.lastname, a.operatedate, a.operatetime, a.operatename, a.isinvalid, a.invalidid, a.invaliddate, a.invalidtime 
from workflow_requestoperatelog a 
left join hrmresource b on a.operatorid = b.id 
where a.requestid = ''
order by a.id desc


---流程退回操作的记录通常存储在`workflow_requestlog`表中。在这个表中,可以通过`logtype`字段来识别退回操作,其中`logtype`值为'3'代表退回操作。可以通过查询这个表来获取流程退回的相关信息。

=======================删除流程中的数据================

delete from workflow_currentoperator where requestid in(select REQUESTID from formtable_main_172  where YCRQ between '2020-01-01' and '2020-12-31');

delete from workflow_form where requestid in(select REQUESTID from formtable_main_172  where YCRQ between '2020-01-01' and '2020-12-31');

delete from SysPoppupRemindInfoNew where type=0 and  requestid in(select REQUESTID from formtable_main_172  where YCRQ between '2020-01-01' and '2020-12-31');

delete from workflow_logviewusers  where exists (select 1 from workflow_requestLog where workflow_requestLog.requestid in(select REQUESTID from formtable_main_172  where YCRQ between '2020-01-01' and '2020-12-31') and workflow_requestLog.logid = workflow_logviewusers.logid);

delete from formtable_main_172_dt1 where formtable_main_172_dt1.mainid in (select b.id from formtable_main_172 b where b.requestid  in(select REQUESTID from formtable_main_172  where YCRQ between '2020-01-01' and '2020-12-31'));


delete from workflow_requestbase where requestid in(select REQUESTID from formtable_main_172  where YCRQ between '2021-01-01' and '2021-12-31');


delete from FORMTABLE_MAIN_172_DT1 where mainid in(select id from formtable_main_172 where REQUESTID in(select REQUESTID from formtable_main_172  where YCRQ between '2020-01-01' and '2020-12-31'));

delete from formtable_main_172 where requestid in(select REQUESTID from formtable_main_172  where YCRQ between '2020-01-01' and '2020-12-31');



--------------------删除离职人员抄送节点数据
delete workflow_groupdetail where id in(select GROUPDETAILID
from Workflow_HrmOperator where objid in(
	select id from HRMRESOURCE where status>4
) and SIGNORDER=3 AND TYPE=3 );

delete Workflow_HrmOperator where objid in(
	select id from HRMRESOURCE where status>4
)  and SIGNORDER=3 AND TYPE=3;






删除后清理缓存CacheFactory.getInstance().reset();

================待办转已办

根据我掌握的知识,在E8系统中,没有批量已读功能。如果是抄送不需提交的数据,可以参考以下脚本来实现从待办到已办的转换:

```sql
UPDATE workflow_currentoperator
SET isremark = 2, islasttimes = 1
WHERE userid = '需要修改的用户ID'
```

在这个脚本中,`isremark=2` 表示已操作,`islasttimes=1` 表示这条数据是这个人对这个请求最后一次的流转操作。`userid` 是流程在谁的待办中,需要改到已办中,这里就填写谁的 `userid`。

请注意,在执行任何数据库操作之前,务必确保您有足够的权限,并且对数据库结构有足够的了解。如果您不确定如何操作,建议联系系统管理员或技术支持人员获取帮助。同时,操作前应确保备份相关数据,以防止数据丢失或损坏。

资料

泛微Ecology8.0二次开发指导手册_泛微e8二次开发-CSDN博客==

### 配置系统中的免登录页面 为了实现在系统中某些特定页面可以不经过身份验证即可访问,通常需要对应用服务器以及Web容器进行相应的配置调整。对于基于Java EE架构构建的应用程序而言,在Servlet过滤器或者安全约束定义里指定哪些URL模式不需要认证就能被浏览是一个常见做法。 #### 修改web.xml文件来设置免登路径 如果要使某个具体的URI能够绕过系统的统一权限校验机制,则可以在部署描述符`WEB-INF/web.xml`中添加如下形式的安全约束: ```xml <security-constraint> <web-resource-collection> <url-pattern>/public/*</url-pattern> <!-- 定义允许匿名访问的资源 --> </web-resource-collection> <auth-constraint/> </security-constraint> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> ``` 上述XML片段表明任何匹配到`/public/`开头的请求都将不会受到保护,并且可以直接展示给最终用户而无需先完成登陆过程[^1]。 另外一种方法是在代码层面处理,比如通过自定义Filter拦截器的方式实现更灵活的功能逻辑判断;也可以利用Spring Security框架提供的API快速搭建起一套完整的鉴权体系并从中豁免部分接口调用。 需要注意的是开放过多不受限的服务端点可能会带来潜在风险,因此应当谨慎评估业务需求后再做决定。同时确保这些公开链接仅提供必要的功能和服务,避免泄露敏感数据或造成其他安全隐患[^2]。 针对具体版本号不同的产品线可能还会存在差异化的操作指南,请参照官方文档获取最权威的信息支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值