kdtable 树形结构

/**
* output package name
*/
package com.kingdee.eas.fdc.aimcost.client;

import java.awt.Color;
import java.io.ByteArrayInputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.swing.SwingUtilities;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreeNode;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.log4j.Logger;
import org.w3c.dom.Document;

import com.kingdee.bos.BOSException;
import com.kingdee.bos.ctrl.kdf.table.IColumn;
import com.kingdee.bos.ctrl.kdf.table.IRow;
import com.kingdee.bos.ctrl.kdf.table.KDTDataRequestManager;
import com.kingdee.bos.ctrl.kdf.table.KDTMergeManager;
import com.kingdee.bos.ctrl.kdf.table.KDTSelectManager;
import com.kingdee.bos.ctrl.kdf.table.KDTable;
import com.kingdee.bos.ctrl.kdf.table.event.KDTMouseEvent;
import com.kingdee.bos.ctrl.swing.tree.DefaultKingdeeTreeNode;
import com.kingdee.bos.dao.IObjectValue;
import com.kingdee.bos.dao.ormapping.ObjectUuidPK;
import com.kingdee.bos.dao.query.IQueryExecutor;
import com.kingdee.bos.metadata.IMetaDataPK;
import com.kingdee.bos.metadata.entity.EntityViewInfo;
import com.kingdee.bos.metadata.entity.FilterInfo;
import com.kingdee.bos.metadata.entity.FilterItemInfo;
import com.kingdee.bos.metadata.entity.SelectorItemCollection;
import com.kingdee.bos.metadata.entity.SelectorItemInfo;
import com.kingdee.bos.metadata.query.util.CompareType;
import com.kingdee.bos.ui.face.CoreUIObject;
import com.kingdee.eas.base.commonquery.IQuerySolutionFacade;
import com.kingdee.eas.base.commonquery.QueryPanelCollection;
import com.kingdee.eas.base.commonquery.QuerySolutionFacadeFactory;
import com.kingdee.eas.base.commonquery.QuerySolutionInfo;
import com.kingdee.eas.base.commonquery.client.CommonQueryDialog;
import com.kingdee.eas.base.commonquery.client.CustomerParams;
import com.kingdee.eas.base.commonquery.client.CustomerQueryPanel;
import com.kingdee.eas.base.permission.client.longtime.ILongTimeTask;
import com.kingdee.eas.base.permission.client.longtime.LongTimeDialog;
import com.kingdee.eas.base.permission.client.util.UITools;
import com.kingdee.eas.basedata.org.FullOrgUnitInfo;
import com.kingdee.eas.basedata.org.OrgStructureInfo;
import com.kingdee.eas.basedata.org.client.OrgViewUtils;
import com.kingdee.eas.common.EASBizException;
import com.kingdee.eas.common.client.SysContext;
import com.kingdee.eas.fdc.aimcost.IMeasureCost;
import com.kingdee.eas.fdc.aimcost.MeasureCostCollection;
import com.kingdee.eas.fdc.aimcost.MeasureCostFactory;
import com.kingdee.eas.fdc.aimcost.MeasureCostInfo;
import com.kingdee.eas.fdc.basedata.ApportionTypeInfo;
import com.kingdee.eas.fdc.basedata.CostAccountFactory;
import com.kingdee.eas.fdc.basedata.CostAccountInfo;
import com.kingdee.eas.fdc.basedata.CurProjectFactory;
import com.kingdee.eas.fdc.basedata.CurProjectInfo;
import com.kingdee.eas.fdc.basedata.FDCBillStateEnum;
import com.kingdee.eas.fdc.basedata.FDCConstants;
import com.kingdee.eas.fdc.basedata.FDCCustomerParams;
import com.kingdee.eas.fdc.basedata.FDCHelper;
import com.kingdee.eas.fdc.basedata.FDCSQLBuilder;
import com.kingdee.eas.fdc.basedata.IProjectIndexDataEntry;
import com.kingdee.eas.fdc.basedata.IncomeAccountFactory;
import com.kingdee.eas.fdc.basedata.IncomeAccountInfo;
import com.kingdee.eas.fdc.basedata.ProjectIndexDataEntryCollection;
import com.kingdee.eas.fdc.basedata.ProjectIndexDataEntryFactory;
import com.kingdee.eas.fdc.basedata.ProjectIndexDataEntryInfo;
import com.kingdee.eas.fdc.basedata.ProjectStageEnum;
import com.kingdee.eas.fdc.basedata.client.FDCClientHelper;
import com.kingdee.eas.fdc.basedata.client.ProjectTreeBuilder;
import com.kingdee.eas.fdc.contract.FDCUtils;
import com.kingdee.eas.framework.ICoreBase;
import com.kingdee.eas.framework.ITreeBase;
import com.kingdee.eas.util.SysUtil;
import com.kingdee.jdbc.rowset.IRowSet;

/**
* output class name
*/
public class AimCostApprovalUI extends AbstractAimCostApprovalUI
{
    private static final Logger logger = CoreUIObject.getLogger(AimCostApprovalUI.class);
    
    private TreeSelectionListener treeSelectionListener;
        
    //从目标成本获得当前节点下所有项目最终版本的目标成本映射(prjid,costMap) costMap(acctNumber,amount)
    Map aimCostMap = new HashMap();
    
    //从项目收入测算获取有当前节点下所有有最终版本工程项目的收入映射(prjId,incomeMap) incomeMap(acctNumer,amount)
    Map aimIncomeMap = new HashMap();

    //当前节点下所有项目中含有最终目标成本的prjid集(有目标成本)
    HashSet lastVerPrjIdSet = new HashSet();
    
    //lastVerPrjIdSet工程项目名称、测算阶段(从目标成本测算中获得)
    Map projectMeasureMap = new HashMap();
    
    //lastVerPrjIdSet建筑面积集合
    Map buildAreaSet = new HashMap();
    
    private CustomerQueryPanel filterUI = null;

private CommonQueryDialog commonQueryDialog = null;

private static final String DEVCOSTACCT ="DevCostAcct";
    private static final String INDIRECTCOSTACCT ="IndirectCostAcct";
    private static final String LANDCOSTACCT ="LandCostAcct";

private String DevCostAcct;
    private String IndirectCostAcct;
    private String LandCostAcct;
    
    /**
     * output class constructor
     */
    public AimCostApprovalUI() throws Exception
    {
        super();
    }

protected String getEditUIName() {
  // TODO Auto-generated method stub
  return null;
}  


protected Object getSelectObj() {
  DefaultKingdeeTreeNode node = (DefaultKingdeeTreeNode) treeMain.getLastSelectedPathComponent();
  if (node == null || node.getUserObject() == null || OrgViewUtils.isTreeNodeDisable(node)) {
   return null;
  }
  if (node.getUserObject() instanceof CurProjectInfo) {
   CurProjectInfo projectInfo = (CurProjectInfo) node.getUserObject();
   return projectInfo;
  } else if (node.getUserObject() instanceof OrgStructureInfo) {
   OrgStructureInfo oui = (OrgStructureInfo) node.getUserObject();
   if (oui.getUnit() == null) {
    return null;
   }
   FullOrgUnitInfo info = oui.getUnit();
   return info;
  }
  return null;
}

protected String getSelectObjId() {
  Object obj=getSelectObj();
  if(obj!=null){
   return ((IObjectValue)obj).getString("id");
  }
  return null;
}

protected ITreeBase getTreeInterface() throws Exception {
  return CurProjectFactory.getRemoteInstance();
}

protected boolean isCanOrderTable() {
  return false;
}

protected void tblMain_tableClicked(KDTMouseEvent e) throws Exception {
  // TODO Auto-generated method stub
  //super.tblMain_tableClicked(e);
}

protected ICoreBase getBizInterface() throws Exception {
  return null;
} 

protected void execQuery() {
  // TODO Auto-generated method stub
  //super.execQuery();
  //获得方案设置值
  getSettingFilterData();
}

protected void initTree() throws Exception {  
  tblMain.checkParsed();
  tblMain.setRefresh(false);
  tblMain.getDataRequestManager().setDataRequestMode(KDTDataRequestManager.REAL_MODE);
  tblMain.setColumnMoveable(true);
  
  ProjectTreeBuilder treeBuilder = new ProjectTreeBuilder();
  treeBuilder.build(this, this.treeMain, this.actionOnLoad);
  this.treeMain.expandAllNodes(true, (TreeNode) (this.treeMain.getModel()).getRoot());
}


@Override
protected IQueryExecutor getQueryExecutor(IMetaDataPK arg0,
   EntityViewInfo arg1) {
  // TODO Auto-generated method stub
  return super.getQueryExecutor(arg0, arg1);
}

protected CommonQueryDialog initCommonQueryDialog() {
  if (commonQueryDialog != null) {
   return commonQueryDialog;
  }
  commonQueryDialog = super.initCommonQueryDialog();
  commonQueryDialog.setWidth(400);
  commonQueryDialog.addUserPanel(this.getFilterUI());
  commonQueryDialog.setUiObject(null);
  commonQueryDialog.setShowFieldCompare(false);
  commonQueryDialog.setShowFilter(false);
  commonQueryDialog.setShowSorter(false);
  //commonQueryDialog.setMaxReturnCountVisible(false);
  commonQueryDialog.setTitle(this.getUITitle() + " - "+ "方案设置");
  return commonQueryDialog;  
}

private CustomerQueryPanel getFilterUI() {
  if (this.filterUI == null) {
   try {
    this.filterUI = new AimCostApprovalFilterUI();
   } catch (Exception e) {
    e.printStackTrace();
    abort(e);
   }
  }
  return this.filterUI;
}

/**
  * 
  * 初始化默认过滤条件
  * 
  * @return 如果重载了(即做了初始化动作),请返回true;默认返回false;
  */
protected boolean initDefaultFilter() {
  return true;
}

private void getSettingFilterData(){
  try{
   FDCCustomerParams objParam = new FDCCustomerParams();
   CustomerParams customerParams = getFilterUI().getCustomerParams();
   objParam = new FDCCustomerParams(customerParams);   
   DevCostAcct = objParam.get(DEVCOSTACCT);
   IndirectCostAcct = objParam.get(INDIRECTCOSTACCT);
   LandCostAcct = objParam.get(LANDCOSTACCT);
  }catch(Exception e){
   handUIException(e);
  }  
}

private void getSettingFilterData2() throws Exception
{
  String queryName2 ="com.kingdee.eas.fdc.aimcost.app.AimCostApprovalFilterQuery";
  EntityViewInfo defaultEntityView;
  IQuerySolutionFacade iQuery = QuerySolutionFacadeFactory.getRemoteInstance();
  QuerySolutionInfo ds = iQuery.getDefaultSolution(getClass().getName(), queryName2);
  if(ds != null){
   if(!FDCHelper.isEmpty(ds.getEntityViewInfo())){
    defaultEntityView = new EntityViewInfo(ds.getEntityViewInfo());
   }else{
    defaultEntityView = new EntityViewInfo();;
    defaultEntityView.setFilter(new FilterInfo());
   }
   QueryPanelCollection queryPanelInfo = ds.getQueryPanelInfo();
   if(queryPanelInfo.size() > 0){
    for(int i = 0; i<queryPanelInfo.size(); i++){
     String filterUICName = getFilterUI().getClass().getName();
     if(filterUICName.equals(queryPanelInfo.get(i).getPanelClassName())){
      String tempParam = queryPanelInfo.get(i).getCustomerParams();   
     
      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
      DocumentBuilder builder = factory.newDocumentBuilder();
      Document doc = builder.parse(new ByteArrayInputStream(tempParam.getBytes()));
      int nodeLen = doc.getElementsByTagName("property").getLength();
      String paramName;
      for(int j=0;j<nodeLen;j++){
       paramName = doc.getElementsByTagName("name").item(j).getFirstChild().getNodeValue();
       if(paramName.equals(DEVCOSTACCT)){
        DevCostAcct = doc.getElementsByTagName("value").item(j).getFirstChild().getNodeValue();
       }
       if(paramName.equals(INDIRECTCOSTACCT)){
        IndirectCostAcct = doc.getElementsByTagName("value").item(j).getFirstChild().getNodeValue();
       }
       if(paramName.equals(LANDCOSTACCT)){
        LandCostAcct = doc.getElementsByTagName("value").item(j).getFirstChild().getNodeValue();
       }
      }
     }
    }
   }   
  }
} 

private String getAcctNumberByParam(String objId) throws EASBizException, BOSException{
  String longnumber = null;
  if(objId == null) return longnumber;
  
  CostAccountInfo info = null;
  SelectorItemCollection sic = new SelectorItemCollection();
  sic.add(new SelectorItemInfo("longnumber"));
  //sic.add(new SelectorItemInfo("name"));
  info = CostAccountFactory.getRemoteInstance().getCostAccountInfo(new ObjectUuidPK(objId), sic);
  if(info != null){
   longnumber = info.getLongNumber().replace("!", ".");
  }  
  return longnumber;
}

public void onLoad() throws Exception {
  // TODO Auto-generated method stub  
  TreeSelectionListener[] listeners = treeMain.getTreeSelectionListeners();
        treeSelectionListener = listeners[0];
        treeMain.removeTreeSelectionListener(treeSelectionListener);//加载时不进行是否明细工程的判断
        
  initControl();
  super.onLoad();   
  treeMain.addTreeSelectionListener(treeSelectionListener);
  
  //获得方案设置值
  getSettingFilterData2();
  
  initTableColumn(tblMain);  
  SwingUtilities.invokeLater(new Runnable() {
   public void run() {
    int freezeIndex=tblMain.getColumn("acctName").getColumnIndex()+1;
    tblMain.getViewManager().freeze(0, freezeIndex);
  }});
}

private void initControl() {
  this.actionImportData.setVisible(false);
  this.menuBiz.setVisible(false);
  this.menuBiz.setEnabled(false);
  this.menuItemCancel.setVisible(false);
  this.menuItemCancelCancel.setVisible(false);
  this.actionAddNew.setVisible(false);
  this.actionEdit.setVisible(false);
  this.actionEdit.setEnabled(false);
  this.actionRemove.setVisible(false);
  this.actionRemove.setEnabled(false);
  this.actionView.setVisible(false);
  this.actionView.setEnabled(false);  
  this.actionLocate.setVisible(false);
  this.menuBiz.setVisible(false);
  this.menuEdit.setVisible(false);
  this.menuView.setVisible(false);  
  this.MenuItemAttachment.setVisible(false);
  
  this.actionQuery.setVisible(true);
  this.actionQuery.setEnabled(true);
  this.btnQuery.setText("方案设置");
}

private void initTableColumn(KDTable table){
  table.removeHeadRows();
  table.removeColumns();
   
  table.addHeadRows(3);
  IRow rowH = table.getHeadRow(2);  
  IColumn column = table.addColumn();
  column.setKey("id");
  rowH.getCell("id").setValue("id");  
  column = table.addColumn();
  column.setKey("acctNumber");
  rowH.getCell("acctNumber").setValue("科目编码"); 
  column = table.addColumn();
  column.setKey("acctName");
  rowH.getCell("acctName").setValue("科目名称"); 
  column = table.addColumn();
  column.setKey("total");
  rowH.getCell("total").setValue("汇总合价(万元)");
  //FDCHelper.formatTableNumber(table, "total");
  FDCHelper.formatTableNumber(table, "total", "###,###.0000");
  
  KDTMergeManager mm = table.getHeadMergeManager();
  mm.mergeBlock(0, 1, 2, 1);//科目编码
  mm.mergeBlock(0, 2, 2, 2);//科目名称
  mm.mergeBlock(0, 3, 2, 3);//汇总合价

  table.getSelectManager().setSelectMode(KDTSelectManager.ROW_SELECT);    
  table.getColumn("id").getStyleAttributes().setHided(true);
  
  int freezeIndex=table.getColumn("acctName").getColumnIndex();
  table.getViewManager().freeze(0, freezeIndex);     
  //table.getViewManager().setFreezeView(0, freezeIndex); 
}

    private void addTableColumn(KDTable table){
     if(projectMeasureMap.size()==0){
   SysUtil.abort();
  } 
     IRow rowH = null;
     IColumn column = null;     
     KDTMergeManager mm = table.getHeadMergeManager();
  
  int mmColBegin = 3;
  for(Iterator items = projectMeasureMap.keySet().iterator();items.hasNext();){
   String item = items.next().toString();
   MeasureCostInfo info = (MeasureCostInfo)projectMeasureMap.get(item);
   if(info.getProject() == null){continue;}
   String prjId = info.getProject().getId().toString();
   column = table.addColumn();
   column.setKey(prjId+"total");
   column = table.addColumn();
   column.setKey(prjId+"avg");
    
   rowH = table.getHeadRow(0);//项目名称
   if(info.getProject().getParent() != null){
    rowH.getCell(prjId+"total").setValue(info.getProject().getParent().getName()+"_"+info.getProject().getName());
   }else{
    rowH.getCell(prjId+"total").setValue(info.getProject().getName());
   }
   mm.mergeBlock(0, mmColBegin+1, 0, mmColBegin+2);//项目名称
   
   rowH = table.getHeadRow(1);//测算阶段
   rowH.getCell(prjId+"total").setValue(info.getMeasureStage().getName());
   mm.mergeBlock(1, mmColBegin+1, 1, mmColBegin+2);//测算阶段
   
   rowH = table.getHeadRow(2);//列名 合价 建筑单方
   rowH.getCell(prjId+"total").setValue("合价(万元)");
   FDCHelper.formatTableNumber(table, prjId+"total", "###,###.0000");
   rowH.getCell(prjId+"avg").setValue("建筑单方(元/m2)");
   FDCHelper.formatTableNumber(table, prjId+"avg");
   
   mmColBegin = mmColBegin +2;//每个项目占两列
  }
    }

protected void treeMain_valueChanged(TreeSelectionEvent e) throws Exception {
  fetchAndFill();
}

private void fetchAndFill() throws EASBizException,BOSException, Exception {
  LongTimeDialog dialog = UITools.getDialog(this);
  if(dialog==null) return;
        dialog.setLongTimeTask(new ILongTimeTask() {
            public Object exec() throws Exception {
             fillTable();
//       int acctNameIndex=tblMain.getColumn("acctName").getColumnIndex()+1;
//       tblMain.getViewManager().freeze(0, acctNameIndex);          
                return null;
            }
            public void afterExec(Object result) throws Exception {               
            }
        });
        //开启了一个线程来显示进度条来提升用户的体验
        try {
         dialog.show();
  } catch (NullPointerException e) {
   // TODO: handle exception
  }
}
  
protected void fillTable() throws Exception {
  tblMain.removeRows(false);
  for(int i = tblMain.getColumnCount()-1; i> tblMain.getColumnIndex("total"); i--){
   tblMain.removeColumn(i);
  }  
  aimIncomeMap.clear();
  aimCostMap.clear();
  lastVerPrjIdSet.clear();
  buildAreaSet.clear();
  projectMeasureMap.clear();
  
  //prjid目标成本映射、有最终目标成本prjid集合
  getAimCostMap(); 
  //获得lastVerPrjIdSet的项目名称、测算阶段名称
  getProjectMeasureInfo();
  //获取建筑面积集合
  getBuildAreaSet();

  if(projectMeasureMap.size()==0){
   SysUtil.abort();
  }
  
  //收入测算
  getAimIncomeMap();
  
  //加列
  addTableColumn(tblMain);
  
  int maxLevel = 0;
  //收入科目树
  if(getSelectObj() != null){
   FilterInfo incomeAcctFilter = new FilterInfo();
   //收入科目采用当前选择的工程对象
   if(getSelectObj() instanceof CurProjectInfo){
incomeAcctFilter.getFilterItems().add(new FilterItemInfo("curProject.id",getSelectObjId(),CompareType.EQUALS));
   }else if(getSelectObj() instanceof FullOrgUnitInfo){
incomeAcctFilter.getFilterItems().add(new FilterItemInfo("fullOrgUnit.id",getSelectObjId(),CompareType.EQUALS));
   }
   incomeAcctFilter.getFilterItems().add(new FilterItemInfo("isEnabled", new Integer(1)));
   
   TreeModel incomeAcctTree;
   incomeAcctTree = FDCClientHelper.createDataTree(IncomeAccountFactory.getRemoteInstance(), incomeAcctFilter);
   DefaultKingdeeTreeNode root = (DefaultKingdeeTreeNode) incomeAcctTree.getRoot();
   Enumeration childrens = root.depthFirstEnumeration();
   while(childrens.hasMoreElements()){
    DefaultMutableTreeNode node = (DefaultMutableTreeNode) childrens.nextElement();
    if(node.getUserObject() != null && node.getLevel() > maxLevel){
     maxLevel = node.getLevel();
    }
   }
   tblMain.getTreeColumn().setDepth(maxLevel);
   for(int i = 0; i < root.getChildCount(); i++){
    fillIncomeAcctNode((DefaultMutableTreeNode) root.getChildAt(i));
   }
  }

  //成本科目树
  if(getSelectObj() != null){
   FilterInfo costAcctFilter = new FilterInfo();
   //成本科目采用当前选择的工程对象
   //costAcctFilter.getFilterItems().add(new FilterItemInfo("id",getCostAcctIds(),CompareType.INCLUDE));
   if(getSelectObj() instanceof CurProjectInfo){
    costAcctFilter.getFilterItems().add(new FilterItemInfo("curProject.id",getSelectObjId(),CompareType.EQUALS));
   }else if(getSelectObj() instanceof FullOrgUnitInfo){
    costAcctFilter.getFilterItems().add(new FilterItemInfo("fullOrgUnit.id",getSelectObjId(),CompareType.EQUALS));
   }
   costAcctFilter.getFilterItems().add(new FilterItemInfo("isEnabled", new Integer(1)));
   
   TreeModel costAcctTree;
   costAcctTree = FDCClientHelper.createDataTree(CostAccountFactory.getRemoteInstance(), costAcctFilter);
   DefaultKingdeeTreeNode root = (DefaultKingdeeTreeNode) costAcctTree.getRoot();
   Enumeration childrens = root.depthFirstEnumeration();
   int maxLevel2 = 0;
   while (childrens.hasMoreElements()) {
    DefaultMutableTreeNode node = (DefaultMutableTreeNode) childrens.nextElement();
    if (node.getUserObject() != null && node.getLevel() > maxLevel2) {
     maxLevel2 = node.getLevel();
    }
   }
   if(maxLevel2 > maxLevel){    
    tblMain.getTreeColumn().setDepth(maxLevel2);
   }
   
   for (int i = 0; i < root.getChildCount(); i++) {
    fillCostAcctNode((DefaultMutableTreeNode) root.getChildAt(i));
   }
  }
  //上下级汇总、汇总合价计算
  setUnionData(tblMain);

//添加末尾5各计算行
  addCalculateRow(tblMain);
}

private void fillIncomeAcctNode(DefaultMutableTreeNode node){
  IncomeAccountInfo incomeAcct = (IncomeAccountInfo) node.getUserObject();
  if(incomeAcct == null){
   return;
  }
  String acctNumber = incomeAcct.getLongNumber().replace('!', '.');
  IRow row = tblMain.addRow();
  row.setTreeLevel(node.getLevel() - 1);
  row.getCell("acctNumber").setValue(acctNumber);
  row.getCell("acctName").setValue(incomeAcct.getName());
  //row.getCell(0).setUserObject(acctNumber);  
  if(node.isLeaf()){
   //row.getCell(0).setUserObject(null);
   row.setUserObject(incomeAcct);
   Map incomeMap = null;
   BigDecimal amount = null;
   BigDecimal buildArea = null;
   for(Iterator items = projectMeasureMap.keySet().iterator();items.hasNext();){
    String prjId = items.next().toString();
    incomeMap = (Map)aimIncomeMap.get(prjId);
    if(incomeMap == null){continue;}
    if(incomeMap.size() > 0){
     amount = FDCHelper.toBigDecimal(incomeMap.get(acctNumber));
     if(amount.compareTo(FDCHelper.ZERO) != 0){
      row.getCell(prjId+"total").setValue(amount.divide(FDCHelper.toBigDecimal(10000), 4, BigDecimal.ROUND_HALF_UP));     
     }
    }
    if(buildAreaSet.size() > 0){
     buildArea = FDCHelper.toBigDecimal(buildAreaSet.get(prjId));
     if(buildArea.compareTo(FDCHelper.ZERO) != 0 && amount.compareTo(FDCHelper.ZERO) != 0){
      row.getCell(prjId+"avg").setValue(amount.divide(buildArea,2,BigDecimal.ROUND_HALF_UP));
     }
    }
   }
  }else{
   row.getCell(0).setUserObject("income");
   row.getStyleAttributes().setBackground(new Color(0xF0EDD9));
  }
  for (int i = 0; i < node.getChildCount(); i++) {
   this.fillIncomeAcctNode((DefaultMutableTreeNode) node.getChildAt(i));
  }
}

private void fillCostAcctNode(DefaultMutableTreeNode node){
  CostAccountInfo costAcct = (CostAccountInfo) node.getUserObject();
  if (costAcct == null) {
   return;
  }
  //String acctId = costAcct.getId().toString();
  String acctNumber = costAcct.getLongNumber().replace('!', '.');
  IRow row = tblMain.addRow();
  row.setTreeLevel(node.getLevel() - 1);
  row.getCell("acctNumber").setValue(acctNumber);
  row.getCell("acctName").setValue(costAcct.getName());
  //row.getCell(0).setUserObject(acctNumber);
  if (node.isLeaf()) {
   //row.getCell(0).setUserObject(null);
   row.setUserObject(costAcct);   
   Map costMap = null;
   BigDecimal amount = null;
   BigDecimal buildArea = null;
   for(Iterator items = projectMeasureMap.keySet().iterator();items.hasNext();){
    String prjId = items.next().toString();
    costMap = (Map)aimCostMap.get(prjId);
    if(costMap == null){continue;}
    if(costMap.size() >0){
     //amount = (BigDecimal) costMap.get(acctNumber);
     amount = FDCHelper.toBigDecimal(costMap.get(acctNumber));
     if(amount.compareTo(FDCHelper.ZERO) != 0){      
      row.getCell(prjId+"total").setValue(amount.divide(FDCHelper.toBigDecimal(10000), 4, BigDecimal.ROUND_HALF_UP));     
     }          
    }
    if(buildAreaSet.size() >0){
     //buildArea = (BigDecimal) buildAreaSet.get(prjId);
     buildArea = FDCHelper.toBigDecimal(buildAreaSet.get(prjId));
     if(buildArea.compareTo(FDCHelper.ZERO) !=0 && amount.compareTo(FDCHelper.ZERO) !=0){
      row.getCell(prjId+"avg").setValue(amount.divide(buildArea,2,BigDecimal.ROUND_HALF_UP));
     }
    }
   }
  }else{
   row.getCell(0).setUserObject("cost");
   row.getStyleAttributes().setBackground(new Color(0xF0EDD9));
  }
  
  for (int i = 0; i < node.getChildCount(); i++) {
   this.fillCostAcctNode((DefaultMutableTreeNode) node.getChildAt(i));
  }
} 

//获取每个prjid的目标成本映射,并得到有最终目标成本的prjid集合
private void getAimCostMap() throws BOSException{
  DefaultKingdeeTreeNode node = (DefaultKingdeeTreeNode)treeMain.getLastSelectedPathComponent();
  Set prjIds = FDCClientHelper.getProjectLeafsOfNode(node);
  Map aimMap = null;
  for(Iterator items = prjIds.iterator(); items.hasNext();){
   String prjId = items.next().toString();
   aimMap = getAcctAimCostData(prjId);
   if(aimMap.size() > 0){
    aimCostMap.put(prjId, aimMap);
    lastVerPrjIdSet.add(prjId);
   }   
  } 
}

//获得目标成本
private Map getAcctAimCostData(String prjId) throws BOSException {
  // TODO 用SQL来实现  FDCCostRptFacadeControllerBean.java  
  Map aimMap = new HashMap();
  try {
   FDCSQLBuilder builder = new FDCSQLBuilder();
   if(FDCUtils.getDefaultFDCParamByKey(
     null, SysContext.getSysContext().getCurrentFIUnit().getId().toString(), FDCConstants.FDC_PARAM_AIMCOSTAUDIT)){
    builder.appendSql("select entry.fcostaccountid as acctid,acct.flongnumber,sum(entry.fcostamount) as amount from T_AIM_AimCost head " +
      " inner join T_AIM_CostEntry entry on entry.fheadid=head.fid " +
      "   left join t_fdc_costaccount acct on entry.fcostaccountid=acct.fid "+
      " where head.fisLastVersion=1 and  head.ForgOrProId=? " +
      " and head.fstate=?"+
      " group by entry.fcostaccountid,acct.flongnumber ");
    builder.addParam(prjId);
    builder.addParam(FDCBillStateEnum.AUDITTED_VALUE);
   }else{
    builder.appendSql("select entry.fcostaccountid as acctid,acct.flongnumber,sum(entry.fcostamount) as amount from T_AIM_AimCost head " +
      " inner join T_AIM_CostEntry entry on entry.fheadid=head.fid " +
      "   left join t_fdc_costaccount acct on entry.fcostaccountid=acct.fid "+
      " where head.fisLastVersion=1 and  head.ForgOrProId=? " +
      " group by entry.fcostaccountid,acct.flongnumber ");
    builder.addParam(prjId);
   }
  
   final IRowSet rowSet = builder.executeQuery();
   while (rowSet.next()) {
    //aimMap.put(rowSet.getString("acctid"), rowSet.getBigDecimal("amount"));
    aimMap.put(rowSet.getString("flongnumber").replace("!", "."), rowSet.getBigDecimal("amount"));
   }

  } catch (SQLException e) {
   throw new BOSException(e);
  } catch (EASBizException e) {
   throw new BOSException(e);
  }  
  return aimMap;
} 

//获得收入测算映射
private void getAimIncomeMap() throws BOSException{
  if(projectMeasureMap.size() == 0){
   SysUtil.abort();
  }
  Map incomeMap = null;
  for(Iterator items =projectMeasureMap.keySet().iterator();items.hasNext();){
   String prjId = items.next().toString();
   MeasureCostInfo info = (MeasureCostInfo)projectMeasureMap.get(prjId);
   String measureCostId = info.getId().toString();
   incomeMap = getAcctIncomeData(prjId,measureCostId);
   if(incomeMap.size() > 0){
    aimIncomeMap.put(prjId, incomeMap);
   }
  }  
}

//通过prjId及目标成本测算id,获得项目收入测算
private Map getAcctIncomeData(String prjId, String srcMeasureCostId) throws BOSException{
  Map aimMap = new HashMap();
  try {
   FDCSQLBuilder builder = new FDCSQLBuilder();
   
   builder.appendSql("select entry.fincomeaccountid as acctid,acct.flongnumber,sum(entry.famount) as amount from T_AIM_MeasureIncome head " +
     " inner join T_AIM_MeasureIncomeEntry entry on entry.fheadid=head.fid " +
     "   left join t_fdc_incomeaccount acct on entry.fincomeaccountid=acct.fid "+
     " where head.FprojectId=? and head.FsrcMeasureCostId=? " +
     " group by entry.fincomeaccountid,acct.flongnumber ");
   builder.addParam(prjId);
   builder.addParam(srcMeasureCostId);
  
   final IRowSet rowSet = builder.executeQuery();
   while (rowSet.next()) {
    //aimMap.put(rowSet.getString("acctid"), rowSet.getBigDecimal("amount"));
    aimMap.put(rowSet.getString("flongnumber").replace("!", "."), rowSet.getBigDecimal("amount"));
   }
  } catch (SQLException e) {
   throw new BOSException(e);
  } 
  return aimMap;
}

//获取所有工程下所有成本科目,相同number的取一条 。用当前选择工程的成本科目作为所以下级工程的共有科目,本方法暂时不用
private Set getCostAcctIds() throws BOSException{
  Set costAcctIds = new HashSet();
  if(lastVerPrjIdSet.size()==0){
   return costAcctIds;
  }
  try{
   StringBuffer prjIdBuff = new StringBuffer();
   for(Iterator items = lastVerPrjIdSet.iterator();items.hasNext();){    
    prjIdBuff.append("'"+items.next().toString()+"',");
   }
   String inPrjIds = prjIdBuff.toString().substring(0, prjIdBuff.length() -1);
   FDCSQLBuilder builder = new FDCSQLBuilder();
   builder.appendSql("select t1.fid from t_fdc_costaccount t1 where flongnumber in "+
     "(select distinct t2.flongnumber from t_fdc_costaccount t2 where t2.fcurproject in ("+
     inPrjIds+") "+
     "and t2.fisEnable=1) and t1.fissource=1 order by t1.flongnumber");
   final IRowSet rowSet = builder.executeQuery();
   while(rowSet.next()){
    costAcctIds.add(rowSet.getString("fid"));
   }
  } catch(SQLException e){
   throw new BOSException(e);
  } 
  return costAcctIds;
}

//从目标成本测算中获得lastVerPrjIdSet的项目名称、测算阶段名称
private void getProjectMeasureInfo() throws BOSException{
  if(lastVerPrjIdSet.size()==0){
   SysUtil.abort();
  }
  
  IMeasureCost imc = MeasureCostFactory.getRemoteInstance();
  EntityViewInfo evi = new EntityViewInfo();
  FilterInfo filter = new FilterInfo();
  
  evi.getSelector().add(new SelectorItemInfo("id"));
  evi.getSelector().add(new SelectorItemInfo("project.id"));
  evi.getSelector().add(new SelectorItemInfo("project.name"));
  evi.getSelector().add(new SelectorItemInfo("project.parent.name"));
  evi.getSelector().add(new SelectorItemInfo("measureStage.name"));
  filter.getFilterItems().add(new FilterItemInfo("project.id",lastVerPrjIdSet,CompareType.INCLUDE));
  filter.getFilterItems().add(new FilterItemInfo("isLastVersion",new Integer(1)));
  evi.setFilter(filter);
  
  MeasureCostCollection mcc = imc.getMeasureCostCollection(evi);
  if(mcc.size()>0){
   for(int i=0; i<mcc.size(); i++){
    MeasureCostInfo info = mcc.get(i);
    if(!projectMeasureMap.containsKey(info.getProject().getId().toString())){
     projectMeasureMap.put(info.getProject().getId().toString(), info);
    }
   } 
  }  
}

/*
  * //获得lastVerPrjIdSet的总建筑面积
private BigDecimal getBuildArea(String prjId) throws BOSException{
  Map map = ProjectHelper.getIndexValue(null, prjId, new String[] { ApportionTypeInfo.buildAreaType}, ProjectStageEnum.AIMCOST, false);
  BigDecimal buildArea = (BigDecimal) map.get(prjId + " " + ApportionTypeInfo.buildAreaType);

  if(buildArea ==null){
   buildArea = FDCHelper.ZERO;
  }
  return buildArea;
}
  */ 

//获得lastVerPrjIdSet的总建筑面积集合
private void getBuildAreaSet() throws BOSException {
  if(lastVerPrjIdSet.size()==0){
   SysUtil.abort();
  }
  //Map indexValues = new HashMap();  
  EntityViewInfo view = new EntityViewInfo();
  FilterInfo filter = new FilterInfo();
  filter.getFilterItems().add(new FilterItemInfo("parent.projOrOrgId", lastVerPrjIdSet,CompareType.INCLUDE));
  filter.getFilterItems().add(new FilterItemInfo("parent.projectStage", ProjectStageEnum.AIMCOST.getValue()));
  filter.getFilterItems().add(new FilterItemInfo("parent.isLatestVer", Boolean.TRUE));
  filter.getFilterItems().add(new FilterItemInfo("apportionType.id", ApportionTypeInfo.buildAreaType));
  //filter.getFilterItems().add(new FilterItemInfo("parent.productType.id", null,CompareType.EQUALS));

  view.setFilter(filter);
  view.getSelector().add("indexValue");
  view.getSelector().add("apportionType.id");
  view.getSelector().add("parent.projOrOrgID");
  //view.getSelector().add("parent.productType.id");
  IProjectIndexDataEntry iProjectIndexDataEntry = null;
  iProjectIndexDataEntry = ProjectIndexDataEntryFactory.getRemoteInstance();
  ProjectIndexDataEntryCollection projectIndexDataEntryCollection = iProjectIndexDataEntry.getProjectIndexDataEntryCollection(view);
  
  if(projectIndexDataEntryCollection == null || projectIndexDataEntryCollection.size() == 0){
   //return indexValues;
  }else{
   for (Iterator iter = projectIndexDataEntryCollection.iterator(); iter.hasNext();) {
    ProjectIndexDataEntryInfo element = (ProjectIndexDataEntryInfo) iter.next();
    String key=element.getParent().getProjOrOrgID().toString();
    buildAreaSet.put(key, element.getIndexValue());
   }
  }
  //return indexValues;
}

protected List getUnionColumns(){
  List columns = new ArrayList();  
  for(Iterator items = projectMeasureMap.keySet().iterator();items.hasNext();){
   String item = items.next().toString();
   MeasureCostInfo info = (MeasureCostInfo)projectMeasureMap.get(item);
   if(info.getProject() == null){continue;}
   String prjId = info.getProject().getId().toString();
   columns.add(prjId+"total");
  }
  return columns;
}

protected void setUnionData(KDTable table) {
  List columns = getUnionColumns();
  
  //获取科目下级汇总
  for (int i = 0; i < table.getRowCount(); i++) {
   IRow row = table.getRow(i);
   if (row.getUserObject() == null) {
    // 设置汇总行
    int level = row.getTreeLevel();
    List rowList = new ArrayList();
    for (int j = i + 1; j < table.getRowCount(); j++) {
     IRow rowAfter = table.getRow(j);
     if (rowAfter.getTreeLevel() <= level) {
      break;
     }
     if (rowAfter.getUserObject() != null) {
      rowList.add(rowAfter);
     }
    }
    
    for (int k = 0; k < columns.size(); k++) {
     BigDecimal amount = FDCHelper.ZERO;
     String colName = (String) columns.get(k);
     for (int rowIndex = 0; rowIndex < rowList.size(); rowIndex++) {
      IRow rowAdd = (IRow) rowList.get(rowIndex);
      Object value = rowAdd.getCell(colName).getValue();
      if (value != null) {       
       amount = amount.add(FDCHelper.toBigDecimal(value, 4));
      }
     }
     row.getCell(colName).setValue(amount);
    }    
   }
  }
  //计算 汇总合价 列
  for (int i = 0; i < table.getRowCount(); i++) {
   IRow row = table.getRow(i);
   for (int k = 0; k < columns.size(); k++) {
    String colName = (String) columns.get(k);
    Object value = row.getCell(colName).getValue();
    if (value != null) {
     Object totalValue = row.getCell("total").getValue();
     if(totalValue == null){
      row.getCell("total").setValue(FDCHelper.toBigDecimal(value, 4));
     }else{
      row.getCell("total").setValue(FDCHelper.toBigDecimal(totalValue,4).add(FDCHelper.toBigDecimal(value, 4)));
     }
    }
   }
  }  
}

/*
//添加最后五行
private void addCalculateRow(KDTable table) throws Exception{
  String devCostAcct = getAcctNumberByParam(DevCostAcct);
  String indirectCostAcct = getAcctNumberByParam(IndirectCostAcct);
  String landCostAcct = getAcctNumberByParam(LandCostAcct);
  
  BigDecimal devAmount = FDCHelper.ZERO;
  BigDecimal indirectAmount = FDCHelper.ZERO;
  BigDecimal landAmount = FDCHelper.ZERO;
  
  BigDecimal incomeAmount = FDCHelper.ZERO;
  BigDecimal costAmount = FDCHelper.ZERO;  
  
  //获取参数对应科目的汇总合价;获取收入、成本科目中层次为1的汇总合价
  for(int i = 0; i < table.getRowCount(); i++){
   IRow row = table.getRow(i);
   
   //获取参数对应科目的汇总合价
   String acctNumber = row.getCell("acctNumber").getValue().toString();
   if(acctNumber.equals(devCostAcct)){
    Object value = row.getCell("total").getValue();
    if(value != null){
     devAmount = FDCHelper.toBigDecimal(value);
    }
   }
   if(acctNumber.equals(indirectCostAcct)){
    Object value = row.getCell("total").getValue();
    if(value != null){
     indirectAmount = FDCHelper.toBigDecimal(value);
    }
   }
   if(acctNumber.equals(landCostAcct)){
    Object value = row.getCell("total").getValue();
    if(value != null){
     landAmount = FDCHelper.toBigDecimal(value);
    }
   }
   
   //获取收入、成本科目中层次为1的汇总合价
   if((row.getCell(0).getUserObject() != null) && (row.getTreeLevel() == 0)){
    Object obj = row.getCell(0).getUserObject();
    if(obj instanceof String){
     if(obj.equals("income")){
      Object value = row.getCell("total").getValue();
      incomeAmount = incomeAmount.add(FDCHelper.toBigDecimal(value));
     }else if(obj.equals("cost")){
      Object value = row.getCell("total").getValue();
      costAmount = costAmount.add(FDCHelper.toBigDecimal(value));
     }
    }
   }   
  }
  
  //添加行
  IRow rowAddTotalIn = table.addRow();
  rowAddTotalIn.getCell("acctName").setValue("总收入");//所有明细收入科目汇总值
  rowAddTotalIn.getCell("total").setValue(incomeAmount);
  rowAddTotalIn.getStyleAttributes().setBackground(new Color(0xF0EDD9));
  
  IRow rowAddTotalOut = table.addRow();
  rowAddTotalOut.getCell("acctName").setValue("总成本");//所有明细成本科目汇总值
  rowAddTotalOut.getCell("total").setValue(costAmount);
  rowAddTotalOut.getStyleAttributes().setBackground(new Color(0xF0EDD9));
  
  IRow rowAddControl = table.addRow();
  rowAddControl.getCell("acctName").setValue("可控成本");//开发成本+开发间接费用-土地成本
  rowAddControl.getCell("total").setValue(devAmount.add(indirectAmount).subtract(landAmount));
  rowAddControl.getStyleAttributes().setBackground(new Color(0xF0EDD9));
  
  IRow rowAddJLR = table.addRow();
  rowAddJLR.getCell("acctName").setValue("净利润");//总收入-总成本
  rowAddJLR.getCell("total").setValue(incomeAmount.subtract(costAmount));
  rowAddJLR.getStyleAttributes().setBackground(new Color(0xF0EDD9));
  
  IRow rowAddTZLRL = table.addRow();
  rowAddTZLRL.getCell("acctName").setValue("投资利润率");// 净利润/(开发成本+开发间接费用)
  rowAddTZLRL.getCell("total").getStyleAttributes().setNumberFormat("0.00%");
  rowAddTZLRL.getStyleAttributes().setBackground(new Color(0xF0EDD9));
  if(devAmount.add(indirectAmount).compareTo(FDCHelper.ZERO) != 0){
   BigDecimal jlr = incomeAmount.subtract(costAmount);
   BigDecimal tzlrl = jlr.divide(devAmount.add(indirectAmount), 4, RoundingMode.HALF_DOWN);//.multiply(FDCHelper.toBigDecimal(100));
   rowAddTZLRL.getCell("total").setValue(tzlrl.toString());
   
  }else{
   rowAddTZLRL.getCell("total").setValue(FDCHelper.ZERO);
  }
}
*/

//添加最后五行
private void addCalculateRow(KDTable table) throws Exception{
  String devCostAcct = getAcctNumberByParam(DevCostAcct);
  String indirectCostAcct = getAcctNumberByParam(IndirectCostAcct);
  String landCostAcct = getAcctNumberByParam(LandCostAcct);
  
  BigDecimal devAmount = FDCHelper.ZERO;
  BigDecimal indirectAmount = FDCHelper.ZERO;
  BigDecimal landAmount = FDCHelper.ZERO;  
  BigDecimal incomeAmount = FDCHelper.ZERO;
  BigDecimal costAmount = FDCHelper.ZERO; 
  
  //添加行
  IRow rowAddTotalIn = table.addRow();//收入行
  IRow rowAddTotalOut = table.addRow();//成本行
  IRow rowAddControl = table.addRow();//可控成本
  IRow rowAddJLR = table.addRow();//净利润
  IRow rowAddTZLRL = table.addRow();//投资利润率
  
  rowAddTotalIn.getCell("acctName").setValue("总收入");  
  rowAddTotalIn.getStyleAttributes().setBackground(new Color(0xF0EDD9));  
  
  rowAddTotalOut.getCell("acctName").setValue("总成本");  
  rowAddTotalOut.getStyleAttributes().setBackground(new Color(0xF0EDD9));  
  
  rowAddControl.getCell("acctName").setValue("可控成本");  
  rowAddControl.getStyleAttributes().setBackground(new Color(0xF0EDD9));  
  
  rowAddJLR.getCell("acctName").setValue("净利润");  
  rowAddJLR.getStyleAttributes().setBackground(new Color(0xF0EDD9));  
  
  rowAddTZLRL.getCell("acctName").setValue("投资利润率");  
  rowAddTZLRL.getStyleAttributes().setBackground(new Color(0xF0EDD9));
  
  List columns = getUnionColumns();
  if(! columns.contains("total")){
   columns.add(0, "total");
  }
  
  for(int k = 0; k < columns.size(); k++){
   String colName = (String) columns.get(k);
   
   devAmount = FDCHelper.ZERO;
   indirectAmount = FDCHelper.ZERO;
   landAmount = FDCHelper.ZERO;   
   incomeAmount = FDCHelper.ZERO;
   costAmount = FDCHelper.ZERO; 
   
   //获取参数对应科目的汇总合价;获取收入、成本科目中层次为1的汇总合价
   for(int i = 0; i < table.getRowCount(); i++){
    IRow row = table.getRow(i);
    if(row.getCell("acctNumber").getValue() == null){
     //最后五个汇总行不用计算
     continue;
    }
    
    //获取参数对应科目的汇总合价
    String acctNumber = row.getCell("acctNumber").getValue().toString();
    if(acctNumber.equals(devCostAcct)){
     Object value = row.getCell(colName).getValue();
     if(value != null){
      devAmount = FDCHelper.toBigDecimal(value);
     }
    }
    if(acctNumber.equals(indirectCostAcct)){
     Object value = row.getCell(colName).getValue();
     if(value != null){
      indirectAmount = FDCHelper.toBigDecimal(value);
     }
    }
    if(acctNumber.equals(landCostAcct)){
     Object value = row.getCell(colName).getValue();
     if(value != null){
      landAmount = FDCHelper.toBigDecimal(value);
     }
    }
    
    //获取收入、成本科目中层次为1的汇总合价
    if((row.getCell(0).getUserObject() != null) && (row.getTreeLevel() == 0)){
     Object obj = row.getCell(0).getUserObject();
     if(obj instanceof String){
      if(obj.equals("income")){
       Object value = row.getCell(colName).getValue();
       incomeAmount = incomeAmount.add(FDCHelper.toBigDecimal(value));
      }else if(obj.equals("cost")){
       Object value = row.getCell(colName).getValue();
       costAmount = costAmount.add(FDCHelper.toBigDecimal(value));
      }
     }
    }   
   }
   //所有明细收入科目汇总值
   rowAddTotalIn.getCell(colName).setValue(incomeAmount);
   //所有明细成本科目汇总值
   rowAddTotalOut.getCell(colName).setValue(costAmount);
   //开发成本+开发间接费用-土地成本
   rowAddControl.getCell(colName).setValue(devAmount.add(indirectAmount).subtract(landAmount));
   //总收入-总成本
   rowAddJLR.getCell(colName).setValue(incomeAmount.subtract(costAmount));
   // 净利润/(开发成本+开发间接费用)
   rowAddTZLRL.getCell(colName).getStyleAttributes().setNumberFormat("0.00%");
   if(devAmount.add(indirectAmount).compareTo(FDCHelper.ZERO) != 0){
    BigDecimal jlr = incomeAmount.subtract(costAmount);
    BigDecimal tzlrl = jlr.divide(devAmount.add(indirectAmount), 4, RoundingMode.HALF_DOWN);//.multiply(FDCHelper.toBigDecimal(100));
    rowAddTZLRL.getCell(colName).setValue(tzlrl.toString());
    
   }else{
    rowAddTZLRL.getCell(colName).setValue(FDCHelper.ZERO);
   }
  }
}

}


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值