【小西】优化生日品同步网易严选功能,使其支持多SPU对多SKU关系

news2024/11/17 4:24:33

目录

  • 前言
  • 思路
  • 代码实现
    • 实体ThemeActivityGift:spuId由 String类型变为JSONArray
    • ThemeActivityGiftServiceImpl改造
      • handleYxGiftByOperation:保存的是严选的生日品
      • checkSpuIds:校验SPU有效性
      • checkSpuIdExist:校验单个spuId是否存在
      • checkSkuIds:校验SKUs的有效性
      • checkSkuIdExist:校验单个SKU ID是否存在
      • checkNoRepeatValue:判断是否有重复的值

前言

业务需求如下:
在这里插入图片描述
内心觉得这个需求写的真“棒”,我花了好长时间才理解清楚,这需求的写法对刚加入进来项目的新人一点都不友好。唉,而且这个需求它写出来都有错(改善点中应该是SPUID而不是SKUID),所以啊工作中还是要多交流,不然呵呵 ,被带偏绝对跑不了,增加开发难度,唉

思路

首先:理解业务需求:
现状:上架网易严选生日品的功能中SPU名称不支持输入多个值,SPU名称和SKU列表是一对多关系。需加入多SPU对多SKU的场景。

重点:从一个开发者角度考虑的场景,这个思路清晰了可帮助我们自测代码,减少BUG。

我觉得场景可以分以下四种情况:
第一种:输入正确的SPU和SKU

1、单SPU+单SKU通过
2、单SPU+多SKU通过
3、多SPU+多SKU通过

第二种:输入错误的SPU和SKU

1、单SPU+单SKU不通过
2、单SPU+多SKU不通过
3、多SPU+多SKU不通过

第三种:添加是正确的但不是网易严选的SPU 不通过

第四种:重复插入的SPU 不通过

重点考虑多SPU+多SKU 的校验场景,我的想法为:验证SKU的模块中,只要所有的sku去遍历spu,只要校验通过其中一个spu,就算校验成功。

举例如下:
商品A和B的SPU和SKU如下所示:

ASPU:10018002 SKU :10019005
BSPU:1273186784766128130 SKU:1273186784774516738,1273186784778711042

现在在前端输入多SPU+多SKU,如下所示:

名称SPU列表和SKU列表
A+BSPU:10018002,1273186784766128130 SKU : 10019005,1273186784774516738,1273186784778711042

那么校验SKU时,只要SKU中的值和其中一个SPU校验通过,就算成功。

代码实现

实体ThemeActivityGift:spuId由 String类型变为JSONArray

    /**
     * 对接网易严选的spuName
     */
    private String spuName;
    /**
     * 对接网易严选的spuId(外键)
     */
	@TableField(typeHandler = JsonArrayTypeHandler.class, jdbcType = JdbcType.VARCHAR)
    private JSONArray spuIdArray;
    /**
     * 对接网易严选的skuIdArray(外键)
     */
    @TableField(typeHandler = JsonArrayTypeHandler.class, jdbcType = JdbcType.VARCHAR)
    private JSONArray skuIdArray;

ThemeActivityGiftServiceImpl改造

礼品新增功能访问的是如下方法:

    /**
     * @Description: 主题活动礼品新增
     */
    @Override
    public R saveGift(ThemeActivityGiftDTO themeActivityGiftDto) {
        //虚拟商品的积分值不能为空,请检查
        if (ObjectUtil.isNotNull(themeActivityGiftDto.getIsVirtual()) && themeActivityGiftDto.getIsVirtual().equals(WelfareBlessingVirtualEnum.IS_VIRTUAL.getValue())) {
            if (ObjectUtil.isNull(themeActivityGiftDto.getPointsValue())) {
                return R.failed("虚拟商品的积分值不能为空,请检查");
            }
        }
        //对9级的逻辑进行礼品价格层面的限制。
        //保存的是网易品
        if (StrUtil.isAllNotBlank(themeActivityGiftDto.getSpuIds(), themeActivityGiftDto.getSpuName(), themeActivityGiftDto.getSkuIds())) {
            Pair<Boolean, String> handleResult = handleYxGiftByOperation(themeActivityGiftDto, WelfareConst.OPERATION_CREATE);
            if (handleResult.getKey().equals(Boolean.FALSE)) {
                return R.failed(handleResult.getValue());
            }
            return R.ok();
        }
        ThemeActivityGift themeActivityGift = BeanUtil.copyProperties(themeActivityGiftDto, ThemeActivityGift.class);
        //保存的是主题活动
        if (themeActivityGift.getType().equals(ThemeActivityGiftTypeEnum.DEFAULT.getValue())) {
            if (StrUtil.hasBlank(themeActivityGiftDto.getSpec(), themeActivityGiftDto.getSpecValueString())) {
                return R.failed("请输入对应的规格以及规格值!");
            }
            String spec = themeActivityGiftDto.getSpec();
            String specValues = themeActivityGiftDto.getSpecValueString();
            themeActivityGift.setSpec(spec);
            themeActivityGift.setSpecValueArray(JSONUtil.parseArray(StrUtil.splitToArray(specValues, ThemeActivityConst.COMMA)));
        }
        themeActivityGift.setSpuName(null);
        themeActivityGift.setSpuIdArray(null);
        themeActivityGift.setSkuIdArray(null);
        return R.ok(baseMapper.insert(themeActivityGift));
    }

要对其中网易品实现方法handleYxGiftByOperation进行改造,重点改造checkSpuIds()和checkSkuIds()方法

handleYxGiftByOperation:保存的是严选的生日品

    /**
     * @Description: 保存的是严选的生日品
     */
    private Pair<Boolean, String> handleYxGiftByOperation(ThemeActivityGiftDTO themeActivityGiftDto, int operation) {
        String spuIds = themeActivityGiftDto.getSpuIds();
        String skuIds = themeActivityGiftDto.getSkuIds();
        Pair<Boolean, String> checkSpuIdFlag = checkSpuIds(themeActivityGiftDto, spuIds);

        Pair<Boolean, String> checkSkuIdFlag = checkSkuIds(spuIds, skuIds);
        if (Boolean.FALSE.equals(checkSpuIdFlag.getKey())) {
            return new Pair<>(Boolean.FALSE, checkSpuIdFlag.getValue());
        }
        if (Boolean.FALSE.equals(checkSkuIdFlag.getKey())) {
            return new Pair<>(Boolean.FALSE, checkSkuIdFlag.getValue());
        }
        ThemeActivityGift themeActivityGift = BeanUtil.copyProperties(themeActivityGiftDto, ThemeActivityGift.class);
		themeActivityGift.setSpuIdArray(JSONUtil.parseArray(StrUtil.splitToArray(spuIds, ThemeActivityConst.COMMA)));
        themeActivityGift.setSkuIdArray(JSONUtil.parseArray(StrUtil.splitToArray(skuIds, ThemeActivityConst.COMMA)));
        if (WelfareConst.OPERATION_CREATE == operation) {
            baseMapper.insert(themeActivityGift);
        } else {
            baseMapper.updateById(themeActivityGift);
        }
        return new Pair<>(Boolean.TRUE, null);
    }

checkSpuIds:校验SPU有效性

 /**
     * @Description: 校验SPU有效性
     */
    private Pair<Boolean, String> checkSpuIds(ThemeActivityGiftDTO themeActivityGiftDto, String spuIdArrays) {
        //兼容新建礼品时,没有giftId
        String giftId = ObjectUtil.isNotNull(themeActivityGiftDto.getId()) ? themeActivityGiftDto.getId() : "";
        if (StrUtil.isBlank(spuIdArrays)) {
            return new Pair<>(Boolean.FALSE, "spuIds不能为空,请检查");
        }
		//把string转化为数据库存储的数组形式来进行新增重复数据校验,如10018002,1273186784766128130 转化为["10018002,1273186784766128130"]
		spuIdArrays=spuIdArrays.replace(",", "\",\"");
		spuIdArrays="[\""+spuIdArrays+"\"]";
		//在更新礼品记录时,校验重复,不能与自身记录进行判断
		Wrapper<ThemeActivityGift> queryWrapper;
		if (StrUtil.isBlank(giftId)) {
			queryWrapper = Wrappers.<ThemeActivityGift>lambdaQuery()
					.eq(ThemeActivityGift::getSpuIdArray,spuIdArrays);
		} else {
			queryWrapper = Wrappers.<ThemeActivityGift>lambdaQuery()
					.eq(ThemeActivityGift::getSpuIdArray, spuIdArrays)
					.ne(ThemeActivityGift::getId, giftId);
		}
		ThemeActivityGift themeActivityGift = this.baseMapper.selectOne(queryWrapper);
		if (ObjectUtil.isNotNull(themeActivityGift)) {
			return new Pair<>(Boolean.FALSE, "该SpuId已与现有的礼品绑定,请检查");
		}
		//重复校验完后进行复原
		spuIdArrays=spuIdArrays.replace("\",\"",",");
		spuIdArrays=spuIdArrays.replace("[\"", "");
		spuIdArrays=spuIdArrays.replace("\"]", "");

		//多个SPU
		if (spuIdArrays.contains(ThemeActivityConst.COMMA)) {
			String[] spuIdArray = StrUtil.splitToArray(spuIdArrays, ThemeActivityConst.COMMA);
			if (!checkNoRepeatValue(spuIdArray)) {
				return new Pair<>(Boolean.FALSE, "检测到重复的spuId,请检查");
			}
			for (String spuId : spuIdArray) {
				if (!checkSpuIdExist(spuId)) {
					return new Pair<>(Boolean.FALSE, "校验单个SPU ID是否存在失败,spuId =" + spuId);
				}
			}
			return new Pair<>(Boolean.TRUE, null);
		}
		//单个SPU
		if (!checkSpuIdExist(spuIdArrays)) {
			return new Pair<>(Boolean.FALSE, "校验单个SPU ID是否存在失败, spuIdArrays =" + spuIdArrays);
		}
		return new Pair<>(Boolean.TRUE, null);
    }

checkSpuIdExist:校验单个spuId是否存在

	/**
	 * @Description: 校验单个spuId是否存在
	 */
	private boolean checkSpuIdExist(String spuId) {
		log.info("checkSpuIdExist spuId= 【{}】", spuId);
		GoodsSpu goodsSpu = goodsSpuService.getById(spuId);
		if (ObjectUtil.isNull(goodsSpu)) {
			log.info("获取GoodSpu异常,请检查");
			return  Boolean.FALSE;
		}
		if (!ProductChannelEnum.YANXUAN.getValue().equals(goodsSpu.getChannel())) {
			log.info("维护的SpuId并非网易严选的品,请检查");
			return  Boolean.FALSE;
		}
		return Boolean.TRUE;
	}

checkSkuIds:校验SKUs的有效性

    /**
     * @Description: 校验SKUs的有效性
     */
    private Pair<Boolean, String> checkSkuIds(String spuIds, String skuIdArrays) {
        if (StrUtil.isBlank(skuIdArrays)) {
            return new Pair<>(Boolean.FALSE, " SKU ID数组不能为空,请检查");
        }
        //多个SKU
        if (skuIdArrays.contains(ThemeActivityConst.COMMA)) {
            String[] skuIdArray = StrUtil.splitToArray(skuIdArrays, ThemeActivityConst.COMMA);
            if (!checkNoRepeatValue(skuIdArray)) {
                return new Pair<>(Boolean.FALSE, "检测到重复的skuId,请检查");
            }
            for (String skuId : skuIdArray) {
                if (!checkSkuIdExist(spuIds, skuId)) {
                    return new Pair<>(Boolean.FALSE, "获取GoodSku异常,校验单个SKU ID是否存在,skuId =" + skuId);
                }
            }
            return new Pair<>(Boolean.TRUE, null);
        }
        //单个SKU
        if (!checkSkuIdExist(spuIds, skuIdArrays)) {
            return new Pair<>(Boolean.FALSE, "获取GoodSku异常,校验单个SKU ID是否存在, skuIdArrays =" + skuIdArrays);
        }
        return new Pair<>(Boolean.TRUE, null);
    }

checkSkuIdExist:校验单个SKU ID是否存在

       /**
     * @Description: 校验单个SKU ID是否存在
     */
    private boolean checkSkuIdExist(String spuIds, String skuId) {
        log.info("checkSkuIdExist spuIds= 【{}】,skuId= 【{}】", spuIds, skuId);
        GoodsSku goodsSku = goodsSkuService.getById(skuId);
        if (ObjectUtil.isNull(goodsSku)) {
            log.error("checkSkuIdExist fail. goodsSku是空的!请检查!");
            return Boolean.FALSE;
        }
		//多SPU
		if (spuIds.contains(ThemeActivityConst.COMMA)) {
			String[] spuIdArray = StrUtil.splitToArray(spuIds, ThemeActivityConst.COMMA);
			boolean  checkSpuFlag=false;
			//检查多spu+多spu的情况,只要spu和其中一个sku对应上,就检验成功
			for (String  spuId : spuIdArray) {
				if (StrUtil.equals(spuId, goodsSku.getSpuId())) {
					checkSpuFlag=true;
				}
			}
			if (checkSpuFlag) {
				return Boolean.TRUE;
			}else{
				log.error("checkSkuIdExist fail. 添加的skuId必须是属于这个spu商品的!请检查!");
				return Boolean.FALSE;
			}
		} else{
			//单SPU
			if (!StrUtil.equals(spuIds, goodsSku.getSpuId())) {
				log.error("checkSkuIdExist fail. 添加的skuId必须是属于这个spu商品的!请检查!");
				return Boolean.FALSE;
			}
		}
        return Boolean.TRUE;
    }

checkNoRepeatValue:判断是否有重复的值

    /**
     * @Description: 判断是否有重复的值
     */
    public static boolean checkNoRepeatValue(String[] array) {
        HashSet<String> hashSet = new HashSet<>();
        for (int i = 0; i < array.length; i++) {
            hashSet.add(array[i]);
        }
        if (hashSet.size() == array.length) {
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/129000.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言函数栈帧的创建和销毁

前期学习的时候&#xff0c;我们可能有很多困惑&#xff0c;比如&#xff1a; 局部变量是怎么创建的&#xff1f; 为什么局部变量的值是随机值&#xff1f; 函数是怎么传参的&#xff1f;传参的顺序是怎样的&#xff1f; 形参和实参是什么关系&#xff1f; 函数调用是怎么…

分享丨品牌零售行业三大实践解读,全面搭建并落地数字化运营体系

以下内容来自神策数据创始人 & CEO 桑文锋关于数据驱动零售品牌业务增长的相关分享。点击文末“阅读原文”&#xff0c;了解神策品牌零售行业完整版解决方案。神策从 2020 年深入品牌零售领域&#xff0c;一路走来跌跌撞撞&#xff0c;不过思路越来越清晰&#xff0c;对该领…

Echarts:饼图默认高亮和选中(突出并高亮)/添加单击事件/X轴字符标签换行处理

饼图默认高亮: // 我这里实现的是饼图// 获取 this.sysfbChart this.$echarts.init(document.getElementById(sysfb))// 默认高亮第一个 // highlight:突出 this.sysfbChart.dispatchAction({type: highlight,seriesIndex: 0,dataIndex: 0}); 效果图: 饼图选中(突出并高亮):…

为什么自学 Python 看不进去?

如果刚开始学习python&#xff0c;没看懂&#xff0c;那就多看几次就会了。看不进去很正常&#xff0c;这个过程会很乏味&#xff0c;但是对于你建立牢固的编程思维是必须的。会有看不进去的这个阶段 python学习的秘诀在于对技术了解的广度和对数据结构研究的深度&#xff0c;不…

2022“易观之星”奖项公布,聚焦数字经济,助力数智创新

12月29日&#xff0c;“易观之星”颁奖典礼线上举办&#xff0c;重磅颁出2022“易观之星”奖项。 2022“易观之星”设置数字产品、数字企业2个系列共7大奖项&#xff0c;覆盖金融、品牌零售、汽车出行、文化消费等领域&#xff0c;挖掘和表彰各领域表现卓越的数字产品、数字企业…

【go语言之http模型reactor】

go语言之http模型reactor示例gnet.ServeinitListenerserveactivateEventLoopspolling前面说了go自带的原生netpoll模型&#xff0c;大致的流程就是每一个新的连接都会开启一个goroutine去处理&#xff0c;这样的处理的过程简单&#xff0c;高效&#xff0c;充分利用了go的底层的…

在 K8S 中测试环境中搭建 mongodb

1.可在服务器上面创建 https://kubernetes.io/docs/home/ #k8s官网 搜索Deployment 第一个就是例子 vi rs-mongodb.yaml apiVersion: apps/v1 kind: Deployment #资源类型 metadata:namespace: klvchenname: mongodblabels:app: mongodb spec:replicas: 1selector:mat…

STM32CubeMX学习笔记(50)——USB接口使用(DFU固件升级)

一、USB简介 USB&#xff08;Universal Serial BUS&#xff09;通用串行总线&#xff0c;是一个外部总线标准&#xff0c;用于规范电脑与外部设备的连接和通讯。是应用在 PC 领域的接口技术。USB 接口支持设备的即插即用和热插拔功能。USB 是在 1994 年底由英特尔、康柏、IBM、…

量子+智慧交通!玻色量子中标北京城市轨道交通项目

​2022年11月&#xff0c;玻色量子与北京交通大学国家重点实验室组成联合体&#xff0c;接受北京城市轨道交通咨询有限公司委托&#xff0c;三方共同探索和实施量子计算在智慧地铁中的应用场景研究工作。 北京城市轨道交通咨询有限公司 此次科研合作&#xff0c;玻色量子将充分…

IB学生申请牛津剑桥需要注意什么?

HL要选修3门颇具挑战性的课程&#xff0c;SL还要再选3门课程&#xff0c;写好IA&#xff0c;通过包括EE\CAS\TOK在内的3门核心科目&#xff0c;IB课程的学习压力确实挺大。。 对于志在牛剑这样顶尖高校的IB学生而言&#xff0c;压力更大&#xff0c;因为牛剑等顶尖高校对于IB小…

【JavaEE】在Linux上搭建一个Java部署环境

努力经营当下&#xff0c;直至未来明朗&#xff01; 文章目录在Linux上搭建一个Java部署环境1. 安装jdk2. 安装tomcat3. 安装mysql小结普通小孩也要热爱生活&#xff01; 在Linux上搭建一个Java部署环境 为了部署java web程序&#xff0c;需要安装&#xff1a;jdk、tomcat、m…

Pandas处理大数据的性能优化技巧

Pandas是Python中最著名的数据分析工具。在处理数据集时&#xff0c;每个人都会使用到它。但是随着数据大小的增加&#xff0c;执行某些操作的某些方法会比其他方法花费更长的时间。所以了解和使用更快的方法非常重要&#xff0c;特别是在大型数据集中&#xff0c;本文将介绍一…

百趣代谢组学文献分享:《Food Function》发表过的封面文章

百趣代谢组学今日分享西北大学食品科学与工程学院曹炜教授团队在食品科学领域国际著名学术期刊《Food& Function》上发表封面文章&#xff1a;Effects of honey-extracted polyphenols on serum antioxidant capacity and metabolic phenotype in rats。该研究在国际上首次…

Springboot定时调度任务动态管理

前言 现在智能手表、手环&#xff0c;相信很多人都使用过&#xff0c;其中有一个功能&#xff0c;就是会有各种的提醒&#xff0c;如喝水提醒、运动提醒、远眺提醒&#xff0c;本质上根据用户的设置&#xff0c;间隔一定时间执行一个调度任务&#xff0c;提醒用户做某件事情。这…

myBaits Expert Human Affinities Kit ——捕获人类样本中的 SNPs 信息,化石、法医样本和降解 DNA 样本均适用

myBaits Expert Human Affinities Kit用于人类基因组SNPs富集&#xff0c;该试剂盒与古人类种群遗传学领域的专家合作设计和开发&#xff0c;针对古代和现代人类种群中已知的2M以上多态位点设计&#xff0c;特异性捕获人类基因组文库中标志性的有效信息&#xff0c;提高人类种群…

ardupilot EKF3核心算法《可以使用的传感器》

目录 文章目录 目录摘要1.可以使用的传感器2.可以使用的传感器如果从代码中提供原始数据2.1 IMU传感器提供的有用数据2.2地磁传感器提供的有用数据2.3 GPS传感器提供的有用数据2.4 气压计传感器提供的有用数据摘要 本节主要讲解Ardupilot EKF3核心算法《可以使用的传感器》。 …

java租房app房东直租系统租房网站

简介 本系统是前后端分离的项目&#xff0c;前端使用mui开发科打包成为安卓的apk。后端采用springboot开发。主要是房东登录注册后&#xff0c;可以发布房源信息&#xff0c;可以上架下架编辑删除房源信息等&#xff0c;租房者可以搜索自己需要的房子&#xff0c;然后进入详情…

Maven基础知识

第1章 Maven 介绍 1.1 什么是 Maven 1.1.1 什么是 Maven Maven 的正确发音是[ˈmevən]&#xff0c;而不是“马瘟”以及其他什么瘟。Maven 在美国是一个口语化的词 语&#xff0c;代表专家、内行的意思。 一个对 Maven 比较正式的定义是这么说的&#xff1a;Maven 是一个项…

代码随想录算法训练营第二天 java : 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II ,

文章目录Leecode977.有序数组的平方题目链接题目暴力解法双指针解法小结Leecode209.长度最小的子数组。题目连接题目难点 &#xff1a;滑动窗口Leecode59.螺旋矩阵II题目链接题目思路用到的变量代码总结今日收获Leecode977.有序数组的平方 题目链接 题目 给你一个按 非递减顺…

攻防世界-shrine

题目 访问题目场景 这个界面很乱奥&#xff0c;我们访问网页源代码&#xff0c;我们就能看见我们需要审计的源码了 我们把python源码复制下来&#xff0c;进行分析 import flask import osapp flask.Flask(__name__)app.config[FLAG] os.environ.pop(FLAG)app.route(/) def…