刘帅
2026-09-28 2914eea299ec5a1d6bfdf40b2743226ef9cbc5af
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package com.dsh.other.controller;
 
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dsh.other.entity.AppGuideBanner;
import com.dsh.other.entity.AppGuideConfig;
import com.dsh.other.entity.QrLink;
import com.dsh.other.enums.EnableStatusEnum;
import com.dsh.other.enums.QrLinkTypeEnum;
import com.dsh.other.mapper.AppGuideBannerMapper;
import com.dsh.other.mapper.AppGuideConfigMapper;
import com.dsh.other.mapper.QrLinkMapper;
import com.dsh.other.util.ResultUtil;
import com.dsh.other.util.TokenUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
 
import javax.annotation.Resource;
import java.util.*;
 
/** 对外下载引导页与 App 扫码解析接口。 */
@RestController
@Api(tags = "APP下载引导与场地二维码")
public class AppGuideController {
    @Autowired private AppGuideConfigMapper appGuideConfigMapper;
    @Autowired private AppGuideBannerMapper appGuideBannerMapper;
    @Autowired private QrLinkMapper qrLinkMapper;
    @Autowired private TokenUtil tokenUtil;
 
//    @GetMapping("/q/{shortCode}")
//    public void guidePage(@PathVariable String shortCode, HttpServletRequest request,
//                          HttpServletResponse response) throws IOException {
//        // 仅重定向到静态 H5;避免 String 被 MVC 当作视图名并触发 LocaleResolver。
//        String code = shortCode.replaceAll("[^A-Za-z0-9]", "");
//        response.sendRedirect(request.getContextPath() + "/app-guide.html?code=" + code);
//    }
 
    @RequestMapping("/public/app-guide/config")
    @ApiOperation("获取下载引导页配置(无需登录)")
    public ResultUtil<Map<String, Object>> guideConfig(String code) {
        AppGuideConfig config = appGuideConfigMapper.selectOne(new QueryWrapper<AppGuideConfig>()
                .eq("enabled", EnableStatusEnum.ENABLED.getCode()).orderByDesc("updateTime").last("limit 1"));
        if (config == null) return ResultUtil.error("下载引导页尚未配置");
        QrLink link = validLink(code);
        if (code != null && !code.isEmpty() && link == null) return ResultUtil.error("二维码无效或已失效");
        Map<String, Object> data = new HashMap<>();
        data.put("appName", StringUtils.isNotBlank(config.getAppName()) ? config.getAppName() : "玩湃生活");
        data.put("androidPackage", StringUtils.isNotBlank(config.getAndroidPackage()) ? config.getAndroidPackage() : "com.sinata.wepark");
        data.put("iosPackage", StringUtils.isNotBlank(config.getIosPackage()) ? config.getIosPackage() : "com.sinata.WeParkLife");
        data.put("iosStoreUrl", config.getIosStoreUrl());
        data.put("apkUrl", config.getApkUrl());
        data.put("androidDeepLink", config.getAndroidDeepLink() + (StringUtils.isNotBlank(code) ? "?route=" + code : ""));
        data.put("iosDeepLink", "weparklife://app" + (StringUtils.isNotBlank(code) ? "?code=" + code : ""));
        data.put("banners", appGuideBannerMapper.selectList(new QueryWrapper<AppGuideBanner>()
                .eq("enabled", EnableStatusEnum.ENABLED.getCode()).orderByAsc("sort").orderByDesc("id")));
//        if (link != null) data.put("target", target(link));
        return ResultUtil.success(data);
    }
 
    @RequestMapping("/api/qr/resolve")
    @ApiOperation("App扫码解析二维码")
    public ResultUtil<Map<String, Object>> resolve(String code) {
        QrLink link = validLink(code);
        if (link == null) return ResultUtil.error("二维码无效或已失效");
        return ResultUtil.success(target(link));
    }
 
    private QrLink validLink(String code) {
        if (code == null || !code.matches("[A-Za-z0-9]{6,32}")) return null;
        QrLink link = qrLinkMapper.selectOne(new QueryWrapper<QrLink>().eq("shortCode", code).last("limit 1"));
        if (link == null || !Integer.valueOf(1).equals(link.getEnabled())
                || (link.getExpiresAt() != null && link.getExpiresAt().before(new Date()))) return null;
        return link;
    }
 
    private Map<String, Object> target(QrLink link) {
        Map<String, Object> target = new HashMap<>();
        target.put("pageName", link.getPageName());
        Map<String, Object> params = new HashMap<>();
        params.put("id", link.getSiteId().toString());
        target.put("params", JSON.toJSONString(params));
        return target;
    }
 
    private Object parseJson(String text) {
        if (text == null || text.trim().isEmpty()) return Collections.emptyMap();
        try { return JSON.parseObject(text); } catch (Exception ignored) { return Collections.emptyMap(); }
    }
}