package com.jeequan.jeepay.mgr.ctrl.merchant;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.common.collect.HashMultiset;
import com.google.common.collect.Multiset;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.MchInfo;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.interfaces.device.IPrinterService;
import com.jeequan.jeepay.core.interfaces.device.ISpeakerService;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.device.PayOrderInfo4Device;
import com.jeequan.jeepay.core.model.device.PluginCdKeyParams;
import com.jeequan.jeepay.core.model.device.ZwParams;
import com.jeequan.jeepay.core.utils.DateKit;
import com.jeequan.jeepay.core.utils.SeqKit;
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import com.jeequan.jeepay.db.entity.*;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.DeviceProvideConfigService;
import com.jeequan.jeepay.service.impl.MchQrcDeviceRelaService;
import com.jeequan.jeepay.service.impl.MchQrcodeCardService;
import com.jeequan.jeepay.service.impl.MchStoreDeviceService;
import com.jeequan.jeepay.thirdparty.device.printer.fePrinter.FePrinterService;
import com.jeequan.jeepay.thirdparty.device.printer.ylyPrinter.YlyPrinterService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 设备厂商配置管理类
 *
 * @author zx
 *
 * @date 2021-12-28 09:15
 */
@Slf4j
@RestController
@RequestMapping("api/store/device")
public class MchStoreDeviceController extends CommonCtrl {

	@Autowired private DeviceProvideConfigService deviceProvideConfigService;
	@Autowired private MchStoreDeviceService mchStoreDeviceService;
	@Autowired private MchQrcodeCardService mchQrcodeCardService;
	@Autowired private MchQrcDeviceRelaService mchQrcDeviceRelaService;

	/**
	 * @author: zx
	 * @date: 2021-12-28 09:15
	 * @describe: 门店设备列表
	 */
	@PreAuthorize("hasAnyAuthority('ENT_DEVICE_SPEAKER_DEVICE_LIST', 'ENT_DEVICE_PRINTER_DEVICE_LIST', " +
			"'ENT_DEVICE_POS_DEVICE_LIST', 'ENT_DEVICE_PLUGIN_CDKEY_LIST', 'ENT_DEVICE_FACE_APP')")
	@GetMapping
	public ApiRes pages() {
		MchStoreDevice mchStoreDevice = getObject(MchStoreDevice.class);

		IPage<MchStoreDevice> page = mchStoreDeviceService.selectPage(getIPage(), mchStoreDevice);
		//返回数据
		return ApiRes.page(page);
	}

	/**
	 * @author: zx
	 * @date: 2021-12-28 09:15
	 * @describe: 批量添加设备
	 */
	@PreAuthorize("hasAnyAuthority('ENT_DEVICE_SPEAKER_DEVICE_ADD', 'ENT_DEVICE_PRINTER_DEVICE_ADD', " +
			"'ENT_DEVICE_POS_DEVICE_ADD', 'ENT_DEVICE_PLUGIN_CDKEY_ADD', 'ENT_DEVICE_FACE_APP_ADD')")
	@MethodLog(remark = "批量添加设备")
	@PostMapping
	public ApiRes add() {
		MchStoreDevice mchStoreDevice = getObject(MchStoreDevice.class);
		mchStoreDevice.setState(CS.YES);
		mchStoreDevice.setBindState(CS.NO);

		// 设备类型必填项
		Byte deviceType = getValByteRequired("deviceType");

		// 非智能POS设备类型   校验厂商&&设置厂商参数，智能pos厂商为支付接口ifCode
		DeviceProvideConfig deviceProvideConfig = null;
		if (!(deviceType == MchStoreDevice.DEVICE_TYPE_AUTO_POS || deviceType == MchStoreDevice.DEVICE_TYPE_FACE_APP
				|| deviceType == MchStoreDevice.DEVICE_TYPE_RUYI)) {
			deviceProvideConfig = deviceProvideConfigService.getById(mchStoreDevice.getConfigId());
			if (deviceProvideConfig == null || deviceProvideConfig.getState() != CS.YES) {
				return ApiRes.customFail("厂商配置不存在");
			}
			mchStoreDevice.setProvider(deviceProvideConfig.getProvider());
		}

		// 收银插件 -- 新增激活码，系统自动创建激活码，无需前端传入设备号字段
		if (deviceType == MchStoreDevice.DEVICE_TYPE_PLUGIN) {
			return addPluginCdKey(mchStoreDevice, getValIntegerDefault("num", 1), getValStringDefault("expiredTime", "0"));
		}

		// 设备号必填项
		String deviceNoParams = getValStringRequired("deviceNoParams");
		String[] deviceNoArr = deviceNoParams.replaceAll(" ", "").split(",");

		// 飞鹅云打印，需调用上游接口注册
		if (deviceType == MchStoreDevice.DEVICE_TYPE_PRINTER && "fe".equals(mchStoreDevice.getProvider())) {
			return addFeiEDevice(deviceNoArr, mchStoreDevice, deviceProvideConfig);
		}
		// 智网云打印，需调用上游接口注册
		if (deviceType == MchStoreDevice.DEVICE_TYPE_PRINTER && CS.DEVICE_PROVIDER.ZW.equals(mchStoreDevice.getProvider())) {
			addZwEDevice(deviceNoArr, mchStoreDevice, deviceProvideConfig);
			// 新增设备
			return mchStoreDeviceService.addDeviceByZw(mchStoreDevice);
		}
		// 易联云打印，需调用上游接口绑定
		if (deviceType == MchStoreDevice.DEVICE_TYPE_PRINTER && CS.DEVICE_PROVIDER.YLY.equals(mchStoreDevice.getProvider())) {
			return addYlyDevice(deviceNoArr, mchStoreDevice, deviceProvideConfig);
		}

		// 批量新增设备
		return mchStoreDeviceService.addDeviceBatch(mchStoreDevice, deviceNoArr);
	}


	/**
	 * @author: zx
	 * @date: 2021-12-28 09:15
	 * @describe: 批量添加云喇叭
	 */
	@PreAuthorize("hasAnyAuthority('ENT_DEVICE_SPEAKER_DEVICE_ADD')")
	@MethodLog(remark = "批量添加云喇叭")
	@PostMapping("/addSpeaker")
	public ApiRes addSpeaker() {
		MchStoreDevice mchStoreDevice = getObject(MchStoreDevice.class);
		mchStoreDevice.setState(CS.YES);
		mchStoreDevice.setBindState(CS.NO);

		DeviceProvideConfig deviceProvideConfig = deviceProvideConfigService.getById(mchStoreDevice.getConfigId());
		if (deviceProvideConfig == null || deviceProvideConfig.getState() != CS.YES) {
			return ApiRes.customFail("厂商配置不存在");
		}
		mchStoreDevice.setDeviceType(deviceProvideConfig.getDeviceType());
		mchStoreDevice.setProvider(deviceProvideConfig.getProvider());

		// 设备号&码牌ID  Array：[{ deviceNo: '', bindQrcId: '' }]
		String deviceNoParams = getValStringRequired("deviceNoParams");
		List<JSONObject> deviceAndQrcIdList = JSONArray.parseArray(deviceNoParams, JSONObject.class);

		// 检查云喇叭设备号、码牌ID是否唯一
		checkDeviceNoAndQrcIdUnique(deviceAndQrcIdList, mchStoreDevice.getProvider(), mchStoreDevice.getDeviceType());

		List<MchStoreDevice> list = new LinkedList<>();

		deviceAndQrcIdList.forEach(item -> {
			MchStoreDevice newRecord = new MchStoreDevice();
			BeanUtil.copyProperties(mchStoreDevice, newRecord);

			newRecord.setDeviceName(RandomUtil.randomString(4));
			if (StringUtils.isNotBlank(item.getString("bindQrcId"))) {
				newRecord.setBindQrcId(item.getLong("bindQrcId"));
			}

			JSONObject deviceJSON = new JSONObject();
			deviceJSON.put("deviceNo", item.getString("deviceNo"));
			newRecord.setDeviceParams(deviceJSON.toJSONString());
			newRecord.setDeviceNo(item.getString("deviceNo"));

			list.add(newRecord);
		});

		if (mchStoreDeviceService.saveBatch(list)) {
			return ApiRes.ok();
		}
		return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_CREATE);
	}


	/**
	 * @author: zx
	 * @date: 2021-12-28 09:15
	 * @describe: 门店设备修改
	 */
	@PreAuthorize("hasAnyAuthority('ENT_DEVICE_SPEAKER_DEVICE_EDIT', 'ENT_DEVICE_PRINTER_DEVICE_EDIT', " +
			"'ENT_DEVICE_POS_DEVICE_EDIT', 'ENT_DEVICE_PLUGIN_CDKEY_EDIT', 'ENT_DEVICE_FACE_APP_EDIT')")
	@MethodLog(remark = "设备厂商配置修改")
	@PutMapping("/{deviceId}")
	public ApiRes update(@PathVariable("deviceId") Long deviceId) {
		MchStoreDevice mchStoreDevice = getObject(MchStoreDevice.class);
		mchStoreDevice.setDeviceId(deviceId);
		mchStoreDevice.setBatchId(null);
		mchStoreDevice.setCreatedAt(null);
		mchStoreDevice.setUpdatedAt(null);

		MchStoreDevice dbRecord = mchStoreDeviceService.getById(deviceId);
		if (dbRecord == null) {
			return ApiRes.customFail("设备不存在！");
		}

		// 收银插件更新
		if (dbRecord.getDeviceType() == MchStoreDevice.DEVICE_TYPE_PLUGIN) {
			return updatePluginCdKey(mchStoreDevice, dbRecord, getValString("expiredTime"));
		}


		// 云喇叭修改初始绑定码牌时的校验
		if (dbRecord.getDeviceType() == MchStoreDevice.DEVICE_TYPE_SPEAKER && mchStoreDevice.getBindQrcId() != null
				&& (dbRecord.getBindQrcId() == null || !dbRecord.getBindQrcId().equals(mchStoreDevice.getBindQrcId()))) {

			// 云喇叭绑定状态不允许修改初始码牌ID
			if (dbRecord.getBindState() == CS.YES) {
				return ApiRes.customFail("设备已绑定至商户，请检查！");
			}

			if (mchStoreDeviceService.count(MchStoreDevice.gw()
					.eq(MchStoreDevice::getBindQrcId, mchStoreDevice.getBindQrcId())
					.ne(MchStoreDevice::getDeviceId, dbRecord.getDeviceId())) > 0) {
				return ApiRes.customFail("码牌已绑定其他设备，请检查！");
			}

			MchQrcodeCard mchQrcodeCard = mchQrcodeCardService.getById(mchStoreDevice.getBindQrcId());
			if (mchQrcodeCard == null || mchQrcodeCard.getBindState() == CS.YES) {
				return ApiRes.customFail("码牌不存在或已绑定至商户，请检查！");
			}
		}

		// 飞鹅云打印  同步修改上游
		if (CS.DEVICE_PROVIDER.FE.equals(mchStoreDevice.getProvider())) {
			DeviceProvideConfig deviceProvideConfig = deviceProvideConfigService.getById(dbRecord.getConfigId());
			if (deviceProvideConfig == null || deviceProvideConfig.getState() != CS.YES) {
				return ApiRes.customFail("厂商配置不存在或已禁用");
			}

			return updateFeiEDevice(mchStoreDevice, dbRecord, deviceProvideConfig);
		}
		// 智网云打印，需调用上游接口注册
		if (CS.DEVICE_PROVIDER.ZW.equals(mchStoreDevice.getProvider())) {
			String deviceNo = dbRecord.getDeviceNo();

			String[] deviceNoArr = deviceNo.split("_");
			DeviceProvideConfig deviceProvideConfig = deviceProvideConfigService.getById(dbRecord.getConfigId());
			addZwEDevice(deviceNoArr, mchStoreDevice, deviceProvideConfig);

			return updateZwDevice(mchStoreDevice, dbRecord, deviceProvideConfig);
		}
		// 易联云打印，需调用上游接口注册
		if (CS.DEVICE_PROVIDER.YLY.equals(mchStoreDevice.getProvider())) {
			DeviceProvideConfig deviceProvideConfig = deviceProvideConfigService.getById(dbRecord.getConfigId());
			return updateYlyDevice(mchStoreDevice, dbRecord, deviceProvideConfig);
		}
		// 设备号
		String deviceNoParams = getValString("deviceNoParams");

		// 校验设备号唯一性
		if (StringUtils.isNotBlank(deviceNoParams)) {
			if (mchStoreDeviceService.count(MchStoreDevice.gw()
					.eq(MchStoreDevice::getDeviceNo, deviceNoParams)
					.eq(MchStoreDevice::getDeviceType, mchStoreDevice.getDeviceType())
					.ne(MchStoreDevice::getDeviceId, deviceId)) > 0) {
				return ApiRes.customFail("设备号重复");
			}

			JSONObject deviceJSON = new JSONObject();
			deviceJSON.put("deviceNo", deviceNoParams);
			mchStoreDevice.setDeviceParams(deviceJSON.toJSONString());
			mchStoreDevice.setDeviceNo(deviceNoParams);
		}

		if(!mchStoreDeviceService.updateById(mchStoreDevice)) {
            return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_UPDATE);
        }

		return ApiRes.ok();
	}


	/**
	 * @author: zx
	 * @date: 2021-12-28 09:15
	 * @describe: 根据ID获取门店设备
	 */
	@PreAuthorize("hasAnyAuthority('ENT_DEVICE_SPEAKER_DEVICE_VIEW', 'ENT_DEVICE_PRINTER_DEVICE_VIEW', " +
			"'ENT_DEVICE_POS_DEVICE_VIEW', 'ENT_DEVICE_PLUGIN_CDKEY_VIEW', 'ENT_DEVICE_FACE_APP_VIEW')")
	@GetMapping("/{deviceId}")
	public ApiRes get(@PathVariable("deviceId") Long deviceId) {

		MchStoreDevice dbRecord = mchStoreDeviceService.getById(deviceId);

		List<MchQrcDeviceRela> relaList = mchQrcDeviceRelaService.list(MchQrcDeviceRela.gw().eq(MchQrcDeviceRela::getDeviceId, deviceId));
		if (!CollectionUtils.isEmpty(relaList)) {
			dbRecord.addExt("qrcIdList", relaList.stream().map(MchQrcDeviceRela::getQrcId).collect(Collectors.toList()));
		}

		return ApiRes.ok(dbRecord);
	}

	/**
	 * @author: zx
	 * @date: 2021-12-28 09:15
	 * @describe: 门店设备删除
	 */
	@PreAuthorize("hasAnyAuthority('ENT_DEVICE_SPEAKER_DEVICE_DEL', 'ENT_DEVICE_PRINTER_DEVICE_DEL', " +
			"'ENT_DEVICE_POS_DEVICE_DEL', 'ENT_DEVICE_PLUGIN_CDKEY_DEL', 'ENT_DEVICE_FACE_APP_DEL')")
	@MethodLog(remark = "门店设备删除")
	@DeleteMapping
	public ApiRes delete() {

		String delDeviceIds = getValStringRequired("delDeviceIds");

		List<String> deviceIdList = Arrays.stream(delDeviceIds.split(",")).collect(Collectors.toList());

		long count = mchStoreDeviceService.count(MchStoreDevice.gw()
				.eq(MchStoreDevice::getBindState, CS.YES)
				.in(MchStoreDevice::getDeviceId, deviceIdList)
		);
		if (count > 0) {
			return ApiRes.customFail("设备已绑定商户，不可删除！");
		}

		if(mchStoreDeviceService.removeByIds(deviceIdList)) {
			return ApiRes.ok();
		}

		return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_DELETE);
	}

	/**
	 * @author: zx
	 * @date: 2021-12-28 09:15
	 * @describe: 播报测试
	 */
	@PreAuthorize("hasAnyAuthority('ENT_DEVICE_SPEAKER_DEVICE_TEST')")
	@PostMapping("/speak/{deviceId}")
	public ApiRes speak(@PathVariable("deviceId") Long deviceId) {

		Long amountL = getRequiredAmountL("amount");

		MchStoreDevice mchStoreDevice = mchStoreDeviceService.getById(deviceId);
		if (mchStoreDevice == null || mchStoreDevice.getState() != CS.YES) {
			return ApiRes.customFail("设备不存在或已禁用");
		}

		DeviceProvideConfig provideConfig = deviceProvideConfigService.getById(mchStoreDevice.getConfigId());
		if (provideConfig == null || provideConfig.getState() != CS.YES) {
			return ApiRes.customFail("设备厂商未配置或已禁用");
		}

		// 设备类型
		String provider = mchStoreDevice.getProvider();
		ISpeakerService speakerService = SpringBeansUtil.getBean(provider + "SpeakerService", ISpeakerService.class);

		// 设备参数
		JSONObject deviceParams = new JSONObject();
		deviceParams.put("deviceParams", mchStoreDevice.getDeviceParams());
		deviceParams.put("bizConfigParams", mchStoreDevice.getBizConfigParams());
		deviceParams.put("providerParams", provideConfig.getProviderParams());

		// 消息内容
		PayOrderInfo4Device speakPayOrderInfo = new PayOrderInfo4Device();
		speakPayOrderInfo.setAmount(amountL);
		speakPayOrderInfo.setWayCodeType(CS.PAY_WAY_CODE_TYPE.WECHAT);
		// speakPayOrderInfo.setWayCodeType(PayOrderInfo4Device.BOARD_TYPE_CANCEL);
		speakPayOrderInfo.setPayOrderId(String.valueOf(DateKit.currentTimeMillis()));

		try {
			speakerService.send(deviceParams, speakPayOrderInfo);
			return ApiRes.ok();
		}catch (BizException e) {
			throw e;
		}
	}

	/**
	 * @author: zx
	 * @date: 2021-12-28 09:15
	 * @describe: 打印测试
	 */
	@PreAuthorize("hasAnyAuthority('ENT_DEVICE_PRINTER_DEVICE_TEST')")
	@PostMapping("/print/{deviceId}")
	public ApiRes print(@PathVariable("deviceId") Long deviceId) {

		Long amountL = getRequiredAmountL("amount");

		MchStoreDevice mchStoreDevice = mchStoreDeviceService.getById(deviceId);
		if (mchStoreDevice == null || mchStoreDevice.getState() != CS.YES) {
			return ApiRes.customFail("设备不存在或已禁用");
		}

		DeviceProvideConfig provideConfig = deviceProvideConfigService.getById(mchStoreDevice.getConfigId());
		if (provideConfig == null || provideConfig.getState() != CS.YES) {
			return ApiRes.customFail("设备厂商未配置或已禁用");
		}

		// 设备类型
		String provider = mchStoreDevice.getProvider();
		IPrinterService printerService = SpringBeansUtil.getBean(provider + "PrinterService", IPrinterService.class);

		// 设备参数
		JSONObject deviceParams = new JSONObject();
		deviceParams.put("deviceParams", mchStoreDevice.getDeviceParams());
		deviceParams.put("bizConfigParams", mchStoreDevice.getBizConfigParams());
		deviceParams.put("providerParams", provideConfig.getProviderParams());

		// 消息内容
		PayOrderInfo4Device payOrderInfo = new PayOrderInfo4Device();
		payOrderInfo.setAmount(amountL);
		if(StringUtils.isNotEmpty(mchStoreDevice.getStoreId())){
			MchStore store = mchStoreService.getById(mchStoreDevice.getStoreId());
			if(store != null){
				payOrderInfo.setStoreName(store.getStoreName());
			}
		}

		payOrderInfo.setWayCodeType(CS.PAY_WAY_CODE_TYPE.WECHAT);
		payOrderInfo.setPayOrderId(String.valueOf(DateKit.currentTimeMillis()));
		payOrderInfo.setCreatedAt(DateUtil.date());
		// payOrderInfo.setWayCodeType(PayOrderInfo4Device.BOARD_TYPE_CANCEL); // 取消收款播报

		try {
			printerService.send(deviceParams, payOrderInfo);
			// printerService.sendCustomMsg(deviceParams, payOrderInfo);
			return ApiRes.ok();
		}catch (BizException e) {
			throw e;
		}
	}

	/**
	 * @author: zx
	 * @date: 2021-12-28 09:15
	 * @describe: 清空打印队列
	 */
	@PreAuthorize("hasAnyAuthority('ENT_DEVICE_PRINTER_DEVICE_CLEAR')")
	@PostMapping("/clear/{deviceId}")
	public ApiRes clear(@PathVariable("deviceId") Long deviceId) {

		MchStoreDevice mchStoreDevice = mchStoreDeviceService.getById(deviceId);
		if (mchStoreDevice == null || mchStoreDevice.getState() != CS.YES) {
			return ApiRes.customFail("设备不存在");
		}

		DeviceProvideConfig provideConfig = deviceProvideConfigService.getById(mchStoreDevice.getConfigId());
		if (provideConfig == null || provideConfig.getState() != CS.YES) {
			return ApiRes.customFail("设备厂商未配置");
		}

		// 设备类型
		String provider = mchStoreDevice.getProvider();
		IPrinterService printerService = SpringBeansUtil.getBean(provider + "PrinterService", IPrinterService.class);

		// 设备参数
		JSONObject deviceParams = new JSONObject();
		deviceParams.put("deviceParams", mchStoreDevice.getDeviceParams());
		deviceParams.put("bizConfigParams", mchStoreDevice.getBizConfigParams());
		deviceParams.put("providerParams", provideConfig.getProviderParams());

		try {
			printerService.clearPrinter(deviceParams);
			return ApiRes.ok();
		}catch (Exception e) {
			return ApiRes.customFail(e.getMessage());
		}
	}

	/**
	 * @author: zx
	 * @date: 2021-12-28 09:15
	 * @describe: 绑定设备
	 */
	@PreAuthorize("hasAnyAuthority('ENT_DEVICE_SPEAKER_DEVICE_EDIT', 'ENT_DEVICE_PRINTER_DEVICE_EDIT', " +
			"'ENT_DEVICE_POS_DEVICE_EDIT', 'ENT_DEVICE_PLUGIN_CDKEY_EDIT', 'ENT_DEVICE_FACE_APP_EDIT')")
	@PutMapping("/bind/{deviceId}")
	public ApiRes bind(@PathVariable("deviceId") Long deviceId) {

		String mchNo = getValStringRequired("mchNo");
		String storeId = getValStringRequired("storeId");
		Byte bindType = getValByte("bindType");

		MchInfo mchInfo = mchInfoService.getById(mchNo);
		if (mchInfo == null) {
			throw new BizException("商户不存在");
		}

		String agetnNo = "";
		MchStoreDevice dbRecord = mchStoreDeviceService.getById(deviceId);

		// 未划拨服务商且商户存在上级代理，则绑定商户时，同时划拨给服务商
		if (StringUtils.isBlank(dbRecord.getAgentNo()) && StringUtils.isNotBlank(mchInfo.getAgentNo())) {

				agetnNo = mchInfo.getAgentNo();

		}else if (StringUtils.isNotBlank(dbRecord.getAgentNo()) && !dbRecord.getAgentNo().equals(mchInfo.getAgentNo())) {
			throw new BizException("选择的商户不属于设备已划拨的服务商，请收回设备或绑定其他商户");
		}

		// 扫码POS、智能POS需绑定商户应用
		String appId = "";
		if (dbRecord.getDeviceType() != MchStoreDevice.DEVICE_TYPE_SPEAKER && dbRecord.getDeviceType() != MchStoreDevice.DEVICE_TYPE_PRINTER) {
			appId = getValStringRequired("appId");
		}
		// 打印设备获取appId
		if (dbRecord.getDeviceType() == MchStoreDevice.DEVICE_TYPE_PRINTER && (CS.DEVICE_PROVIDER.ZW.equals(dbRecord.getProvider()) || CS.DEVICE_PROVIDER.YLY.equals(dbRecord.getProvider()))) {
			appId = getValStringRequired("appId");
		}

		MchStoreDevice updateRecord = new MchStoreDevice();
		updateRecord.setDeviceId(deviceId).setMchNo(mchNo).setAppId(appId).setStoreId(storeId).setBindState(CS.YES).setBindTime(new Date());
		if (StringUtils.isNotBlank(agetnNo)) {
			updateRecord.setAgentNo(agetnNo);
		}
		if (null != bindType) {
			updateRecord.setBindType(bindType);
		}

		// 云喇叭  同步绑定码牌
		if (dbRecord.getDeviceType() == MchStoreDevice.DEVICE_TYPE_SPEAKER) {

			String qrcIdListStr = getValString("qrcIdList");

			// 绑定类型 为码牌时，需传入绑定的码牌id
			List<Long> qrcList = new LinkedList<>();
			if (null != bindType && bindType == MchStoreDevice.DEVICE_BIND_TYPE_QRC && StringUtils.isNotBlank(qrcIdListStr)) {
				qrcList = JSONArray.parseArray(qrcIdListStr, Long.class);
			}

			boolean result = mchStoreDeviceService.bindSpeakerDevice(updateRecord, dbRecord.getBindQrcId(), qrcList);
			if (!result) {
				return ApiRes.customFail("绑定失败");
			}
			return ApiRes.ok();
		}

		// 云打印、扫码pos执行更新
		if (mchStoreDeviceService.updateById(updateRecord)) {
			return ApiRes.ok();
		}

		return ApiRes.customFail("绑定失败");
	}

	/**
	 * @author: zx
	 * @date: 2021-12-28 09:15
	 * @describe: 解绑设备
	 */
	@PreAuthorize("hasAnyAuthority('ENT_DEVICE_SPEAKER_DEVICE_EDIT', 'ENT_DEVICE_PRINTER_DEVICE_EDIT', " +
			"'ENT_DEVICE_POS_DEVICE_EDIT', 'ENT_DEVICE_PLUGIN_CDKEY_EDIT', 'ENT_DEVICE_FACE_APP_EDIT')")
	@PostMapping("/unbind/{deviceId}")
	public ApiRes unbind(@PathVariable("deviceId") Long deviceId) {

		MchStoreDevice dbRecord = mchStoreDeviceService.getById(deviceId);
		if (dbRecord == null) {
			return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
		}

		mchStoreDeviceService.unbind(dbRecord);

		return ApiRes.ok();
	}

	/**
	 * @author: zx
	 * @date: 2021-12-28 09:15
	 * @describe: 划拨/收回设备
	 */
	@PreAuthorize("hasAnyAuthority('ENT_DEVICE_SPEAKER_DEVICE_ALLOT', 'ENT_DEVICE_PRINTER_DEVICE_ALLOT', " +
			"'ENT_DEVICE_POS_DEVICE_ALLOT', 'ENT_DEVICE_PLUGIN_CDKEY_ALLOT', 'ENT_DEVICE_FACE_APP_ALLOT')")
	@PostMapping("/allotDevice")
	public ApiRes allotDevice() {

		String allotType = getValStringRequired("allotType"); // 划拨类型：select-勾选划拨  batch-批次划拨
		String allotOrRecover = getValStringRequired("allotOrRecover"); // 分配类型：allot-划拨  recover-收回

		// 构建批量更新设备ID集合
		List<Long> deviceIdList = null;
		if (allotType.equals("select")) {

			String allotDeviceIds = getValStringRequired("allotDeviceIds");
			deviceIdList = Arrays.stream(allotDeviceIds.split(",")).map(Long::parseLong).collect(Collectors.toList());

		}else if (allotType.equals("batch")) {

			String batchId = getValStringRequired("batchId");
			List<MchStoreDevice> list = mchStoreDeviceService.list(MchStoreDevice.gw().eq(MchStoreDevice::getBatchId, batchId));
			if (CollUtil.isEmpty(list)) {
				throw new BizException("批次号错误");
			}
			deviceIdList = list.stream().map(MchStoreDevice::getDeviceId).collect(Collectors.toList());

		}else {
			throw new BizException("划拨类型错误");
		}
		if (CollUtil.isEmpty(deviceIdList)) {
			throw new BizException("请选择设备");
		}

		// 1、收回设备
		if (allotOrRecover.equals("recover")) {
			mchStoreDeviceService.recoverDevice(true, deviceIdList, null, null);
			return ApiRes.ok();
		}

		// 2、划拨设备
		String agentNo = getValStringRequired("agentNo");
		List<String> mchNoList = getMchNoListByAgentNo(agentNo);

		mchStoreDeviceService.allotDevice(true, agentNo, deviceIdList, mchNoList, null);

		return ApiRes.ok();
	}



	/** 处理智网设备参数，参数格式：deviceNo_deviceKey, 且需在上游注册 */
	private void addZwEDevice(String[] deviceNoArr, MchStoreDevice mchStoreDevice, DeviceProvideConfig deviceProvideConfig) {

		// 校验是否需要配置
		ZwParams.DeviceParams printConfig = JSONObject.parseObject(mchStoreDevice.getDeviceParams(), ZwParams.DeviceParams.class);

		if (printConfig != null && printConfig.getConfigFlag() != null && printConfig.getConfigFlag() == CS.YES) {
			for (String deviceNo : deviceNoArr) {
				// 设置为 {"deviceNo":"","deviceKey":""} 格式参数
				printConfig.setDeviceNo(deviceNo);
				mchStoreDevice.setDeviceParams(JSON.toJSONString(printConfig)); // 设备参数

				// 上游注册设备参数
				JSONObject feChannelDeviceParams = new JSONObject();
				feChannelDeviceParams.put("deviceParams", mchStoreDevice.getDeviceParams());
				feChannelDeviceParams.put("bizConfigParams", mchStoreDevice.getBizConfigParams());
				feChannelDeviceParams.put("providerParams", deviceProvideConfig.getProviderParams());

				try {
					IPrinterService printerService = SpringBeansUtil.getBean(mchStoreDevice.getProvider() + "PrinterService", IPrinterService.class);
					String addResult = printerService.addPrinter(feChannelDeviceParams);
					if (StringUtils.isBlank(addResult)) {
						log.error("新增失败");
						throw new BizException("新增失败");
					}
				}catch (Exception e) {
					log.error(e.getMessage());
					throw new BizException(e.getMessage());
				}

			}
		}

	}

	/** 处理易联云设备参数，参数格式：deviceNo_deviceKey, 且需在上游注册 */
	private ApiRes addYlyDevice(String[] deviceNoArr, MchStoreDevice mchStoreDevice, DeviceProvideConfig deviceProvideConfig) {

		List<String> deviceNoList = new LinkedList<>();
		for (String deviceNo : deviceNoArr) {
			String[] feParamsArr = deviceNo.split("_");
			if (feParamsArr.length != 2) {
				throw new BizException("设备参数格式错误");
			}
			deviceNoList.add(feParamsArr[0]);
		}

		List<MchStoreDevice> list = new LinkedList<>();

		for (String deviceNo : deviceNoArr) {
			String[] paramsArr = deviceNo.split("_");

			// 设置为 {"deviceNo":"","deviceKey":""} 格式参数
			JSONObject params = new JSONObject();
			params.put("deviceNo", paramsArr[0]);
			params.put("deviceKey", paramsArr[1]);
			mchStoreDevice.setDeviceParams(params.toJSONString()); // 设备参数

			// 上游注册设备参数
			JSONObject feChannelDeviceParams = new JSONObject();
			feChannelDeviceParams.put("deviceParams", mchStoreDevice.getDeviceParams());
			feChannelDeviceParams.put("bizConfigParams", mchStoreDevice.getBizConfigParams());
			feChannelDeviceParams.put("providerParams", deviceProvideConfig.getProviderParams());

			try {
				IPrinterService printerService = SpringBeansUtil.getBean(mchStoreDevice.getProvider() + "PrinterService", IPrinterService.class);
				String addResult = printerService.addPrinter(feChannelDeviceParams);
				if (StringUtils.isBlank(addResult)) {
					log.error("新增失败");
					throw new BizException("新增失败");
				}

				MchStoreDevice newRecord = new MchStoreDevice();
				BeanUtil.copyProperties(mchStoreDevice, newRecord);

				newRecord.setDeviceName(RandomUtil.randomString(4)); // 设备名称
				newRecord.setDeviceNo(paramsArr[0]); // 设备号
				list.add(newRecord);

			}catch (Exception e) {
				log.error(e.getMessage());
				throw new BizException(e.getMessage());
			}

		}

		if (mchStoreDeviceService.saveBatch(list)) {
			return ApiRes.ok();
		}
		return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_CREATE);
	}

	/** 处理飞鹅设备参数，参数格式：deviceNo_deviceKey, 且需在上游注册 */
	private ApiRes addFeiEDevice(String[] deviceNoArr, MchStoreDevice mchStoreDevice, DeviceProvideConfig deviceProvideConfig) {

		List<String> deviceNoList = new LinkedList<>();
		for (String deviceNo : deviceNoArr) {
			String[] feParamsArr = deviceNo.split("_");
			if (feParamsArr.length != 2) {
				throw new BizException("设备参数格式错误");
			}
			deviceNoList.add(feParamsArr[0]);
		}

		List<MchStoreDevice> list = new LinkedList<>();

		for (String deviceNo : deviceNoArr) {

			String[] feParamsArr = deviceNo.split("_");

			// 设置为 {"deviceNo":"","deviceKey":""} 格式参数
			JSONObject feParams = new JSONObject();
			feParams.put("deviceNo", feParamsArr[0]);
			feParams.put("deviceKey", feParamsArr[1]);
			mchStoreDevice.setDeviceParams(feParams.toJSONString()); // 设备参数

			// 上游注册设备参数
			JSONObject feChannelDeviceParams = new JSONObject();
			feChannelDeviceParams.put("deviceParams", mchStoreDevice.getDeviceParams());
			feChannelDeviceParams.put("bizConfigParams", mchStoreDevice.getBizConfigParams());
			feChannelDeviceParams.put("providerParams", deviceProvideConfig.getProviderParams());

			try {
				IPrinterService printerService = SpringBeansUtil.getBean(mchStoreDevice.getProvider() + "PrinterService", IPrinterService.class);
				String addResult = printerService.addPrinter(feChannelDeviceParams);
				if (StringUtils.isBlank(addResult)) {
					return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_CREATE);
				}
			}catch (Exception e) {
				return ApiRes.customFail(e.getMessage());
			}

			MchStoreDevice newRecord = new MchStoreDevice();
			BeanUtil.copyProperties(mchStoreDevice, newRecord);

			newRecord.setDeviceName(RandomUtil.randomString(4)); // 设备名称
			newRecord.setDeviceNo(feParamsArr[0]); // 设备号

			list.add(newRecord);
		}

		if (mchStoreDeviceService.saveBatch(list)) {
			return ApiRes.ok();
		}
		return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_CREATE);
	}

	/** 处理飞鹅设备参数，参数格式：deviceNo_deviceKey, 且需在上游注册 */
	private ApiRes updateFeiEDevice(MchStoreDevice updateRecord, MchStoreDevice dbRecord, DeviceProvideConfig deviceProvideConfig) {

		// 校验设备号唯一性
		String deviceNoParams = getValString("deviceNoParams");

		if (StringUtils.isNotBlank(deviceNoParams)) {
			String[] feParamsArr = deviceNoParams.split("_");
			if (feParamsArr.length != 2) {
				throw new BizException("设备参数格式错误");
			}

			if (mchStoreDeviceService.count(MchStoreDevice.gw()
					.eq(MchStoreDevice::getDeviceNo, feParamsArr[0])
					.eq(MchStoreDevice::getDeviceType, dbRecord.getDeviceType())
					.ne(MchStoreDevice::getDeviceId, updateRecord.getDeviceId())) > 0) {
				return ApiRes.customFail("设备号重复");
			}

			// 上游更新设备参数，设备号/设备key修改时  再提交
			JSONObject dbParams = (JSONObject) JSONObject.parse(dbRecord.getDeviceParams());
			if (!feParamsArr[0].equals(dbRecord.getDeviceNo()) || !feParamsArr[1].equals(dbParams.getString("deviceKey"))) {

				JSONObject feChannelDeviceParams = new JSONObject();

				// 添加上游所需设备名称字段
				JSONObject deviceJSON = JSONObject.parseObject(updateRecord.getDeviceParams());
				deviceJSON.put("deviceName", updateRecord.getDeviceName());

				// 构造 {"deviceNo":"","deviceKey":""} 格式参数
				JSONObject feParams = new JSONObject();
				feParams.put("deviceNo", feParamsArr[0]);
				feParams.put("deviceKey", feParamsArr[1]);
				updateRecord.setDeviceParams(feParams.toJSONString()); // 设备参数

				feChannelDeviceParams.put("deviceParams", feParams.toJSONString());
				feChannelDeviceParams.put("bizConfigParams", updateRecord.getBizConfigParams());
				feChannelDeviceParams.put("providerParams", deviceProvideConfig.getProviderParams());

				try {
					FePrinterService fePrinterService = SpringBeansUtil.getBean(FePrinterService.class);

					String editResult = fePrinterService.editPrinter(feChannelDeviceParams);
					if (StringUtils.isBlank(editResult)) {
						return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_UPDATE);
					}
				}catch (Exception e) {
					return ApiRes.customFail(e.getMessage());
				}
			}
		}

		if(!mchStoreDeviceService.updateById(updateRecord)) {
			return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_UPDATE);
		}

		return ApiRes.ok();
	}

	/** 处理易联云设备参数，参数格式：deviceNo_deviceKey, 且需在上游注册 */
	private ApiRes updateYlyDevice(MchStoreDevice updateRecord, MchStoreDevice dbRecord, DeviceProvideConfig deviceProvideConfig) {

		// 校验设备号唯一性
		String deviceNoParams = getValString("deviceNoParams");

		if (StringUtils.isNotBlank(deviceNoParams)) {
			String[] paramsArr = deviceNoParams.split("_");
			if (paramsArr.length != 2) {
				throw new BizException("设备参数格式错误");
			}

			if (mchStoreDeviceService.count(MchStoreDevice.gw()
					.eq(MchStoreDevice::getDeviceNo, paramsArr[0])
					.eq(MchStoreDevice::getDeviceType, dbRecord.getDeviceType())
					.ne(MchStoreDevice::getDeviceId, updateRecord.getDeviceId())) > 0) {
				return ApiRes.customFail("设备号重复");
			}

			// 上游更新设备参数，设备号/设备key修改时  再提交
			JSONObject dbParams = (JSONObject) JSONObject.parse(dbRecord.getDeviceParams());
			if (!paramsArr[0].equals(dbRecord.getDeviceNo()) || !paramsArr[1].equals(dbParams.getString("deviceKey"))) {

				JSONObject channelDeviceParams = new JSONObject();

				// 构造 {"deviceNo":"","deviceKey":""} 格式参数
				JSONObject params = new JSONObject();
				params.put("deviceNo", paramsArr[0]);
				params.put("deviceKey", paramsArr[1]);
				updateRecord.setDeviceNo(paramsArr[0]);
				updateRecord.setDeviceParams(params.toJSONString()); // 设备参数

				channelDeviceParams.put("deviceParams", params.toJSONString());
				channelDeviceParams.put("bizConfigParams", updateRecord.getBizConfigParams());
				channelDeviceParams.put("providerParams", deviceProvideConfig.getProviderParams());

				try {
					YlyPrinterService ylyPrinterService = SpringBeansUtil.getBean(YlyPrinterService.class);

					String editResult = ylyPrinterService.editPrinter(channelDeviceParams);
					if (StringUtils.isBlank(editResult)) {
						return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_UPDATE);
					}
				}catch (Exception e) {
					return ApiRes.customFail(e.getMessage());
				}
			}else {
				updateRecord.setDeviceParams(null);
			}
		}

		if(!mchStoreDeviceService.updateById(updateRecord)) {
			return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_UPDATE);
		}

		return ApiRes.ok();
	}

	private ApiRes updateZwDevice(MchStoreDevice updateRecord, MchStoreDevice dbRecord, DeviceProvideConfig deviceProvideConfig) {

		ZwParams.DeviceParams deviceParams = JSONObject.parseObject(updateRecord.getDeviceParams(), ZwParams.DeviceParams.class);
		// 校验设备号唯一性
		if (StringUtils.isNotBlank(updateRecord.getDeviceNo())) {

			if (mchStoreDeviceService.count(MchStoreDevice.gw()
					.eq(MchStoreDevice::getDeviceNo, updateRecord.getDeviceNo())
					.eq(MchStoreDevice::getDeviceType, dbRecord.getDeviceType())
					.ne(MchStoreDevice::getDeviceId, updateRecord.getDeviceId())) > 0) {
				return ApiRes.customFail("设备号重复");
			}

			JSONObject feChannelDeviceParams = new JSONObject();

			// 添加上游所需设备名称字段
			JSONObject deviceJSON = JSONObject.parseObject(updateRecord.getDeviceParams());
			deviceJSON.put("deviceName", updateRecord.getDeviceName());

			updateRecord.setDeviceParams(JSON.toJSONString(deviceParams)); // 设备参数
		}

		if(!mchStoreDeviceService.updateById(updateRecord)) {
			return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_UPDATE);
		}

		return ApiRes.ok();
	}

	private void checkDeviceNoAndQrcIdUnique(List<JSONObject> deviceAndQrcIdList, String provider, Byte deviceType) {

		if (CollectionUtils.isEmpty(deviceAndQrcIdList)) {
			throw new BizException("设备号不能为空");
		}

		// 去重
		HashSet<JSONObject> hashSet = new HashSet<>(deviceAndQrcIdList);
		ArrayList<JSONObject> arrayList = new ArrayList<>(hashSet);

		List<String> deviceNoList = new LinkedList<>(); // 要添加的设备号List
		List<Long> qrcIdList = new LinkedList<>(); // 要绑定的码牌IDList

		arrayList.forEach(item -> {
			deviceNoList.add(item.getString("deviceNo"));

			if (item.getLong("bindQrcId") != null) {
				qrcIdList.add(item.getLong("bindQrcId"));
			}
		});

		if (CollectionUtils.isEmpty(deviceNoList)) {
			throw new BizException("设备号不能为空");
		}

		// 重复的设备号集合
		List<String> repeatedDeviceNoList = HashMultiset.create(deviceNoList).entrySet().stream()
				.filter(w ->w.getCount() > 1)
				.map(Multiset.Entry::getElement)
				.collect(Collectors.toList());
		if (!CollectionUtils.isEmpty(repeatedDeviceNoList)) {
			throw new BizException("输入了重复的设备号：【" + repeatedDeviceNoList.get(0) + "】");
		}

		// 同厂商下   设备号唯一
		List<MchStoreDevice> waitAddDeviceList = mchStoreDeviceService.list(MchStoreDevice.gw()
				.eq(MchStoreDevice::getProvider, provider)
				.eq(MchStoreDevice::getDeviceType, deviceType)
				.in(MchStoreDevice::getDeviceNo, deviceNoList));
		if (!CollectionUtils.isEmpty(waitAddDeviceList)) {
			throw new BizException("设备号【"+CollUtil.join(waitAddDeviceList.stream().map(MchStoreDevice::getDeviceNo).collect(Collectors.toList()), ", ")+"】重复，请检查！");
		}

		// 码牌ID为空，不校验码牌相关
		if (CollectionUtils.isEmpty(qrcIdList)) {
			return;
		}

		// 重复的码牌ID集合
		List<Long> repeatedQrcList = HashMultiset.create(qrcIdList).entrySet().stream()
						.filter(w ->w.getCount() > 1)
						.map(Multiset.Entry::getElement)
						.collect(Collectors.toList());
		if (!CollectionUtils.isEmpty(repeatedQrcList)) {
			throw new BizException("输入了重复的码牌ID：【" + repeatedQrcList.get(0) + "】");
		}

		// 检查码牌是否存在
		List<MchQrcodeCard> existQrcList = mchQrcodeCardService.list(MchQrcodeCard.gw().in(MchQrcodeCard::getQrcId, qrcIdList));
		if (CollectionUtils.isEmpty(existQrcList)) {
			throw new BizException("码牌【" + qrcIdList.get(0) + "】不存在，请检查！");
		}

		List<Long> existQrcIdist = existQrcList.stream().map(MchQrcodeCard::getQrcId).collect(Collectors.toList());
		if (existQrcIdist.size() < qrcIdList.size()) {
			qrcIdList.forEach(qrcId -> {
				if (!existQrcIdist.contains(qrcId)) {
					throw new BizException("码牌【" + qrcId + "】不存在，请检查！");
				}
			});
		}

		// 绑定码牌ID唯一，设备码牌一对一关系
		List<MchStoreDevice> list = mchStoreDeviceService.list(MchStoreDevice.gw().in(MchStoreDevice::getBindQrcId, qrcIdList));
		if (list.size() > 0) {
			throw new BizException("码牌【" + list.get(0).getBindQrcId() + "】已绑定至其他云喇叭设备，请检查！");
		}
	}


	/** 批量添加收银插件激活码 */
	private ApiRes addPluginCdKey(MchStoreDevice mchStoreDevice, Integer num, String expiredTime) {
		mchStoreDevice.setState(CS.NO); // 默认待激活状态

		if (!"0".equals(expiredTime)) {
			expiredTime = DateUtil.formatDateTime(DateUtil.endOfDay(DateUtil.parseDate(expiredTime))); // 转为当前日期的 23:59:59
		}

		List<MchStoreDevice> list = new LinkedList<>();
		for (int i = 0; i < num; i++) {
			MchStoreDevice newRecord = new MchStoreDevice();
			BeanUtil.copyProperties(mchStoreDevice, newRecord);

			// 激活码参数
			PluginCdKeyParams cdKeyParams = new PluginCdKeyParams();
			cdKeyParams.setCdKey(SeqKit.genPluginCdKey());
			cdKeyParams.setExpiredTime(expiredTime);

			newRecord.setDeviceNo(cdKeyParams.getCdKey());
			newRecord.setDeviceParams(JSONObject.toJSONString(cdKeyParams));
			newRecord.setDeviceName(RandomUtil.randomString(4)); // 随机名称

			list.add(newRecord);
		}
		if (mchStoreDeviceService.saveBatch(list)) {
			return ApiRes.ok();
		}
		return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_CREATE);
	}

	/** 更新收银插件激活码 */
	private ApiRes updatePluginCdKey(MchStoreDevice mchStoreDevice, MchStoreDevice dbRecord, String expiredTime) {

		if (StringUtils.isNotBlank(expiredTime) && !"0".equals(expiredTime)) {
			expiredTime = DateUtil.formatDateTime(DateUtil.endOfDay(DateUtil.parseDate(expiredTime))); // 转为当前日期的 23:59:59
		}

		MchStoreDevice updatePluginCdKeyRecord = new MchStoreDevice();
		updatePluginCdKeyRecord.setDeviceId(dbRecord.getDeviceId());
		updatePluginCdKeyRecord.setDeviceName(mchStoreDevice.getDeviceName());
		updatePluginCdKeyRecord.setState(mchStoreDevice.getState());
		updatePluginCdKeyRecord.setConfigId(mchStoreDevice.getConfigId());

		PluginCdKeyParams cdKeyParams = JSONObject.parseObject(dbRecord.getDeviceParams(), PluginCdKeyParams.class);
		// 修改有效期
		if (StringUtils.isNotBlank(expiredTime)) {
			cdKeyParams.setExpiredTime(expiredTime);
			updatePluginCdKeyRecord.setDeviceParams(JSONObject.toJSONString(cdKeyParams));
		}

		// 解除激活
		if (mchStoreDevice.getState() != null && mchStoreDevice.getState() == CS.NO) {
			cdKeyParams.setDeActiveTime(DateUtil.now()); // 解除激活时间
			updatePluginCdKeyRecord.setDeviceParams(JSONObject.toJSONString(cdKeyParams));
		}

		if(!mchStoreDeviceService.updateById(updatePluginCdKeyRecord)) {
			return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_UPDATE);
		}
		return ApiRes.ok();
	}


}
