public with sharing class AssetMaintainController {
    public static Asset StaticAssetQuertResult;
    // 按钮区域
    public String assertQueryCondition {get; private set;}
    public Boolean allBlueFlag {get; private set;}  // 查看全部保有设备蓝色按钮Flag
    public Boolean consumableBlueFlag {get; private set;}  // 查看在库的保有设备蓝色按钮Flag
    public Boolean lendingBlueFlag {get; private set;}  // 查看出借中保有设备蓝色按钮Flag
    public Boolean repairingBlueFlag {get; private set;}  // 查看修理中保有设备蓝色按钮Flag
    public Boolean scrappingBlueFlag {get; private set;}  // 查看待报废保有设备蓝色按钮Flag
    public Boolean scrappedBlueFlag {get; private set;}  //查看已报废保有设备蓝色按钮Flag
    public Boolean consumedBlueFlag {get; private set;}  //查看已消耗的保有设备
    public Boolean soonExpiredBlueFlag {get; private set;} //查看即将到期的保有设备
    public Boolean expiredBlueFlag {get; private set;}  //查看已过期的保有设备
    // 检索区域
    public static final String NONE = system.label.StartTrading_None;  // 「なし」ラベル [Chinese:--无--]
    private String internalAssetLocation;  // 后台使用的
    public String internalAssetLocationLogin {get; set;}  // login的备品存放地
    private String internalAssetLocationSet; // 备品存放地 Internal_asset_location__c
    private String beipinCunFangDi;  // 备品存放地

    public SearchBean searchB {get; set;} // 检索用Bean
    public Boolean editmode {get; private set;}
    public AssetMaintainHeader__c amHeader{get;set;}
    public Boolean showTop {get; private set;}
    public Boolean importCSVButtonActive{get; private set;}
    public Boolean saveButtonActive{get;private set;}
    public Boolean submitButtonActive{get;private set;}
    public Boolean deleteButtonActive{get;private set;}
    public Boolean abandonButtonActive{get;private set;}
    public Boolean editButtonActive{get;private set;}
    public String notScrappedReportId{get;private set;}
    public String scrappedReportId{get;private set;}


    // 备品存放地 检索条件设置区
    public List<SelectOption> internalAssetLocationOptionList {
        get {
            if (internalAssetLocationOptionList == null) {
                internalAssetLocationOptionList = getPlickList('Asset', 'Internal_asset_location__c');
            }
            return internalAssetLocationOptionList;
        }
        set;
    }

    // 维护类型 数据适用区
    public List<SelectOption> maintainTypeOptionList {
        get {
            if (maintainTypeOptionList == null) {
                maintainTypeOptionList = getPlickList('AssetMaintainDetail__c', 'MaintainType__c');
                // 去掉后4个
                for(Integer i = 0; i < 4; i++){
                    maintainTypeOptionList.remove(maintainTypeOptionList.size()-1);
                }
            }
            return maintainTypeOptionList;
        }
        set;
    }

    public String assetStatus {get; set;}  // 备品状态 Asset_Status__c 左侧快捷按钮
    public String assetStatus1 {get; set;}  // 备品状态 Asset_Status__c 右侧检索区的
    public String fieldName {get;set;}
    public String fieldValue {get;set;}
    public String operator {get;set;}
    public List<SelectOption> fieldNameOpts {
        get{
            List<SelectOption> selectOptions = new List<SelectOption> { new SelectOption(NONE, NONE) };
            selectOptions.add(new SelectOption('Internal_asset_location__c' , '备品存放地'));
            selectOptions.add(new SelectOption('Salesdepartment__c' , '所在地区(本部)'));
            selectOptions.add(new SelectOption('Fixture_Model_No__c' , '备品配套明细型号'));
            selectOptions.add(new SelectOption('Internal_Asset_number_key__c' , '固定资产编号(Key)'));
            selectOptions.add(new SelectOption('Manage_type__c' , '管理种类'));
            selectOptions.add(new SelectOption('SerialNumber__c' , '机身编号'));
            selectOptions.add(new SelectOption('MaintainReason__c' , '维护原因'));
            selectOptions.add(new SelectOption('MaintainCount__c' , '维护数量'));
            selectOptions.add(new SelectOption('AbandonReason__c' , '废弃原因'));
            selectOptions.add(new SelectOption('AbandonCount__c' , '废弃数量'));
            selectOptions.add(new SelectOption('Is_OneToOne_Accessory__c' , '是否一对一附属品'));
            selectOptions.add(new SelectOption('OneToOne_Main_QRCode__c' , '一对一主体选择QRCode'));
            selectOptions.add(new SelectOption('DisconnectCount__c' , '断开数量'));
            return selectOptions;
        }
    }
    public List<SelectOption> operatorOpts {
        get{
            List<SelectOption> selectOptions = new List<SelectOption> { new SelectOption(NONE, NONE) };
            selectOptions.add(new SelectOption('==','等于'));
            selectOptions.add(new SelectOption('!=','不等于'));
            selectOptions.add(new SelectOption('<','<'));
            selectOptions.add(new SelectOption('>','>'));
            selectOptions.add(new SelectOption('<=','<='));
            selectOptions.add(new SelectOption('>=','>='));
            selectOptions.add(new SelectOption('contains','包含'));
            selectOptions.add(new SelectOption('notcontains','不包含'));
            selectOptions.add(new SelectOption('starts with','起始字符'));
            return selectOptions;
        }
    }

    public List<SelectOption> assetStatusOptionList {
        get {
            // FIXME StartTrading_None を使う、--なし-- はNGでしょう
            List<SelectOption> selectOptions = new List<SelectOption> { new SelectOption(NONE, NONE) };
            //无保有
            selectOptions.add(new SelectOption(FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Wu_Bao_You.ordinal()), FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Wu_Bao_You.ordinal())));
            //无库存
            selectOptions.add(new SelectOption(FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Mei_You_Ku_Cun.ordinal()), FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Mei_You_Ku_Cun.ordinal())));
            //可分配
            selectOptions.add(new SelectOption(FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Ke_Yi_Fen_Pei.ordinal()), FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Ke_Yi_Fen_Pei.ordinal())));
            //暂定分配
            selectOptions.add(new SelectOption(FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Zan_Ding_Fen_Pei.ordinal()), FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Zan_Ding_Fen_Pei.ordinal())));
            //已出库指示
            selectOptions.add(new SelectOption(FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Yi_Chu_Ku_Zhi_Shi.ordinal()), FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Yi_Chu_Ku_Zhi_Shi.ordinal())));
            //已下架
            selectOptions.add(new SelectOption(FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Yi_Xia_Jia.ordinal()), FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Yi_Xia_Jia.ordinal())));
            //出库前已检测
            selectOptions.add(new SelectOption(FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Chu_Ku_Qian_Yi_Jian_Ce.ordinal()), FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Chu_Ku_Qian_Yi_Jian_Ce.ordinal())));
            //已出库
            selectOptions.add(new SelectOption(FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Yi_Chu_Ku.ordinal()), FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Yi_Chu_Ku.ordinal())));
            //申请者已收货
            selectOptions.add(new SelectOption(FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Shen_Qing_Zhe_Yi_Shou_Huo.ordinal()), FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Shen_Qing_Zhe_Yi_Shou_Huo.ordinal())));
            //申请者收货NG
            selectOptions.add(new SelectOption(FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Shen_Qing_Zhe_Shou_Huo_NG.ordinal()), FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Shen_Qing_Zhe_Shou_Huo_NG.ordinal())));
            //医院已装机确认
            selectOptions.add(new SelectOption(FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Yi_Yuan_Yi_Zhuang_Ji_Que_Ren.ordinal()), FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Yi_Yuan_Yi_Zhuang_Ji_Que_Ren.ordinal())));
            //已回寄
            selectOptions.add(new SelectOption(FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Yi_Hui_Ji.ordinal()), FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Yi_Hui_Ji.ordinal())));
            //欠品中
            selectOptions.add(new SelectOption(FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Qian_Pin_Zhong.ordinal()), FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Qian_Pin_Zhong.ordinal())));
            //已回收
            selectOptions.add(new SelectOption(FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Yi_Hui_Shou.ordinal()), FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Yi_Hui_Shou.ordinal())));
            //回收后已CDS
            selectOptions.add(new SelectOption(FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Hui_Shou_Hou_Yi_CDS.ordinal()), FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Hui_Shou_Hou_Yi_CDS.ordinal())));
            //待上架
            selectOptions.add(new SelectOption(FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Dai_Shang_Jia.ordinal()), FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Dai_Shang_Jia.ordinal())));
            //待移至报废区
            selectOptions.add(new SelectOption(FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Yi_Zhi_Bao_Fei_Qu.ordinal()), FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Yi_Zhi_Bao_Fei_Qu.ordinal())));
            //待废弃
            selectOptions.add(new SelectOption(FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Dai_Fei_Qi.ordinal()), FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Dai_Fei_Qi.ordinal())));
            //废弃
            selectOptions.add(new SelectOption(FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Fei_Qi.ordinal()), FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Fei_Qi.ordinal())));
            //修理草案中
            selectOptions.add(new SelectOption(FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Xiu_Li_Cao_An_Zhong.ordinal()), FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Xiu_Li_Cao_An_Zhong.ordinal())));
            //修理中
            selectOptions.add(new SelectOption(FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Xiu_Li_Zhong.ordinal()), FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Xiu_Li_Zhong.ordinal())));
            //冻结
            selectOptions.add(new SelectOption(FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Dong_Jie.ordinal()), FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Dong_Jie.ordinal())));
            //丢失
            selectOptions.add(new SelectOption(FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Diu_Shi.ordinal()), FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Diu_Shi.ordinal())));

            return selectOptions;
        }
    }
    public List<SelectOption> bodyOrAccessoryOptionList {
        get {
            List<SelectOption> selectOptions = new List<SelectOption> { new SelectOption(NONE, NONE) };
            //主体
            selectOptions.add(new SelectOption('主体', '主体'));
            //附属品
            selectOptions.add(new SelectOption('附属品', '附属品'));

            return selectOptions;
        }
    }
    public List<SelectOption> limitOpts {
        get {
            List<SelectOption> limitOpts = new List<SelectOption>();
            limitOpts.add(new SelectOption('20','20'));
            limitOpts.add(new SelectOption('100','100'));
            limitOpts.add(new SelectOption('500','500'));
            limitOpts.add(new SelectOption('1000','1000'));
            return limitOpts;
        }
    }

    // 分公司号PlickList
    public List<SelectOption> companyOfEquipmentOpts {
        get {
            if (companyOfEquipmentOpts == null) {
                companyOfEquipmentOpts = getPlickList('Asset', 'CompanyOfEquipment__c');
            }
            return companyOfEquipmentOpts;
        }
        set;
    }

    //  产品分类PlickList
    public List<SelectOption> product_categoryOpts {
        get {
            if (product_categoryOpts == null) {
                product_categoryOpts = getPlickList('Asset', 'Product_category__c');
            }
            return product_categoryOpts;
        }
        set;
    }

    // 备品分类PlickList
    public List<SelectOption> equipment_TypeOpts {
        get {
            if (equipment_TypeOpts == null) {
                equipment_TypeOpts = getPlickList('Asset', 'Equipment_Type__c');
            }
            return equipment_TypeOpts;
        }
        set;
    }

    // 管理种类PlickList
    public List<SelectOption> manage_typeOpts {
        get {
            if (manage_typeOpts == null) {
                manage_typeOpts = getPlickList('Asset', 'Manage_type__c');
            }
            return manage_typeOpts;
        }
        set;
    }

    // 所在地区(本部)PlickList
    public List<SelectOption> salesdepartmentOpts {
        get {
            if (salesdepartmentOpts == null) {
                salesdepartmentOpts = getPlickList('Asset', 'Salesdepartment__c');
            }
            return salesdepartmentOpts;
        }
        set;
    }

    // 所在地区(省)PlickList
    public List<SelectOption> salesProvinceOpts {
        get {
            if (salesProvinceOpts == null) {
                salesProvinceOpts = getPlickList('Asset', 'SalesProvince__c');
            }
            return salesProvinceOpts;
        }
        set;
    }
    // 备品类别PlickList
    public List<SelectOption> assetLoanerCategoryOpts {
        get {
            if(assetLoanerCategoryOpts == null){
                assetLoanerCategoryOpts = new List<SelectOption>();
                assetLoanerCategoryOpts.add(new SelectOption('', NONE));
                assetLoanerCategoryOpts.add(new SelectOption('备品', '备品'));
                assetLoanerCategoryOpts.add(new SelectOption('耗材', '耗材'));
            }
            return assetLoanerCategoryOpts;
        }
        set;
    }
    // 到期时间picklist
    public List<SelectOption> daysToExpiredOpts {
        get {
            if(daysToExpiredOpts == null){
                daysToExpiredOpts = new List<SelectOption>();
                daysToExpiredOpts.add(new SelectOption('', NONE));
                daysToExpiredOpts.add(new SelectOption('7', '一周内到期'));
                daysToExpiredOpts.add(new SelectOption('14', '两周内到期'));
            }
            return daysToExpiredOpts;
        }
        set;
    }

    private String targetColumusStr;  // SOQL中的检索列

    // 项目set 字段标签
    public List<String> amdLeftLabelList {get; private set;}
    public List<String> amdRightLabelList {get; private set;}
    public List<String> amdAllLabelList {get; private set;}

    public Integer amdLeftLabelSize {
        get {
            return amdLeftLabelList.size();
        }
    }
    // 项目set 字段名
    public List<List<String>> leftApiList {get; private set;}  // 参照項目用
    public List<List<String>> amdLeftApiList {get; private set;}  // 参照項目用
    public List<List<String>> rightApiList {get; private set;}  // 参照項目用
    public List<List<String>> amdRightApiList {get; private set;}  // 参照項目用
    public List<String> allApiList {get; private set;}  // 参照項目用
    public List<String> amdAllApiList {get; private set;}  // 参照項目用

    public List<String> columnAmdLeftCssList {get; private set;}  // css 用
    public List<String> columnAmdRightCssList {get; private set;}  // css 用
    public Map<String, String> columnAmdLeftRWMap {get; private set;}  // r,w,wm用
    public Map<String, String> columnAmdRightRWMap {get; private set;}  // r,w,wm用
    private List<String> canChangeFlagList;  // 是否可编辑
    private List<Asset> allAssetDataList;  // 明细结果(不包括checkoutbox)
    public Integer getAllAssetDataListSize() {  // 明细条数
        return allAssetInfoList.size() + assetFromSearchList.size();
    }
    public Integer getCheckedSize(){return allAssetInfoList.size();}
    @testvisible private List<AssetInfo> allAssetInfoList;  // 存打勾部分
    public List<AssetInfo> allAssetInfoShowList {get; set;}  // allAssetInfoList中要显示在画面上的部分
    public List<AssetInfo> assetFromSearchList{get;set;}
    private Set<Id> amdDeleteIdSet ; // 打开维护单时已有的明细Id

    public String changeFlg {get; set;}  // 监视刷新画面前是否存在未保持的值
    public Boolean searchFromBtn {get; private set;}  // 是否来自快捷键进行检索
    public Boolean onlyReadFlag {get; set;}  // 只读权限
    public Boolean returnFirstPageFlag {get; private set;}  // 返回首页
    public Boolean beipincunfangdiEditableFlag {get; private set;}  // 备品存放地权限
    public Boolean beipinfenleiEditableFlag {get; private set;}  // 备品分类权限

    public Boolean equipmentSetManagmentCodeEditableFlag {get; private set;}  // 备品管理编码权限
    public Boolean internalAssetNumberEditableFlag {get; private set;}  // 固定资产号权限
    public Boolean serialNumberEditableFlag {get; private set;}  // 机身号权限
    public Boolean companyEquipmentEditableFlag {get; private set;}  // 分公司号权限
    public Boolean productCategoryEditableFlag {get; private set;}  // 产品分类权限
    public Boolean manageTypeEditableFlag {get; private set;}  // 管理种类权限
    public Boolean salesDepartmentEditableFlag {get; private set;}  // 所在地区(本部)
    public Boolean salesProvinceEditableFlag {get; private set;}  // 所在地区(省)
    public Boolean consumableGuaranteenEndEditableFlag {get; private set;}  // 消耗品有效期至
    public Integer detailCountLimit{get;private set;}

    // 排序用
    public String sortKey {get; set;}
    public String preSortKey {get; set;}
    public Boolean sortOrderAsc {get; set;}
    public List<String> sortOrderList {get; set;}
    public Integer totalSoqlRecordNum {get; set;}  // 总数据数量
    public Integer totalNum {get; set;}  // 检索出的总数量 = 检索出的数量 + 打勾固定的数量
    // 分页用
    public String selRecordOption { get; set; }  // 选择的每页记录数
    public Integer selctRecordNum { get { return Integer.valueOf(selRecordOption); } } // 选择的每页记录数
    public Integer currPage { get; set; }  // 当前页
    public Integer totalPage { get; set; }  // 总页数
    public Integer totalFixDataNum { get; set; }  // 打勾固定数据数量
    public Integer totalUnfixDataNum { get; set; }  // 未打勾固定数据数量
    public List<User> loginUserList { get; set; }
    public String fromQuickBarFlag;  // 是否来自导航区按钮检索

    public String appliedSelectOption {get; set;}

    public Integer checkedAssetInfoNum {get; set;}
    public String checkFromQuickBarFlag;

    public AssetMaintainController() {
        currPage = 1;
        selRecordOption = '20';  // 初始化时默认选择数量
        totalNum = 0;
        onlyReadFlag = false;
        showTop = true;
        importCSVButtonActive = true;
        saveButtonActive = false;
        submitButtonActive = false;
        deleteButtonActive = false;
        abandonButtonActive = false;
        editButtonActive = true;
        try{
            Id parId = System.currentPageReference().getParameters().get('Id');
            String saveType = System.currentPageReference().getParameters().get('saveType');
            this.amHeader = [
                SELECT Id
                    , Name
                    , MaintainType__c
                    , Submit_Time__c
                    , Status__c
                    , Submit_Person__c
                    , Date__c
                    , CC_User1__c
                    , CC_User2__c
                    , CC_User3__c
                    , CC_User4__c
                    , CC_User5__c
                    , CC_Email1__c
                    , CC_Email2__c
                    , CC_Email3__c
                FROM AssetMaintainHeader__c
                WHERE Id =:parId LIMIT 1
            ];
            importCSVButtonActive = false;
            showTop = false;
            if(this.amHeader.MaintainType__c == '实物报废'){
                if(this.amHeader.Status__c == '草案中'){
                    submitButtonActive = true;
                    deleteButtonActive = true;
                    importCSVButtonActive = true;
                    saveButtonActive = true;
                    showTop = true;
                }
                else if(this.amHeader.Status__c == '申请中'){
                    onlyReadFlag = true;
                    editButtonActive = false;
                }
                else if(this.amHeader.Status__c == '已批准'){
                    abandonButtonActive = true;
                    onlyReadFlag = true;
                    editButtonActive = false;
                }
                else{
                    onlyReadFlag = true;
                    editButtonActive = false;
                }
            }
            else{
                onlyReadFlag = true;
                editButtonActive = false;
                if(saveType == '1'){
                    ApexPages.Message message = new ApexPages.Message(ApexPages.severity.INFO, '保存成功并已启动Batch，完成时会发送邮件');
                    ApexPages.addMessage(message);
                }
            }
        }
        catch(Exception e){
            this.amHeader = new AssetMaintainHeader__c();
        }
    }

    // 画面初始化
    public void init() {
        searchB = new SearchBean();
        checkFromQuickBarFlag = 'false';
        checkedAssetInfoNum = 0;
        bp3_Setting__c bp3config = bp3_Setting__c.getOrgDefaults();
        detailCountLimit = Integer.valueOf(bp3config.AssetMaintainDetailCountLimit__c);
        scrappedReportId = bp3config.AssetMaintain_Scrapped_VF_ReportId__c;
        notScrappedReportId = bp3config.AssetMaintain_NotScrapped_VF_ReportId__c;

        fromQuickBarFlag = 'false';

        appliedSelectOption = '';
        changeFlg = '0';
        searchFromBtn = false;
        onlyReadFlag = false;
        initSearchButtonColor();
        returnFirstPageFlag = true;
        allAssetDataList = new List<Asset>();
        allAssetInfoList = new List<AssetInfo>();
        assetFromSearchList = new List<AssetInfo>();
        setAssetFieldSetInfo();
        totalFixDataNum = 0;
        totalUnfixDataNum =0;
        editmode = false;
        amdDeleteIdSet = new Set<Id>();

        // 权限
        beipincunfangdiEditableFlag = Schema.sObjectType.Asset.fields.getMap().get('Internal_asset_location__c').getDescribe().isUpdateable();
        beipinfenleiEditableFlag = Schema.sObjectType.Asset.fields.getMap().get('Equipment_Type__c').getDescribe().isUpdateable();
        // 备品管理编码权限
        equipmentSetManagmentCodeEditableFlag = Schema.sObjectType.Asset.fields.getMap().get('EquipmentSet_Managment_Code__c').getDescribe().isUpdateable();
        // 固定资产号权限
        internalAssetNumberEditableFlag = Schema.sObjectType.Asset.fields.getMap().get('Internal_Asset_number__c').getDescribe().isUpdateable();
        // 机身号权限
        serialNumberEditableFlag = Schema.sObjectType.Asset.fields.getMap().get('SerialNumber').getDescribe().isUpdateable();
        // 分公司号权限
        companyEquipmentEditableFlag = Schema.sObjectType.Asset.fields.getMap().get('CompanyOfEquipment__c').getDescribe().isUpdateable();
        // 产品分类权限
        productCategoryEditableFlag = Schema.sObjectType.Asset.fields.getMap().get('Product_category__c').getDescribe().isUpdateable();
        // 管理种类权限
        manageTypeEditableFlag = Schema.sObjectType.Asset.fields.getMap().get('Manage_type__c').getDescribe().isUpdateable();
        // 所在地区(本部)
        salesDepartmentEditableFlag = Schema.sObjectType.Asset.fields.getMap().get('Salesdepartment__c').getDescribe().isUpdateable();
        // 所在地区(省)
        salesProvinceEditableFlag = Schema.sObjectType.Asset.fields.getMap().get('SalesProvince__c').getDescribe().isUpdateable();
        // 消耗品有效期至
        consumableGuaranteenEndEditableFlag = Schema.sObjectType.Asset.fields.getMap().get('Consumable_Guaranteen_end__c').getDescribe().isUpdateable();
        //loginUserList = new List<User>();
        loginUserList = [SELECT Id, Default_Referable_Apply_Equipment_Center__c
                         FROM User
                         WHERE Id = :Userinfo.getUserId()];
        beipinCunFangDi = loginUserList[0].Default_Referable_Apply_Equipment_Center__c;  // User.默认可参照备品中心

        if (UserInfo.getProfileId() == System.Label.ProfileId_SystemAdmin || System.Label.ProfileId_EquCenAdmin.contains(UserInfo.getProfileId())) {
            internalAssetLocationLogin = FixtureUtil.bieCunFangDiOpsMap.get('备品管理中心')[0].getValue();  // SelectOption('All', '--全部--')
        } else {
            List<SelectOption> tempBieCunFangDiOpsList = FixtureUtil.bieCunFangDiOpsMap.get('备品管理中心');
            internalAssetLocationLogin = beipinCunFangDi;  // User.默认可参照备品中心
        }
        if(String.isNotBlank(this.amHeader.Id)){
            loadMaintainDetail(this.amHeader.Id);
        }
        else {
            checkAssetBtn();
        }
    }
    private void loadMaintainDetail(Id headId){
        List<AssetMaintainDetail__c> amdList = [SELECT Id
                                                     , Asset__c
                                                     , Internal_asset_location__c
                                                     , Salesdepartment__c
                                                     , Fixture_Model_No__c
                                                     , Internal_Asset_number_key__c
                                                     , Manage_type__c
                                                     , SerialNumber__c
                                                     , Is_OneToOne_Accessory__c
                                                     , MaintainType__c
                                                     , MaintainCount__c
                                                     , MaintainReason__c
                                                     , AbandonCount__c
                                                     , AbandonReason__c
                                                     , DisconnectCount__c
                                                     , OneToOne_Main__c
                                                     , Batch_Status__c
                                                     , AssetMaintainHeader__r.Submit_Time__c
                                                     , AssetMaintainHeader__r.Approved_Time__c
                                                  FROM AssetMaintainDetail__c
                                                 WHERE AssetMaintainHeader__c=:headId];
        for(AssetMaintainDetail__c amd: amdList){
            AssetInfo info = new AssetInfo(amd);
            amdDeleteIdSet.add(amd.Id);
            allAssetInfoList.add(info);
        }
        fillShowList(1);
    }

    public void setAssetFieldSetInfo() {
        amdLeftLabelList = new List<String>();
        amdRightLabelList = new List<String>();
        amdAllLabelList = new List<String>();

        leftApiList = new List<List<String>>();
        amdLeftApiList = new List<List<String>>();
        rightApiList = new List<List<String>>();
        amdRightApiList = new List<List<String>>();
        allApiList = new List<String>();
        amdAllApiList = new List<String>();

        columnAmdLeftCssList = new List<String>();
        columnAmdRightCssList = new List<String>();
        columnAmdLeftRWMap = new Map<String, String>();
        columnAmdRightRWMap = new Map<String, String>();
        List<String> columnAmdLeftFieldPathList = new List<String>();
        List<String> columnAmdRightFieldPathList = new List<String>();
        // 获得納入商品 項目セット
        Map<String, Schema.FieldSet> assetFieldSetMap = Asset.sObjectType.getDescribe().fieldSets.getMap();
        Map<String, Schema.FieldSet> assetMaintainFieldSetMap = AssetMaintainDetail__c.sObjectType.getDescribe().fieldSets.getMap();
        // 項目セット查看保有设备_左侧固定
        Schema.FieldSet leftFieldSetSet = assetFieldSetMap.get('CheckAsset_LeftFix');
        Schema.FieldSet amdLeftFieldSetSet = assetMaintainFieldSetMap.get('AssetMaintain_L');
        // 項目セット查看保有设备_右侧固定
        Schema.FieldSet rightFieldSetSet = assetFieldSetMap.get('CheckAsset_Right');
        Schema.FieldSet amdRightFieldSetSet = assetMaintainFieldSetMap.get('AssetMaintain_R');
        // 获得左侧固定項目セット中的所有项目
        List<FieldSetMember> leftFieldSetMemberList = leftFieldSetSet.getFields();
        List<FieldSetMember> amdLeftFieldSetMemberList = amdLeftFieldSetSet.getFields();
        // 获得右侧項目セット中的所有项目
        List<FieldSetMember> rightFieldSetMemberList = rightFieldSetSet.getFields();
        List<FieldSetMember> amdRightFieldSetMemberList = amdRightFieldSetSet.getFields();
        Boolean haveWrongField = false;
        for (FieldSetMember eachLeftFieldSetMember : leftFieldSetMemberList) {
            List<String> splitLeftFieldPathList = eachLeftFieldSetMember.getFieldPath().split('\\.');  // List size > 1 对应关联表
            leftApiList.add(splitLeftFieldPathList);  // List<List<String>>() 左侧項目セットAPI
        }
        for (FieldSetMember eachAmdLeftFieldSetMember : amdLeftFieldSetMemberList) {
            List<String> splitAmdLeftFieldPathList = eachAmdLeftFieldSetMember.getFieldPath().split('\\.');  // List size > 1 对应关联表
            amdLeftLabelList.add(eachAmdLeftFieldSetMember.getLabel());  // 左侧項目セットLabel
            columnAmdLeftFieldPathList.add(eachAmdLeftFieldSetMember.getFieldPath());  // 左侧項目セットAPI
            amdLeftApiList.add(splitAmdLeftFieldPathList);  // List<List<String>>() 左侧項目セットAPI
            columnAmdLeftRWMap.put(eachAmdLeftFieldSetMember.getFieldPath(), 'r');  // 只读
        }
        for (String eachColumnAmdLeftFieldPath : columnAmdLeftFieldPathList) {
            columnAmdLeftCssList.add(eachcolumnAmdLeftFieldPath.replace('.', '_'));  // 与API相同
        }
        // 項目セット查看保有设备_右侧可拖动
        for (FieldSetMember eachRightFieldSetMember : rightFieldSetMemberList) {
            List<String> splitRightFieldPathList = eachRightFieldSetMember.getFieldPath().split('\\.');  // 与上面的相同
            rightApiList.add(splitRightFieldPathList);  // List<List<String>>() 左侧項目セットAPI

        }

        for (String eachColumnAmdRightFieldPath : columnAmdRightFieldPathList) {
            columnAmdRightCssList.add(eachcolumnAmdRightFieldPath.replace('.', '_'));  // 与API相同
        }

        for (FieldSetMember eachAmdRightFieldSetMember : AmdRightFieldSetMemberList) {
            List<String> splitAmdRightFieldPathList = eachAmdRightFieldSetMember.getFieldPath().split('\\.');  // 与上面的相同

            // 类型未定或实物报废的要显示【废弃数量】
            if(eachAmdRightFieldSetMember.getFieldPath() == 'AbandonCount__c' || eachAmdRightFieldSetMember.getFieldPath() == 'AbandonReason__c'){
                if(String.isNotBlank(this.amHeader.MaintainType__c) && this.amHeader.MaintainType__c != '实物报废'){
                    continue;
                }
            }
            amdRightLabelList.add(eachAmdRightFieldSetMember.getLabel());  // 左侧項目セットLabel
            columnAmdRightFieldPathList.add(eachAmdRightFieldSetMember.getFieldPath());  // 左侧項目セットAPI
            amdRightApiList.add(splitAmdRightFieldPathList);  // List<List<String>>() 左侧項目セットAPI
            columnAmdRightRWMap.put(eachAmdRightFieldSetMember.getFieldPath(), 'w');  // 可读可写

        }

        for (String eachColumnAmdRightFieldPath : columnAmdRightFieldPathList) {
            columnAmdRightCssList.add(eachcolumnAmdRightFieldPath.replace('.', '_'));  // 与API相同
        }
        amdAllLabelList.addAll(amdLeftLabelList);
        amdAllLabelList.addAll(amdRightLabelList);
        for (List<String> eachApiList : leftApiList) {
            allApiList.add(eachApiList[0]);
        }
        for (List<String> eachApiList : amdLeftApiList) {
            amdAllApiList.add(eachApiList[0]);
        }
        for (List<String> eachApiList : rightApiList) {
            allApiList.add(eachApiList[0]);
        }
        for (List<String> eachApiList : amdRightApiList) {
            amdAllApiList.add(eachApiList[0]);
        }

        Map<String, SObjectField> queryAssetFieldMap = AssetMaintainDetail__c.getSObjectType().getDescribe().fields.getMap();
        canChangeFlagList = new List<String>();
        for (String eachApi : amdAllApiList) {
            DescribeFieldResult queryAssetFieldResult = queryAssetFieldMap.get(eachApi).getDescribe();
            if (!queryAssetFieldResult.isCalculated()) {
                canChangeFlagList.add('');
            } else {
                canChangeFlagList.add('（不可修改）');
            }
        }
        allApiList.add('Fixture_OneToOne_Link__r.Main_Asset__c');
        allApiList.add('Fixture_OneToOne_Link__r.Main_Asset__r.Fixture_QRCode__c');
        targetColumusStr = String.join(allApiList, ', ');

        // 默认排序
        this.sortKey = '0';
        this.preSortKey = '0';
        this.sortOrderAsc = true;
        this.sortOrderList = new List<String>();
        this.sortOrderList.add('↑');
        for (Integer i = 0; i < amdAllLabelList.size(); i++) {
            this.sortOrderList.add(' ');
        }
    }

    // 初始化按钮颜色
    public void initSearchButtonColor() {
        allBlueFlag = true;  // 初始页面上全部保有设备按钮为蓝色
        consumableBlueFlag = false;
        lendingBlueFlag = false;
        repairingBlueFlag = false;
        scrappingBlueFlag = false;
        scrappedBlueFlag = false;
        consumedBlueFlag = false;
        soonExpiredBlueFlag = false;
        expiredBlueFlag = false;
    }
    // 检索按钮 查看保有设备
    public void checkAssetBtn() {
        // get方式传url参数
        if (String.isBlank(assertQueryCondition)) {
            assertQueryCondition = ApexPages.currentPage().getParameters().get('searchType');
        }
        // 来自按钮
        String tempAssertQueryCondition = ApexPages.currentPage().getParameters().get('assertCondition');
        String fromQuickBarFlag = ApexPages.currentPage().getParameters().get('fromQuickBarFlag');
        checkFromQuickBarFlag = fromQuickBarFlag;
        if (String.isNotBlank(tempAssertQueryCondition)) {
            assertQueryCondition = tempAssertQueryCondition;
        }
        if (String.isNotBlank(assertQueryCondition) && assertQueryCondition != null) {
            allBlueFlag = false;
            consumableBlueFlag = false;
            lendingBlueFlag = false;
            repairingBlueFlag = false;
            scrappingBlueFlag = false;
            scrappedBlueFlag = false;
            consumedBlueFlag = false;
            soonExpiredBlueFlag = false;
            expiredBlueFlag = false;
            if (assertQueryCondition == 'all') {  //  备品检索条件assertQueryCondition为空视为 查看全部保佑设备
                allBlueFlag = true;
            } else if (assertQueryCondition == 'consumable') {
                consumableBlueFlag = true;
            } else if (assertQueryCondition == 'lending') {
                lendingBlueFlag = true;
            } else if (assertQueryCondition == 'repairing') {
                repairingBlueFlag = true;
            } else if (assertQueryCondition == 'scrapping') {
                scrappingBlueFlag = true;
            } else if (assertQueryCondition == 'scrapped') {
                scrappedBlueFlag = true;
            } else if (assertQueryCondition == 'consumed') {
                consumedBlueFlag = true;
            } else if (assertQueryCondition == 'soonExpired') {
                soonExpiredBlueFlag = true;
            } else if (assertQueryCondition == 'expired') {
                expiredBlueFlag = true;
            }
        }
        searchBtn();
    }

    // 检索按钮
    public void searchBtn() {
        returnFirstPageFlag = true;
        getAllAssetData();
    }
    // 取消按钮 先清空所有打钩项
    public void clearAllCheckedBtn() {
        searchFromBtn = true;
        returnFirstPageFlag = false;  // 取消时不回到首页
        getAllAssetData();
    }

    // 明细排序
    public void sortTable() {
        searchFromBtn = false;  // 点击排序时，不需要清空打勾
        returnFirstPageFlag = true;  // 排序时回到首页
        // 排序
        this.sortKey = ApexPages.currentPage().getParameters().get('sortKey');

        if (this.sortKey == this.preSortKey) {
            // 方向が変わるのみ
            this.sortOrderAsc = !this.sortOrderAsc;
            this.sortOrderList[Integer.valueOf(this.sortKey)] = (this.sortOrderAsc == true ? '↑' : '↓');
        } else {
            if (preSortKey == '') {
                preSortKey = '0';
            }
            this.sortOrderAsc = true;
            this.sortOrderList[Integer.valueOf(this.preSortKey)] = ' ';
            this.sortOrderList[Integer.valueOf(this.sortKey)] = (this.sortOrderAsc == true ? '↑' : '↓');
        }
        this.preSortKey = this.sortKey;
        // 获取排序后借出备品一览
        getAllAssetData();
    }

    // 获取保有设备
    private void getAllAssetData() {
        removeUnchecked();
        internalAssetLocation = searchB.internal_asset_location;
        List<AssetInfo> newAssetInfoList = new List<AssetInfo>();
        List<Id> oldAssetDataIdList = new List<Id>();
        List<Id> checkedSavingDataIdList = new List<Id>();
        for (AssetInfo eachOldAssetInfo : allAssetInfoList) {
            if (eachOldAssetInfo.isCheck == true) {
                oldAssetDataIdList.add(eachOldAssetInfo.amd.Asset__c);
            }
        }
        checkedAssetInfoNum = allAssetInfoList.size();
        assetFromSearchList.clear();

        totalFixDataNum = allAssetInfoList.size();

        if (searchFromBtn == true) {  // 来自导航快捷键，去掉打钩项
            oldAssetDataIdList.clear();
            searchFromBtn = false;
            totalFixDataNum = 0;
        }

        String dateToday = String.valueOf(Date.today());
        String soqlAsset = '';
        soqlAsset += 'SELECT Id, ' + targetColumusStr + ' FROM Asset ';

        soqlAsset += 'WHERE Asset_Owner__c = \'' + 'Olympus' + '\' ';
        soqlAsset += 'AND Delete_Flag__c = false ';  // 逻辑删除
        soqlAsset += 'AND AssetManageConfirm__c = true ';  // 备品中心确认

        if (oldAssetDataIdList.size() > 0) {
            soqlAsset += 'AND Id NOT IN :oldAssetDataIdList ';
        }

        if (String.isNotBlank(assertQueryCondition)) {  // 导航区快捷键备品状态
            if (assertQueryCondition == 'all') {  // 备品检索条件assertQueryCondition为空视为 查看全部保佑设备
                assetStatus = NONE;
            } else if (assertQueryCondition == 'consumable') {
                assetStatus = NONE;
                soqlAsset += 'AND You_Xiao_Ku_Cun__c > 0 ';  // 有效库存
            } else if (assertQueryCondition == 'lending') {  //  查看出借中保有设备
                assetStatus = NONE;
                soqlAsset += 'AND Out_of_wh__c > 0 ';  // 借出分配数
            } else if (assertQueryCondition == 'repairing') {  //  修理中
                assetStatus = NONE;
                soqlAsset += 'AND (Repairing_Count__c > 0 OR Draft_Repair_Count__c > 0) ';  // 修理中件数 + 草案中修理件数 > 0
            } else if (assertQueryCondition == 'scrapping') {  //  待报废
                assetStatus = NONE;
                soqlAsset += 'AND (Abandoned_RealThing__c > 0 OR Abandoned_Inventory__c  > 0) ';  // 待废弃数(实物) 或者 待废弃数(丢失/盘亏)
            } else if (assertQueryCondition == 'scrapped') {  //  已报废
                assetStatus = FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Fei_Qi.ordinal());
            } else if (assertQueryCondition == 'consumed') {  //  已消耗
                assetStatus = NONE;
                soqlAsset += 'AND Consumed_Count__c > 0 ';// 已消耗数大于0
            } else if (assertQueryCondition == 'soonExpired') {  //  即将到期
                assetStatus = NONE;
                Datetime time1 = Datetime.now();
                Datetime future = time1.addMonths(1);
                // 这次能用format的原因是左边是Date类型，右边是DateTime类型
                // 如果左边和右边都是DateTime类型的话就不能这么用了，因为Salfesforce里面保存的是格林志时间
                soqlAsset += 'AND (Consumable_Guaranteen_end__c > ' + time1.format('YYYY-MM-dd') + ' AND Consumable_Guaranteen_end__c <= ' + future.format('YYYY-MM-dd') + ') ';
                //  1个月内即将到期的
            } else if (assertQueryCondition == 'expired') {  //  已过期
                assetStatus = NONE;
                soqlAsset += 'AND Expired_Count_F__c > 0 ';//  已过期数＞0
            }
        }
        String notScriptedAssetStatus1 = '';
        if(assetStatus != FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Fei_Qi.ordinal()) && checkFromQuickBarFlag == 'false') {
            assetStatus = searchB.fixture_Status;
        } else if (searchB.fixture_Status != NONE && checkFromQuickBarFlag == 'false') {  // 如果查看废弃保有设备同时选择了其他备品状态
            notScriptedAssetStatus1 = searchB.fixture_Status;
        }
        fromQuickBarFlag = 'false';
        if (checkFromQuickBarFlag == null || checkFromQuickBarFlag == 'true') {
            internalAssetLocation = '';
        }
        if (UserInfo.getProfileId() != System.Label.ProfileId_SystemAdmin && !(System.Label.ProfileId_EquCenAdmin.contains(UserInfo.getProfileId()))) {  // ProfileId 2B3_备品中心管理者
            if (String.isBlank(internalAssetLocation)) {
                internalAssetLocation = loginUserList[0].Default_Referable_Apply_Equipment_Center__c;  // User.默认可参照备品中心
                searchB.internal_asset_location = loginUserList[0].Default_Referable_Apply_Equipment_Center__c;  // User.默认可参照备品中心
            }
        }
        if (String.isNotBlank(internalAssetLocation)) {
            if (UserInfo.getProfileId() == System.Label.ProfileId_SystemAdmin || System.Label.ProfileId_EquCenAdmin.contains(UserInfo.getProfileId())) {
                if (internalAssetLocation != '全部' && internalAssetLocation != 'All') {
                    soqlAsset += 'AND Internal_asset_location__c = \'' + String.escapeSingleQuotes(internalAssetLocation) + '\' ';
                }
            } else if (internalAssetLocation != loginUserList[0].Default_Referable_Apply_Equipment_Center__c) {
                if (internalAssetLocation != '全部' && internalAssetLocation != 'All') {
                    soqlAsset += 'AND Internal_asset_location__c = \'' + String.escapeSingleQuotes(internalAssetLocation) + '\' ';
                }
            } else {
                if (internalAssetLocation != '全部' && internalAssetLocation != 'All') {
                    soqlAsset += 'AND Internal_asset_location__c = \'' + String.escapeSingleQuotes(internalAssetLocation) + '\' ';
                }
            }  // 备品存放地
        }
        if (String.isNotBlank(searchB.fixture_Model_No) && checkFromQuickBarFlag == 'false') {
            soqlAsset += 'AND Fixture_Model_No_F__c LIKE \'%' + String.escapeSingleQuotes(searchB.fixture_Model_No.trim().replaceAll('%', '\\%')) + '%\' ';
        }  // 备品配套明细型号
        if (String.isNotBlank(searchB.wh_location) && checkFromQuickBarFlag == 'false') {
            soqlAsset += 'AND WH_Location__c = \'' + String.escapeSingleQuotes(searchB.wh_location.trim()) + '\' ';
        }  // 货架号
        if (assetStatus != NONE && assetStatus != null && assetStatus != '') {
            if (assetStatus ==  FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Xiu_Li_Zhong.ordinal())) {  // 修理中
                // 个体管理: 备品状态; 数量管理: 修理中件数 + 草案中修理件数 > 0
                soqlAsset += 'AND (Fixture_Status__c = \'' + String.escapeSingleQuotes(assetStatus) + '\' ';
                soqlAsset += 'OR (Repairing_Count__c > 0 ';
                soqlAsset += 'OR Draft_Repair_Count__c > 0)) ';
            } else if (assetStatus ==  FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Dai_Fei_Qi.ordinal())) {  // 待报废
                // 个体管理: 备品状态; 数量管理: 待废弃数(实物) > 0
                soqlAsset += 'AND (Fixture_Status__c = \'' + String.escapeSingleQuotes(assetStatus) + '\' ';
                soqlAsset += 'OR Abandoned_RealThing__c > 0) ';
            } else if (assetStatus ==  FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Fei_Qi.ordinal())) {  // 已报废
                // 备品状态
                soqlAsset += 'AND Fixture_Status__c = \'' + String.escapeSingleQuotes(assetStatus) + '\' ';
            } else {
                assetStatus = assetStatus == '废弃' ? FixtureUtil.assetFixtureStatusMap.get(FixtureUtil.AssetFixtureStatus.Fei_Qi.ordinal()) : assetStatus;
                soqlAsset += 'AND Fixture_Status__c = \'' + String.escapeSingleQuotes(assetStatus) + '\' ';
            }
            if (notScriptedAssetStatus1 != '') {
                soqlAsset += 'AND Fixture_Status__c = \'' + String.escapeSingleQuotes(notScriptedAssetStatus1) + '\' ';
            }
        }  // 备品状态
        if (String.isNotBlank(searchB.equipmentSet_Managment_Code) && checkFromQuickBarFlag == 'false') {
            soqlAsset += 'AND EquipmentSet_Managment_Code__c = \'' + String.escapeSingleQuotes(searchB.equipmentSet_Managment_Code.trim()) + '\' ';
        }  // 备品管理编码
        if (String.isNotBlank(searchB.internal_Asset_number) && checkFromQuickBarFlag == 'false') {
            soqlAsset += 'AND Internal_Asset_number__c = \'' + String.escapeSingleQuotes(searchB.internal_Asset_number.trim()) + '\' ';
        }  // 固定资产编号
        if (String.isNotBlank(searchB.serialNumber) && checkFromQuickBarFlag == 'false') {
            soqlAsset += 'AND SerialNumber = \'' + String.escapeSingleQuotes(searchB.serialNumber.trim()) + '\' ';
        }  // 机身号 シリアル番号
        if (String.isNotBlank(searchB.companyOfEquipment) && checkFromQuickBarFlag == 'false') {
            soqlAsset += 'AND CompanyOfEquipment__c = \'' + String.escapeSingleQuotes(searchB.companyOfEquipment) + '\' ';
        }  // 财务所属分公司
        if (searchB.bodyOrAccessory != NONE && searchB.bodyOrAccessory != null && searchB.bodyOrAccessory != '' && checkFromQuickBarFlag == 'false') {
            if (searchB.bodyOrAccessory == '主体') {
                soqlAsset += 'AND Loaner_accsessary__c = false ';
            } else {
                soqlAsset += 'AND Loaner_accsessary__c = true ';
            }
        }  // 主体/附属品
        if (String.isNotBlank(searchB.product_category) && checkFromQuickBarFlag == 'false') {
            soqlAsset += 'AND Product_category__c = \'' + String.escapeSingleQuotes(searchB.product_category.trim()) + '\' ';
        }  // 产品分类
        if (String.isNotBlank(searchB.equipment_Type) && checkFromQuickBarFlag == 'false') {
            soqlAsset += 'AND Equipment_Type__c = \'' + String.escapeSingleQuotes(searchB.equipment_Type.trim()) + '\' ';
        }  // 备品分类
        if (String.isNotBlank(searchB.manage_type) && checkFromQuickBarFlag == 'false') {
            soqlAsset += 'AND Manage_type__c = \'' + String.escapeSingleQuotes(searchB.manage_type.trim()) + '\' ';
        }  // 管理种类
        if (String.isNotBlank(searchB.salesdepartment) && checkFromQuickBarFlag == 'false') {
            soqlAsset += 'AND Salesdepartment__c = \'' + String.escapeSingleQuotes(searchB.salesdepartment.trim()) + '\' ';
        }  // 所在地区 本部 Saless_Department__c
        if (String.isNotBlank(searchB.salesProvince) && checkFromQuickBarFlag == 'false') {
            soqlAsset += 'AND SalesProvince__c = \'' + String.escapeSingleQuotes(searchB.salesProvince.trim()) + '\' ';
        }  // 所在地区 省 Sales_Province__c
        if (String.isNotBlank(searchB.asset_loaner_category) && checkFromQuickBarFlag == 'false') {
            if(searchB.asset_loaner_category == '耗材') {
                soqlAsset += 'AND Asset_loaner_category__c = \'耗材\'';
            }
            else {
                soqlAsset += 'AND Asset_loaner_category__c != \'耗材\'';
            }
        }  // 备品类别
        if (String.isNotBlank(searchB.daysToExpired) && checkFromQuickBarFlag == 'false') {
            Datetime time1 = Datetime.now();
            Datetime future = time1.addDays(Integer.valueOf(searchB.daysToExpired));
            // 这次能用format的原因是左边是Date类型，右边是DateTime类型
            // 如果左边和右边都是DateTime类型的话就不能这么用了，因为Salfesforce里面保存的是格林志时间
            soqlAsset += 'AND (Consumable_Guaranteen_end__c > ' + time1.format('YYYY-MM-dd') + ' AND Consumable_Guaranteen_end__c <= ' + future.format('YYYY-MM-dd') + ') ';
        }  // 到期时间
        if (searchB.consumable_Guaranteen_end != NULL && checkFromQuickBarFlag == 'false') {
            Date tempDate;
            tempDate = searchB.consumable_Guaranteen_end;
            soqlAsset += 'AND Consumable_Guaranteen_end__c = :tempDate ';
        }  // 消耗品有效期至 Consumable_Guaranteen_End__c
        // ---------------检索区---------------

        if (!allApiList.contains('Id')) {
            allApiList.add(0, 'Id');
        }
        // 判断200条限制
        Integer allAssetDataCheckSize = Database.query(soqlAsset + ' LIMIT 201 ').size();
        if(allAssetDataCheckSize > 200) {
            ApexPages.Message excess2000Msg = new ApexPages.Message(ApexPages.severity.WARNING, '检索数据已超过200条，无法显示超过200条的部分，请追加检索条件。');
            ApexPages.addMessage(excess2000Msg);
        }

        soqlAsset += ' ORDER BY ' + this.allApiList[Integer.valueOf(this.sortKey)] + ' ' + (this.sortOrderAsc == true ? 'asc nulls first ' : 'desc nulls last ');
        totalSoqlRecordNum = allAssetDataCheckSize > 200 ? 200 : allAssetDataCheckSize;
        soqlAsset += ' limit ' + totalSoqlRecordNum;

        totalNum = allAssetInfoList.size();  // 总的显示数量
        totalPage = (totalNum/selctRecordNum) + (Math.mod(totalNum, selctRecordNum) > 0 ? 1 : 0);  // 总页数
        if (returnFirstPageFlag) {
            currPage = 1;
        }
        // 最终检索结果
        allAssetDataList = Database.query(soqlAsset);

        if (allAssetDataList.size() > 0) {
            Set<Id> assetIdSet= new Set<Id>();
            for (Asset eachAsset : allAssetDataList) {
                assetIdSet.add(eachAsset.Id);
            }
            // 判断一对一附属品
            AggregateResult[] results = [SELECT count(Id) linkCount
                                              , Accessory_Asset__c
                                           FROM Fixture_OneToOne_Link__c
                                          WHERE Accessory_Asset__c IN :assetIdSet
                                          GROUP BY Accessory_Asset__c ];

            Set<Id> oneToOneAccessorySet = new Set<Id>();
            for(AggregateResult ar: results){
                oneToOneAccessorySet.add((Id) ar.get('Accessory_Asset__c'));
            }

            for (Asset eachAsset : allAssetDataList) {
                AssetInfo info = new AssetInfo(eachAsset);
                info.isCheck = false;
                if(oneToOneAccessorySet.contains(eachAsset.Id)){
                    info.amd.Is_OneToOne_Accessory__c = true;
                    if(info.amd.Manage_type__c == '个体管理'){
                        info.amd.DisconnectCount__c = 1;
                        info.amd.OneToOne_Main__c = eachAsset.Fixture_OneToOne_Link__r.Main_Asset__c;
                    }
                    else{
                        // 数量管理的一对一附属品在主体未知的情况下，断开数量默认值不容易确定，需要手动来填
                        info.amd.DisconnectCount__c = null;
                    }
                }
                else{
                    info.amd.Is_OneToOne_Accessory__c = false;
                }
                newAssetInfoList.add(info);
            }
            assetFromSearchList.addAll(newAssetInfoList);
        }

        totalUnfixDataNum = assetFromSearchList.size();

        fillShowList(1);
        checkFromQuickBarFlag = 'false';
    }

    // 保存完了信息提示
    public void setSaveSuccessMsg() {
        ApexPages.Message savingSuccessfullyMessage = new ApexPages.Message(ApexPages.severity.INFO, '保存成功。');
        ApexPages.addMessage(savingSuccessfullyMessage);
    }
    /**
    @description allAssetInfoList中移除未打勾的，添加assetFromSearchList打勾的
    */
    private void removeUnchecked(){
        Integer j = 0;
        while (j < allAssetInfoList.size()) {
            if(!allAssetInfoList.get(j).isCheck){
                allAssetInfoList.remove(j);
            }
            else {
                j++;
            }
        }
        for(AssetInfo info: assetFromSearchList){
            if(info.isCheck){
                allAssetInfoList.add(info);
            }
        }
        assetFromSearchList.clear();
    }
    public void importCSVFile() {
        removeUnchecked();  // 清掉没打勾的asset
        allAssetDataList.clear();  // 清空检索结果 用于统计数量
        String csvData = ApexPages.currentPage().getParameters().get('csvData');
        String csvMaintaintype = ApexPages.currentPage().getParameters().get('csvMaintaintype');
        List<List<String>> tempCsvBody = CSVReader.readIETFRFC4180CSVFile(Blob.valueof(csvData));  // 全部CSV数据
        List<String> importLabelList = tempCsvBody[0];  // CSV读入的标题行 ID + Label
        Map<Id, Asset> importAssetMap = new Map<Id, Asset>();  // 导入CSV生成的AssetList
        List<AssetMaintainDetail__c> importAmdList = new List<AssetMaintainDetail__c>();
        Set<Id> assetIdSet = new Set<Id>();

        // 检索CSV中的ID检索Asset获得List<Asset>
        Map<String, String> labelToApiMap = createLabelApiMap();
        Map<String, SObjectField> queryAssetFieldMap = AssetMaintainDetail__c.getSObjectType().getDescribe().fields.getMap();
        for (Integer i = 1; i < tempCsvBody.size(); i++) {
            AssetMaintainDetail__c tempAmd = new AssetMaintainDetail__c();
            for (Integer j = 0; j < importLabelList.size(); j++) {
                String api = labelToApiMap.get(importLabelList[j]);
                if (queryAssetFieldMap.containsKey(api) == false) {
                    throw new ControllerUtil.myException('字段:【' + importLabelList[j] + '】在' + AssetMaintainDetail__c.getSObjectType().getDescribe().getLabel() + '里不存在, 请确认。');
                }
                DescribeFieldResult queryAssetFieldResult = queryAssetFieldMap.get(api).getDescribe();
                if (String.isNotBlank(tempCsvBody[i][j])){
                    String value = String.valueOf(tempCsvBody[i][j]).trim();
                    if (queryAssetFieldResult.getType() == Schema.DisplayType.Date) {
                        tempAmd.put(api, Date.valueOf(value));
                    } else if (queryAssetFieldResult.getType() == Schema.DisplayType.Boolean) {
                        tempAmd.put(api, Boolean.valueOf(value));
                    } else if (queryAssetFieldResult.getType() == Schema.DisplayType.Double) {
                        tempAmd.put(api, Decimal.valueOf(value));
                    } else {
                        tempAmd.put(api, value);
                    }
                }
            }
            String tempMaintainType = tempAmd.MaintainType__c;
            if(String.isNotBlank(tempMaintainType) && tempMaintainType != csvMaintaintype){
                throw new ControllerUtil.myException('【' + queryAssetFieldMap.get('MaintainType__c').getDescribe().getLabel() + '】与所选不符');
            }
            else{
                tempAmd.MaintainType__c = csvMaintaintype;
            }
            Id assetId = tempAmd.Asset__c;
            if(String.isBlank(assetId)){
                throw new ControllerUtil.myException('【' + queryAssetFieldMap.get('Asset__c').getDescribe().getLabel() + '】不可为空' + tempAmd);
            }
            else{
                assetIdSet.add(assetId);
            }

            if(csvMaintaintype != '实物报废'){
                tempAmd.AbandonReason__c = null;
                tempAmd.AbandonCount__c = null;
            }
            importAmdList.add(tempAmd);
        }
        // 实物报废之外的隐藏 废弃原因和废弃数量
        if(csvMaintaintype != '实物报废'){
            String label = AssetMaintainDetail__c.AbandonReason__c.getDescribe().getLabel();
            Integer index = amdRightLabelList.indexOf(label);
            if(index > -1){
                amdRightLabelList.remove(index);
                amdRightApiList.remove(index);
            }

            label = AssetMaintainDetail__c.AbandonCount__c.getDescribe().getLabel();
            index = amdRightLabelList.indexOf(label);
            if(index > -1){
                amdRightLabelList.remove(index);
                amdRightApiList.remove(index);
            }
        }
        if (!importAmdList.isEmpty() && !assetIdSet.isEmpty()) {
            String soqlAsset = '';
            soqlAsset += 'SELECT Id, ' + targetColumusStr + ' FROM Asset ';
            soqlAsset += 'WHERE Asset_Owner__c = \'' + 'Olympus' + '\' ';
            soqlAsset += 'AND (Id IN :assetIdSet)';
            // 导入csv时，获取相应的数据库中的数据与导入的CSV数据比较，只更新存在差异的文件。
            allAssetDataList = Database.query(soqlAsset);
            for(Asset ass : allAssetDataList){
                importAssetMap.put(ass.Id, ass);
            }
            // 判断一对一附属品
            List<Fixture_OneToOne_Link__c> linkList = [
                SELECT Accessory_Asset__c
                     , Main_Asset__c
                     , Main_Asset__r.Fixture_QRCode__c
                FROM Fixture_OneToOne_Link__c
                WHERE Accessory_Asset__c IN :assetIdSet
            ];
            Map<Id, List<Fixture_OneToOne_Link__c>> assetLinksMap = new Map<Id, List<Fixture_OneToOne_Link__c>>();//<附属品Id，该Id相关所有link>

            Set<Id> oneToOneAccessorySet = new Set<Id>();
            for(Fixture_OneToOne_Link__c link:linkList){
                List<Fixture_OneToOne_Link__c> links = new List<Fixture_OneToOne_Link__c>();
                if(assetLinksMap.containsKey(link.Accessory_Asset__c)){
                    links = assetLinksMap.get(link.Accessory_Asset__c);
                }
                links.add(link);
                assetLinksMap.put(link.Accessory_Asset__c, links);
            }

            List<String> warningList = new List<String>();
            Integer modifiedCount = 0;
            for(AssetMaintainDetail__c amd: importAmdList){
                if(!importAssetMap.containsKey(amd.Asset__c)){
                    warningList.add(amd.Asset__c + '不存在或不可维护');
                    continue;
                }
                Asset ass = importAssetMap.get(amd.Asset__c);
                AssetInfo info = new AssetInfo(ass, amd);
                info.isCheck = true;
                String warningFields = '';
                // 一对一附属品相关字段赋值
                if(assetLinksMap.containsKey(amd.Asset__c)){
                    List<Fixture_OneToOne_Link__c> links = assetLinksMap.get(amd.Asset__c);
                    // 如果csv里一对一是false，系统里实际是true，提醒并修正
                    if(!info.amd.Is_OneToOne_Accessory__c){
                        warningFields += '【是否一对一附属品】';
                        info.amd.Is_OneToOne_Accessory__c = true;
                    }
                    if(info.amd.Manage_type__c == '个体管理'){
                        if(info.amd.DisconnectCount__c != 1){
                            warningFields += '【断开数量】';
                            info.amd.DisconnectCount__c = 1;
                        }
                        if(info.amd.OneToOne_Main_QRCode__c != ass.Fixture_OneToOne_Link__r.Main_Asset__r.Fixture_QRCode__c){
                            warningFields += '【一对一主体选择】';
                        }
                        if(links.size() == 1){
                            info.amd.OneToOne_Main__c = links[0].Main_Asset__c;
                        }
                    }
                    else{
                        Boolean isQRExist = false;
                        for(Fixture_OneToOne_Link__c link:links){
                            if(info.amd.OneToOne_Main_QRCode__c == link.Main_Asset__r.Fixture_QRCode__c){
                                info.amd.OneToOne_Main__c = link.Main_Asset__c;
                                isQRExist = true;
                                break;
                            }
                        }
                        if(!isQRExist){
                            warningFields += '【一对一主体选择】QRCode不存在';
                            info.amd.OneToOne_Main__c = null;
                            info.amd.OneToOne_Main_QRCode__c = null;
                            info.amd.DisconnectCount__c = null;
                        }
                    }
                }
                else{
                    // csv里一对一是true，系统里是false，提醒并修正
                    if(info.amd.Is_OneToOne_Accessory__c){
                        warningFields += '【是否一对一附属品】';
                        info.amd.Is_OneToOne_Accessory__c = false;
                    }
                    if(String.isNOtBlank(info.amd.OneToOne_Main_QRCode__c)){
                        warningFields += '【一对一主体选择】';
                        info.amd.OneToOne_Main__c = null;
                        info.amd.OneToOne_Main_QRCode__c = null;
                    }
                    if(intValueOf(info.amd.DisconnectCount__c)>0){
                        warningFields += '【断开数量】';
                        info.amd.DisconnectCount__c = null;
                    }
                }
                if(String.isNotBlank(warningFields)){
                    warningList.add(info.amd.Fixture_Model_No__c+warningFields);
                    modifiedCount++;
                }
                allAssetInfoList.add(info);
            }
            for(Integer i = 0; i < Math.min(5, warningList.size()); i++){
                ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.WARNING, warningList[i]));
            }
            if (modifiedCount > 5) {
                ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.WARNING, '等' + modifiedCount + '条记录已根据系统数据修正'));
            }
            else if (modifiedCount > 0) {
                ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.WARNING, modifiedCount + '条记录已根据系统数据修正'));
            }
            if (warningList.size() - modifiedCount > 0) {
                ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.WARNING, warningList.size() - modifiedCount + '条记录不存在或不可维护'));
            }
        }
        saveButtonActive = true;
        totalFixDataNum = allAssetInfoList.size();
        totalUnfixDataNum = assetFromSearchList.size();
        totalSoqlRecordNum = 0;
        Integer importAssetMapSize = allAssetInfoList.size();
        if (importAssetMapSize == 0) {
            ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.WARNING, '未导入任何数据，请检查CSV文件'));
        } else {
            String importSuccessfulMsg = '导入CSV文件完成，成功导入' + importAssetMapSize + '条数据。';
            ApexPages.Message errorMessage = new ApexPages.Message(ApexPages.severity.INFO, importSuccessfulMsg);
            ApexPages.addMessage(errorMessage);
            fillShowList(1);
        }
    }

    private void fillShowList(Integer k){
        totalNum = allAssetInfoList.size();
        totalPage = (totalNum / selctRecordNum) + (Math.mod(totalNum, selctRecordNum) > 0 ? 1 : 0);  // 总页
        allAssetInfoShowList = new List<AssetInfo>();
        Integer a = (k-1)*selctRecordNum;
        Integer b = Math.min(k*selctRecordNum, allAssetInfoList.size());
        for (Integer i = a ; i < b ; i++) {
            allAssetInfoShowList.add(allAssetInfoList[i]);
        }
    }

    public void firstPage() {
        currPage = 1;
        fillShowList(currPage);
    }

    // 向前翻页
    public void previousPage() {
        if(currPage > 1) {
            currPage --;
        }
        fillShowList(currPage);

    }

    // 向后翻页
    public void nextPage() {
        if (totalPage <=1 ) {
            currPage = 1;
        } else {
            currPage ++;
        }
        fillShowList(currPage);
    }

    // 翻页到尾页
    public void endPage() {
        if (totalPage <= 1){
            currPage  = 1;
        } else {
            currPage = totalPage;  // 将当前页数置为总页数
        }
        fillShowList(currPage);
    }

    // 清空检索条件
    public void clearAllSearchConditionWhenCancel() {
        searchB.internal_asset_location = internalAssetLocationLogin;
        searchB.fixture_Model_No = '';  // 备品配套明细型号
        searchB.wh_location = '';  // 货架号
        searchB.fixture_Status = '';  // 备品状态
        searchB.equipmentSet_Managment_Code = '';  // 备品管理编码
        searchB.internal_Asset_number = '';  // 固定资产号
        searchB.serialNumber = '';  // 机身号
        searchB.companyOfEquipment = '';  // 分公司号
        searchB.bodyOrAccessory = '';  // 主体/附属品
        searchB.product_category = '';  // 产品分类
        searchB.equipment_Type = '';  // 备品分类
        searchB.manage_type = '';  // 管理种类
        searchB.salesdepartment = '';  // 所在地区(本部)
        searchB.salesProvince = '';  // 所在地区(省)
        searchB.consumable_Guaranteen_endStr = '';  // 消耗品有效期至
        searchB.asset_loaner_category = ''; // 备品类别
        searchB.daysToExpired = ''; // 到期时间
        searchBtn();
    }

    public List<SelectOption> getPlickList(String objApi, String fieldApi) {
        Schema.DescribeFieldResult fieldResult = Schema.getGlobalDescribe().get(objApi).getDescribe().fields.getMap().get(fieldApi).getDescribe();
        List<SelectOption> pickListValuesList= new List<SelectOption>();
        List<Schema.PicklistEntry> ple = fieldResult.getPicklistValues();
        pickListValuesList.add(new SelectOption('', NONE));
        for( Schema.PicklistEntry pickListVal : ple){
            pickListValuesList.add(new SelectOption(pickListVal.getValue(), pickListVal.getLabel()));
        }
        return pickListValuesList;
    }

    // 画面检索Bean
    public Class SearchBean {
        // 为了节省viewstate所以不使用Sobject
        public String internal_asset_location {get; set;} // 备品存放地
        public String fixture_Model_No {get; set;}  // 备品配套明细型号 Fixture_Model_No__c
        public String wh_location {get; set;} // 货架号 WH_location__c
        public String fixture_Status {get; set;} // 备品状态
        public String equipmentSet_Managment_Code {get; set;} // 备品管理编码
        public String internal_Asset_number {get; set;} // 固定资产号
        public String serialNumber {get; set;} // 机身号
        public String companyOfEquipment {get; set;} // 分公司号
        public String bodyOrAccessory {get; set;} // 主体/附属品
        public String product_category {get; set;} // 产品分类
        public String equipment_Type {get; set;} // 备品分类
        public String manage_type {get; set;} // 管理种类
        public String salesdepartment {get; set;} // 所在地区(本部)
        public String salesProvince {get; set;} // 所在地区(省)
        public String asset_loaner_category {get; set;} // 备品类别
        public String daysToExpired {get;set;} // 到期时间
        public Date consumable_Guaranteen_end {get; set;} // 消耗品有效期至
        public String consumable_Guaranteen_endStr {
            get;
            set{
                consumable_Guaranteen_endStr = value;
                if (String.isNotBlank(consumable_Guaranteen_endStr)) {
                    consumable_Guaranteen_end = Date.valueOf(consumable_Guaranteen_endStr.replace('/', '-'));
                }
                else {
                    consumable_Guaranteen_end = null;
                }
            }
        } // 消耗品有效期至
    }
    /**
    @description 编辑按钮
    */
    public void changeEditable() {
        if (!editmode && (this.amHeader.MaintainType__c != '实物报废' || this.amHeader.Status__c=='草案中')) {
            editmode = true;
            saveButtonActive = true;
            submitButtonActive = false;
            deleteButtonActive = false;
        }
        else{
            editmode = false;
        }
    }
    /**
    @description 保存按钮
    */
    public PageReference saveApply(){
        removeUnchecked();
        fillShowList(currPage);
        if (allAssetInfoList.size() > detailCountLimit) {
            ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.ERROR, '一个维护单下创建的明细不可超过' + detailCountLimit));
            return null;
        }

        Set<Id> assetIdSet = new Set<Id>();
        List<AssetMaintainDetail__c> amdList = new List<AssetMaintainDetail__c>();
        // 收集Asset
        String maintainType = '';
        for (AssetInfo info : allAssetInfoList) {
            if (info.isCheck) {
                // 单条明细检查
                if(String.isBlank(maintainType)){
                    maintainType = info.amd.MaintainType__c;
                }
                if(String.isBlank(info.amd.MaintainType__c)){
                    ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.ERROR, info.amd.Fixture_Model_No__c + '【维护类型】不可为空'));
                    return null;
                }
                else if(maintainType != info.amd.MaintainType__c){
                    ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.ERROR, info.amd.Fixture_Model_No__c + '【维护类型】必须相同'));
                    return null;
                }

                if(!checkSingleDetail(info, maintainType)){
                    return null;
                }
                if(info.editable){
                    assetIdSet.add(info.amd.Asset__c);
                    amdList.add(info.amd);
                }
            }
        }
        if(assetIdSet.isEmpty()){
            return null;
        }

        // 更新表头和明细
        Savepoint sp = Database.setSavepoint();
        try {
            // 检查各数量的合法性
            List<String> errorList = new List<String>();
            if(maintainType == '实物报废'){
                errorList = AssetMaintainManualBatch.checkAllDetailAndAsset(amdList, assetIdSet, maintainType, AssetMaintainManualBatch.Operation.FROZEN).errorList;
            }
            else{
                errorList = AssetMaintainManualBatch.checkAllDetailAndAsset(amdList, assetIdSet, maintainType, AssetMaintainManualBatch.Operation.PROCESS).errorList;
            }
            if (errorList.size()>0) {
                for (String errMsg:errorList) {
                    ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.ERROR, errMsg));
                }
                return null;
            }
            if(this.amHeader.Id == null){
                this.amHeader.MaintainType__c = maintainType;
                this.amHeader.Date__c = System.today();
                insert this.amHeader;
            }
            else {
                update this.amHeader;
            }
            Integer i = 1;
            if(maintainType != '实物报废'){
                for(AssetMaintainDetail__c amd:amdList){
                    amd.AssetMaintainHeader__c = this.amHeader.Id;
                    amd.Batch_Status__c = '未处理';
                    amd.OrderNumber__c = i++;
                }
                upsert amdList;
                setMaintainConuntToAsset(amdList);
                Boolean needCheck = false; // 上面代码检查过数量合法性，这里不需要检查
                AssetMaintainManualBatch amBatch = new AssetMaintainManualBatch(amHeader.Id, needCheck);
                Database.executeBatch(amBatch);
            }
            else{
                for(AssetMaintainDetail__c amd:amdList){
                    if (amdDeleteIdSet.contains(amd.Id)) {
                        amdDeleteIdSet.remove(amd.Id);
                    }
                    amd.AssetMaintainHeader__c = this.amHeader.Id;
                    amd.OrderNumber__c = i++;
                }
                upsert amdList;
                // 删除未打勾的明细
                if(!amdDeleteIdSet.isEmpty()){
                    List<AssetMaintainDetail__c> amdDeleteList = [
                        SELECT Id FROM AssetMaintainDetail__c WHERE Id IN:amdDeleteIdSet
                    ];
                    delete amdDeleteList;
                }
            }

            PageReference pageRef = new PageReference('/apex/AssetMaintain?savetype=1&id='+amHeader.Id);
            pageRef.setRedirect(true);
            return pageRef;
        }
        catch(Exception e){
            Database.rollback(sp);
            ApexPages.addMessages(e);
            return null;
        }
    }
    /**
    @description 把维护数写到asset
    */
    private void setMaintainConuntToAsset(List<AssetMaintainDetail__c> amdList){
        Set<Id> assetIdSet = new Set<Id>();
        for (AssetMaintainDetail__c amd: amdList) {
            assetIdSet.add(amd.Asset__c);
        }
        Map<Id, Asset> assetMap = new Map<Id, Asset>([
            SELECT Id
                 , MaintainCount_For_Processing__c
              FROM Asset
             WHERE Id IN:assetIdSet
               FOR UPDATE
        ]);
        for (AssetMaintainDetail__c amd: amdList) {
            if(assetMap.containsKey(amd.Asset__c)) {
                Asset ass = assetMap.get(amd.Asset__c);
                ass.MaintainCount_For_Processing__c = intValueOf(ass.MaintainCount_For_Processing__c) + intValueOf(amd.MaintainCount__c);
                assetMap.put(ass.Id, ass);
            }
        }
        Oly_TriggerHandler.bypass('AssetHandler');
        update assetMap.values();
        Oly_TriggerHandler.clearBypass('AssetHandler');
    }
    /**
    @description 一条维护明细内检查, 可用入力规则实现
    */
    @testvisible private Boolean checkSingleDetail(AssetInfo info, String maintainType){
        // 是否一对一附属品数据为空时，一对一主体选择必须为空
        if(!info.amd.Is_OneToOne_Accessory__c){
            if(info.amd.OneToOne_Main__c != null){
                ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.ERROR, info.amd.Fixture_Model_No__c + '一对一附属品数据为空时，一对一主体选择必须为空'));
                return false;
            }
            if(intValueOf(info.amd.DisconnectCount__c)>0){
                ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.ERROR, info.amd.Fixture_Model_No__c + '一对一附属品数据为空时，断开数量不可填'));
                return false;
            }
        }
        if(maintainType == '实物报废'){
            // 废弃数量 废弃原因都不可为空
            if(intValueOf(info.amd.AbandonCount__c)<=0 || String.isBlank(info.amd.AbandonReason__c)){
                ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.ERROR, info.amd.Fixture_Model_No__c + '【废弃数量】【废弃原因】不可为空'));
                return false;
            }
            // 维护数量<=废弃数量
            if(intValueOf(info.amd.MaintainCount__c) > intValueOf(info.amd.AbandonCount__c)){
                ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.ERROR, info.amd.Fixture_Model_No__c + '【维护数量】不可超过【废弃数量】'));
                return false;
            }
            // 维护数量和维护原因同时有值或同时为空
            if(intValueOf(info.amd.MaintainCount__c) == 0 ^ String.isBlank(info.amd.MaintainReason__c)){
                ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.ERROR, info.amd.Fixture_Model_No__c + '【维护数量】【维护原因】必须同时有值，【维护数量】必须是正数'));
                return false;
            }
            // 维护数量有值时，必须满足：断开数量<=维护数量
            if(intValueOf(info.amd.MaintainCount__c) > 0 && intValueOf(info.amd.DisconnectCount__c) > intValueOf(info.amd.MaintainCount__c)){
                ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.ERROR, info.amd.Fixture_Model_No__c + '【断开数量】不可超过【维护数量】'));
                return false;
            }

        }
        else{
            // 维护原因,维护数量必填
            if(intValueOf(info.amd.MaintainCount__c) <= 0){
                ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.ERROR, info.amd.Fixture_Model_No__c + '【维护数量】必须是正数'));
                return false;
            }
            if(String.isBlank(info.amd.MaintainReason__c)){
                ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.ERROR, info.amd.Fixture_Model_No__c + '【维护原因】不可为空'));
                return false;
            }
            // 废弃原因、废弃数量必须为空
            if(String.isNotBlank(info.amd.AbandonReason__c)){
                ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.ERROR, info.amd.Fixture_Model_No__c + '【废弃原因】必须为空'));
                return false;
            }
            if(intValueOf(info.amd.AbandonCount__c) != 0) {
                ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.ERROR, info.amd.Fixture_Model_No__c + '【废弃数量】必须为空'));
                return false;
            }

        }
        return true;
    }

    /**
    @description 提交按钮
    */
    public void submitApply(){
        String result = AssetMaintainHeaderWebService.submitApply(this.amHeader.Id);
        if(result == '1'){
            ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.INFO, '提交申请成功'));
            submitButtonActive = false;
            deleteButtonActive = true;
            showTop = false;
            importCSVButtonActive = false;
            this.amHeader = [
                SELECT Id
                    , Name
                    , MaintainType__c
                    , Submit_Time__c
                    , Status__c
                    , Submit_Person__c
                    , Date__c
                    , CC_User1__c
                    , CC_User2__c
                    , CC_User3__c
                    , CC_User4__c
                    , CC_User5__c
                    , CC_Email1__c
                    , CC_Email2__c
                    , CC_Email3__c
                FROM AssetMaintainHeader__c
               WHERE Id =:this.amHeader.Id
               LIMIT 1
            ];
        }
        else{
            ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.ERROR, result));
        }
        return ;
    }
    /**
    @description 删除按钮
    */
    public void deleteApply(){
        String result = AssetMaintainHeaderWebService.deleteApply(this.amHeader.Id);
        if(result == '1'){
            showTop = false;
            importCSVButtonActive = false;
            saveButtonActive = false;
            submitButtonActive = false;
            deleteButtonActive = false;
            abandonButtonActive = false;
            editButtonActive = false;
            allAssetInfoList.clear();
            allAssetInfoShowList.clear();
            assetFromSearchList.clear();
            this.amHeader = new AssetMaintainHeader__c();
            ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.INFO, '删除申请成功'));
        }
        else{
            ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.ERROR, result));
        }
        return ;
    }
    /**
    @description 废弃按钮
    */
    public void abandon(){
        String result = AssetMaintainHeaderWebService.abandon(this.amHeader.Id);
        if(result == '1'){
            abandonButtonActive = false;
            ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.Info, '已启动batch，完成时会有邮件提醒'));
        }
        else{
            ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.ERROR, result));
        }
        return ;
    }
    /**
    @description 对选中的明细筛选
    */
    public void filter() {
        if (fieldName != NONE && operator != NONE) {
            allAssetInfoShowList.clear();
            for (AssetInfo info : allAssetInfoList) {
                String fieldValueInRecord = info.amd.get(fieldName) == null ? '' :String.valueOf(info.amd.get(fieldName));
                if(fieldValue == null) {
                    fieldValue = '';
                }
                Boolean meet = false;
                if (operator == '==' && fieldValueInRecord == String.valueOf(fieldValue)) {
                    meet = true;
                }
                else if (operator == '!=' && fieldValueInRecord != String.valueOf(fieldValue)) {
                    meet = true;
                }
                else if (operator == '<' && fieldValueInRecord < String.valueOf(fieldValue)) {
                    meet = true;
                }
                else if (operator == '<=' && fieldValueInRecord <= String.valueOf(fieldValue)) {
                    meet = true;
                }
                else if (operator == '>' && fieldValueInRecord > String.valueOf(fieldValue)) {
                    meet = true;
                }
                else if (operator == '>=' && fieldValueInRecord >= String.valueOf(fieldValue)) {
                    meet = true;
                }
                else if (operator == 'contains' && fieldValueInRecord.contains(String.valueOf(fieldValue))) {
                    meet = true;
                }
                else if (operator == 'notcontains' && !fieldValueInRecord.contains(String.valueOf(fieldValue))) {
                    meet = true;
                }
                else if (operator == 'starts with' && fieldValueInRecord.startsWith(String.valueOf(fieldValue))) {
                    meet = true;
                }
                if (meet) {
                    allAssetInfoShowList.add(info);
                }
            }
            Integer filterLimit = 1000;
            if (allAssetInfoShowList.size() > filterLimit) {
                while (allAssetInfoShowList.size() > filterLimit) {
                    allAssetInfoShowList.remove(filterLimit);
                }
                ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.WARNING, '满足条件的超过1000条，此处只显示前1000，请更换筛选条件'));
            }
        }
        else {
            ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.ERROR, '请填写筛选条件'));
            fillShowList(1);
        }
    }

    private Integer intValueOf(Decimal d) {
        if(d == null || d < 0) {
            return 0;
        }
        return Integer.valueOf(d);
    }

    private static Map<String, String> createLabelApiMap(){
        Map<String,String> apiMap = new Map<String,String>();
        Map<String,Schema.SObjectField> mfields = AssetMaintainDetail__c.sObjectType.getDescribe().fields.getMap();
        for(String strField:mfields.keySet()) {
            SObjectField fl = mfields.get(strField);
            apiMap.put(fl.getDescribe().getlabel(), strField);
        }
        return apiMap;
    }

    // 明细类
    @testvisible class AssetInfo {
        public Boolean isCheck {get; set;}  // 是否选择
        transient Asset asset; // 借出备品set一览
        public AssetMaintainDetail__c amd {get;set;}
        public Boolean editable{get;set;} // 是否可编辑

        public AssetInfo(Asset ass) {

            this.isCheck = false;
            this.asset = ass;
            this.editable = true;
            this.amd = new AssetMaintainDetail__c();
            this.amd.Asset__c = ass.Id;
            this.amd.Internal_asset_location__c = ass.Internal_asset_location__c;
            this.amd.Salesdepartment__c = ass.Salesdepartment__c;
            this.amd.Fixture_Model_No__c = ass.Fixture_Model_No_F__c;
            this.amd.Internal_Asset_number_key__c = ass.Internal_Asset_number_key__c;
            this.amd.Manage_type__c = ass.Manage_type__c;
            this.amd.SerialNumber__c = ass.SerialNumber;

        }
        public AssetInfo(Asset ass, AssetMaintainDetail__c amd) {
            this.isCheck = false;
            this.asset = ass;
            this.editable = true;
            this.amd = amd;
            this.amd.Asset__c = ass.Id;
            this.amd.Internal_asset_location__c = ass.Internal_asset_location__c;
            this.amd.Salesdepartment__c = ass.Salesdepartment__c;
            this.amd.Fixture_Model_No__c = ass.Fixture_Model_No_F__c;
            this.amd.Internal_Asset_number_key__c = ass.Internal_Asset_number_key__c;
            this.amd.Manage_type__c = ass.Manage_type__c;
            this.amd.SerialNumber__c = ass.SerialNumber;
        }
        public AssetInfo(AssetMaintainDetail__c amd){
            this.isCheck = true;
            this.editable = (amd.Batch_Status__c == '未处理' || amd.Batch_Status__c == null);
            this.amd = amd;
            this.asset = new Asset(Id=amd.Asset__c);
        }
    }
}