欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java?實(shí)現(xiàn)微信小程序不同人員生成不同小程序碼并追蹤掃碼來(lái)源(最新推薦)

 更新時(shí)間:2025年06月05日 08:58:02   作者:VipSoft  
這篇文章主要介紹了Java實(shí)現(xiàn)微信小程序不同人員生成不同小程序碼并追蹤掃碼來(lái)源,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧

下面我將詳細(xì)介紹如何使用Java后臺(tái)實(shí)現(xiàn)這一功能。

一、整體架構(gòu)設(shè)計(jì)

  • 前端:微信小程序
  • 后端:Java (Spring Boot)
  • 數(shù)據(jù)庫(kù):MySQL/其他
  • 微信接口:調(diào)用微信小程序碼生成API

二、數(shù)據(jù)庫(kù)設(shè)計(jì)

1. 推廣人員表(promoter)

CREATE TABLE `promoter` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL COMMENT '推廣人員姓名',
  `mobile` varchar(20) COMMENT '聯(lián)系電話',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

2. 用戶-推廣關(guān)系表(user_promoter_relation)

CREATE TABLE `user_promoter_relation` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `user_id` varchar(64) NOT NULL COMMENT '小程序用戶openid',
  `promoter_id` bigint NOT NULL COMMENT '推廣人員ID',
  `first_scan_time` datetime NOT NULL COMMENT '首次掃碼時(shí)間',
  `last_scan_time` datetime NOT NULL COMMENT '最近掃碼時(shí)間',
  `scan_count` int NOT NULL DEFAULT '1' COMMENT '掃碼次數(shù)',
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_user_promoter` (`user_id`,`promoter_id`),
  KEY `idx_promoter` (`promoter_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

三、Java后端實(shí)現(xiàn)

1. 添加微信小程序Java SDK依賴

<dependency>
    <groupId>com.github.binarywang</groupId>
    <artifactId>weixin-java-miniapp</artifactId>
    <version>4.1.0</version>
</dependency>

2. 配置微信小程序參數(shù)

@Configuration
public class WxMaConfiguration {
    @Value("${wx.miniapp.appid}")
    private String appid;
    @Value("${wx.miniapp.secret}")
    private String secret;
    @Bean
    public WxMaService wxMaService() {
        WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
        config.setAppid(appid);
        config.setSecret(secret);
        WxMaService service = new WxMaServiceImpl();
        service.setWxMaConfig(config);
        return service;
    }
}

3. 生成帶參數(shù)的小程序碼

@RestController
@RequestMapping("/api/qrcode")
public class QrCodeController {
    @Autowired
    private WxMaService wxMaService;
    @Autowired
    private PromoterService promoterService;
    /**
     * 生成推廣二維碼
     * @param promoterId 推廣人員ID
     * @return 二維碼圖片字節(jié)流
     */
    @GetMapping("/generate")
    public void generatePromoterQrCode(@RequestParam Long promoterId, 
                                     HttpServletResponse response) throws IOException {
        // 驗(yàn)證推廣人員是否存在
        Promoter promoter = promoterService.getById(promoterId);
        if (promoter == null) {
            throw new RuntimeException("推廣人員不存在");
        }
        // 生成小程序碼
        String scene = "promoterId=" + promoterId;
        WxMaQrcodeService qrcodeService = wxMaService.getQrcodeService();
        File qrCodeFile = qrcodeService.createWxaCodeUnlimit(scene, "pages/index/index", 430, true, null, false);
        // 返回圖片流
        response.setContentType("image/jpeg");
        try (InputStream in = new FileInputStream(qrCodeFile);
             OutputStream out = response.getOutputStream()) {
            byte[] buffer = new byte[1024];
            int len;
            while ((len = in.read(buffer)) != -1) {
                out.write(buffer, 0, len);
            }
        }
    }
}

4. 處理掃碼進(jìn)入事件

@RestController
@RequestMapping("/api/track")
public class TrackController {
    @Autowired
    private UserPromoterRelationService relationService;
    /**
     * 記錄用戶掃碼行為
     * @param dto 包含用戶信息和推廣信息
     * @return 操作結(jié)果
     */
    @PostMapping("/scan")
    public Result trackScan(@RequestBody ScanTrackDTO dto) {
        // 解析scene參數(shù)
        String scene = dto.getScene();
        Map<String, String> sceneParams = parseScene(scene);
        String promoterIdStr = sceneParams.get("promoterId");
        if (StringUtils.isBlank(promoterIdStr)) {
            return Result.fail("缺少推廣人員參數(shù)");
        }
        try {
            Long promoterId = Long.parseLong(promoterIdStr);
            relationService.recordUserScan(dto.getOpenid(), promoterId);
            return Result.success();
        } catch (NumberFormatException e) {
            return Result.fail("推廣人員參數(shù)格式錯(cuò)誤");
        }
    }
    private Map<String, String> parseScene(String scene) {
        Map<String, String> params = new HashMap<>();
        if (StringUtils.isBlank(scene)) {
            return params;
        }
        String[] pairs = scene.split("&");
        for (String pair : pairs) {
            String[] kv = pair.split("=");
            if (kv.length == 2) {
                params.put(kv[0], kv[1]);
            }
        }
        return params;
    }
}

5. 用戶-推廣關(guān)系服務(wù)

@Service
public class UserPromoterRelationServiceImpl implements UserPromoterRelationService {
    @Autowired
    private UserPromoterRelationMapper relationMapper;
    @Override
    @Transactional
    public void recordUserScan(String openid, Long promoterId) {
        // 查詢是否已有記錄
        UserPromoterRelation relation = relationMapper.selectByUserAndPromoter(openid, promoterId);
        Date now = new Date();
        if (relation == null) {
            // 新建關(guān)系記錄
            relation = new UserPromoterRelation();
            relation.setUserId(openid);
            relation.setPromoterId(promoterId);
            relation.setFirstScanTime(now);
            relation.setLastScanTime(now);
            relation.setScanCount(1);
            relationMapper.insert(relation);
        } else {
            // 更新已有記錄
            relation.setLastScanTime(now);
            relation.setScanCount(relation.getScanCount() + 1);
            relationMapper.updateById(relation);
        }
    }
}

四、小程序前端處理

在小程序的app.js中處理掃碼進(jìn)入的場(chǎng)景:

App({
  onLaunch: function(options) {
    // 處理掃碼進(jìn)入的情況
    if (options.scene === 1047 || options.scene === 1048 || options.scene === 1049) {
      // 這些scene值表示是通過(guò)掃碼進(jìn)入
      const scene = decodeURIComponent(options.query.scene);
      // 上報(bào)掃碼信息到后端
      wx.request({
        url: 'https://yourdomain.com/api/track/scan',
        method: 'POST',
        data: {
          scene: scene,
          openid: this.globalData.openid // 需要先獲取用戶openid
        },
        success: function(res) {
          console.log('掃碼記錄成功', res);
        }
      });
    }
  }
})

五、數(shù)據(jù)統(tǒng)計(jì)接口實(shí)現(xiàn)

@RestController
@RequestMapping("/api/stat")
public class StatController {
    @Autowired
    private UserPromoterRelationMapper relationMapper;
    /**
     * 獲取推廣人員業(yè)績(jī)統(tǒng)計(jì)
     * @param promoterId 推廣人員ID
     * @param startDate 開(kāi)始日期
     * @param endDate 結(jié)束日期
     * @return 統(tǒng)計(jì)結(jié)果
     */
    @GetMapping("/promoter")
    public Result getPromoterStats(@RequestParam Long promoterId,
                                 @RequestParam(required = false) @DateTimeFormat(pattern="yyyy-MM-dd") Date startDate,
                                 @RequestParam(required = false) @DateTimeFormat(pattern="yyyy-MM-dd") Date endDate) {
        // 構(gòu)建查詢條件
        QueryWrapper<UserPromoterRelation> query = new QueryWrapper<>();
        query.eq("promoter_id", promoterId);
        if (startDate != null) {
            query.ge("first_scan_time", startDate);
        }
        if (endDate != null) {
            query.le("first_scan_time", endDate);
        }
        // 執(zhí)行查詢
        int totalUsers = relationMapper.selectCount(query);
        List<Map<String, Object>> dailyStats = relationMapper.selectDailyStatsByPromoter(promoterId, startDate, endDate);
        // 返回結(jié)果
        Map<String, Object> result = new HashMap<>();
        result.put("totalUsers", totalUsers);
        result.put("dailyStats", dailyStats);
        return Result.success(result);
    }
}

六、安全注意事項(xiàng)

  • 參數(shù)校驗(yàn):所有傳入的promoterId需要驗(yàn)證是否存在
  • 防刷機(jī)制:限制同一用戶頻繁上報(bào)掃碼記錄
  • HTTPS:確保所有接口使用HTTPS協(xié)議
  • 權(quán)限控制:推廣數(shù)據(jù)統(tǒng)計(jì)接口需要添加權(quán)限驗(yàn)證
  • 日志記錄:記錄所有二維碼生成和掃碼行為

七、擴(kuò)展功能建議

  • 二級(jí)分銷:可以擴(kuò)展支持多級(jí)推廣關(guān)系
  • 獎(jiǎng)勵(lì)機(jī)制:根據(jù)掃碼用戶的活動(dòng)情況給推廣人員獎(jiǎng)勵(lì)
  • 實(shí)時(shí)通知:當(dāng)有新用戶掃碼時(shí),實(shí)時(shí)通知推廣人員
  • 數(shù)據(jù)分析:提供更詳細(xì)的數(shù)據(jù)分析報(bào)表

通過(guò)以上Java實(shí)現(xiàn),你可以完整地構(gòu)建一個(gè)支持不同人員生成不同小程序碼并能追蹤掃碼來(lái)源的系統(tǒng)。

到此這篇關(guān)于Java 實(shí)現(xiàn)微信小程序不同人員生成不同小程序碼并追蹤掃碼來(lái)源的文章就介紹到這了,更多相關(guān)Java 實(shí)現(xiàn)微信小程序不同人員生成不同小程序碼內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring @Async無(wú)法實(shí)現(xiàn)異步的解決方案

    Spring @Async無(wú)法實(shí)現(xiàn)異步的解決方案

    這篇文章主要介紹了Spring @Async無(wú)法實(shí)現(xiàn)異步的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • JVM創(chuàng)建對(duì)象及訪問(wèn)定位過(guò)程詳解

    JVM創(chuàng)建對(duì)象及訪問(wèn)定位過(guò)程詳解

    這篇文章主要介紹了JVM創(chuàng)建對(duì)象及訪問(wèn)定位過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-12-12
  • Mybatis一對(duì)多查詢列表屬性處理示例詳解

    Mybatis一對(duì)多查詢列表屬性處理示例詳解

    使用MyBatis進(jìn)行多表聯(lián)查的關(guān)鍵是構(gòu)建數(shù)據(jù)庫(kù)中表的字段和java中對(duì)象的屬性的映射關(guān)系,下面這篇文章主要給大家介紹了關(guān)于Mybatis一對(duì)多查詢列表屬性處理的相關(guān)資料,需要的朋友可以參考下
    2023-05-05
  • java實(shí)現(xiàn)ftp上傳 如何創(chuàng)建文件夾

    java實(shí)現(xiàn)ftp上傳 如何創(chuàng)建文件夾

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)ftp上傳的相關(guān)資料,教大家如何創(chuàng)建文件夾?具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • idea ssm項(xiàng)目java程序使用十六進(jìn)制rxtx包向串口發(fā)送指令的方法

    idea ssm項(xiàng)目java程序使用十六進(jìn)制rxtx包向串口發(fā)送指令的方法

    這篇文章主要介紹了idea ssm項(xiàng)目java程序向串口發(fā)送指令并且使用十六進(jìn)制 rxtx包,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-08-08
  • Java contains用法示例

    Java contains用法示例

    這篇文章主要介紹了Java contains的用法示例,幫助大家更好的理解和學(xué)習(xí)Java,感興趣的朋友可以了解下
    2020-11-11
  • java中JDBC實(shí)現(xiàn)往MySQL插入百萬(wàn)級(jí)數(shù)據(jù)的實(shí)例代碼

    java中JDBC實(shí)現(xiàn)往MySQL插入百萬(wàn)級(jí)數(shù)據(jù)的實(shí)例代碼

    這篇文章主要介紹了java中JDBC實(shí)現(xiàn)往MySQL插入百萬(wàn)級(jí)數(shù)據(jù)的實(shí)例代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2017-01-01
  • SpringBoot+fileUpload獲取文件上傳進(jìn)度

    SpringBoot+fileUpload獲取文件上傳進(jìn)度

    這篇文章主要為大家詳細(xì)介紹了SpringBoot+fileUpload獲取文件上傳進(jìn)度,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-08-08
  • Java中String類常用類型實(shí)例總結(jié)

    Java中String類常用類型實(shí)例總結(jié)

    在我們開(kāi)發(fā)中經(jīng)常會(huì)用到很多的常用的工具類,這里做一個(gè)總結(jié),下面這篇文章主要給大家介紹了關(guān)于Java中String類常用類型的相關(guān)資料,String類代表字符串,需要的朋友可以參考下
    2021-12-12
  • 淺析Java中的SPI原理

    淺析Java中的SPI原理

    SPI:由調(diào)用方制定接口標(biāo)準(zhǔn),實(shí)現(xiàn)方來(lái)針對(duì)接口提供不同的實(shí)現(xiàn),SPI其實(shí)就是"為接口查找實(shí)現(xiàn)"的一種服務(wù)發(fā)現(xiàn)機(jī)制。本文將淺談一下SPI機(jī)制的原理,需要的可以參考一下
    2022-09-09

最新評(píng)論