# 表单多选参照翻译处理代码模板

* 代码需要全部生成到client/src目录下

## 开发步骤
1. 继承Translator类，实现自定义翻译处理类CustomerTranslator
2. 修改TranslatorCell类，实现一个构造函数，添加Item参数
3. 使用Translator对象做翻译处理的代码，里氏替换为：CustomerTranslator
4. 修改TranslatorBuilder类，实例化TranslatorCell时补充参数；
5. 约定参照选择个数，修改参照字段长度【**重要**】
   
## 1.继承Translator类，实现自定义翻译处理类CustomerTranslator
```java
package nccloud.framework.web.convert.translate;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import nc.bs.logging.Logger;
import nc.vo.ml.LanguageVO;
import nc.vo.ml.MultiLangContext;
import nccloud.base.collection.tabular.IRow;
import nccloud.base.collection.tabular.IRowSet;
import nccloud.commons.lang.StringUtils;
import nccloud.framework.core.exception.ExceptionUtils;
import nccloud.framework.core.model.entity.IVO;
import nccloud.framework.core.model.meta.IVOMeta;
import nccloud.framework.core.model.meta.ModelType;
import nccloud.framework.service.ServiceLocator;
import nccloud.framework.web.ui.config.Item;
import nccloud.framework.web.ui.config.PageTemplet;
import nccloud.pubitf.platform.translate.ITranslatorRowService;

public class CustomTranslator extends Translator{

	public static final Integer REFER_TYPE = 204;
	public static final String VALUE_SPLITER = ",";
	
	public CustomTranslator() {
		super();
	}

	public CustomTranslator(PageTemplet templet) {
		super(templet);
	}

	@Override
	protected void noMetaTranslate(TranslateCell[] cells) {
		super.noMetaTranslate(cells);
		translateMultiCell(cells);
	}

	@Override
	protected void translate(TranslateCell[] cells) {
		super.translate(cells);
		translateMultiCell(cells);
		
	}
	/**
	 * 多选cell翻译
	 * @param cells
	 */
	private void translateMultiCell(TranslateCell[] cells) {
		
		//过滤出参照类型 实际多选的cell
		TranslateCell[] multiSelectedCells = Arrays.stream(cells).filter(cell->{
			Item item = cell.getItem();
			int datatype = item.getDatatype();
			String dataval = item.getDataval();
//			Boolean isMultiSelectedEnabled = item.getIsMultiSelectedEnabled();
			Object valueObj = cell.getCell().getValue();
			if(
					REFER_TYPE == datatype &&
					!StringUtils.isEmpty(dataval) &&
//					isMultiSelectedEnabled &&
					valueObj!=null &&
					((String)valueObj).contains(VALUE_SPLITER)
					) {
				return true;
			}
			return false;
			
		}).collect(Collectors.toList()).toArray(new TranslateCell[0]);
		if(multiSelectedCells == null || multiSelectedCells.length == 0) {
			return;
		}
		LanguageVO lvo = MultiLangContext.getInstance().getCurrentLangVO();
		ITranslatorRowService service =
		        ServiceLocator.find(ITranslatorRowService.class);
		//翻译
		Arrays.stream(multiSelectedCells).forEach(cell->{
			Item item = cell.getItem();
			Object cellValue = cell.getCell().getValue();
			String[] values = ((String)cellValue).split(VALUE_SPLITER);
			List<MetaPath> paths = cell.getPaths();
			IVOMeta vometa = paths.get(0).getCurrentVOMeta();
			String code = item.getCode();
			String pkName = vometa.getPrimaryAttribute().getName();
			
			String primaryTableName = vometa.getNCVOMeta().getDefaulttablename();
			
			Set<String> nameset = new HashSet<String>();
			try {
				ModelType modType = cell.getPaths().get(0).getCurrentAttribute().getModelType();
				String name = null;

				if (cell.getPaths().size() == 2) {
					modType = cell.getPaths().get(1).getCurrentAttribute().getModelType();
					String str1 = cell.getPaths().get(0).getCurrentAttribute().getName();
					String str2 = cell.getPaths().get(1).getCurrentAttribute().getName();
					if (ModelType.MultiLangTextType.equals(modType)) {
						if (lvo.getLangseq().intValue() == 1) {
							nameset.add(str1);
							nameset.add(str2);

						} else {
							nameset.add(str1);
							nameset.add(str2);
							nameset.add(str2 + lvo.getLangseq().toString());
						}
					} else {
						nameset.add(str1);
						nameset.add(str2);
					}
				}

				else {
					// 多语文本处理
					if (ModelType.MultiLangTextType.equals(modType)) {
						String str = cell.getPaths().get(0).getCurrentAttribute().getName();
						if (lvo.getLangseq().intValue() == 1) {
							name = str;
							nameset.add(name);
						} else {
							nameset.add(str);
							name = str + lvo.getLangseq().toString();
							nameset.add(name);
						}
					} else {
						name = cell.getPaths().get(0).getCurrentAttribute().getName();
						nameset.add(name);
					}
				}

			} catch (Exception e) {
				Logger.error("TranslateCell cell.MetaPath.vometa entityfullname:  "
						+ cell.getPaths().get(0).getCurrentVOMeta().getEntityFullName());
				Logger.error("TranslateCell cell.MetaPath.path:  " + cell.getPaths().get(0).getPath());
				ExceptionUtils.wrapException(e);
			}
			String[] names = nameset.toArray(new String[0]);
			IRowSet rowset = service.getRowSet(primaryTableName, pkName, values, names);
			List<IVO> list = new ArrayList<IVO>();
			String name = null;
			List<String> nameValList = new ArrayList<String>();
			
			
			while (rowset.hasNext()) {
				IRow row = rowset.next();
				//~~~简单处理 不考虑多语~~~
				String value = row.getString(0);
				
				//~~~复杂处理 考虑了多语~~~
//				IVO vo = new VirtualVO(vometa);
//				for (int i = 0; i < names.length; i++) {
//					vo.setAttributeValue(names[i], row.getObject(i));
//				}
//				String str = cell.getPaths().get(0).getCurrentAttribute().getName();
//				if (lvo.getLangseq().intValue() == 1) {
//					name = str;
//					value = ValueUtils.getString(vo.getAttributeValue(name));
//				}else {
//					if(str.equals("systypecode")) {
//						value = ValueUtils.getString(vo.getAttributeValue(str));
//					}else if (str.equals("systypename")) {
//						value = nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID(
//								"funcode",
//								ValueUtils.getString(vo.getAttributeValue("resid")));
//					}
//				}
				
				nameValList.add(value);
			}
			
			cell.setValue(StringUtils.join(nameValList,VALUE_SPLITER));
		});
	}
}

```

## 2.修改TranslatorCell类，实现一个构造函数，添加Item参数
```java
package nccloud.framework.web.convert.translate;

import java.util.ArrayList;
import java.util.List;
import nccloud.framework.web.ui.model.row.Cell;
import nccloud.framework.web.ui.config.Item;

public class TranslateCell {
    private final Cell cell;
    private Boolean isFromEditRelation;
    private Boolean isNoMetaField;
    private Boolean isSkipReset;
    private final List<MetaPath> paths;
    //添加成员变量
    private Item item;

    public TranslateCell(Cell cell, List<MetaPath> paths) {
        this.isFromEditRelation = Boolean.FALSE;
        this.isSkipReset = Boolean.FALSE;
        this.cell = cell;
        this.paths = paths;
    }

    public TranslateCell(Cell cell, List<MetaPath> paths, Boolean isNoMetaField) {
        this.isFromEditRelation = Boolean.FALSE;
        this.isSkipReset = Boolean.FALSE;
        this.cell = cell;
        this.paths = paths;
        this.isNoMetaField = isNoMetaField;
    }

    public TranslateCell(Cell cell, MetaPath path) {
        this.isFromEditRelation = Boolean.FALSE;
        this.isSkipReset = Boolean.FALSE;
        this.cell = cell;
        List<MetaPath> paths = new ArrayList();
        paths.add(path);
        this.paths = paths;
    }

    public TranslateCell(Cell cell, MetaPath path, Boolean isNoMetaField) {
        this.isFromEditRelation = Boolean.FALSE;
        this.isSkipReset = Boolean.FALSE;
        this.cell = cell;
        List<MetaPath> paths = new ArrayList();
        paths.add(path);
        this.paths = paths;
        this.isNoMetaField = isNoMetaField;
    }

    /**
     * 新增构造函数，添加Item参数
     * /
    public TranslateCell(Cell cell, MetaPath path, Boolean isNoMetaField, Item item) {
        this.isFromEditRelation = Boolean.FALSE;
        this.isSkipReset = Boolean.FALSE;
        this.cell = cell;
        List<MetaPath> paths = new ArrayList();
        paths.add(path);
        this.paths = paths;
        this.isNoMetaField = isNoMetaField;
        //设置item的值
        this.item = item;
    }

    public Cell getCell() {
        return this.cell;
    }
    //item的get set方法
    public Item getItem() {
        return this.item;
    }
    public void setItem(Item item) {
        this.item = item;
    }

    public Boolean getIsFromEditRelation() {
        return this.isFromEditRelation;
    }

    public Boolean getIsNoMetaField() {
        return this.isNoMetaField;
    }

    public Boolean getIsSkipReset() {
        return this.isSkipReset;
    }

    public MetaPath getPath() {
        return (MetaPath)this.paths.get(0);
    }

    public List<MetaPath> getPaths() {
        return this.paths;
    }

    public String getValue() {
        return this.cell.getDisplay();
    }

    public void setIsFromEditRelation(Boolean isFromEditRelation) {
        this.isFromEditRelation = isFromEditRelation;
    }

    public void setIsNoMetaField(Boolean isNoMetaField) {
        this.isNoMetaField = isNoMetaField;
    }

    public void setIsSkipReset(Boolean isSkipReset) {
        this.isSkipReset = isSkipReset;
    }

    public void setValue(String value) {
        this.cell.setDisplay(value);
    }
}
```

## 3.使用Translator对象做翻译处理的代码，里氏替换为：CustomerTranslator
```java
Translator translator = new CustomerTranslator(this.template);
```

## 4.修改TranslatorBuilder类，实例化TranslatorCell时补充参数
```java
package nccloud.framework.web.convert.translate;

import java.util.ArrayList;
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 nc.bs.framework.common.InvocationInfoProxy;
import nc.bs.logging.Logger;
import nc.vo.ml.NCLangRes4VoTransl;
import nc.vo.platform.appsystemplate.AreaVO;
import nc.vo.pub.IAttributeMeta;
import nc.vo.pub.lang.UFBoolean;
import nc.vo.pubapp.pattern.model.entity.view.IDataView;
import nccloud.base.type.ValueUtils;
import nccloud.commons.lang.StringUtils;
import nccloud.framework.core.env.Locator;
import nccloud.framework.core.exception.ExceptionUtils;
import nccloud.framework.core.model.meta.IBillMeta;
import nccloud.framework.core.model.meta.IMetaResource;
import nccloud.framework.core.model.meta.IVOMeta;
import nccloud.framework.core.model.meta.JavaType;
import nccloud.framework.core.reflect.Constructor;
import nccloud.framework.core.util.ToolUtil;
import nccloud.framework.service.ServiceLocator;
import nccloud.framework.web.meta.MetaQueryResource;
import nccloud.framework.web.ui.config.Area;
import nccloud.framework.web.ui.config.ITempletResource;
import nccloud.framework.web.ui.config.Item;
import nccloud.framework.web.ui.config.PageTemplet;
import nccloud.framework.web.ui.config.TempletQueryPara;
import nccloud.framework.web.ui.meta.AreaType;
import nccloud.framework.web.ui.meta.ComponentType;
import nccloud.framework.web.ui.meta.ItemOption;
import nccloud.framework.web.ui.model.GridModel;
import nccloud.framework.web.ui.model.row.Cell;
import nccloud.framework.web.ui.model.row.Row;
import nccloud.framework.web.ui.pattern.billcard.BillCard;
import nccloud.framework.web.ui.pattern.billgrid.BillGrid;
import nccloud.framework.web.ui.pattern.extbillcard.ExtBillCard;
import nccloud.framework.web.ui.pattern.form.Form;
import nccloud.framework.web.ui.pattern.grid.Grid;
import nccloud.pubitf.platform.template.IArea;

public class TranslatorBuilder {
    private List<String> codes;
    private final Map<String, MetaPath> map = new HashMap();
    private PageTemplet templet;
    private List<String> noTranslatorCodes = null;
    private boolean transflag;

    public TranslatorBuilder() {
    }

    public TranslatorBuilder(PageTemplet templet) {
        this.templet = templet;
    }

    public TranslateCell[] create(BillCard card) {
        PageTemplet ptemplet = this.getTemplet(card.getPageid(), card.getTempletid());
        List<TranslateCell> retlist = new ArrayList();
        if (card.getBody() != null) {
            List<TranslateCell> headlist = this.create(card.getBody().getModel(), ptemplet);
            retlist.addAll(headlist);
        }

        if (card.getGrandSons() != null && card.getGrandSons().size() > 0) {
            Map<String, Grid> grandSonMap = card.getGrandSons();

            for(Map.Entry<String, Grid> gridEntry : grandSonMap.entrySet()) {
                Grid grandSon = (Grid)gridEntry.getValue();
                if (grandSon != null) {
                    List<TranslateCell> grandSonTranslateCells = this.create(grandSon.getModel(), ptemplet);
                    retlist.addAll(grandSonTranslateCells);
                }
            }
        }

        if (card.getHead() != null) {
            List<TranslateCell> bodylist = this.create(card.getHead().getModel(), ptemplet);
            retlist.addAll(bodylist);
        }

        if (card.getTail() != null) {
            List<TranslateCell> taillist = this.create(card.getTail().getModel(), ptemplet);
            retlist.addAll(taillist);
        }

        TranslateCell[] cells = this.resetDuplicates(retlist);
        return cells;
    }

    public TranslateCell[] create(BillGrid bgrid) {
        PageTemplet ptemplet = this.getTemplet(bgrid.getPageid(), bgrid.getTempletid());
        List<TranslateCell> retlist = new ArrayList();
        if (bgrid.getBody() != null) {
            List<TranslateCell> headlist = this.create(bgrid.getBody().getModel(), ptemplet);
            retlist.addAll(headlist);
        }

        if (bgrid.getHead() != null) {
            List<TranslateCell> bodylist = this.create(bgrid.getHead().getModel(), ptemplet);
            retlist.addAll(bodylist);
        }

        TranslateCell[] cells = this.resetDuplicates(retlist);
        return cells;
    }

    public TranslateCell[] create(BillGrid[] bgrids) {
        PageTemplet ptemplet = this.getTemplet(bgrids[0].getPageid(), bgrids[0].getTempletid());
        List<TranslateCell> retlist = new ArrayList();

        for(BillGrid bgrid : bgrids) {
            if (bgrid.getBody() != null) {
                List<TranslateCell> headlist = this.create(bgrid.getBody().getModel(), ptemplet);
                retlist.addAll(headlist);
            }

            if (bgrid.getHead() != null) {
                List<TranslateCell> bodylist = this.create(bgrid.getHead().getModel(), ptemplet);
                retlist.addAll(bodylist);
            }
        }

        TranslateCell[] cells = this.resetDuplicates(retlist);
        return cells;
    }

    public TranslateCell[] create(ExtBillCard extbillcard) {
        PageTemplet ptemplet = this.getTemplet(extbillcard.getPageid(), extbillcard.getTempletid());
        List<TranslateCell> retlist = new ArrayList();
        List<TranslateCell> headlist = this.create(extbillcard.getHead().getModel(), ptemplet);
        retlist.addAll(headlist);

        for(Grid grid : extbillcard.getAllBodys()) {
            if (grid != null) {
                List<TranslateCell> body = this.create(grid.getModel(), ptemplet);
                retlist.addAll(body);
            }
        }

        if (extbillcard.getGrandSons() != null && extbillcard.getGrandSons().size() > 0) {
            for(Grid grandSonGrid : extbillcard.getGrandSons().values()) {
                if (grandSonGrid != null) {
                    List<TranslateCell> grandSon = this.create(grandSonGrid.getModel(), ptemplet);
                    retlist.addAll(grandSon);
                }
            }
        }

        TranslateCell[] cells = this.resetDuplicates(retlist);
        return cells;
    }

    public TranslateCell[] create(ExtBillCard[] extbillcards) {
        PageTemplet ptemplet = this.getTemplet(extbillcards[0].getPageid(), extbillcards[0].getTempletid());
        List<TranslateCell> retlist = new ArrayList();

        for(ExtBillCard extbillcard : extbillcards) {
            List<TranslateCell> headlist = this.create(extbillcard.getHead().getModel(), ptemplet);
            retlist.addAll(headlist);
            if (extbillcard.getAllBodys() != null) {
                for(Grid grid : extbillcard.getAllBodys()) {
                    if (grid != null) {
                        List<TranslateCell> bodylist = this.create(grid.getModel(), ptemplet);
                        retlist.addAll(bodylist);
                    }
                }

                if (extbillcard.getGrandSons() != null && extbillcard.getGrandSons().size() > 0) {
                    for(Grid grandSonGrid : extbillcard.getGrandSons().values()) {
                        if (grandSonGrid != null) {
                            List<TranslateCell> grandSon = this.create(grandSonGrid.getModel(), ptemplet);
                            retlist.addAll(grandSon);
                        }
                    }
                }
            }
        }

        TranslateCell[] cells = this.resetDuplicates(retlist);
        return cells;
    }

    public TranslateCell[] create(Form form) {
        PageTemplet ptemplet = this.getTemplet(form.getPageid(), form.getTempletid());
        List<TranslateCell> gridlist = this.create(form.getModel(), ptemplet);
        TranslateCell[] cells = this.resetDuplicates(gridlist);
        return cells;
    }

    public TranslateCell[] create(Grid grid) {
        PageTemplet ptemplet = this.getTemplet(grid.getPageid(), grid.getTempletid());
        List<TranslateCell> gridlist = this.create(grid.getModel(), ptemplet);
        TranslateCell[] cells = this.resetDuplicates(gridlist);
        return cells;
    }

    public TranslateCell[] create(Grid[] grids) {
        PageTemplet ptemplet = this.getTemplet(grids[0].getPageid(), grids[0].getTempletid());
        List<TranslateCell> list = new ArrayList();

        for(Grid grid : grids) {
            List<TranslateCell> gridlist = this.create(grid.getModel(), ptemplet);
            list.addAll(gridlist);
        }

        if (list.size() == 0) {
            return null;
        } else {
            TranslateCell[] cells = this.resetDuplicates(list);
            return cells;
        }
    }

    public PageTemplet getTemplet() {
        return this.templet;
    }

    public PageTemplet getTemplet(String pageid, String templetid) {
        if (this.templet == null) {
            ITempletResource resource = (ITempletResource)Locator.find(ITempletResource.class);
            TempletQueryPara para = new TempletQueryPara();
            para.setPagecode(pageid);
            para.setTemplateid(templetid);
            this.templet = resource.query(para);
            if (this.templet == null) {
                ExceptionUtils.wrapBusinessException(NCLangRes4VoTransl.getNCLangRes().getStrByID("1501003_0", "01501003-0063"));
            }
        }

        return this.templet;
    }

    public void setCodes(List<String> codes) {
        this.codes = codes;
    }

    public void setTemplet(PageTemplet templet) {
        this.templet = templet;
    }

    public void setTransflag(boolean transflag) {
        this.transflag = transflag;
    }

    protected Map<String, Item> create(Area area) {
        Item[] items = area.getItems();
        Map<String, Item> index = new HashMap();

        for(Item item : items) {
            if (this.transflag) {
                index.put(item.getCode(), item);
            } else if (item.isVisible()) {
                index.put(item.getCode(), item);
            } else if (this.codes != null && this.codes.contains(item.getCode())) {
                index.put(item.getCode(), item);
            }
        }

        return index;
    }

    protected List<TranslateCell> create(IMetaResource resource, Map<String, Item> index, String vometa, Row row) {
        List<TranslateCell> list = new ArrayList();

        for(String itemname : index.keySet()) {
            Item item = (Item)index.get(itemname);
            if ((this.transflag || item.isVisible() || this.codes != null && this.codes.contains(item.getCode())) && (this.noTranslatorCodes == null || !this.noTranslatorCodes.contains(item.getCode()))) {
                String metapath = item.getMetapath();
                String mdProperty = item.getMetadataProperty();
                String code = item.getCode();
                Cell cell = row.getCell(itemname);
                String[] names = null;
                int length = 0;
                if (StringUtils.isNotEmpty(metapath)) {
                    names = metapath.split("\\.");
                    length = names.length;
                }

                String tmpvometa = vometa;
                if (names != null && length > 1) {
                    IBillMeta docbill = resource.getBillMetaData(vometa);

                    for(IVOMeta child : docbill.getChildren()) {
                        String relation = docbill.getRelationEndAlias(child);
                        if (names[0].equals(relation)) {
                            metapath = metapath.substring(names[0].length() + 1);
                            tmpvometa = child.getEntityFullName();
                            break;
                        }
                    }
                }

                if (cell instanceof RelationCell && StringUtils.isNotEmpty(mdProperty)) {
                    String name = mdProperty.split("\\.")[2];
                    if (StringUtils.isNotEmpty(metapath)) {
                        mdProperty = null;
                    }

                    if (code.equals(metapath) && !name.equals(names[length - 1])) {
                        metapath = metapath + "." + name;
                    }
                }

                if (StringUtils.isEmpty(metapath) && StringUtils.isEmpty(mdProperty)) {
                    if (item.getOptions() != null && cell != null && cell.getValue() != null) {
                        ItemOption[] options = item.getOptions();

                        for(ItemOption option : options) {
                            if (String.valueOf(cell.getValue()).equals(option.getValue())) {
                                cell.setDisplay(option.getDisplay());
                            }
                        }
                    }
                } else if (cell != null && cell.getValue() != null && !"".equals(cell.getValue())) {
                    List<MetaPath> paths = new ArrayList();
                    TranslateCell translateCell = null;
                    if (StringUtils.isEmpty(mdProperty)) {
                        if (metapath.indexOf("+") != -1) {
                            String codeString = metapath.substring(metapath.lastIndexOf(".") + 1, metapath.length()).split("\\+")[0];
                            String nameString = metapath.substring(metapath.lastIndexOf(".") + 1, metapath.length()).split("\\+")[1];
                            String var10003 = metapath.substring(0, metapath.lastIndexOf("."));
                            paths.add(this.getMetaPathFromCach(tmpvometa, var10003 + "." + codeString));
                            var10003 = metapath.substring(0, metapath.lastIndexOf("."));
                            paths.add(this.getMetaPathFromCach(tmpvometa, var10003 + "." + nameString));
                        } else {
                            paths.add(this.getMetaPathFromCach(tmpvometa, metapath));
                        }

                        int cursor = metapath.indexOf(".");
                        if (cursor > 0) {
                            String idname = metapath.substring(0, cursor);
                            Cell idCell = row.getCell(idname);
                            if (idCell != null) {
                                cell.setDisplay(ValueUtils.getString(idCell.getValue()));
                            }
                        }
                        //增加item参数 不影响原逻辑
                        translateCell = new TranslateCell(cell, paths, Boolean.FALSE,item);
                    }

                    if (StringUtils.isNotEmpty(mdProperty)) {
                        String nometa = mdProperty.substring(0, ToolUtil.getCharacterPosition(mdProperty, 2, "\\."));
                        String nometaPath = mdProperty.substring(nometa.length() + 1, mdProperty.length());
                        if (nometaPath.indexOf("+") != -1) {
                            paths.add(this.getMetaPathFromCach(nometa, nometaPath.split("\\+")[0]));
                            paths.add(this.getMetaPathFromCach(nometa, nometaPath.split("\\+")[1]));
                        } else {
                            paths.add(this.getMetaPathFromCach(nometa, nometaPath));
                        }

                        cell.setDisplay(ValueUtils.getString(cell.getValue()));
                        //增加item参数 不影响原逻辑
                        translateCell = new TranslateCell(cell, paths, Boolean.TRUE,item);
                    }

                    this.enumTranslator(paths, cell, item);
                    list.add(translateCell);
                }
            }
        }

        return list;
    }

    protected List<TranslateCell> create(IMetaResource resource, List<HashMap<String, Object>> tran, String vometa) {
        List<TranslateCell> list = new ArrayList();
        List<TranslateCell> cellList = new ArrayList();

        for(HashMap<String, Object> item : tran) {
            String metapath = (String)item.get("metapath");
            String mdProperty = (String)item.get("metadataProperty");
            String code = (String)item.get("attrcode");
            HashMap<String, Object> initial = (HashMap)item.get("initialvalue");
            String initialvalues = (String)initial.get("value");
            String[] initialvalue = initialvalues.split("\\,");
            List<MetaPath> paths = new ArrayList();
            if (StringUtils.isNotEmpty(mdProperty)) {
                String nometa = mdProperty.substring(0, ToolUtil.getCharacterPosition(mdProperty, 2, "\\."));
                String nometaPath = mdProperty.substring(nometa.length() + 1, mdProperty.length());
                if (nometaPath.indexOf("+") != -1) {
                    paths.add(this.getMetaPathFromCach(nometa, nometaPath.split("\\+")[0]));
                    paths.add(this.getMetaPathFromCach(nometa, nometaPath.split("\\+")[1]));
                } else {
                    paths.add(this.getMetaPathFromCach(nometa, nometaPath));
                }

                for(String value : initialvalue) {
                    if (!StringUtils.isEmpty(value)) {
                        Cell transCell = new Cell();
                        transCell.setDisplay(value);
                        transCell.setValue(value);
                        cellList.add(new TranslateCell(transCell, paths, Boolean.TRUE));
                    }
                }
            }

            Translator translator = new Translator();
            translator.noMetaTranslate((TranslateCell[])cellList.toArray(new TranslateCell[0]));
            StringBuffer sb = new StringBuffer();

            for(TranslateCell cell : cellList) {
                sb.append(cell.getCell().getDisplay());
                sb.append(",");
            }

            sb.deleteCharAt(sb.toString().length() - 1);
            initial.put("display", sb.toString());
        }

        return list;
    }

    protected List<TranslateCell> createDataView(IMetaResource resource, Map<String, Item> index, IDataView bean, Row row, String vometa) {
        List<TranslateCell> list = new ArrayList();

        for(String itemname : index.keySet()) {
            Item item = (Item)index.get(itemname);
            if (this.noTranslatorCodes == null || !this.noTranslatorCodes.contains(item.getCode())) {
                String metapath = item.getMetapath();
                String code = item.getCode();
                String mdProperty = item.getMetadataProperty();
                Cell cell = row.getCell(itemname);
                String[] names = null;
                int length = 0;
                if (StringUtils.isNotEmpty(metapath)) {
                    names = metapath.split("\\.");
                    length = names.length;
                }

                if (names != null && length > 1) {
                    IBillMeta docbill = resource.getBillMetaData(vometa);

                    for(IVOMeta child : docbill.getChildren()) {
                        String relation = docbill.getRelationEndAlias(child);
                        if (names[0].equals(relation)) {
                            metapath = metapath.substring(names[0].length() + 1);
                            break;
                        }
                    }
                }

                if (cell instanceof RelationCell && StringUtils.isNotEmpty(mdProperty)) {
                    String name = mdProperty.split("\\.")[2];
                    if (StringUtils.isNotEmpty(metapath)) {
                        mdProperty = null;
                    }

                    if (code.equals(metapath) && !name.equals(names[length - 1])) {
                        metapath = metapath + "." + name;
                    }
                }

                if (StringUtils.isEmpty(metapath) && StringUtils.isEmpty(mdProperty)) {
                    if (item.getOptions() != null && cell != null && cell.getValue() != null) {
                        ItemOption[] options = item.getOptions();

                        for(ItemOption option : options) {
                            if (String.valueOf(cell.getValue()).equals(option.getValue())) {
                                cell.setDisplay(option.getDisplay());
                            }
                        }
                    }
                } else if (cell != null) {
                    List<MetaPath> paths = new ArrayList();
                    TranslateCell translateCell = null;
                    if (StringUtils.isEmpty(mdProperty)) {
                        IAttributeMeta attrMeta = bean.getMetaData().getAttribute(itemname);
                        if (attrMeta == null) {
                            int cursor = metapath.indexOf(".");
                            if (cursor <= 0) {
                                continue;
                            }

                            attrMeta = bean.getMetaData().getAttribute(itemname.substring(0, cursor));
                            if (attrMeta == null || attrMeta.getVOMeta() == null) {
                                continue;
                            }
                        } else if (attrMeta.getVOMeta() == null) {
                            continue;
                        }

                        String tmpvometa = attrMeta.getVOMeta().getEntityName();
                        if (names != null && length > 1) {
                            IBillMeta docbill = resource.getBillMetaData(vometa);
                            String[] newNames = metapath.split("\\.");
                            if (docbill.getParent().getAttribute(newNames[0]) != null) {
                                tmpvometa = vometa;
                            }
                        }

                        if (metapath.indexOf("+") != -1) {
                            String codeString = metapath.substring(metapath.lastIndexOf(".") + 1, metapath.length()).split("\\+")[0];
                            String nameString = metapath.substring(metapath.lastIndexOf(".") + 1, metapath.length()).split("\\+")[1];
                            String var10003 = metapath.substring(0, metapath.lastIndexOf("."));
                            paths.add(this.getMetaPathFromCach(tmpvometa, var10003 + "." + codeString));
                            var10003 = metapath.substring(0, metapath.lastIndexOf("."));
                            paths.add(this.getMetaPathFromCach(tmpvometa, var10003 + "." + nameString));
                        } else {
                            paths.add(this.getMetaPathFromCach(tmpvometa, metapath));
                        }

                        int cursor = metapath.indexOf(".");
                        if (cursor > 0) {
                            String idname = metapath.substring(0, cursor);
                            Cell idCell = row.getCell(idname);
                            if (idCell != null) {
                                cell.setDisplay((String)idCell.getValue());
                            }
                        }
                        //增加item参数 不影响原逻辑
                        translateCell = new TranslateCell(cell, paths, Boolean.FALSE,item);
                    }

                    if (StringUtils.isNotEmpty(mdProperty)) {
                        String nometa = mdProperty.substring(0, ToolUtil.getCharacterPosition(mdProperty, 2, "\\."));
                        String nometaPath = mdProperty.substring(nometa.length() + 1, mdProperty.length());
                        if (nometaPath.indexOf("+") != -1) {
                            paths.add(this.getMetaPathFromCach(nometa, nometaPath.split("\\+")[0]));
                            paths.add(this.getMetaPathFromCach(nometa, nometaPath.split("\\+")[1]));
                        } else {
                            paths.add(this.getMetaPathFromCach(nometa, nometaPath));
                        }

                        cell.setDisplay(ValueUtils.getString(cell.getValue()));
                        //增加item参数 不影响原逻辑
                        translateCell = new TranslateCell(cell, paths, Boolean.TRUE,item);
                    }

                    this.enumTranslator(paths, cell, item);
                    list.add(translateCell);
                }
            }
        }

        return list;
    }

    private List<TranslateCell> create(GridModel model, PageTemplet ptemplet) {
        Area area = ptemplet.getArea(model.getAreacode());
        Area[] areas = ptemplet.getAllAreas();
        List<String> relationAreaCodes = new ArrayList();

        for(Area areaItem : areas) {
            if (areaItem.getRelationcode() != null && areaItem.getRelationcode().equals(area.getCode()) || areaItem.getCorerelation() != null && areaItem.getCorerelation().equals(area.getCode()) || areaItem.getAssociatedTab() != null && areaItem.getAssociatedTab().equals(area.getCode())) {
                relationAreaCodes.add(areaItem.getCode());
            }
        }

        Map<String, Map<String, Item>> index = new HashMap();

        for(Area childArea : areas) {
            if (!childArea.getAreaType().equals(AreaType.Search) && childArea.getClazz() != null && childArea.getClazz().equals(area.getClazz()) && relationAreaCodes.contains(childArea.getCode())) {
                Map<String, Item> cmap = this.create(childArea);
                if (index.get(area.getCode()) == null) {
                    index.put(area.getCode(), cmap);
                } else {
                    ((Map)index.get(area.getCode())).putAll(cmap);
                }
            }
        }

        if (index.get(area.getCode()) != null) {
            ((Map)index.get(area.getCode())).putAll(this.create(area));
        } else {
            index.put(area.getCode(), this.create(area));
        }

        ArrayList<TranslateCell> list = new ArrayList();
        Row[] rows = model.getRows();
        Class<?> areaclass = Constructor.load(area.getClazz());
        Map<String, Item> codemap = (Map)index.get(area.getCode());
        IMetaResource resource = (IMetaResource)Locator.find(IMetaResource.class);

        for(Row row : rows) {
            List<TranslateCell> retlist = null;
            if (IDataView.class.isAssignableFrom(areaclass)) {
                IDataView bean = (IDataView)Constructor.construct(areaclass);
                InvocationInfoProxy.getInstance().setProperty("AREACODE", area.getCode());
                retlist = this.createDataView(resource, codemap, bean, row, area.getVometa());
            } else {
                InvocationInfoProxy.getInstance().setProperty("AREACODE", area.getCode());
                retlist = this.create(resource, codemap, area.getVometa(), row);
            }

            list.addAll(retlist);
        }

        return list;
    }

    public List<TranslateCell> create(List<HashMap<String, Object>> tran, String areaid) {
        AreaVO areavo = ((IArea)ServiceLocator.find(IArea.class)).queryArea(areaid);
        String vometa = "";
        if (areavo.getMetaid() != null) {
            String[] metaid = new String[1];
            metaid[0] = areavo.getMetaid();
            Map<String, String> map = MetaQueryResource.queryFullPathByClassid(metaid);

            for(Iterator<Map.Entry<String, String>> m = map.entrySet().iterator(); m.hasNext(); vometa = ((String)((Map.Entry)m.next()).getValue()).toString()) {
            }
        }

        IMetaResource resource = (IMetaResource)Locator.find(IMetaResource.class);
        this.create(resource, tran, vometa);
        return null;
    }

    private MetaPath getMetaPathFromCach(String vometa, String path) {
        MetaPath metapath = (MetaPath)this.map.get(vometa + "&&" + path);
        if (metapath == null) {
            metapath = new MetaPath(vometa, path);
            this.map.put(vometa + "&&" + path, metapath);
        }

        return (MetaPath)metapath.clone();
    }

    private TranslateCell[] resetDuplicates(List<TranslateCell> retlist) {
        List<TranslateCell> list = new ArrayList();
        Set<Cell> set = new HashSet();

        for(TranslateCell cell : retlist) {
            if (!set.contains(cell.getCell())) {
                set.add(cell.getCell());
                list.add(cell);
            }
        }

        return (TranslateCell[])list.toArray(new TranslateCell[0]);
    }

    public void setNoTranslatorCodes(List<String> noTranslatorCodes) {
        this.noTranslatorCodes = noTranslatorCodes;
    }

    private void enumTranslator(List<MetaPath> paths, Cell cell, Item item) {
        if (paths.get(0) == null || ((MetaPath)paths.get(0)).getCurrentAttribute() == null) {
            Logger.error("TranslatorBuilder-enumTranslator 元数据对应属性信息为空！字段编码：" + item.getCode());
        }

        JavaType javatype = ((MetaPath)paths.get(0)).getCurrentAttribute().getJavaType();
        if (javatype != JavaType.UFStringEnum && javatype != JavaType.UFFlag) {
            if ((cell.getValue() == null || !ComponentType.Select.equals(item.getItemtype())) && !ComponentType.Checkbox.equals(item.getItemtype()) && !ComponentType.Radio.equals(item.getItemtype())) {
                if (item.getDatatype() == 32 && (ComponentType.Checkbox_switch.equals(item.getItemtype()) || ComponentType.Switch.equals(item.getItemtype())) && cell.getValue() != null) {
                    cell.setValue(UFBoolean.valueOf(String.valueOf(cell.getValue())).booleanValue());
                }
            } else {
                ItemOption[] options = item.getOptions();
                String[] valuesStrings = String.valueOf(cell.getValue()).split("\\,");
                String[] displayStrings = new String[valuesStrings.length];
                String displayString = "";
                if (options != null) {
                    if (valuesStrings.length == 1) {
                        for(ItemOption option : options) {
                            if (String.valueOf(cell.getValue()).equals(option.getValue())) {
                                cell.setDisplay(option.getDisplay());
                            }
                        }
                    } else {
                        for(int i = 0; i < valuesStrings.length; ++i) {
                            for(ItemOption option : options) {
                                if (valuesStrings[i].equals(option.getValue())) {
                                    displayStrings[i] = option.getDisplay();
                                }
                            }

                            displayString = displayString + displayStrings[i] + ",";
                        }

                        cell.setDisplay(displayString.substring(0, displayString.length() - 1));
                    }
                }
            }
        } else {
            String display = ValueUtils.getString(cell.getValue());
            cell.setDisplay(display);
        }

    }
}
```

## 5.约定参照选择个数，修改参照字段长度【**重要**】
* 高级版中，主键长度为20，参照设置为多选后，举例说明多选个数与占用字段长度的关系：
  * 参照选一条数据：20*1+0 = 20个字符，占用20个字符
  * 参照选两条数据：20*2+1 = 41个字符，占用41个字符
  * 参照选三条数据：20*3+2 = 62个字符，占用62个字符
* 根据以上规则，字段的长度应该至少设置为：20*N+N-1 长度，其中N为参照选择数据的个数。
* **注意：这种方案要与客户沟通好，约定选择的个数，不然会出现数据长度不够的情况。**
* 修改SQL语句：
```sql
ALTER TABLE 表名 MODIFY 字段名 VARCHAR(N*20+N-1);
```