zoufan_kd преди 7 месеца
родител
ревизия
bbd98b1ea7
променени са 3 файла, в които са добавени 1446 реда и са изтрити 0 реда
  1. 279 0
      src/main/java/fi/cas/opplugin/PayBillToolUtil.java
  2. 48 0
      src/main/java/fi/cas/opplugin/PayToZFQZOP.java
  3. 1119 0
      src/main/java/fi/cas/opplugin/TypeUtils.java

+ 279 - 0
src/main/java/fi/cas/opplugin/PayBillToolUtil.java

@@ -0,0 +1,279 @@
+package fi.cas.opplugin;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.entity.EntityMetadataCache;
+import kd.bos.logging.Log;
+import kd.bos.logging.LogFactory;
+import kd.bos.orm.query.QFilter;
+import kd.bos.servicehelper.BusinessDataServiceHelper;
+
+import java.io.*;
+import java.math.RoundingMode;
+import java.net.Socket;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import kd.bos.servicehelper.operation.OperationServiceHelper;
+import kd.bos.servicehelper.operation.SaveServiceHelper;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.json.JSONObject;
+import org.json.XML;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+public class PayBillToolUtil {
+    public static final String ENTITY_NAME = "cas_paybill";
+    protected static final Log log = LogFactory.getLog(PayBillToolUtil.class);
+
+    public static String createSinglePaymentRequest(DynamicObject payBillEntity) {
+        try {
+            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
+            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
+            Document doc = dBuilder.newDocument();
+
+            Element rootElement = doc.createElement("Message");
+            doc.appendChild(rootElement);
+
+            Element body = doc.createElement("Body");
+            rootElement.appendChild(body);
+
+
+            createElement(doc, body, "transcode", "BTSCO001");
+            createElement(doc, body, "trxcode", "jfgx");//渠道交易代码
+            createElement(doc, body, "channelcode", "经费共享");//发起渠道
+            Calendar currentdate = Calendar.getInstance();
+            createElement(doc, body, "channeldate", TypeUtils.date2String(currentdate.getTime(),"yyyyMMdd"));//发起渠道日期
+            String channelserno = payBillEntity.get("billno")+"-"+payBillEntity.getInt("nckd_bbh");
+            createElement(doc, body, "channelserno", channelserno);//发起渠道流水
+            createElement(doc, body, "channeltime", currentdate.get(Calendar.HOUR)+""+currentdate.get(Calendar.MINUTE)+""+currentdate.get(Calendar.SECOND));
+
+            createElement(doc, body, "brno", "");//交易发起机构,可为空,默认100800
+            createElement(doc, body, "bustype", "");//业务类型,可为空,默认为0-汇兑
+            createElement(doc, body, "buskind", "");//业务种类,可为空,默认为0-普通汇兑
+
+            createElement(doc, body, "payeracctype", "1");//付款账户类型 0-对公账户 1-个人账户.待补充
+            //付款账号
+            DynamicObject payeracctbankEntity = BusinessDataServiceHelper.loadSingle(payBillEntity.getDynamicObject("payeracctbank").getPkValue(), "am_accountbank");
+            String payeracc = payeracctbankEntity.getString("bankaccountnumber");
+            String payername = payeracctbankEntity.getString("name");
+            createElement(doc, body, "payeracc", payeracc);//付款账户
+            createElement(doc, body, "payername", payername);//付款人名称
+            createElement(doc, body, "realpayeracc", payeracc);//实际付款人账户
+            createElement(doc, body, "realpayername", payername);//实际付款人名称
+
+
+            createElement(doc, body, "payeeacc", payBillEntity.getString("payeebanknum"));//收款账号
+            createElement(doc, body, "payeename",  payBillEntity.getString("payeename"));//收款人名称
+            createElement(doc, body, "amount", payBillEntity.getBigDecimal("actpayamt").setScale(2, RoundingMode.DOWN).toString());//金额
+            createElement(doc, body, "feeflag", "0");//收费标志0-暂不收费 1-计费 2-按月计费
+            createElement(doc, body, "postscript", "测试江西银行经费共享系统付款");
+
+            DynamicObject skyhinfo =  BusinessDataServiceHelper.loadSingle(payBillEntity.getDynamicObject("payeebank").getPkValue(), "bd_bebank");
+
+            createElement(doc, body, "recvbank", skyhinfo.getString("union_number"));// 如果是跨行业务,需填写接收行号
+            createElement(doc, body, "paysysid", "0");// 如果是跨行业务,需填写汇路
+
+            TransformerFactory transformerFactory = TransformerFactory.newInstance();
+            Transformer transformer = transformerFactory.newTransformer();
+
+            // 指定编码格式为GBK
+            transformer.setOutputProperty(OutputKeys.ENCODING, "GBK");
+            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+
+
+            DOMSource source = new DOMSource(doc);
+            StringWriter writer = new StringWriter();
+            StreamResult result = new StreamResult(writer);
+            transformer.transform(source, result);
+
+            return writer.toString();
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    private static void createElement(Document doc, Element parent, String name, String value) {
+        Element element = doc.createElement(name);
+        element.appendChild(doc.createTextNode(value));
+        parent.appendChild(element);
+    }
+
+    /**
+     * 支付单同步
+     * @params billEntities
+     * @returns 返回报错信息
+     *
+     */
+    public static String payBillForCBSSync(DynamicObject[] billEntities) {
+        StringBuffer errMsg = new StringBuffer();
+        //获取接口链接等信息
+        DynamicObject jkpzxx = BusinessDataServiceHelper.loadSingle("nckd_jkpzxx",new QFilter[]{new QFilter("number","=","paytozfqz")});
+        String servername =  jkpzxx.getString("nckd_servername");
+        String port =  jkpzxx.getString("nckd_port");
+
+        for (DynamicObject dataEntity : billEntities) {
+            boolean isSuccess = false;
+            boolean isZFQZ = true;
+            Map<String, String> qzObject = new HashMap<>();
+            DynamicObject payBillEntity = BusinessDataServiceHelper.loadSingle(dataEntity.getPkValue(), ENTITY_NAME);
+
+            String cbsUrlBill ="";
+
+            /**
+             *   判断是否可以走前置支付
+             *   1、付款单为审核状态
+             *   2、支付状态为未支付
+             *   3、版本号>=1时,必须等于付款次数
+             */
+            String billNum = payBillEntity.getString("billno");
+            String billstatusString = payBillEntity.getString("billstatus");
+            String paystatus = payBillEntity.getString("nckd_paystatus");
+            int bbh = payBillEntity.getInt("nckd_bbh");
+            int fkcs = payBillEntity.getInt("nckd_fkcs");
+
+            if (!"C".equals(billstatusString)) {
+                errMsg.append("单据号:").append(billNum).append(",付款单为审核状态,才能提交~\r\n");
+                isZFQZ = false;
+            }
+            if (!"1".equals(paystatus) && !"".equals(paystatus)) {
+                errMsg.append("单据号:").append(billNum).append(",付款单为未支付,才能提交~\r\n");
+                isZFQZ = false;
+            }
+            if(bbh>=1 && bbh!=fkcs){
+                errMsg.append("单据号:").append(billNum).append(",付款单版本号有误,请检查数据,或联系管理员~\r\n");
+                isZFQZ = false;
+            }
+            if(payBillEntity.getDynamicObject("payeracctbank")==null) {
+                errMsg.append("单据号:").append(billNum).append(",付款账户为空~\r\n");
+                isZFQZ = false;
+            }
+            if(payBillEntity.getDynamicObject("payeebank")==null) {
+                errMsg.append("单据号:").append(billNum).append(",收款账户为空~\r\n");
+                isZFQZ = false;
+            }
+
+
+            //构建请求xml
+            String bodyxml =  createSinglePaymentRequest(payBillEntity);
+            if(bodyxml==null){
+                isZFQZ = false;
+                errMsg.append("单据号:").append(billNum).append(",无法拼出正确的xml请求~\r\n");
+            }
+
+            if(!isZFQZ){
+                continue;
+            }
+            log.info("单据号:"+billNum+"传入参数"+bodyxml);
+            JSONObject cbsReturnJson =socketService(servername,port,bodyxml);
+            log.info("单据号:"+billNum+"返回参数"+cbsReturnJson.toString());
+            //存入日志表
+            savelog(payBillEntity,bodyxml,cbsReturnJson.toString());
+
+
+            if(cbsReturnJson==null){
+                isSuccess = false;
+                errMsg.append("单据号:").append(billNum).append(",推送支付前置失败,");
+                errMsg.append("错误号:").append("XXXXXX");
+                errMsg.append(",错误原因:").append("接口无法连通,未获取到返回结果");
+                errMsg.append("\r\n");
+            }else{
+                String errcode =cbsReturnJson.getString("errorcode");
+
+                if ("FIN0000".equals(errcode)) {//已受理,不代表支付成功
+                    isSuccess = true;
+                    errMsg.append("单据号:").append(billNum).append(",推送支付前置成功!");
+                    payBillEntity.set("nckd_fkcs", fkcs+1);//付款次数+1
+                    payBillEntity.set("nckd_sbyy",cbsReturnJson.getString("errormsg"));//错误信息
+                    String zfstatus = cbsReturnJson.getString("status");
+                    if("S".equals(zfstatus)){//成功
+                        payBillEntity.set("nckd_paystatus",3);
+                    }else if("U".equals(zfstatus)){//在途
+                        payBillEntity.set("nckd_paystatus",2);//支付中
+                    }else if("F".equals(zfstatus)){//失败
+                        payBillEntity.set("nckd_paystatus",4);//支付失败
+                    }
+
+                } else {
+                    isSuccess = false;
+                    errMsg.append("单据号:").append(billNum).append(",推送支付前置失败,");
+                    errMsg.append("错误号:").append(errcode);
+                    errMsg.append(",错误原因:").append(cbsReturnJson.getString("errormsg"));
+                    errMsg.append("\r\n");
+                }
+            }
+            ////返回日志处理
+            System.out.println("调用支付前置接口返回值:" + cbsReturnJson.toString());
+
+            if (isSuccess) {
+                SaveServiceHelper.update(new DynamicObject[]{payBillEntity});
+            }
+        }
+        return errMsg.toString();
+    }
+
+    public static void savelog(DynamicObject payBillEntity,String qqbw,String fhbw){
+        try {
+            DynamicObject logInfo = new DynamicObject( EntityMetadataCache.getDataEntityType("nckd_zfjkdyrz"));
+            String channelserno = payBillEntity.get("billno")+"-"+payBillEntity.getInt("nckd_bbh");
+            logInfo.set("number",channelserno);
+            logInfo.set("name",payBillEntity.get("billno")+"付款日志");
+            logInfo.set("status","A");
+            logInfo.set("nckd_billno",payBillEntity.get("billno"));
+            logInfo.set("nckd_payid",payBillEntity.getPkValue()+"");
+            logInfo.set("nckd_qqbw",qqbw);
+            logInfo.set("nckd_fhbw",fhbw);
+            logInfo.set("nckd_djlx","1");
+            OperationServiceHelper.executeOperate("save","nckd_zfjkdyrz",new DynamicObject[]{logInfo});
+
+        }catch (Exception e){
+            log.info("保存日志报错"+e.getMessage());
+
+        }
+
+
+    }
+
+    public static JSONObject socketService(String serverName,String port,String xmlData){
+        try {
+            Socket client = new Socket(serverName,TypeUtils.nullToInt(port));
+            int messageLength = xmlData.getBytes("GBK").length;
+            String header = String.format("%08dXMLBTSCO001%%%%%%%%%%%%%%%%%%%%%%%%", messageLength);
+            String fullMessage = header + xmlData;
+            OutputStream outToServer = client.getOutputStream();
+
+            PrintWriter out = new PrintWriter(new OutputStreamWriter(outToServer, "GBK"), true);
+            out.println(fullMessage);
+
+            InputStream inFromServer = client.getInputStream();
+            BufferedReader in = new BufferedReader(new InputStreamReader(inFromServer, "GBK"));
+            StringBuilder responseBuilder = new StringBuilder();
+            String line;
+            while ((line = in.readLine()) != null) {
+                responseBuilder.append(line);
+            }
+            String responseJson = responseBuilder.toString();
+            if(responseJson.indexOf("<?xml")>0){
+                int index = responseJson.indexOf("<?xml");
+                responseJson.substring(index);
+            }
+
+            JSONObject jsonObject = XML.toJSONObject(responseJson);
+            client.close();
+            return  jsonObject;
+        } catch (IOException e) {
+            e.printStackTrace();
+            log.info(e.getMessage());
+        }
+        return null;
+    }
+
+}

+ 48 - 0
src/main/java/fi/cas/opplugin/PayToZFQZOP.java

@@ -0,0 +1,48 @@
+package fi.cas.opplugin;
+
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
+import kd.bos.entity.plugin.AddValidatorsEventArgs;
+import kd.bos.entity.plugin.args.AfterOperationArgs;
+import kd.bos.entity.plugin.args.BeforeOperationArgs;
+import com.alibaba.druid.util.StringUtils;
+
+
+public class PayToZFQZOP  extends AbstractOperationServicePlugIn {
+    private static final String ENTITY_NAME = "cas_paybill";
+
+    @Override
+    public void onAddValidators(AddValidatorsEventArgs e) {
+        super.onAddValidators(e);
+
+
+    }
+
+    @Override
+    public void beforeExecuteOperationTransaction(BeforeOperationArgs e) {
+
+        String errMsg = "";
+
+        //获取选中行
+        DynamicObject[] billEntities = e.getDataEntities();
+
+        //获取操作按钮操作编码
+        String operationKey = e.getOperationKey();
+        if (StringUtils.equals( "paytoqianzhi",operationKey)){
+            errMsg =  PayBillToolUtil.payBillForCBSSync(billEntities);
+        }
+        if(!errMsg.isEmpty()) {
+            ////将错误信息返回到前端
+            e.setCancelMessage(errMsg);
+            e.setCancel(true);
+            System.out.println("PayToZFQZOP 错误信息:" + errMsg.toString());
+        }
+    }
+
+
+    @Override
+    public void afterExecuteOperationTransaction(AfterOperationArgs e) {
+        super.afterExecuteOperationTransaction(e);
+
+    }
+}

+ 1119 - 0
src/main/java/fi/cas/opplugin/TypeUtils.java

@@ -0,0 +1,1119 @@
+package fi.cas.opplugin;
+
+
+import java.math.BigDecimal;
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+
+public class TypeUtils {
+
+
+    public static double StringToDouble(Object obj){
+        return obj==null?0.0:Double.parseDouble(obj.toString());
+    }
+
+
+
+    public static final String NODE_PATH_SPERATOR="/";
+    /**
+     * HOUR_UNIT这个常量表示单位:人时
+     *
+     * @see #HOUR_UNIT :人时
+     * @see #DAY_UNIT :人天
+     * @see #WEEK_UNIT :人周
+     * @see #MONTH_UNIT :人月
+     */
+    public final static int HOUR_UNIT = 1;
+    /**
+     * DAY_UNIT这个常量表示单位:人天
+     *
+     * @see #HOUR_UNIT :人时
+     * @see #DAY_UNIT :人天
+     * @see #WEEK_UNIT :人周
+     * @see #MONTH_UNIT :人月
+     */
+    public final static int DAY_UNIT = 2;
+    /**
+     * WEEK_UNIT这个常量表示单位:人周
+     *
+     * @see #HOUR_UNIT :人时
+     * @see #DAY_UNIT :人天
+     * @see #WEEK_UNIT :人周
+     * @see #MONTH_UNIT :人月
+     */
+    public final static int WEEK_UNIT = 3;
+    /**
+     * MONTH_UNIT这个常量表示单位:人月
+     *
+     * @see #HOUR_UNIT :人时
+     * @see #DAY_UNIT :人天
+     * @see #WEEK_UNIT :人周
+     * @see #MONTH_UNIT :人月
+     */
+    public final static int MONTH_UNIT = 4;
+
+    /**
+     * 这个常量表示分组方式:按任务分组
+     *
+     * @see #BY_TASK:按任务分组
+     * @see #BY_RESOURCE:按资源分组
+     * @see #BY_RESOURCE_TYPE:按资源类型分组
+     * @see #BY_PROJECT:按项目分组
+     * @see #BY_NON_PROJECT_TYPE:按非项目类型分组
+     * @see #BY_EXPENSE_TYPE:按费用类型分组
+     * @see #BY_BENEFIT_TYPE:按收益类型分组
+     * @see #BY_PHASE:按阶段分组
+     * @see #BY_REPORT_BY:按报告分组
+     * @see #BY_OUTLINE:按一级大纲任务分组
+     * @see #BY_TYPE:按类型分组
+     */
+    public final static int BY_TASK = 1;
+    /**
+     * 这个常量表示分组方式:按资源分组
+     *
+     * @see #BY_TASK:按任务分组
+     * @see #BY_RESOURCE:按资源分组
+     * @see #BY_RESOURCE_TYPE:按资源类型分组
+     * @see #BY_PROJECT:按项目分组
+     * @see #BY_NON_PROJECT_TYPE:按非项目类型分组
+     * @see #BY_EXPENSE_TYPE:按费用类型分组
+     * @see #BY_BENEFIT_TYPE:按收益类型分组
+     * @see #BY_PHASE:按阶段分组
+     * @see #BY_REPORT_BY:按报告分组
+     * @see #BY_OUTLINE:按一级大纲任务分组
+     * @see #BY_TYPE:按类型分组
+     */
+    public final static int BY_RESOURCE = 2;
+    /**
+     * 这个常量表示分组方式:按资源类型分组
+     *
+     * @see #BY_TASK:按任务分组
+     * @see #BY_RESOURCE:按资源分组
+     * @see #BY_RESOURCE_TYPE:按资源类型分组
+     * @see #BY_PROJECT:按项目分组
+     * @see #BY_NON_PROJECT_TYPE:按非项目类型分组
+     * @see #BY_EXPENSE_TYPE:按费用类型分组
+     * @see #BY_BENEFIT_TYPE:按收益类型分组
+     * @see #BY_PHASE:按阶段分组
+     * @see #BY_REPORT_BY:按报告分组
+     * @see #BY_OUTLINE:按一级大纲任务分组
+     * @see #BY_TYPE:按类型分组
+     */
+    public final static int BY_RESOURCE_TYPE = 3;
+    /**
+     * 这个常量表示分组方式:按项目类型分组
+     *
+     * @see #BY_TASK:按任务分组
+     * @see #BY_RESOURCE:按资源分组
+     * @see #BY_RESOURCE_TYPE:按资源类型分组
+     * @see #BY_PROJECT:按项目分组
+     * @see #BY_NON_PROJECT_TYPE:按非项目类型分组
+     * @see #BY_EXPENSE_TYPE:按费用类型分组
+     * @see #BY_BENEFIT_TYPE:按收益类型分组
+     * @see #BY_PHASE:按阶段分组
+     * @see #BY_REPORT_BY:按报告分组
+     * @see #BY_OUTLINE:按一级大纲任务分组
+     * @see #BY_TYPE:按类型分组
+     */
+    public final static int BY_PROJECT = 4;
+    /**
+     * 这个常量表示分组方式:按非项目类型分组
+     *
+     * @see #BY_TASK:按任务分组
+     * @see #BY_RESOURCE:按资源分组
+     * @see #BY_RESOURCE_TYPE:按资源类型分组
+     * @see #BY_PROJECT:按项目分组
+     * @see #BY_NON_PROJECT_TYPE:按非项目类型分组
+     * @see #BY_EXPENSE_TYPE:按费用类型分组
+     * @see #BY_BENEFIT_TYPE:按收益类型分组
+     * @see #BY_PHASE:按阶段分组
+     * @see #BY_REPORT_BY:按报告分组
+     * @see #BY_OUTLINE:按一级大纲任务分组
+     * @see #BY_TYPE:按类型分组
+     */
+    public final static int BY_NON_PROJECT_TYPE = 5;
+    /**
+     * 这个常量表示分组方式:按费用类型分组
+     *
+     * @see #BY_TASK:按任务分组
+     * @see #BY_RESOURCE:按资源分组
+     * @see #BY_RESOURCE_TYPE:按资源类型分组
+     * @see #BY_PROJECT:按项目分组
+     * @see #BY_NON_PROJECT_TYPE:按非项目类型分组
+     * @see #BY_EXPENSE_TYPE:按费用类型分组
+     * @see #BY_BENEFIT_TYPE:按收益类型分组
+     * @see #BY_PHASE:按阶段分组
+     * @see #BY_REPORT_BY:按报告分组
+     * @see #BY_OUTLINE:按一级大纲任务分组
+     * @see #BY_TYPE:按类型分组
+     */
+    public final static int BY_EXPENSE_TYPE = 6;
+    /**
+     * 这个常量表示分组方式:按收益类型分组
+     *
+     * @see #BY_TASK:按任务分组
+     * @see #BY_RESOURCE:按资源分组
+     * @see #BY_RESOURCE_TYPE:按资源类型分组
+     * @see #BY_PROJECT:按项目分组
+     * @see #BY_NON_PROJECT_TYPE:按非项目类型分组
+     * @see #BY_EXPENSE_TYPE:按费用类型分组
+     * @see #BY_BENEFIT_TYPE:按收益类型分组
+     * @see #BY_PHASE:按阶段分组
+     * @see #BY_REPORT_BY:按报告分组
+     * @see #BY_OUTLINE:按一级大纲任务分组
+     * @see #BY_TYPE:按类型分组
+     */
+    public final static int BY_BENEFIT_TYPE = 7;
+    /**
+     * 这个常量表示分组方式:按阶段分组
+     *
+     * @see #BY_TASK:按任务分组
+     * @see #BY_RESOURCE:按资源分组
+     * @see #BY_RESOURCE_TYPE:按资源类型分组
+     * @see #BY_PROJECT:按项目分组
+     * @see #BY_NON_PROJECT_TYPE:按非项目类型分组
+     * @see #BY_EXPENSE_TYPE:按费用类型分组
+     * @see #BY_BENEFIT_TYPE:按收益类型分组
+     * @see #BY_PHASE:按阶段分组
+     * @see #BY_REPORT_BY:按报告分组
+     * @see #BY_OUTLINE:按一级大纲任务分组
+     * @see #BY_TYPE:按类型分组
+     */
+    public final static int BY_PHASE = 8;
+    /**
+     * 这个常量表示分组方式:按报告分组
+     *
+     * @see #BY_TASK:按任务分组
+     * @see #BY_RESOURCE:按资源分组
+     * @see #BY_RESOURCE_TYPE:按资源类型分组
+     * @see #BY_PROJECT:按项目分组
+     * @see #BY_NON_PROJECT_TYPE:按非项目类型分组
+     * @see #BY_EXPENSE_TYPE:按费用类型分组
+     * @see #BY_BENEFIT_TYPE:按收益类型分组
+     * @see #BY_PHASE:按阶段分组
+     * @see #BY_REPORT_BY:按报告分组
+     * @see #BY_OUTLINE:按一级大纲任务分组
+     * @see #BY_TYPE:按类型分组
+     */
+    public final static int BY_REPORT_BY = 9;
+    /**
+     * 这个常量表示分组方式:按一级大纲任务分组
+     *
+     * @see #BY_TASK:按任务分组
+     * @see #BY_RESOURCE:按资源分组
+     * @see #BY_RESOURCE_TYPE:按资源类型分组
+     * @see #BY_PROJECT:按项目分组
+     * @see #BY_NON_PROJECT_TYPE:按非项目类型分组
+     * @see #BY_EXPENSE_TYPE:按费用类型分组
+     * @see #BY_BENEFIT_TYPE:按收益类型分组
+     * @see #BY_PHASE:按阶段分组
+     * @see #BY_REPORT_BY:按报告分组
+     * @see #BY_OUTLINE:按一级大纲任务分组
+     * @see #BY_TYPE:按类型分组
+     */
+    public final static int BY_OUTLINE = 10;// 一级大纲任务分组
+    /**
+     * 这个常量表示分组方式:按类型分组
+     *
+     * @see #BY_TASK:按任务分组
+     * @see #BY_RESOURCE:按资源分组
+     * @see #BY_RESOURCE_TYPE:按资源类型分组
+     * @see #BY_PROJECT:按项目分组
+     * @see #BY_NON_PROJECT_TYPE:按非项目类型分组
+     * @see #BY_EXPENSE_TYPE:按费用类型分组
+     * @see #BY_BENEFIT_TYPE:按收益类型分组
+     * @see #BY_PHASE:按阶段分组
+     * @see #BY_REPORT_BY:按报告分组
+     * @see #BY_OUTLINE:按一级大纲任务分组
+     * @see #BY_TYPE:按类型分组
+     */
+    public final static int BY_TYPE = 11;// 一级大纲任务分组
+    public final static int BY_PRODUCT = 12;// 工作产品
+
+    /**
+     * 这个常量表示信号灯:无信号灯
+     *
+     * @see #NONE:无信号灯
+     * @see #GREEN:绿灯
+     * @see #YELLOW:黄灯
+     * @see #RED:红灯
+     * @see #COMPLETED:已经完成
+     */
+    public final static int NONE = 1;
+    /**
+     * 这个常量表示信号灯:绿灯
+     *
+     * @see #NONE:无信号灯
+     * @see #GREEN:绿灯
+     * @see #YELLOW:黄灯
+     * @see #RED:红灯
+     * @see #COMPLETED:已经完成
+     */
+    public final static int GREEN = 2;
+    /**
+     * 这个常量表示信号灯:黄灯
+     *
+     * @see #NONE:无信号灯
+     * @see #GREEN:绿灯
+     * @see #YELLOW:黄灯
+     * @see #RED:红灯
+     * @see #COMPLETED:已经完成
+     */
+    public final static int YELLOW = 3;
+    /**
+     * 这个常量表示信号灯:红灯
+     *
+     * @see #NONE:无信号灯
+     * @see #GREEN:绿灯
+     * @see #YELLOW:黄灯
+     * @see #RED:红灯
+     * @see #COMPLETED:已经完成
+     */
+    public final static int RED = 4;
+
+    /**
+     * 这个常量表示信号灯:待我确认
+     *
+     * @see #NONE:无信号灯
+     * @see #GREEN:绿灯
+     * @see #YELLOW:黄灯
+     * @see #RED:红灯
+     * @see #PURPLE:紫色
+     * @see #LIGHT_BLUE:深蓝
+     * @see #COMPLETED:已经完成
+     */
+    public final static int PURPLE = 5;
+
+    /**
+     * 这个常量表示信号灯:被退回
+     *
+     * @see #NONE:无信号灯
+     * @see #GREEN:绿灯
+     * @see #YELLOW:黄灯
+     * @see #RED:红灯
+     * @see #COMPLETED:已经完成
+     */
+    public final static int LIGHT_BLUE = 6;
+    /**
+     * 这个常量表示信号灯:已经完成
+     *
+     * @see #NONE:无信号灯
+     * @see #GREEN:绿灯
+     * @see #YELLOW:黄灯
+     * @see #RED:红灯
+     * @see #COMPLETED:已经完成
+     */
+    public final static int COMPLETED = -1;
+    /**
+     * 这个常量是取得long数据类型的系统当前时间
+     */
+    private static long current = System.currentTimeMillis();
+
+    /**
+     * 这个获取根据时间或许系统唯一的ID
+     */
+    public static synchronized long getUniqueID() {
+        return current++;
+    }
+
+    /**
+     * 这个方法是将一个可能为<code>null</code>或者为<code>"null"</code>(忽略大小写)的
+     * <code>String</code>转换为非空的<code>String</code>.<br/>
+     * 即如果当参数<code>inString</code>为<code>null</code>时,返回值就为<code>""</code>
+     * ,如果不为空则返回inString.trim()值.
+     *
+     * @param inString
+     *            为一个可能为<code>null</code>或者为<code>"null"</code>(忽略大小写)的
+     *            <code>String</code>类型数据
+     * @return 如果当参数<code>inString</code>为<code>null</code>时,返回值就为
+     *         <code>""</code>,如果不为空则返回inString.trim()值.
+     */
+    public static String nullToString(String inString) {
+        return ((inString == null || "null".equalsIgnoreCase(inString.trim())) ? "" : inString.trim());
+    }
+
+    /**
+     * 这个方法是将一个可能为<code>null</code>或者为<code>"null"</code>(忽略大小写)的
+     * <code>String</code>数据类型<code>inString</code>, 如果转换为给定的默认值
+     * <code>defaultString</code>为<code>null</code>或者为<code>"null"</code>
+     * (忽略大小写),返回默认值,否则返回inString.trim()值.
+     *
+     * @param inString
+     *            为一个可能为<code>null</code>或者为<code>"null"</code>(忽略大小写)的
+     *            <code>String</code>类型数据.
+     * @param defaultString
+     *            为<code>String</code>类型的数据,它用于当<code>inString</code>
+     *            为空时,就将它作为返回值.
+     * @return 如果当参数<code>inString</code>为<code>null</code>时,返回值就为给定的默认值
+     *         <code>defaultString</code>,如果不为空则返回inString.trim()值.
+     */
+    public static String nullToString(String inString, String defaultString) {
+        return ((inString == null || "null".equalsIgnoreCase(inString.trim())) ? defaultString : inString.trim());
+    }
+
+    /**
+     * 这个方法是将一个可能为<code>null</code>或者为<code>"null"</code>(忽略大小写)的
+     * <code>Object</code>类型的数据转换为非空的<code>String</code>.<br/>
+     * 即如果当参数<code>inObject</code>为空时,返回值就为<code>""</code>
+     * ,如果不为空则返回inObject.toString()值.
+     *
+     * @param inObject
+     *            为一个可能为<code>null</code>或者为<code>"null"</code>(忽略大小写)的
+     *            <code>Object</code>类型数据
+     * @return 如果当参数<code>inObject</code>为空时,返回值就为<code>""</code>
+     *         ,如果不为空则返回inObject.trim()值.
+     */
+    public static String nullToString(Object inObject) {
+        return ((inObject == null || "null".equalsIgnoreCase(inObject.toString().trim())) ? "" : inObject.toString());
+    }
+
+    /**
+     * 将给定的字符串数组用分隔符加起来.<br/>
+     * 例如:<code>ss={"11","22","33"} split="," </code>其返回结果为
+     * <code>"11,22,33"</code>
+     *
+     * @param ss
+     *            为要拼的字符串数组
+     * @param split
+     *            为分隔符
+     * @return 用分隔符拼接好后的结果
+     */
+    public static String joinString(String[] ss, String split) {
+        StringBuffer sb = new StringBuffer();
+        if (ss != null && ss.length > 0) {
+            for (String s : ss) {
+                if (sb.length() > 0) {
+                    sb.append(split);
+                }
+                sb.append(s);
+            }
+        }
+        return sb.toString();
+    }
+
+    /**
+     * 将给定的<code>Object inObject</code>,如果非空或者非<code>"null"</code>
+     * ,返回UTF编码格式的inObject.toString()值,否则返回<code>""</code>.<br/>
+     *
+     * @param inObject
+     *            为一个可能为<code>null</code>或者为<code>"null"</code>(忽略大小写)的
+     *            <code>Object</code>类型数据
+     * @return inObject 的UTF编码格式的String值.
+     */
+    public static String getUTFString(Object inObject) {
+        try {
+            return ((inObject == null || "null".equalsIgnoreCase(inObject.toString().trim())) ? "" : new String(
+                    inObject.toString().getBytes("ISO8859-1")));
+        } catch (Exception e) {
+        }
+        return "";
+    }
+
+    /**
+     * 将给定的<code>Object inObject</code>,如果<code>inObject</code>
+     * 可以转换为数值,则返回转换后的int值,否则返回<code>0</code>.<br/>
+     *
+     * @param inObject
+     *            为一个<code>Object</code>类型数据
+     * @return 如果<code>inObject</code>可以转换为数值,则返回转换后的int值,否则返回int类型值
+     *         <code>0</code>.
+     */
+    public static int nullToInt(Object inObject) {
+        int iRet = 0;
+        if (inObject != null) {
+            try {
+                Double temp = new Double(inObject.toString());
+                iRet = temp.intValue();
+            } catch (Exception e) {
+                iRet = 0;
+            }
+        }
+        return iRet;
+    }
+
+
+
+    /**
+     * 将给定的<code>destStr</code>目标字符串,以新字符串<code>newStr</code>替换每一个旧字符串
+     * <code>oldStr</code>.<br/>
+     *
+     * @param destStr
+     *            为目标字符串
+     * @param oldStr
+     *            为需要被替换的旧字符串
+     * @param newStr
+     *            为要去替换的新字符串
+     * @return 返回替换好了的字符串,如果目标字符串为<code>null</code>,则返回<code>""</code>.
+     *
+     */
+    public static String strReplace(String destStr, String oldStr, String newStr) {
+        if (destStr == null){
+            return "";
+        }
+        String tmpStr = destStr;
+        int foundPos = tmpStr.indexOf(oldStr);
+        while (foundPos >= 0) {
+            tmpStr = tmpStr.substring(0, foundPos) + newStr
+                    + tmpStr.substring(foundPos + oldStr.length(), tmpStr.length());
+            foundPos = tmpStr.indexOf(oldStr, foundPos + newStr.length());
+        }
+        return tmpStr;
+    }
+
+
+
+
+
+
+
+    /**
+     * 将数据转换为html的数据格式.<br/>
+     * 例如:<code>obj="aa\r\nbb\rcc\n"</code> 替换为
+     * <code>"aa&lt;br&gt;bb&lt;br&gt;cc&lt;br&gt;"</code>
+     *
+     * @param obj
+     *            要转换的数据
+     * @return 转换完成的数据
+     */
+    public static String htmlEncoder4Print(Object obj) {
+        String sRet = htmlEncoder(obj);
+        sRet = strReplace(sRet, "\r\n", "<br>");
+        sRet = strReplace(sRet, "\r", "<br>");
+        sRet = strReplace(sRet, "\n", "<br>");
+        return sRet;
+    }
+
+    /**
+     * 将数据中的特殊字符转化为普通字符.<br/>
+     * 比如说我们可能需要将这一段代码<code>"aa&lt;br&gt;bb&lt;br&gt;cc&lt;br&gt;"</code>
+     * 显示在一个输入框内, 或者显示在页面上,我们就可以调用这个方法将那些特殊字符(&lt; &gt; &#039; &quot; )进行转换.
+     *
+     * @param obj
+     *            要转换的数据
+     * @return 转换完成的数据
+     */
+    public static String htmlEncoder(Object obj) {
+        if (obj == null){
+            return ("");
+        }
+        String value = obj.toString();
+
+        char content[] = new char[value.length()];
+        value.getChars(0, value.length(), content, 0);
+        StringBuffer result = new StringBuffer(content.length + 50);
+        for (int i = 0; i < content.length; i++) {
+            switch (content[i]) {
+                case '<':
+                    result.append("&lt;");
+                    break;
+                case '>':
+                    result.append("&gt;");
+                    break;
+                case '\'':
+                    result.append("&#039;");
+                    break;
+                // case '&':
+                // result.append("&amp;");
+                // break;
+                case '"':
+                    result.append("&quot;");
+                    break;
+                default:
+                    result.append(content[i]);
+            }
+        }
+        return (result.toString());
+    }
+
+
+
+
+
+
+
+
+
+
+
+
+    /**
+     * 这个常量表示时间格式:yyyy-MM-dd
+     *
+     * @see #DEFAULT_DATE_FORMAT:yyyy-MM-dd
+     * @see #DEFAULT_TIMESTAMP_FORMAT:yyyy-MM-dd HH:mm:ss
+     * @see #DEFAULT_TIME_FORMAT:yyyy-MM-dd HH:mm
+     * @see #DEFAULT_HOUR_FORMAT:yyyy-MM-dd hha
+     */
+    public static String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
+    /**
+     * 这个常量表示时间格式:yyyy-MM-dd HH:mm:ss
+     *
+     * @see #DEFAULT_DATE_FORMAT:yyyy-MM-dd
+     * @see #DEFAULT_TIMESTAMP_FORMAT:yyyy-MM-dd HH:mm:ss
+     * @see #DEFAULT_TIME_FORMAT:yyyy-MM-dd HH:mm
+     * @see #DEFAULT_HOUR_FORMAT:yyyy-MM-dd hha
+     */
+    public static String DEFAULT_TIMESTAMP_FORMAT = "yyyy-MM-dd HH:mm:ss";
+    /**
+     * 这个常量表示时间格式:yyyy-MM-dd HH:mm
+     *
+     * @see #DEFAULT_DATE_FORMAT:yyyy-MM-dd
+     * @see #DEFAULT_TIMESTAMP_FORMAT:yyyy-MM-dd HH:mm:ss
+     * @see #DEFAULT_TIME_FORMAT:yyyy-MM-dd HH:mm
+     * @see #DEFAULT_HOUR_FORMAT:yyyy-MM-dd hha
+     */
+    public static String DEFAULT_TIME_FORMAT = "yyyy-MM-dd HH:mm";
+    /**
+     * 这个常量表示时间格式:yyyy-MM-dd hha
+     *
+     * @see #DEFAULT_DATE_FORMAT:yyyy-MM-dd
+     * @see #DEFAULT_TIMESTAMP_FORMAT:yyyy-MM-dd HH:mm:ss
+     * @see #DEFAULT_TIME_FORMAT:yyyy-MM-dd HH:mm
+     * @see #DEFAULT_HOUR_FORMAT:yyyy-MM-dd hha
+     */
+    public static String DEFAULT_HOUR_FORMAT = "yyyy-MM-dd hha";
+
+    // public static Date getCurrentDay() {
+    // Calendar c = Calendar.getInstance();
+    // clearCalendar(c);
+    // return new java.sql.Timestamp(c.getTimeInMillis());
+    // }
+
+    // public static Date getLastSaturday() {
+    // Calendar c = Calendar.getInstance();
+    // clearCalendar(c);
+    // c.add(Calendar.DATE, -c.get(Calendar.DAY_OF_WEEK));
+    // return new java.sql.Timestamp(c.getTimeInMillis());
+    // }
+
+    /**
+     * 这个方法是设置<code>Calendar</code>的年月日三个属性,时分秒和毫秒默认为0
+     *
+     * @param c
+     *            -要设置的Calendar
+     * @param year
+     *            -参数年
+     * @param month
+     *            -参数月
+     * @param day
+     *            -参数日
+     * @return 设置好后的Calendar
+     */
+    public static Calendar setCalendar(Calendar c, int year, int month, int day) {
+        c.set(Calendar.YEAR, year);
+        c.set(Calendar.MONTH, month);
+        c.set(Calendar.DAY_OF_MONTH, day);
+        c.set(Calendar.HOUR_OF_DAY, 0);
+        c.set(Calendar.MINUTE, 0);
+        c.set(Calendar.SECOND, 0);
+        c.set(Calendar.MILLISECOND, 0);
+        return c;
+    }
+
+    /**
+     * 这个方法是设置<code>Calendar</code>的Time属性,时分秒和毫秒默认为0
+     *
+     * @param c
+     *            -要设置的Calendar
+     * @param date
+     *            -参数要设置的时间
+     * @return 设置好后的Calendar
+     */
+    public static Calendar setCalendar(Calendar c, Date date) {
+        c.setTime(date);
+        c.set(Calendar.HOUR_OF_DAY, 0);
+        c.set(Calendar.MINUTE, 0);
+        c.set(Calendar.SECOND, 0);
+        c.set(Calendar.MILLISECOND, 0);
+        return c;
+    }
+
+    /**
+     * 将日期类型转换为<code>String</code>类型
+     *
+     * @param dateValue
+     *            要转换的日期
+     * @param dateFormat
+     *            要转换的格式
+     * @return 转换后的结果
+     * @see #DEFAULT_DATE_FORMAT:yyyy-MM-dd
+     * @see #DEFAULT_TIMESTAMP_FORMAT:yyyy-MM-dd HH:mm:ss
+     * @see #DEFAULT_TIME_FORMAT:yyyy-MM-dd HH:mm
+     * @see #DEFAULT_HOUR_FORMAT:yyyy-MM-dd hha
+     */
+    public static String date2String(Date dateValue, String dateFormat) {
+        String sResult = "";
+        if (dateValue != null) {
+            SimpleDateFormat formatter = new SimpleDateFormat(dateFormat);
+            sResult = formatter.format(dateValue);
+        }
+        return sResult;
+    }
+
+    /**
+     * 将Date数据转换成默认日期格式或者默认时间格式的字符串
+     *
+     * @param dateValue
+     *            要转换的Date
+     * @param dateFormat
+     *            如果为0则为默认时间格式(yyyy-MM-dd HH:mm),否则为默认日期(yyyy-MM-dd)
+     * @return 转换后的字符串
+     * @see #DEFAULT_DATE_FORMAT:yyyy-MM-dd
+     * @see #DEFAULT_TIME_FORMAT:yyyy-MM-dd HH:mm
+     */
+    public static String date2String(Date dateValue, int dateFormat) {
+        String f = DEFAULT_DATE_FORMAT;
+        if (dateFormat == 0) {
+            f = DEFAULT_TIME_FORMAT;
+        }
+        return date2String(dateValue, f);
+    }
+
+    /**
+     * 将Date类型的数据转换为默认时间格式(yyyy-MM-dd HH:mm)的字符串
+     *
+     * @param dateValue
+     *            要转换的Date
+     * @return 转换后的字符串
+     */
+    public static String date2String(Date dateValue) {
+        return date2String(dateValue, DEFAULT_TIME_FORMAT);
+    }
+
+    /**
+     * 这个方法将给定的字符串转换为默认的日期类型(yyyy-MM-dd)
+     *
+     * @param sDate
+     *            要转换成日期的字符串
+     * @return 转换完成的字符串
+     * @throws ParseException
+     *             字符串不能转换成日期格式时,出现转换异常
+     * @see #DEFAULT_DATE_FORMAT:yyyy-MM-dd
+     */
+    public static Date string2Date(String sDate) throws ParseException {
+        return string2Date(sDate, DEFAULT_DATE_FORMAT);
+    }
+
+    /**
+     * 这个方法将给定的字符串转换为指定的日期类型
+     *
+     * @param sDate
+     *            要转换成日期的字符串
+     * @param dateFormat
+     *            目标格式
+     * @return 转换后的日期
+     * @throws ParseException
+     *             转换时出现的异常,很可能是sDate格式不正确
+     * @see #DEFAULT_DATE_FORMAT:yyyy-MM-dd
+     * @see #DEFAULT_TIMESTAMP_FORMAT:yyyy-MM-dd HH:mm:ss
+     * @see #DEFAULT_TIME_FORMAT:yyyy-MM-dd HH:mm
+     * @see #DEFAULT_HOUR_FORMAT:yyyy-MM-dd hha
+     */
+    public static Date string2Date(String sDate, String dateFormat) throws ParseException {
+        Date tmp = null;
+        if (sDate != null && !"".equals(sDate)) {
+            SimpleDateFormat formatter = new SimpleDateFormat(dateFormat);
+            formatter.setLenient(true);
+            tmp = formatter.parse(sDate);
+        }
+        return tmp;
+    }
+
+    /**
+     * 将String数据转换成默认日期格式或者默认时间格式的时间或者日期格式
+     *
+     * @param sDate
+     *            要转换的String
+     * @param dateFormat
+     *            如果为0则为默认时间格式(yyyy-MM-dd HH:mm),否则为默认日期(yyyy-MM-dd)
+     * @return 转换后的日期
+     * @see #DEFAULT_DATE_FORMAT:yyyy-MM-dd
+     * @see #DEFAULT_TIME_FORMAT:yyyy-MM-dd HH:mm
+     */
+    public static Date string2Date(String sDate, int dateFormat) throws ParseException {
+        String f = DEFAULT_DATE_FORMAT;
+        if (dateFormat == 0) {
+            f = DEFAULT_TIME_FORMAT;
+        }
+        return string2Date(sDate, f);
+    }
+
+    /**
+     * 将Sting转换成int,如果s的值为null,"null",""则返回默认值0
+     *
+     * @param s
+     *            要转换的String
+     * @return 转换完成的int结果
+     */
+    public static int getIntFromString(String s) {
+        int iRet = 0;
+        if (s != null && !"".equals(s) && !"null".equals(s)) {
+            iRet = Integer.parseInt(s);
+        }
+        return iRet;
+    }
+
+    /**
+     * 将Sting转换成long,如果s的值为null,""则返回默认值0
+     *
+     * @param s
+     *            要转换的String
+     * @return 转换完成的long结果
+     */
+    public static long getLongFromString(String s) {
+        long iRet = 0;
+        if (s != null && !"".equals(s)) {
+            iRet = Long.parseLong(s);
+        }
+        return iRet;
+    }
+
+    /**
+     * 将Sting转换成Integer,如果s的值为null,"null",""则返回null
+     *
+     * @param s
+     *            要转换的String
+     * @return 转换完成的Integer结果
+     */
+    public static Integer getInteger(String s) {
+        if (s == null || "".equals(s)) {
+            return null;
+        }
+        return new Integer(s);
+    }
+
+    /**
+     * 默认的Decimal格式,保留两位小数
+     */
+    private static String FORMAT_PATTERN_DEFAULT = "#0.00";
+
+    /**
+     * 获取指定格式的数值,并以String数据类型返回,如果input是null或者"",返回""
+     *
+     * @param input
+     *            要转换的字符串
+     * @param pattern
+     *            要转换的格式
+     * @return 返回指定格式的String类型的数值(四舍五入)
+     */
+    public static String formatNumber(String input, String pattern) {
+        if (input == null ||"" .equals(input.trim())) {
+            return "";
+        }
+        DecimalFormat format = new DecimalFormat();
+        format.applyLocalizedPattern(pattern);
+        double d = Double.parseDouble(input);
+        return format.format(d);
+    }
+
+
+
+    /**
+     * 获取默认格式的String类型的数值
+     *
+     * @param input
+     *            要转换的String
+     * @return 转换后的数据(四舍五入)
+     */
+    public static String formatNumber(String input) {
+        return formatNumber(input, FORMAT_PATTERN_DEFAULT);
+    }
+
+
+
+    /**
+     * Format given double value to a string with specific precision. Known bug:
+     * If the significant digit count of input double value is greater than 17,
+     * the formatted value will be incorrect For example: 11111111111111111.0000
+     * will be formated to 11111111111111112.0, Double.toString(double) method
+     * will return 1.1111111111111112E16, this is the cause. Note: Don't call
+     * String.valueOf(double) to convert it to a string, which will format the
+     * number as computer science notation format when the value is larger than
+     * 10^7.
+     *
+     * @param d
+     * @return
+     */
+    public static String formatNumber(double d, int scale) {
+        DecimalFormat df = new DecimalFormat(FORMAT_PATTERN_DEFAULT);
+        df.setMaximumFractionDigits(scale);
+        return df.format(d);
+    }
+
+    /**
+     * Format given double value to a string with default precision of 2.
+     *
+     * @param d
+     * @return
+     */
+    public static String formatNumber(double d) {
+        DecimalFormat df = new DecimalFormat(FORMAT_PATTERN_DEFAULT);
+        df.setMaximumFractionDigits(2);
+        return df.format(d);
+    }
+
+    /**
+     * 默认的DECIMAL的数据格式
+     *
+     */
+    public static String DEFAULT_DECIMAL_FORMAT = "##############0.00";
+    /**
+     * 默认的WORKTIME的数据格式
+     *
+     */
+    public static String DEFAULT_WORKTIME_FORMAT = "##############0.0";
+    /**
+     * 默认的PERCENT的数据格式
+     *
+     */
+    public static String DEFAULT_PERCENT_FORMAT = "##############0";
+
+    /**
+     * percent的DecimalFormat格式
+     *
+     * @see decimalFormatter "##############0.00"
+     * @see workTimeFormatter "##############0.0"
+     * @see percentFormatter "##############0"
+     */
+
+    /**
+     * 将给定的double类型的数据,根据默认DecimalFormat格式转化成对应的String类型数值
+     *
+     * @param d
+     *            要转换的double类型数值
+     * @return 转换后的String数值
+     */
+    public static String double2String(double d) {
+        DecimalFormat decimalFormatter = new DecimalFormat(DEFAULT_DECIMAL_FORMAT);
+        return decimalFormatter.format(d).toString();
+    }
+
+    /**
+     * 将给定的double类型的数据,根据percentFormatter格式转化成对应的String类型数值
+     *
+     * @param d
+     *            要转换的double类型数值
+     * @return 转换后的String数值
+     */
+    public static String percent2String(double d) {
+        DecimalFormat percentFormatter = new DecimalFormat(DEFAULT_WORKTIME_FORMAT);
+        return percentFormatter.format(d).toString();
+    }
+
+    /**
+     * 将给定的double类型的数据,根据workTimeFormatter格式转化成对应的String类型数值
+     *
+     * @param d
+     *            要转换的double类型数值
+     * @return 转换后的String数值
+     * @see  "##############0.0"
+     */
+    public static String worktime2String(double d) {
+        DecimalFormat workTimeFormatter = new DecimalFormat(DEFAULT_WORKTIME_FORMAT);
+        return workTimeFormatter.format(d).toString();
+    }
+
+    /**
+     * 将给定的double类型的数据, 根据workTimeFormatter格式转化成对应的String类型数值,
+     * 如果sDouble为""或者为null,则返回默认值0.0
+     *
+     *            要转换的double类型数值
+     * @return 转换后的double数值
+     * @see  "##############0.0"
+     */
+    public static double string2Worktime(String sDouble) {
+        try {
+            if (sDouble != null && !"".equals(sDouble)) {
+                DecimalFormat workTimeFormatter = new DecimalFormat(DEFAULT_WORKTIME_FORMAT);
+                return workTimeFormatter.parse(sDouble).doubleValue();
+            }
+        } catch (Exception e) {
+        }
+        return 0.0;
+    }
+
+    /**
+     * 将给定的double类型的数据, 根据decimalFormatter格式转化成对应的String类型数值,
+     * 如果sDouble为""或者为null,则返回默认值0.00
+     *
+     *            要转换的double类型数值
+     * @return 转换后的double数值
+     * @see  "##############0.00"
+     */
+    public static double string2Double(String sDouble) {
+        try {
+            if (sDouble != null && !"".equals(sDouble)) {
+                DecimalFormat decimalFormatter = new DecimalFormat(DEFAULT_DECIMAL_FORMAT);
+                return decimalFormatter.parse(sDouble).doubleValue();
+            }
+        } catch (Exception e) {
+        }
+        return 0.00;
+    }
+
+    /**
+     * 需要转移
+     *
+     * @param s
+     * @return
+     * @throws Exception
+     */
+    public static String getLimitText(int limit, Object s) throws Exception {
+        String result = "";
+        String value = TypeUtils.nullToString(s);
+        if (limit == 0 || value.length() <= limit) {
+            result = value;
+        } else {
+            result = value.substring(0, limit) + "...";
+        }
+        return result;
+    }
+
+    /**
+     * 将Java的字符串转换成可执行的Javascript代码
+     *
+     * @param s
+     *            要转换的Java代码
+     * @return 转换后生成可执行的Javascript代码
+     */
+    public static String javaString2JavascriptString(String s) {
+        if (s == null) {
+            return null;
+        }
+        s = s.replace("\\", "\\\\");
+        s = s.replace("'", "\\'");
+        s = s.replace("\"", "\\\"");
+        return s;
+    }
+
+
+
+
+
+
+
+    /**
+     * 把double四舍五入到小数点后n位
+     *
+     * @param value
+     *            要转换的double类型的数值
+     * @param afterPoint
+     *            保留多少位小数点
+     * @return 转换后的值
+     */
+    public static double round(double value, int afterPoint) {
+        BigDecimal bd = new BigDecimal(value);
+        BigDecimal bd1 = bd.setScale(afterPoint, BigDecimal.ROUND_HALF_UP);
+        return bd1.doubleValue();
+    }
+
+    /**
+     * 把double四舍五入到小数点后n位,返回String
+     *
+     * @param value
+     *            要转换的double类型的数值
+     * @param afterPoint
+     *            保留多少位小数点
+     * @return 转换后的String类型的数值
+     */
+    public static String roundToString(double value, int afterPoint) {
+        BigDecimal bd = new BigDecimal(value);
+        BigDecimal bd1 = bd.setScale(afterPoint, BigDecimal.ROUND_HALF_UP);
+        NumberFormat formatter = NumberFormat.getNumberInstance();
+        formatter.setMinimumFractionDigits(afterPoint);
+        formatter.setMaximumFractionDigits(afterPoint);
+        String rtnValue = formatter.format(bd1.doubleValue());
+        return rtnValue;
+    }
+
+    /**
+     * 省略年,按MM-dd方式显示
+     *
+     * @param date
+     *            要处理的日期
+     * @return 处理后的日期(MM-dd)格式
+     */
+    public static String noShowYear(Date date) {
+        SimpleDateFormat format = new SimpleDateFormat("MM-dd");
+        return format.format(date);
+    }
+
+
+
+
+    /**
+     * 根据int类型的月份,获取资源文件中的月份key值
+     *
+     * @param month
+     *            int类型的月份值
+     * @return 对应资源文件中的月份key值
+     */
+    private static String getMonthKey(int month) {
+        String key = null;
+        switch (month) {
+            case 0:
+                key = "JAN";
+                break;
+            case 1:
+                key = "FEB";
+                break;
+            case 2:
+                key = "MAR";
+                break;
+            case 3:
+                key = "APR";
+                break;
+            case 4:
+                key = "MAY";
+                break;
+            case 5:
+                key = "JUN";
+                break;
+            case 6:
+                key = "JUL";
+                break;
+            case 7:
+                key = "AUG";
+                break;
+            case 8:
+                key = "SEP";
+                break;
+            case 9:
+                key = "OCT";
+                break;
+            case 10:
+                key = "NOV";
+                break;
+            case 11:
+                key = "DEC";
+                break;
+        }
+        return key;
+    }
+
+    /**
+     * 通过季度,得到以逗号分隔的月份字符串 例: " (0,1,2)"," (3,4,5)"," (6,7,8)"," (9,10,11)".
+     *
+     * @param quarter
+     *            int类型的季度值,可取1,2,3,4这四个值,表示一,二,三,四季度
+     * @return 返回月份的字符串.
+     */
+    public static String getInMonthStringByQuarter(int quarter) {
+        switch (quarter) {
+            case (1):
+                return " (0,1,2)";
+            case (2):
+                return " (3,4,5)";
+            case (3):
+                return " (6,7,8)";
+            case (4):
+                return " (9,10,11)";
+        }
+        return null;
+    }
+
+}