记企业微信调用wx.getContent判断进入H5页面的入口环境

首先引用所需要的js文件

<!-- config -->
<script src="//res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<!-- agentConfig -->
<script type="text/javascript" src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js"></script>

获取config的配置信息,配置成功后在调用你所需要调用企业微信的接口

注意:如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。

调用agentConfig(注入的是应用的身份与权限)时要在config(注入的是企业的身份与权限)信息配置成功后在配置(注意:从企业微信3.0.24及以后版本(可通过企业微信UA判断版本号),无须先调用wx.config,可直接wx.agentConfig.)

wx.agentConfig({
          beta: true, // 必须这么写,否则wx.invoke调用形式的jsapi会有问题
          // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
          // debug: true,
          // 必填,企业微信的corpid,必须与当前登录的企业一致
          corpid: data.wx_corpid,
          // 必填,公众号的唯一标识
          agentid: data.wx_agentid,
          // 必填,生成签名的时间戳
          timestamp: data.sign.timestamp,
          // 必填,生成签名的随机串
          nonceStr: data.sign.nonceStr,
          // 必填,签名
          signature: data.sign.signature,
          // 必填,需要使用的JS接口列表,所有JS接口列表
          jsApiList: ["checkJsApi", "getContext", "getCurExternalContact"],
          success: function(res) {
            _this.checkJsApi()
          }
        })

 checkJsApi:当前客户端版本是否支持指定JS接口

wx.checkJsApi({
    jsApiList: ['chooseImage'], // 需要检测的JS接口列表
    success: function(res) {
        // 以键值对的形式返回,可用的api值true,不可用为false
        // 如:{"checkResult":{"chooseImage":true},"errMsg":"checkJsApi:ok"}
    }
});

成功后调用wx.getContext接口,获取进入的信息,通过wx.getCurExternalContact获取用户id获取数据,后面就根据业务逻辑写就好了

checkJsApi() {
      const _this = this
      wx.checkJsApi({
        jsApiList: [ "getContext", "getCurExternalContact"], // 需要检测的JS接口列表
        success: function (res) {
          // 以键值对的形式返回,可用的api值true,不可用为false
          // 如:{"checkResult":{"chooseImage":true},"errMsg":"checkJsApi:ok"}
          let obj = res.checkResult;
          wx.invoke('getContext', {}, function(res){
            if(res.err_msg == "getContext:ok"){
              // single_kf_tools  客服工具栏进入
              // entry  = res.entry ; //返回进入H5页面的入口类型,目前有normal、contact_profile、single_chat_tools、group_chat_tools、chat_attachment
              if (res.entry === 'single_kf_tools') {
                _this.getUserId()
              }
            }else {
              //错误处理
              _this.$toast('请从微信客服端进入!')
            }
          });
        },
      });
    },
    getUserId() {
      const _this = this
      wx.invoke('getCurExternalContact', {}, function(res){
        if (res.err_msg == "getCurExternalContact:ok") {
          _this.userId  = res.userId ; //返回当前外部联系人userId
          const params = {
            company_id: localStorage.getItem("company_id") || Cookies.get('company_id'),
            weixin_id: _this.userId
          }
          _this.getData(params)
        } else {
          //错误处理
          console.log('getCurExternalContact:err')
          // window.alert(res)
        }
      });
    }

 

<think>我们这里主要完成后台管理系统的后端部分(SpringBoot)和前端部分(Vue3)的代码。由于微信支付需要商户号等敏感信息,这里我们假设使用微信支付的SDK,并预留配置接口。项目结构:backend/#SpringBoot后端src/main/java/com/example/demo/controller/#控制器service/#服务层repository/#数据访问层entity/#实体类config/#配置类dto/#数据传输对象exception/#异常处理resources/application.propertiesfrontend/#Vue3前端(使用HBuilderX开发,可转为小程序)src/components/#组件pages/#页面store/#Vuex状态管理router/#路由(小程序不需要,但H5需要)App.vuemain.js由于篇幅限制,这里只给出关键代码。后端部分:1.实体类(Entity)扩展:增加会员和支付相关字段2.支付接口对接微信支付(使用官方SDK)3.后台管理接口:用户管理、解析录管理、会员管理、轮播图管理前端部分:1.首页:解析输入框和轮播图2.我的页面:用户信息展示、解析录、开通会员(跳转支付)开始编写代码:后端代码:1.实体类扩展```java//User.java增加会员相关字段@Entity@Table(name="users")publicclassUser{//...已有字段(id,username,password,registerTime,parseRecords)@Column(name="avatar_url")privateStringavatarUrl;//用户头像URL@Column(name="is_vip")privateBooleanisVip=false;//是否会员@Column(name="vip_expire_time")privateLocalDateTimevipExpireTime;//会员过期时间//省略getter/setter}//轮播图实体@Entity@Table(name="banners")publicclassBanner{@Id@GeneratedValue(strategy=GenerationType.IDENTITY)privateLongid;@Column(nullable=false)privateStringimageUrl;//图片地址@Column(nullable=false)privateStringlinkUrl;//点击跳转链接(可选)@Column(nullable=false)privateIntegersortOrder=0;//排序@Column(nullable=false)privateBooleanactive=true;//是否激活//gettersandsetters}```2.微信支付服务```java//WxPayService.java@ServicepublicclassWxPayService{//微信支付配置(从配置文件中读取)@Value("${wxpay.appId}")privateStringappId;@Value("${wxpay.mchId}")privateStringmchId;@Value("${wxpay.mchKey}")privateStringmchKey;@Value("${wxpay.notifyUrl}")privateStringnotifyUrl;//创建支付订单(统一下单)publicMap<String,String>createOrder(StringorderId,inttotalFee,Stringbody,Stringopenid)throwsException{WXPaywxpay=newWXPay(newWXPayConfig(){@OverridepublicStringgetAppID(){returnappId;}@OverridepublicStringgetMchID(){returnmchId;}@OverridepublicStringgetKey(){returnmchKey;}//其他配置方法(证书等)根据实际情况实现});Map<String,String>data=newHashMap<>();data.put("body",body);data.put("out_trade_no",orderId);data.put("device_info","WEB");data.put("fee_type","CNY");data.put("total_fee",String.valueOf(totalFee));data.put("spbill_create_ip","123.12.12.123");//实际应获取客户端IPdata.put("notify_url",notifyUrl);data.put("trade_type","JSAPI");//小程序支付data.put("openid",openid);Map<String,String>resp=wxpay.unifiedOrder(data);if("SUCCESS".equals(resp.get("return_code"))&&"SUCCESS".equals(resp.get("result_code"))){//生成小程序端需要的支付参数Map<String,String>result=newHashMap<>();result.put("appId",appId);result.put("timeStamp",String.valueOf(System.currentTimeMillis()/1000));result.put("nonceStr",resp.get("nonce_str"));result.put("package","prepay_id="+resp.get("prepay_id"));result.put("signType","MD5");//生成签名Stringsign=WXPayUtil.generateSignature(result,mchKey,SignType.MD5);result.put("paySign",sign);returnresult;}else{thrownewRuntimeException("微信支付下单失败:"+resp.get("return_msg"));}}//支付回调处理publicvoidprocessNotify(HttpServletRequestrequest,HttpServletResponseresponse)throwsException{//验证签名,处理订单//更新会员状态}}```3.控制器```java//PaymentController.java@RestController@RequestMapping("/api/payment")publicclassPaymentController{privatefinalWxPayServicewxPayService;privatefinalUserServiceuserService;publicPaymentController(WxPayServicewxPayService,UserServiceuserService){this.wxPayService=wxPayService;this.userService=userService;}@PostMapping("/create")publicResponseEntity<?>createPayment(@RequestBodyPaymentRequestrequest,@AuthenticationPrincipalUserDetailsuserDetails){//根据userDetails获取用户信息Useruser=userService.findByUsername(userDetails.getUsername());//生成订单号(示例)StringorderId="ORDER_"+System.currentTimeMillis();try{Map<String,String>payParams=wxPayService.createOrder(orderId,request.getAmount(),"会员开通",user.getWxOpenid()//实际开发中需要存储用户的openid);returnResponseEntity.ok(payParams);}catch(Exceptione){returnResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());}}//支付回调通知接口@PostMapping("/notify")publicvoidnotify(HttpServletRequestrequest,HttpServletResponseresponse){wxPayService.processNotify(request,response);}}//BannerController.java@RestController@RequestMapping("/api/banner")publicclassBannerController{privatefinalBannerRepositorybannerRepository;publicBannerController(BannerRepositorybannerRepository){this.bannerRepository=bannerRepository;}@GetMapping("/active")publicList<Banner>getActiveBanners(){returnbannerRepository.findByActiveTrueOrderBySortOrderAsc();}//后台管理接口(需要管理员权限)@PostMapping@PreAuthorize("hasRole('ADMIN')")publicBannercreateBanner(@RequestBodyBannerbanner){returnbannerRepository.save(banner);}}```4.前端页面Vue3)示例首页:index.vue```vue<template><div><!--轮播图--><swiper:indicator-dots="true":autoplay="true":interval="3000":duration="1000"><swiper-itemv-for="(item,index)inbanners":key="index"><image:src="item.imageUrl"mode="aspectFill"style="width:100%;height:300rpx;"/></swiper-item></swiper><!--解析输入框--><divclass="input-area"><inputv-model="url"placeholder="请输入视频链接"/><button@click="parse">解析</button></div></div></template><script>import{ref,onMounted}from'vue';import{getBanners}from'@/api/banner';exportdefault{setup(){constbanners=ref([]);consturl=ref('');onMounted(async()=>{banners.value=awaitgetBanners();});constparse=async()=>{//调用解析接口console.log('解析链接:',url.value);};return{banners,url,parse};}};</script>```我的页面:my.vue```vue<template><div><divclass="user-info"><img:src="user.avatarUrl"class="avatar"/><divclass="info"><p>用户ID:{{user.id}}</p><p>解析次数:{{user.parseCount}}</p><p>会员状态:{{user.isVip?'VIP会员':'普通用户'}}</p></div></div><buttonv-if="!user.isVip"@click="openVip">开通会员</button><divclass="records"><h3>解析录</h3><ul><liv-for="(record,index)inrecords":key="index">{{record.originalUrl}}-{{record.parseTime}}</li></ul></div></div></template><script>import{ref,onMounted}from'vue';import{getUserDetail,getParseRecords}from'@/api/user';import{createPayment}from'@/api/payment';exportdefault{setup(){constuser=ref({});constrecords=ref([]);onMounted(async()=>{//假设从全局状态获取用户IDconstuserId='123';user.value=awaitgetUserDetail(userId);records.value=awaitgetParseRecords(userId);});constopenVip=async()=>{//调用支付接口constres=awaitcreatePayment({amount:2990,//单位分});//使用微信支付wx.requestPayment({...res,success:()=>{//支付成功,更新会员状态user.value.isVip=true;},fail:(err)=>{console.error('支付失败',err);}});};return{user,records,openVip};}};</script>```由于实际开发中涉及较多细节,以上代码仅为关键部分示例。注意事项:1.微信支付需要配置商户号和密钥,并在微信商户平台设置回调地址。2.用户openid需要通过微信小程序登录获取,并存储在用户表中。3.支付回调需要验证签名和更新订单状态,同时开通会员(设置vip_expire_time)。项目完整结构需要包含:-后端:实体、仓库、服务、控制器、配置、安全等。-前端:页面、组件、状态管理、路由(可选)、API封装等。由于代码量较大,无法在此全部展示,以上为核心代码示例。§§相关问题§§:1.在微信支付回调处理中,如何保证数据的安全性和一致性?2.如何设计会员系统的到期自动取消功能?3.在前端轮播图管理中,如何实现图片上传和存储?4.如何优化解析录的分页查询性能?</think>下面是一个完整的去水印小程序后台管理系统实现方案,包含Spring Boot后端和Vue3前端(HBuilderX可转换小程序版本): ### 后端实现 (Spring Boot) #### 项目结构 ``` src/ ├── main/ │ ├── java/com/watermark/ │ │ ├── config/ # 配置类 │ │ ├── controller/ # 控制器 │ │ ├── entity/ # 实体类 │ │ ├── repository/ # 数据访问层 │ │ ├── service/ # 服务层 │ │ ├── util/ # 工具类 │ │ └── Application.java │ ├── resources/ │ │ ├── application.yml │ │ └── wxpay/ # 微信支付证书 └── test/... ``` #### 核心代码 1. **实体类 (Entity)** ```java // User.java @Entity @Table(name = "users") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(unique = true, nullable = false) private String openid; // 微信openid @Column(nullable = false) private String nickname; private String avatar; // 头像URL @Column(name = "register_time", nullable = false) private LocalDateTime registerTime; @Column(name = "is_vip", nullable = false) private Boolean isVip = false; @Column(name = "vip_expire") private LocalDateTime vipExpire; // Getters & Setters } // ParseRecord.java @Entity @Table(name = "parse_records") public class ParseRecord { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToOne @JoinColumn(name = "user_id", nullable = false) private User user; @Column(name = "original_url", nullable = false, length = 1000) private String originalUrl; @Column(name = "result_url", length = 1000) private String resultUrl; @Column(name = "parse_time", nullable = false) private LocalDateTime parseTime; // Getters & Setters } // Banner.java @Entity @Table(name = "banners") public class Banner { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(nullable = false) private String imageUrl; @Column private String linkUrl; @Column(nullable = false) private Integer sortOrder = 0; @Column(nullable = false) private Boolean active = true; // Getters & Setters } // PaymentOrder.java @Entity @Table(name = "payment_orders") public class PaymentOrder { @Id private String orderId; // 商户订单号 @ManyToOne @JoinColumn(name = "user_id", nullable = false) private User user; @Column(nullable = false) private Integer amount; // 金额(分) @Column(nullable = false) private String status = "CREATED"; // CREATED/SUCCESS/FAILED @Column(name = "create_time", nullable = false) private LocalDateTime createTime; @Column(name = "pay_time") private LocalDateTime payTime; // Getters & Setters } ``` 2. **微信支付服务** ```java // WxPayService.java @Service public class WxPayService { @Value("${wxpay.appId}") private String appId; @Value("${wxpay.mchId}") private String mchId; @Value("${wxpay.mchKey}") private String mchKey; @Value("${wxpay.notifyUrl}") private String notifyUrl; public Map<String, String> createOrder(User user, String productName, int amount) { String orderId = "ORDER" + System.currentTimeMillis() + new Random().nextInt(1000); Map<String, String> data = new HashMap<>(); data.put("appid", appId); data.put("mch_id", mchId); data.put("nonce_str", WxPayUtil.generateNonceStr()); data.put("body", productName); data.put("out_trade_no", orderId); data.put("total_fee", String.valueOf(amount)); data.put("spbill_create_ip", "用户IP"); data.put("notify_url", notifyUrl); data.put("trade_type", "JSAPI"); data.put("openid", user.getOpenid()); try { // 生成签名 String sign = WxPayUtil.generateSignature(data, mchKey); data.put("sign", sign); // 调用统一下单API String xmlResult = WxPayUtil.requestOnce("https://api.mch.weixin.qq.com/pay/unifiedorder", data); Map<String, String> result = WxPayUtil.xmlToMap(xmlResult); if ("SUCCESS".equals(result.get("return_code")) && "SUCCESS".equals(result.get("result_code"))) { // 返回小程序支付参数 Map<String, String> payParams = new HashMap<>(); payParams.put("appId", appId); payParams.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000)); payParams.put("nonceStr", WxPayUtil.generateNonceStr()); payParams.put("package", "prepay_id=" + result.get("prepay_id")); payParams.put("signType", "MD5"); payParams.put("paySign", WxPayUtil.generateSignature(payParams, mchKey)); return payParams; } } catch (Exception e) { throw new RuntimeException("微信支付下单失败", e); } throw new RuntimeException("微信支付下单失败"); } // 支付回调处理 public String handleNotify(HttpServletRequest request) { try { String xmlData = IOUtils.toString(request.getInputStream(), StandardCharsets.UTF_8); Map<String, String> data = WxPayUtil.xmlToMap(xmlData); if (WxPayUtil.isSignatureValid(data, mchKey)) { if ("SUCCESS".equals(data.get("result_code"))) { // 更新订单状态 paymentOrderService.updateOrderStatus( data.get("out_trade_no"), "SUCCESS", LocalDateTime.now() ); // 更新用户VIP状态 userService.activateVip(data.get("out_trade_no")); return "<xml><return_code><![CDATA[SUCCESS]]></return_code></xml>"; } } } catch (Exception e) { // 处理异常 } return "<xml><return_code><![CDATA[FAIL]]></return_code></xml>"; } } ``` 3. **控制器** ```java // ParseController.java @RestController @RequestMapping("/api/parse") public class ParseController { @PostMapping("/process") public ResponseEntity<ParseResult> processUrl(@RequestBody ParseRequest request) { // 解析逻辑 ParseResult result = parseService.processUrl(request.getUrl(), request.getUserId()); return ResponseEntity.ok(result); } @GetMapping("/history/{userId}") public ResponseEntity<List<ParseRecord>> getHistory( @PathVariable Long userId, @RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "10") int size) { Page<ParseRecord> records = parseService.getUserRecords(userId, PageRequest.of(page, size)); return ResponseEntity.ok(records.getContent()); } } // PaymentController.java @RestController @RequestMapping("/api/payment") public class PaymentController { @PostMapping("/create") public ResponseEntity<Map<String, String>> createVipOrder(@RequestBody PaymentRequest request) { User user = userService.getUserById(request.getUserId()); Map<String, String> payParams = wxPayService.createOrder( user, "VIP会员", request.getAmount() ); return ResponseEntity.ok(payParams); } @PostMapping("/notify") public String paymentNotify(HttpServletRequest request) { return wxPayService.handleNotify(request); } } // BannerController.java @RestController @RequestMapping("/api/banner") public class BannerController { @GetMapping("/active") public ResponseEntity<List<Banner>> getActiveBanners() { return ResponseEntity.ok(bannerService.getActiveBanners()); } @PostMapping @PreAuthorize("hasRole('ADMIN')") public ResponseEntity<Banner> createBanner(@RequestBody Banner banner) { return ResponseEntity.ok(bannerService.saveBanner(banner)); } } ``` ### 前端实现 (Vue3 + HBuilderX) #### 项目结构 ``` src/ ├── components/ │ ├── UrlParser.vue │ ├── BannerSwiper.vue │ └── VipCard.vue ├── pages/ │ ├── Home.vue │ ├── My.vue │ └── History.vue ├── store/ │ ├── index.js │ └── user.js ├── api/ │ ├── parse.js │ ├── user.js │ ├── payment.js │ └── banner.js ├── App.vue └── main.js ``` #### 核心页面 1. **首页 (Home.vue)** ```vue <template> <div class="home"> <!-- 轮播图 --> <BannerSwiper :banners="banners" /> <!-- 解析区域 --> <UrlParser @parse="handleParse" /> <!-- VIP开通提示 --> <VipCard v-if="!user.isVip" @click="goToVip" /> </div> </template> <script> import { ref, onMounted } from 'vue'; import { useStore } from 'vuex'; import { getActiveBanners } from '@/api/banner'; import BannerSwiper from '@/components/BannerSwiper.vue'; import UrlParser from '@/components/UrlParser.vue'; import VipCard from '@/components/VipCard.vue'; export default { components: { BannerSwiper, UrlParser, VipCard }, setup() { const store = useStore(); const banners = ref([]); const user = ref(store.state.user); onMounted(async () => { banners.value = await getActiveBanners(); }); const handleParse = async (url) => { const result = await parseUrl(url); // 处理解析结果 }; const goToVip = () => { // 跳转到VIP开通页面 }; return { banners, user, handleParse, goToVip }; } }; </script> ``` 2. **用户中心 (My.vue)** ```vue <template> <div class="my-page"> <div class="user-card"> <img :src="user.avatar" class="avatar" /> <div class="user-info"> <h3>{{ user.nickname }}</h3> <p>用户ID: {{ user.id }}</p> <p>解析次数: {{ user.parseCount }}</p> <p v-if="user.isVip">VIP会员 (有效期至: {{ formatDate(user.vipExpire) }})</p> <p v-else>普通用户</p> </div> </div> <div class="actions"> <button @click="goToHistory">解析录</button> <button v-if="!user.isVip" @click="openVip">开通会员</button> </div> </div> </template> <script> import { ref } from 'vue'; import { useStore } from 'vuex'; import { getUserDetail } from '@/api/user'; import { formatDate } from '@/utils/date'; export default { setup() { const store = useStore(); const user = ref(store.state.user); // 获取用户详情 const fetchUserDetail = async () => { const detail = await getUserDetail(user.value.id); user.value = { ...user.value, ...detail }; store.commit('setUser', user.value); }; const openVip = async () => { // 调用支付接口 const paymentParams = await createVipOrder(29900); // 299元 // 调用微信支付 uni.requestPayment({ ...paymentParams, success: () => { // 支付成功,更新用户状态 fetchUserDetail(); }, fail: (err) => { console.error('支付失败', err); } }); }; const goToHistory = () => { uni.navigateTo({ url: '/pages/History' }); }; return { user, formatDate, openVip, goToHistory }; } }; </script> ``` 3. **微信支付工具类 (wxpay.js)** ```javascript import { createVipOrder } from '@/api/payment'; export const wxPay = { payForVip: async (amount) => { try { const paymentParams = await createVipOrder(amount); return new Promise((resolve, reject) => { uni.requestPayment({ ...paymentParams, success: resolve, fail: reject }); }); } catch (error) { console.error('支付创建失败', error); throw error; } } }; ``` ### 后台管理系统功能 1. **用户管理** - 用户ID、昵称、头像 - 注册时间 - VIP状态及有效期 - 解析次数统计 2. **解析录** - 原始URL - 解析结果URL - 解析时间 - 关联用户 3. **VIP管理** - 微信支付对接 - 会员状态管理 - 支付订单跟踪 4. **轮播图管理** - 图片上传 - 链接配置 - 排序控制 - 激活状态 ### 部署配置 1. **微信支付配置 (application.yml)** ```yml wxpay: appId: wx1234567890abcdef # 小程序APPID mchId: 1234567890 # 商户号 mchKey: your_mch_key # 商户API密钥 notifyUrl: https://yourdomain.com/api/payment/notify ``` 2. **数据库配置** ```sql CREATE TABLE users ( id BIGINT AUTO_INCREMENT PRIMARY KEY, openid VARCHAR(100) NOT NULL UNIQUE, nickname VARCHAR(100) NOT NULL, avatar VARCHAR(500), register_time DATETIME NOT NULL, is_vip BOOLEAN DEFAULT false, vip_expire DATETIME ); CREATE TABLE parse_records ( id BIGINT AUTO_INCREMENT PRIMARY KEY, user_id BIGINT NOT NULL, original_url VARCHAR(1000) NOT NULL, result_url VARCHAR(1000), parse_time DATETIME NOT NULL, FOREIGN KEY (user_id) REFERENCES users(id) ); CREATE TABLE banners ( id BIGINT AUTO_INCREMENT PRIMARY KEY, image_url VARCHAR(500) NOT NULL, link_url VARCHAR(500), sort_order INT DEFAULT 0, active BOOLEAN DEFAULT true ); CREATE TABLE payment_orders ( order_id VARCHAR(50) PRIMARY KEY, user_id BIGINT NOT NULL, amount INT NOT NULL, status VARCHAR(20) DEFAULT 'CREATED', create_time DATETIME NOT NULL, pay_time DATETIME, FOREIGN KEY (user_id) REFERENCES users(id) ); ``` ### 前端转小程序说明 1. 使用HBuilderX的"发行->小程序"功能 2. 配置小程序APPID 3. 替换微信支付相关API调用 4. 调整UI组件适应小程序规范
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值