最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

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

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

二、數(shù)據(jù)庫設(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值表示是通過掃碼進(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 開始日期
     * @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)表

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

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

相關(guān)文章

  • java根據(jù)當(dāng)前時(shí)間獲取yyyy-MM-dd?HH:mm:ss標(biāo)準(zhǔn)格式的時(shí)間代碼示例

    java根據(jù)當(dāng)前時(shí)間獲取yyyy-MM-dd?HH:mm:ss標(biāo)準(zhǔn)格式的時(shí)間代碼示例

    在Java中可以使用java.time包中的LocalDateTime類和DateTimeFormatter類來獲取并格式化當(dāng)前時(shí)間為yyyy-MM-dd?HH:mm:ss的格式,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-10-10
  • Java算法設(shè)計(jì)與分析分治算法

    Java算法設(shè)計(jì)與分析分治算法

    這篇文章主要介紹了Java算法設(shè)計(jì)與分析分治算法,一般分治算法在正文中分解為兩個(gè)即以上的遞歸調(diào)用,并且子類問題一般是不想交的
    2022-07-07
  • Java獲取堆棧信息的三種方法小結(jié)

    Java獲取堆棧信息的三種方法小結(jié)

    在Java編程中,獲取堆棧信息對(duì)于調(diào)試和故障排除非常重要,Java提供了多種方式來獲取當(dāng)前線程的堆棧信息,下面就跟隨小編一起學(xué)習(xí)一下常用的三種吧
    2024-03-03
  • OpenFeign實(shí)現(xiàn)自定義Http請(qǐng)求頭

    OpenFeign實(shí)現(xiàn)自定義Http請(qǐng)求頭

    這篇文章主要介紹了OpenFeign實(shí)現(xiàn)自定義Http請(qǐng)求頭方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2026-03-03
  • Java并發(fā)包工具類CountDownLatch的應(yīng)用詳解

    Java并發(fā)包工具類CountDownLatch的應(yīng)用詳解

    CountDownLatch是Java并發(fā)包中非常實(shí)用的一個(gè)工具類,它可以幫助我們實(shí)現(xiàn)線程之間的同步和協(xié)作。本文主要介紹了CountDownLatch的應(yīng)用場(chǎng)景及最佳實(shí)踐,希望對(duì)大家有所幫助
    2023-04-04
  • Java常用的時(shí)間工具類實(shí)例

    Java常用的時(shí)間工具類實(shí)例

    這篇文章主要介紹了Java常用的時(shí)間工具類,結(jié)合具體實(shí)例形式分析了java日期時(shí)間的常用轉(zhuǎn)換、判斷、輸出相關(guān)操作技巧,需要的朋友可以參考下
    2017-06-06
  • JAVA讀取文本文件內(nèi)容實(shí)例代碼

    JAVA讀取文本文件內(nèi)容實(shí)例代碼

    這篇文章主要給大家介紹了關(guān)于JAVA讀取文本文件內(nèi)容的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • Mybatis實(shí)現(xiàn)自定義的typehandler三步曲

    Mybatis實(shí)現(xiàn)自定義的typehandler三步曲

    這篇文章主要介紹了Mybatis實(shí)現(xiàn)自定義的typehandler三步曲的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-07-07
  • 一篇文章帶你入門java方法

    一篇文章帶你入門java方法

    這篇文章主要介紹了java基礎(chǔ)之方法詳解,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java基礎(chǔ)的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-08-08
  • RocketMq 消息重試機(jī)制及死信隊(duì)列詳解

    RocketMq 消息重試機(jī)制及死信隊(duì)列詳解

    這篇文章主要為大家介紹了RocketMq 消息重試機(jī)制及死信隊(duì)列詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10

最新評(píng)論

南宁市| 漳州市| 界首市| 威远县| 宾阳县| 内黄县| 合川市| 临澧县| 黔西| 桂阳县| 淳安县| 青川县| 旌德县| 府谷县| 关岭| 和龙市| 巴塘县| 吴旗县| 普洱| 固阳县| 城步| 土默特右旗| 封丘县| 衡东县| 南靖县| 四子王旗| 苏州市| 扎兰屯市| 陈巴尔虎旗| 宁化县| 红桥区| 隆安县| 盐城市| 麻栗坡县| 荔浦县| 临沭县| 台南县| 台江县| 古蔺县| 平乡县| 中山市|