盲盒小程序开发

5/26/2023

就像最近很火的地摊盲盒。

讲真的,这之前我都不知道盲盒是啥。

前面有个粉丝让我开发盲盒小程序,为此我还去地摊上找摊位买了几个盲盒玩玩!

很好玩,很有意思。

然后我我去网上看了下,很多的公司都在推盲盒的app或者小程序。

例如网易的盲盒小程序,我一直在csdn更新文章,经常收到他们的盲盒小程序的通知。

1

下面是我开发的:

2

3

4

5

6

7

8

下面和大家简单的介绍下开发的这个小程序。有很多核心的地方,可能没办法公开。

目录

一,技术实现: (opens new window)

二,核心代码 (opens new window)

三,核心数据库 (opens new window)

四,市场定位: (opens new window)

五,小孟建议: (opens new window)

# 一,技术实现:

因为客户没有技术方面的要求,那就按照我习惯用的技术开发的,无所谓什么最新不最新技术了。

后台框架:SpringBoot,

数据库采用的Mysql,

后端的页面采用的Vue进行开发,

缓存用的Redis,

搜索引擎采用的是elasticsearch,

ORM层框架:MyBatis,

连接池:Druid,

分库分表:MyCat,

权限:SpringSecurity,

代码质量检查:sonar。

# 二,核心代码

@Controller
@RequestMapping("/addressInfo")
public class AddressInfoController extends BaseController {

    @Resource
    private AddressInfoService addressInfoService;

    @MustSetForOrderNoAnnotation
    @AuthenticationAnnotation
    @SetMenuAnnotation
    @RequestMapping("listPage")
    public ModelAndView listPage(ModelAndView modelAndView) {
        modelAndView.setViewName("addressInfo/list");
        return modelAndView;
    }

    @MustSetForOrderNoAnnotation
    @AuthenticationAnnotation
    @RequestMapping("addPage")
    public String addPage() {
        return "addressInfo/add";
    }

    @MustSetForOrderNoAnnotation
    @AuthenticationAnnotation
    @RequestMapping("editPage")
    public ModelAndView editPage(ModelAndView modelAndView, Long id) {
        modelAndView.addObject("id", id);
        modelAndView.setViewName("addressInfo/edit");
        return modelAndView;
    }

    @MustSetForOrderNoAnnotation
    @AuthenticationAnnotation
    @RequestMapping("/getList")
    @ResponseBody
    public ReturnDataForLayui getList(AddressInfo addressInfo) {
        addressInfo.setIsDeleted(PageBean.isDeletedNo);
        return addressInfoService.getList(addressInfo);
    }

    @MustSetForOrderNoAnnotation
    @AuthenticationAnnotation
    @RequestMapping("/add")
    @ResponseBody
    public ReturnData add(AddressInfo addressInfo) {
        return addressInfoService.add(addressInfo);
    }

    @MustSetForOrderNoAnnotation
    @AuthenticationAnnotation
    @RequestMapping("/update")
    @ResponseBody
    public ReturnData update(AddressInfo addressInfo) {
        return addressInfoService.update(addressInfo);
    }

    @MustSetForOrderNoAnnotation
    @AuthenticationAnnotation
    @RequestMapping("/updateDelete")
    @ResponseBody
    public ReturnData updateDelete(AddressInfo addressInfo) {
        addressInfo.setIsDeleted(PageBean.isDeletedYes);
        return addressInfoService.updateDelete(addressInfo);
    }

    @MustSetForOrderNoAnnotation
    @AuthenticationAnnotation
    @RequestMapping("/updateDeleteBatch")
    @ResponseBody
    public ReturnData updateDeleteBatch(String ids) {
        List<Long> idList = JSON.parseArray(ids, Long.class);
        return addressInfoService.updateDeleteBatch(idList);
    }
package com.cnewdream.controller;

import com.cnewdream.utils.ReturnData;
import com.cnewdream.utils.RedisUtils;

import javax.annotation.Resource;
import javax.servlet.ServletContext;
public class BaseController {

	@Resource
	protected ServletContext servletContext;
	@Resource
	protected RedisUtils redisUtils;

}
@RequestMapping("/blindBoxInfo")
public class BlindBoxInfoController extends BaseController {

    @Resource
    private BlindBoxInfoService blindBoxInfoService;

    @MustSetForOrderNoAnnotation
    @AuthenticationAnnotation
    @SetMenuAnnotation
    @RequestMapping("listPage")
    public ModelAndView listPage(ModelAndView modelAndView) {
        modelAndView.setViewName("blindBoxInfo/list");
        return modelAndView;
    }

    @MustSetForOrderNoAnnotation
    @AuthenticationAnnotation
    @RequestMapping("addPage")
    public String addPage() {
        return "blindBoxInfo/add";
    }

    @MustSetForOrderNoAnnotation
    @AuthenticationAnnotation
    @RequestMapping("editPage")
    public ModelAndView editPage(ModelAndView modelAndView, Long id) {
        modelAndView.addObject("id", id);
        modelAndView.setViewName("blindBoxInfo/edit");
        return modelAndView;
    }

    @MustSetForOrderNoAnnotation
    @AuthenticationAnnotation
    @RequestMapping("goodsLevelEditPage")
    public ModelAndView goodsLevelEditPage(ModelAndView modelAndView, Long id) {
        BlindBoxInfo blindBoxInfo = new BlindBoxInfo();
        blindBoxInfo.setId(id);
        ReturnDataForLayui list = blindBoxInfoService.getList(blindBoxInfo);
        ArrayList<BlindBoxInfo> blindBoxInfos = (ArrayList<BlindBoxInfo>) list.getData();
        BlindBoxInfo blindBoxInfoDb = blindBoxInfos.get(0);
        String goodsLevel = blindBoxInfoDb.getGoodsLevel();
        GoodsLevelInfo goodsLevelInfo = JSONUtils.json2pojo(goodsLevel, GoodsLevelInfo.class);
        if (goodsLevelInfo == null) {
            goodsLevelInfo = new GoodsLevelInfo();
        }
        goodsLevelInfo.setId(id);
        modelAndView.addObject("goodsLevelInfo", goodsLevelInfo);
        modelAndView.setViewName("blindBoxInfo/goodsLevelEdit");
        return modelAndView;
    }

    @MustSetForOrderNoAnnotation
    @AuthenticationAnnotation
    @RequestMapping("/getList")
    @ResponseBody
    public ReturnDataForLayui getList(BlindBoxInfo blindBoxInfo) {
        blindBoxInfo.setIsDeleted(PageBean.isDeletedNo);
        return blindBoxInfoService.getList(blindBoxInfo);
    }

    @MustSetForOrderNoAnnotation
    @AuthenticationAnnotation
    @RequestMapping("/add")
    @ResponseBody
    public ReturnData add(BlindBoxInfo blindBoxInfo) {
        return blindBoxInfoService.add(blindBoxInfo);
    }
@RequestMapping("/blindBoxInfo")
public class BlindBoxInfoController extends BaseController {

    @Resource
    private BlindBoxInfoService blindBoxInfoService;

    @MustSetForOrderNoAnnotation
    @AuthenticationAnnotation
    @SetMenuAnnotation
    @RequestMapping("listPage")
    public ModelAndView listPage(ModelAndView modelAndView) {
        modelAndView.setViewName("blindBoxInfo/list");
        return modelAndView;
    }

    @MustSetForOrderNoAnnotation
    @AuthenticationAnnotation
    @RequestMapping("addPage")
    public String addPage() {
        return "blindBoxInfo/add";
    }

    @MustSetForOrderNoAnnotation
    @AuthenticationAnnotation
    @RequestMapping("editPage")
    public ModelAndView editPage(ModelAndView modelAndView, Long id) {
        modelAndView.addObject("id", id);
        modelAndView.setViewName("blindBoxInfo/edit");
        return modelAndView;
    }

    @MustSetForOrderNoAnnotation
    @AuthenticationAnnotation
    @RequestMapping("goodsLevelEditPage")
    public ModelAndView goodsLevelEditPage(ModelAndView modelAndView, Long id) {
        BlindBoxInfo blindBoxInfo = new BlindBoxInfo();
        blindBoxInfo.setId(id);
        ReturnDataForLayui list = blindBoxInfoService.getList(blindBoxInfo);
        ArrayList<BlindBoxInfo> blindBoxInfos = (ArrayList<BlindBoxInfo>) list.getData();
        BlindBoxInfo blindBoxInfoDb = blindBoxInfos.get(0);
        String goodsLevel = blindBoxInfoDb.getGoodsLevel();
        GoodsLevelInfo goodsLevelInfo = JSONUtils.json2pojo(goodsLevel, GoodsLevelInfo.class);
        if (goodsLevelInfo == null) {
            goodsLevelInfo = new GoodsLevelInfo();
        }
        goodsLevelInfo.setId(id);
        modelAndView.addObject("goodsLevelInfo", goodsLevelInfo);
        modelAndView.setViewName("blindBoxInfo/goodsLevelEdit");
        return modelAndView;
    }

    @MustSetForOrderNoAnnotation
    @AuthenticationAnnotation
    @RequestMapping("/getList")
    @ResponseBody
    public ReturnDataForLayui getList(BlindBoxInfo blindBoxInfo) {
        blindBoxInfo.setIsDeleted(PageBean.isDeletedNo);
        return blindBoxInfoService.getList(blindBoxInfo);
    }

    @MustSetForOrderNoAnnotation
    @AuthenticationAnnotation
    @RequestMapping("/add")
    @ResponseBody
    public ReturnData add(BlindBoxInfo blindBoxInfo) {
        return blindBoxInfoService.add(blindBoxInfo);
    }
@Controller
@RequestMapping("/goodsInfo")
public class GoodsInfoController extends BaseController {

    @Resource
    private GoodsInfoService goodsInfoService;

    @MustSetForOrderNoAnnotation
    @AuthenticationAnnotation
    @SetMenuAnnotation
    @RequestMapping("listPage")
    public ModelAndView listPage(ModelAndView modelAndView, Long blindId) {
        modelAndView.setViewName("goodsInfo/list");
        modelAndView.addObject("blindId", blindId);
        return modelAndView;
    }

    @MustSetForOrderNoAnnotation
    @AuthenticationAnnotation
    @RequestMapping("addPage")
    public ModelAndView addPage(ModelAndView modelAndView, Long blindId) {
        modelAndView.addObject("blindId", blindId);
        modelAndView.setViewName("goodsInfo/add");
        return modelAndView;
    }

    @MustSetForOrderNoAnnotation
    @AuthenticationAnnotation
    @RequestMapping("editPage")
    public ModelAndView editPage(ModelAndView modelAndView, Long id) {
        modelAndView.addObject("id", id);
        modelAndView.setViewName("goodsInfo/edit");
        return modelAndView;
    }

    @MustSetForOrderNoAnnotation
    @AuthenticationAnnotation
    @RequestMapping("/getList")
    @ResponseBody
    public ReturnDataForLayui getList(GoodsInfo goodsInfo) {
        goodsInfo.setIsDeleted(PageBean.isDeletedNo);
        return goodsInfoService.getList(goodsInfo);
    }

    @MustSetForOrderNoAnnotation
    @AuthenticationAnnotation
    @RequestMapping("/add")
    @ResponseBody
    public ReturnData add(GoodsInfo goodsInfo) {
        return goodsInfoService.add(goodsInfo);
    }

# 三,核心数据库

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for address_info
-- ----------------------------
DROP TABLE IF EXISTS `address_info`;
CREATE TABLE `address_info`  (
  `id` bigint(19) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `person_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '姓名',
  `phone` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '电话',
  `gender` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '性别',
  `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '地址',
  `user_id` bigint(19) NOT NULL COMMENT '用户',
  `is_deleted` char(5) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '是否删除',
  `gmt_create` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间',
  `gmt_update` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '收货地址信息' ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of address_info
-- ----------------------------
INSERT INTO `address_info` VALUES (1, 'zhy', '18034272031', '2', '河北省 衡水市', 1, '0', '2021-09-08 14:39:49', '2021-09-08 15:37:20');
INSERT INTO `address_info` VALUES (2, '张红雨', '18034272031', '2', '北京市 海淀区 中央电视台大楼对面 富尔大厦 3008', 1, '0', '2021-09-08 15:21:00', '2021-09-08 15:37:00');

-- ----------------------------
-- Table structure for blind_box_info
-- ----------------------------
DROP TABLE IF EXISTS `blind_box_info`;
CREATE TABLE `blind_box_info`  (
  `id` bigint(19) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '标题',
  `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '描述',
  `price` bigint(19) NOT NULL COMMENT '单价',
  `sort` int(9) NOT NULL COMMENT '排序',
  `is_on_sale` char(5) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '是否上架',
  `goods_level` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '概率',
  `is_deleted` char(5) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '是否删除',
  `gmt_create` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间',
  `gmt_update` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '盲盒信息' ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of blind_box_info
-- ----------------------------
INSERT INTO `blind_box_info` VALUES (1, '擎天柱重装上阵', '变形金刚变身“咔咔咔咔咔咔”', 1, 0, '1', '{\"id\":1,\"level1\":25,\"level2\":25,\"level3\":25,\"level4\":25}', '0', '2021-09-02 17:21:15', '2021-09-19 13:30:47');
INSERT INTO `blind_box_info` VALUES (2, '苹果iPhone纯享', '苹果手机笔记本平板主机耳机', 1, 0, '1', '{\"id\":2,\"level1\":0.01,\"level2\":0.01,\"level3\":0.01,\"level4\":99.97}', '0', '2021-09-02 17:35:39', '2021-09-19 13:30:48');
INSERT INTO `blind_box_info` VALUES (3, '燃烧生命吧!你的可能性是无限可能,无所不能', '概率所得限量真骨雕新品!', 11, 1, '1', '{\"id\":3,\"level1\":0.01,\"level2\":0.02,\"level3\":0.03,\"level4\":99.94}', '0', '2021-09-02 17:53:36', '2021-09-12 21:44:13');
INSERT INTO `blind_box_info` VALUES (4, '111', '111', 1100, 1, '1', '{\"id\":null,\"level1\":25,\"level2\":25,\"level3\":25,\"level4\":25}', '0', '2021-09-19 13:32:10', '2021-09-19 13:32:27');

-- ----------------------------
-- Table structure for file_upload_info
-- ----------------------------
DROP TABLE IF EXISTS `file_upload_info`;
CREATE TABLE `file_upload_info`  (
  `id` bigint(19) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '路径',
  `file_size` bigint(19) NULL DEFAULT NULL COMMENT '大小',
  `data_from` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '来源',
  `is_deleted` char(5) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '是否删除',
  `gmt_create` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间',
  `gmt_update` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 102 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '文件上传信息' ROW_FORMAT = Dynamic;

-- ----------------------------

# 四,市场定位:

要说什么市场最大?

老人要健康,女人要美丽,男人要赚钱!

客户目标客户就是女人,产品是化妆产品,而且是高端化妆产品。

9

我老婆经常用的化妆品,特意去某东上搜索了下,一小瓶化妆水就是一双球鞋的钱,我好心疼,nnd,我一双球鞋,已经穿7年了。看到销量我裂开了。

一个月过亿。

客户的这次选择的市场绝对是没有问题的,而且游戏很好玩。我原来玩过CF的抽奖游戏,不知道玩了多少轮。

所以客户给我说,他们第一轮要融资2000w,如果搞起来真的有戏。

化妆品的市场太大了。

对了,如果您要找我开发,我要声明以下:

我们对市场一点不感冒,我们只是开发!所以你找我开发,我不加入你的合伙,我只是开发,也不用给我画饼。给我开发的费用即可。

说白了,就想让我免费开发,隔三差五的总有人给我画饼,对不起,我胃最近不好,消化不了大饼。 10

不过创业的风险很大。我前面接了很多开发的活,在众多创业的产品中,只有一个人成功了

给一个留学生做的一个中文交友的网站。

天时、地利、人和,就突然火了,一年利润达到了500w。

其他的99%开发的产品,大部分都gg了。

有的产品的idea很好,市场也很好,但是推广需要极大的费用。一般人是玩不起的。

最惨的一个老板,我们给他开发了一个劳务市场的APP,市场巨大。老板满怀希望的砸了300w推广费,开发费用给我们砸了20w。

不幸的是,最后钱全打水漂了。

最后调查了很久的原因,让老板很郁闷:

农民工兄弟,一般不喜欢用app。如果使用的流程复杂,更不会用。而且推广需要不断的砸钱。

老板直接喷血……

# 五,小孟建议:

有好的idea,我们可以开发,但是,但是……

成功的产品需要运气,更需要资本的注入,需要快速占领。

阿里也过做社交软件,腾讯也做过电子商城,抖音很火,腾讯从微视到视频号………

成功的产品需要天时、地利、人和,缺一不可。

总的来说,产品够不够硬,只有投放到市场,让用户体验才是王道。至于其他的什么idea有时候就是扯淡。

我是小孟,分享各种项目经验和面试资料。

一起加油进步。

如果也想学习小程序的开发,我录制了一个详细的教程,关注下面公众号。回复:小程序实战

spring公众号