package com.ozs.kpim.service.kpiconfig.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.springframework.beans.BeanUtils;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSONObject;
import com.ozs.kpim.dto.kpiconfig.ColumnConfigDTO;
import com.ozs.kpim.dto.kpiconfig.ComputedTypeInfoDTO;
import com.ozs.kpim.dto.kpiconfig.DefinedTypeInfoDTO;
import com.ozs.kpim.dto.kpiconfig.KpiConfigDTO;
import com.ozs.kpim.dto.kpiconfig.KpiConfigForListDTO;
import com.ozs.kpim.dto.kpiconfig.KpiConfigPO;
import com.ozs.kpim.dto.kpiconfig.KpiPrivilegeControlDTO;
import com.ozs.kpim.dto.kpiconfig.KpiRelPO;
import com.ozs.kpim.dto.kpiconfig.RuleConfigDTO;
import com.ozs.kpim.dto.mdm.KpiListColumnDTO;
import com.ozs.kpim.dto.mdm.MdmInfoColumn;
import com.ozs.kpim.mapper.common.CommonMapper;
import com.ozs.kpim.mapper.kpiconfig.KpiConfigMapper;
import com.ozs.kpim.mapper.kpiconfig.KpiRelationMapper;
import com.ozs.kpim.mapper.topic.TopicMapper;
import com.ozs.kpim.service.kpiconfig.KpiConfigService;
import com.ozs.kpim.service.kpiconfig.MdmApi;
import com.ozs.kpim.service.kpiconfig.RpmApi;
import com.ozs.kpim.util.ParamUtil;
import com.ozs.kpim.util.R;
import com.ozs.kpim.util.S;
import com.github.pagehelper.PageHelper;

import lombok.extern.slf4j.Slf4j;

/**
 * @ClassName KpiConfigServiceImpl
 * @Desc KPI配置Service实现类
 * @Author jade
 * @Date 2019/2/22
 * @Version 1.0
 */
@Slf4j
@Service
public class KpiConfigServiceImpl implements KpiConfigService {

	Set<String> signSet = null;

	@Resource
	private TopicMapper topicMapper;

	@Resource
	private KpiConfigMapper kpiConfigMapper;

	@Resource
	private KpiRelationMapper kpiRelationMapper;

	@Resource
	private CommonMapper commonMapper;

	@Resource
	private MdmApi mdmApi;

	@Resource
	private RpmApi rpmApi;

	/*
	 * *
	 * 
	 * @Author jade
	 * 
	 * @Description 新增一条
	 * 
	 * @Date 2019/2/22
	 * 
	 * @Param [kpiConfigDTO]
	 * 
	 * @return R<KpiConfigDTO>
	 **/
	@Transactional
	@Override
	public R<KpiConfigDTO> save(KpiConfigDTO kpiConfigDTO) throws Exception {
		boolean check = saveOne(kpiConfigDTO, false);
		if (check) {
			return new R<>(S.OK, S.getMsg(S.OK));
		} else {
			return new R<>(S.CHECK_EXPRESSION_FAIL, S.getMsg(S.CHECK_EXPRESSION_FAIL));
		}

	}

	/*
	 * *
	 * 
	 * @Author jade
	 * 
	 * @Description
	 * 
	 * @Date 2019/3/28
	 * 
	 * @Param [signs]
	 * 
	 * @return boolean
	 **/
	public boolean ifHasSigns(Set<String> signs) {

		if (signSet == null) {
			signSet = commonMapper.listSigns().stream().map(e -> {
				return e.getSign();
			}).collect(Collectors.toSet());
		}

		if (StringUtils.isEmpty(signs)) {
			return false;
		}

		Set<String> resultSet = new HashSet<>();
		resultSet.addAll(signSet);
		resultSet.retainAll(signs);
		return resultSet.isEmpty() ? false : true;
	}

	/*
	 * *
	 * 
	 * @Author jade
	 * 
	 * @Description 保存操作
	 * 
	 * @Date 2019/3/11
	 * 
	 * @Param [kpiConfigDTO, hasKpiCode]
	 * 
	 * @return void
	 **/
	private boolean saveOne(KpiConfigDTO kpiConfigDTO, boolean hasKpiCode) {
		// 先判断是否计算类型，计算类型要判断规则才能确定是否能保存
		if (2 == kpiConfigDTO.getType()) {
			List<String> signList = new ArrayList<>();
			List<RuleConfigDTO> ruleOptions = kpiConfigDTO.getComputedTypeInfo().getRuleOptions();
			if (ruleOptions != null && ruleOptions.size() > 0) {
				String expression = "";
				expression = setSignList(signList, ruleOptions, expression);

				try {
					// 规则长度大于1要判断是否有符号
					int ruleSize = ruleOptions.size();
					if (ruleSize > 1) {
						if (signList.size() < ruleSize - 1) {
							log.warn("缺少符号，重新填写规则");
							return false;
						}
					}
					ExpressionParser parser = new SpelExpressionParser();
					Integer value = parser.parseExpression(expression).getValue(Integer.class);
				} catch (Exception e) {
					log.warn("规则校验失败了，" + e.getMessage());
					return false;
				}

			}
		}

		KpiConfigPO record = new KpiConfigPO();
		BeanUtils.copyProperties(kpiConfigDTO, record);
		if (!hasKpiCode) {
			// 1.查询KPICODE,并加1
			record.setKpiCode(generateKpiCode());
		}
		// 2.生成主键
		String id = UUID.randomUUID().toString();
		record.setId(id);
		// 转化关联关系内容
		operateByType(kpiConfigDTO, record, id);
		kpiConfigMapper.insert(record);
		// 3.主题关联关系表插入数据
		operateTopicRelation(kpiConfigDTO, id);

		return true;
	}

	/*
	 * *
	 * 
	 * @Author jade
	 * 
	 * @Description 主题关系表操作
	 * 
	 * @Date 2019/3/11
	 * 
	 * @Param [kpiConfigDTO, id]
	 * 
	 * @return void
	 **/
	private void operateTopicRelation(KpiConfigDTO kpiConfigDTO, String id) {
		List<String> topicCodes = kpiConfigDTO.getTopicCodes();
		if (topicCodes != null && topicCodes.size() > 0) {
			List<String> topicIds = topicMapper.listTopicsByTopicCodes(topicCodes).stream().map(e -> e.getId())
					.collect(Collectors.toList());
			List<KpiRelPO> kpiRelTopics = generateStoreList(id, topicIds);
			kpiRelationMapper.insertKpiRelTopicBatch(kpiRelTopics);
		}

	}

	/*
	 * *
	 * 
	 * @Author jade
	 * 
	 * @Description 根据类型的操作
	 * 
	 * @Date 2019/3/11
	 * 
	 * @Param [kpiConfigDTO, record, id]
	 * 
	 * @return void
	 **/
	private void operateByType(KpiConfigDTO kpiConfigDTO, KpiConfigPO record, String id) {
		Integer type = kpiConfigDTO.getType();
		switch (type) {
		// 定义类型：选择数据库/表/字段，保存字段关联关系
		case 1:
			operateDefineAndInput(kpiConfigDTO, id);
			break;
		// 计算类型：保存json数据，保存关联关系
		case 2:
			ComputedTypeInfoDTO computedTypeInfo = kpiConfigDTO.getComputedTypeInfo();
			computedTypeInfo.setDatabaseId(kpiConfigDTO.getDatabaseId());
			record.setRelationship(JSONObject.toJSONBytes(computedTypeInfo));

			List<String> col1 = new ArrayList<>();
			List<ColumnConfigDTO> contents = computedTypeInfo.getContents();
			for (ColumnConfigDTO columnConfigDTO : contents) {
				col1.addAll(columnConfigDTO.getColumnId());
			}

			List<String> col2 = computedTypeInfo.getRelOptions().stream().map(e -> e.getColumnId())
					.collect(Collectors.toList());
			List<String> col3 = computedTypeInfo.getRelOptions().stream().map(e -> e.getRelColumnId())
					.collect(Collectors.toList());

			Set<String> set = new HashSet<>();
			set.addAll(col1);
			set.addAll(col2);
			set.addAll(col3);
			List list = generateStoreList(id, new ArrayList(set));
			if (list != null && list.size() > 0) {
				kpiRelationMapper.insertKpiRelColumnBatch(list);
			}
			break;
		// 输入类型目前和定义类型一样
		case 3:
			operateDefineAndInput(kpiConfigDTO, id);
			break;
		// 新增函数类型KPI,
		case 4:
			// 添加KPI函数关联 TODO
			kpiRelationMapper.insertKpiRelFunctionBatch(id, kpiConfigDTO.getFunctionId());
			// 添加KPI字段关联
			operateFunction(kpiConfigDTO, id);
			break;
		}
	}

	/**
	 * 函数类型KPI保存字段关联
	 * 
	 * @param kpiConfigDTO
	 * @param id
	 */
	private void operateFunction(KpiConfigDTO kpiConfigDTO, String id) {
		List<KpiRelPO> pos = new ArrayList<>();
		List<DefinedTypeInfoDTO> functionKpiColumns = kpiConfigDTO.getFunctionKpiColumns();
		for (DefinedTypeInfoDTO c : functionKpiColumns) {
			String columnId = c.getColumnId();
			KpiRelPO po = new KpiRelPO();
			po.setKpiId(id);
			po.setRelId(columnId);
			po.setSort(functionKpiColumns.indexOf(c) + 1);
			pos.add(po);
		}
		kpiRelationMapper.insertKpiRelColumnBatch(pos);
	}

	/*
	 * *
	 * 
	 * @Author jade
	 * 
	 * @Description 定义/输入类型处理
	 * 
	 * @Date 2019/3/15
	 * 
	 * @Param [kpiConfigDTO, id]
	 * 
	 * @return void
	 **/
	private void operateDefineAndInput(KpiConfigDTO kpiConfigDTO, String id) {
		DefinedTypeInfoDTO definedTypeInfo = kpiConfigDTO.getDefinedTypeInfo();
		String columnId = definedTypeInfo.getColumnId();
		KpiRelPO po = new KpiRelPO();
		po.setKpiId(id);
		po.setRelId(columnId);
		kpiRelationMapper.insertKpiRelColumnBatch(Arrays.asList(po));
	}

	/*
	 * *
	 * 
	 * @Author jade
	 * 
	 * @Description 转化数据
	 * 
	 * @Date 2019/2/22
	 * 
	 * @Param [kpiId, source]
	 * 
	 * @return java.util.List<KpiRelPO>
	 **/
	private List<KpiRelPO> generateStoreList(String kpiId, List<String> source) {
		List<KpiRelPO> target = new ArrayList<>();
		if (source == null || source.isEmpty())
			return target;

		for (String id : source) {
			KpiRelPO po = new KpiRelPO();
			po.setKpiId(kpiId);
			po.setRelId(id);
			target.add(po);
		}
		return target;
	}

	/*
	 * *
	 * 
	 * @Author jade
	 * 
	 * @Description 根据数据库中的最大的KPI_CODE生成编码
	 * 
	 * @Date 2019/2/22
	 * 
	 * @Param []
	 * 
	 * @return java.lang.String
	 **/
	private synchronized String generateKpiCode() {
		String maxKpiCode = kpiConfigMapper.getMaxKpiCode();
		String prefix = maxKpiCode.substring(0, 1);
		long Number = Long.parseLong(maxKpiCode.substring(1));
		return prefix + (Number + 1);
	}

	private synchronized String generateKpiCode(String prevKpiCode) {
		String prefix = prevKpiCode.substring(0, 1);
		long Number = Long.parseLong(prevKpiCode.substring(1));
		return prefix + (Number + 1);
	}

	/*
	 * *
	 * 
	 * @Author jade
	 * 
	 * @Description 更新,所有字段都可以被修改
	 * 
	 * @Date 2019/2/22
	 * 
	 * @Param [kpiConfigDTO]
	 * 
	 * @return R<KpiConfigDTO>
	 **/
	@Transactional
	@Override
	public R<KpiConfigDTO> update(KpiConfigDTO kpiConfigDTO) throws Exception {
		KpiConfigPO po = new KpiConfigPO();
		BeanUtils.copyProperties(kpiConfigDTO, po);
		String id = kpiConfigDTO.getId();
		// 1.查询原数据
		KpiConfigPO oldRecord = kpiConfigMapper.getById(id);
		if (oldRecord == null)
			return new R<>(S.ERROR, S.getMsg(S.ERROR));

		// 先判断是否计算类型，计算类型要判断规则才能确定是否能保存
		if (2 == kpiConfigDTO.getType()) {
			List<String> signList = new ArrayList<>();
			List<RuleConfigDTO> ruleOptions = kpiConfigDTO.getComputedTypeInfo().getRuleOptions();
			if (ruleOptions != null && ruleOptions.size() > 0) {
				String expression = "";
				expression = setSignList(signList, ruleOptions, expression);
				try {
					// 规则长度大于1要判断是否有符号
					int ruleSize = ruleOptions.size();
					if (ruleSize > 1) {
						if (signList.size() < ruleSize - 1) {
							log.warn("缺少符号，重新填写规则");
							return new R<>(S.CHECK_EXPRESSION_FAIL, S.getMsg(S.CHECK_EXPRESSION_FAIL));
						}
					}
					ExpressionParser parser = new SpelExpressionParser();
					Integer value = parser.parseExpression(expression).getValue(Integer.class);
				} catch (Exception e) {
					log.error("规则校验失败了，" + e.getMessage());
					return new R<>(S.CHECK_EXPRESSION_FAIL, S.getMsg(S.CHECK_EXPRESSION_FAIL));
				}
			}
		}
		// 2.删除关联主题表
		kpiRelationMapper.deleteKpiRelTopicByKpiId(id);
		// 3.判断KPI类型，删除字段关联关系表
		if (3 != oldRecord.getType()) {
			kpiRelationMapper.deleteKpiRelColumnByKpiId(id);
		}
		// 函数类型，删除KPI函数关联
		if (4 == oldRecord.getType()) {
			kpiRelationMapper.deleteKpiRelFunctionByKpiId(id);
		}

		// 4.修改数据
		operateByType(kpiConfigDTO, po, id);
		kpiConfigMapper.update(po);

		// 5.插入关联主题
		operateTopicRelation(kpiConfigDTO, id);

		return new R<>(S.OK, S.getMsg(S.OK));
	}

	private String setSignList(List<String> signList, List<RuleConfigDTO> ruleOptions, String expression) {
		for (RuleConfigDTO ruleConfigDTO : ruleOptions) {
			// 数字1用于规则测试,判断是否是正常的表达式
			expression += ruleConfigDTO.getLeftSign() + "1" + ruleConfigDTO.getRightSign();

			if (!StringUtils.isEmpty(ruleConfigDTO.getLeftSign())) {
				signList.add(ruleConfigDTO.getLeftSign());
			}

			if (!StringUtils.isEmpty(ruleConfigDTO.getRightSign())) {
				signList.add(ruleConfigDTO.getRightSign());
			}
		}
		return expression;
	}

	/*
	 * *
	 * 
	 * @Author jade
	 * 
	 * @Description 删除，判断是否KPI配置是否被使用需要调用王一夫的接口
	 * 
	 * @Date 2019/2/22
	 * 
	 * @Param [id]
	 * 
	 * @return R<KpiConfigDTO>
	 **/
	@Override
	@Transactional
	public R<KpiConfigDTO> delete(String id) throws Exception {
		// 1.调用接口查询配置信息是否被使用
		int usedKPI = rpmApi.usedKPI(id);
		if (usedKPI >= 1) {
			return new R<>(S.DELETE_IN_USE, S.getMsg(S.DELETE_IN_USE));
		}
		// 2.未被使用的执行删除操作
		kpiConfigMapper.delete(id);
		// 3.删除主题关联表数据
		kpiRelationMapper.deleteKpiRelTopicByKpiId(id);
		// 4.删除用户关联表数据
		kpiRelationMapper.deleteKpiRelUserByKpiId(id);
		// 5.删除字段关联表数据
		kpiRelationMapper.deleteKpiRelColumnByKpiId(id);

		return new R<>(S.OK, S.getMsg(S.OK));
	}

	/*
	 * *
	 * 
	 * @Author jade
	 * 
	 * @Description 查询详情
	 * 
	 * @Date 2019/2/22
	 * 
	 * @Param [id]
	 * 
	 * @return R<KpiConfigDTO>
	 **/
	@Override
	@Transactional
	public R<KpiConfigDTO> getById(String id) throws Exception {
		KpiConfigDTO kpiConfigDTO = new KpiConfigDTO();
		// 1.查询数据库的记录
		KpiConfigPO record = kpiConfigMapper.getById(id);
		if (record == null) {
			return new R<>(S.OK, S.getMsg(S.OK), kpiConfigDTO);
		}
		getKpiConfigDetail(id, kpiConfigDTO, record);

		return new R<>(S.OK, S.getMsg(S.OK), kpiConfigDTO);
	}

	/*
	 * *
	 * 
	 * @Author jade
	 * 
	 * @Description 详细操作方法
	 * 
	 * @Date 2019/3/11
	 * 
	 * @Param [id, kpiConfigDTO, record]
	 * 
	 * @return void
	 **/
	private void getKpiConfigDetail(String id, KpiConfigDTO kpiConfigDTO, KpiConfigPO record) {
		// 2.查询关联关系字段ID
		List<String> columnIds = kpiRelationMapper.listColumnIdsByKpiId(id);
		// 3.拷贝数据并赋值
		if (record == null) {
			return;
		}
		BeanUtils.copyProperties(record, kpiConfigDTO);

		// 4.查询主题编码
		List<String> topicCodes = topicMapper.listTopicsByKpiId(id).stream().map(e -> e.getTopicCode())
				.collect(Collectors.toList());
		kpiConfigDTO.setTopicCodes(topicCodes);
		Integer type = record.getType();
		switch (type) {
		case 1:
			defineAndInput(kpiConfigDTO, columnIds);
			break;
		case 2:
			byte[] relationship = record.getRelationship();
			if (relationship != null && relationship.length > 0) {
				String jsonStr = new String(relationship);
				ComputedTypeInfoDTO computedTypeInfoDTO = JSONObject.parseObject(jsonStr, ComputedTypeInfoDTO.class);
				kpiConfigDTO.setComputedTypeInfo(computedTypeInfoDTO);
				kpiConfigDTO.setDatabaseId(computedTypeInfoDTO.getDatabaseId());
			}

			break;
		case 3:
			defineAndInput(kpiConfigDTO, columnIds);
			break;

		/**
		 * 函数类型,获取字段信息
		 */
		case 4:
			functionKpi(kpiConfigDTO, columnIds);
			break;
		}

	}

	/**
	 * 函数类型KPI
	 * 
	 * @param kpiConfigDTO
	 * @param columnIds
	 */
	private void functionKpi(KpiConfigDTO kpiConfigDTO, List<String> columnIds) {
		List<DefinedTypeInfoDTO> functionKpiColumns = new ArrayList<>();
		String databaseId = null;
		if (null != columnIds && columnIds.size() > 0) {
			String columnId = columnIds.get(0);
			if (StringUtils.isEmpty(columnId)) {
				log.error("函数类型KPI字段为空不能查询到数据库和表信息");
				return;
			}
			R<MdmInfoColumn> columnInfoById = mdmApi.getColumnInfoById(columnId);
			MdmInfoColumn data = columnInfoById.getData();
			databaseId = data.getDatabaseId();
		}

		List<KpiListColumnDTO> columns = mdmApi.listColumnByIds(columnIds);
		for (KpiListColumnDTO column : columns) {
			DefinedTypeInfoDTO definedTypeInfoDTO = new DefinedTypeInfoDTO();
			definedTypeInfoDTO.setColumnId(column.getId());
			definedTypeInfoDTO.setTableId(column.getTableId());
			functionKpiColumns.add(definedTypeInfoDTO);
		}
		kpiConfigDTO.setFunctionKpiColumns(functionKpiColumns);
		kpiConfigDTO.setDatabaseId(databaseId);
	}

	/*
	 * *
	 * 
	 * @Author jade
	 * 
	 * @Description 定义与输入操作相同
	 * 
	 * @Date 2019/3/12
	 * 
	 * @Param [kpiConfigDTO, columnIds]
	 * 
	 * @return void
	 **/
	private void defineAndInput(KpiConfigDTO kpiConfigDTO, List<String> columnIds) {
		if (null != columnIds && columnIds.size() > 0) {
			String columnId = columnIds.get(0);
			if (StringUtils.isEmpty(columnId)) {
				log.error("定义或输入类型字段为空不能查询到数据库和表信息");
				return;
			}
			R<MdmInfoColumn> columnInfoById = mdmApi.getColumnInfoById(columnId);
			MdmInfoColumn data = columnInfoById.getData();
			DefinedTypeInfoDTO definedTypeInfoDTO = new DefinedTypeInfoDTO();
			definedTypeInfoDTO.setColumnId(data.getId());
			definedTypeInfoDTO.setTableId(data.getTableId());
			kpiConfigDTO.setDefinedTypeInfo(definedTypeInfoDTO);
			kpiConfigDTO.setDatabaseId(data.getDatabaseId());
		}
	}

	/*
	 * *
	 * 
	 * @Author jade
	 * 
	 * @Description 批量保存
	 * 
	 * @Date 2019/2/22
	 * 
	 * @Param [kpiList]
	 * 
	 * @return R<?>
	 **/
	@Transactional
	@Override
	public R<?> batchSave(List<KpiConfigDTO> kpiList) throws Exception {
		if (kpiList == null || kpiList.isEmpty())
			return new R<>(S.OK, S.getMsg(S.OK));
		String kpiCode = generateKpiCode();

		for (KpiConfigDTO dto : kpiList) {
			dto.setKpiCode(kpiCode);
			saveOne(dto, true);
			kpiCode = generateKpiCode(kpiCode);
		}

		kpiCode = null;
		return new R<>(S.OK, S.getMsg(S.OK));
	}

	/*
	 * *
	 * 
	 * @Author jade
	 * 
	 * @Description 查询KPI配置列表
	 * 
	 * @Date 2019/2/22
	 * 
	 * @Param [params, order, page, pageSize]
	 * 
	 * @return R<?>
	 **/
	@Override
	public R<List<KpiConfigForListDTO>> listKpiConfigs(Map<String, Object> params, String sort, String order,
			Integer page, Integer pageSize) {
		R<KpiConfigForListDTO> r = new R<>();
		if (sort != null && order != null) {
			sort = ParamUtil.camelToUnderline(sort);
			order = ParamUtil.getDefaultOrder(order);
			PageHelper.startPage(page, pageSize, "A." + sort + " " + order);
		} else {
			PageHelper.startPage(page, pageSize);
		}
		r.pageStart(sort, order, page, pageSize);
		List<KpiConfigForListDTO> list = kpiConfigMapper.listKpiConfigs(params);
		return r.page(list);
	}

	/*
	 * *
	 * 
	 * @Author jade
	 * 
	 * @Description 字段是否在使用中
	 * 
	 * @Date 2019/2/22
	 * 
	 * @Param [id]
	 * 
	 * @return java.lang.String
	 **/
	@Override
	public String ifColumnInUse(String columnId) {
		return kpiRelationMapper.getCountByColumnId(columnId) > 0 ? "true" : "false";
	}

	/*
	 * *
	 * 
	 * @Author jade
	 * 
	 * @Description 批量验证字段是否被使用
	 * 
	 * @Date 2019/2/28
	 * 
	 * @Param [columnIds]
	 * 
	 * @return java.util.Map<java.lang.String,java.lang.Object>
	 **/
	@Transactional
	@Override
	public Map<String, Object> ifColumnsInUse(List<String> columnIds) throws Exception {
		Map<String, Object> map = new HashMap();
		if (columnIds == null || columnIds.isEmpty()) {
			return map;
		}

		for (String columnId : columnIds) {
			String result = ifColumnInUse(columnId);
			map.put(columnId, result);
		}
		return map;
	}

	/*
	 * *
	 * 
	 * @Author jade
	 * 
	 * @Description 根据主题ID查询关联的KPI配置列表
	 * 
	 * @Date 2019/2/26
	 * 
	 * @Param [topicId]
	 * 
	 * @return R<?>
	 **/
	@Override
	public R<List<KpiConfigForListDTO>> listKpiConfigsByTopic(String topicId, String topicCode, Integer enableStatus) {
		return new R<>(S.OK, S.getMsg(S.OK), kpiConfigMapper.listKpiConfigsByTopic(topicId, topicCode, enableStatus));
	}

	/*
	 * *
	 * 
	 * @Author jade
	 * 
	 * @Description 权限控制保存
	 * 
	 * @Date 2019/2/26
	 * 
	 * @Param [kpiPrivilegeControlDTO]
	 * 
	 * @return R<?>
	 **/
	@Transactional
	@Override
	public R<?> savePrivilegeControlRelations(KpiPrivilegeControlDTO kpiPrivilegeControlDTO) {
		List<String> kpiIds = kpiPrivilegeControlDTO.getKpiIds();
		List<String> userIds = kpiPrivilegeControlDTO.getUserIds();
		if (kpiIds == null || kpiIds.isEmpty()) {
			log.warn("KPI信息为空");
			return new R<>(S.OK, S.getMsg(S.OK));
		}

		if (userIds == null || userIds.isEmpty()) {
			log.warn("用户信息为空");
			return new R<>(S.OK, S.getMsg(S.OK));
		}

		for (String kpiId : kpiIds) {
			// 1.删除以前关联的数据
			kpiRelationMapper.deleteKpiRelUserByKpiId(kpiId);
			// 2.重新插入数据
			List<KpiRelPO> kpiRelUsers = generateStoreList(kpiId, userIds);
			kpiRelationMapper.insertKpiRelUserBatch(kpiRelUsers);
		}

		return new R<>(S.OK, S.getMsg(S.OK));
	}

	/*
	 * *
	 * 
	 * @Author jade
	 * 
	 * @Description 启用/停用
	 * 
	 * @Date 2019/3/6
	 * 
	 * @Param [kpiConfigDTO]
	 * 
	 * @return R<?>
	 **/
	@Override
	public R<?> updateEnableStatus(KpiConfigDTO kpiConfigDTO) throws Exception {
		String id = kpiConfigDTO.getId();
		// 1.使用中不能被停用，需要调用王一夫接口
		int usedKPI = rpmApi.usedKPI(id);
		if (usedKPI >= 1) {
			return new R<>(S.UPDATE_IN_USE, S.getMsg(S.UPDATE_IN_USE));
		}
		// 2.操作
		kpiConfigMapper.updateEnableStatus(id, kpiConfigDTO.getEnableStatus());
		return new R<>(S.OK, S.getMsg(S.OK));
	}

	/*
	 * *
	 * 
	 * @Author jade
	 * 
	 * @Description 查询一组KPI的详情
	 * 
	 * @Date 2019/3/11
	 * 
	 * @Param [ids]
	 * 
	 * @return java.util.List<KpiConfigDTO>
	 **/
	@Override
	public List<KpiConfigDTO> listKpiConfigByKpiIds(List<String> ids) throws Exception {
		List<KpiConfigDTO> list = new ArrayList<>();
		if (ids != null && ids.size() > 0) {
			for (String id : ids) {
				KpiConfigDTO kpiConfigDTO = new KpiConfigDTO();
				KpiConfigPO record = kpiConfigMapper.getById(id);
				if (record == null) {
					continue;
				}
				getKpiConfigDetail(id, kpiConfigDTO, record);
				list.add(kpiConfigDTO);
			}
		}
		return list;
	}

}
