十一、配置内网穿透实现消息模块和授权登陆模块

news2024/11/17 12:58:12

开通内网穿透的服务(后端8333,前端8080):

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DdLILnd3-1684737630542)(/upload/2022/08/image-1659578045294.png)]

启动内网穿透服务:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6i0x51Vz-1684737630543)(/upload/2022/08/image-1659578128085.png)]

创建CourseApiController来实现关键词查询课程信息:

package com.lxl.ggkt.vod.api;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lxl.ggkt.model.vod.Course;
import com.lxl.ggkt.result.Result;
import com.lxl.ggkt.vo.vod.CourseQueryVo;
import com.lxl.ggkt.vo.vod.CourseVo;
import com.lxl.ggkt.vod.service.CourseService;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
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 javax.management.Query;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping(value = "/api/vod/course")
public class CourseApiController {

    @Autowired
    private CourseService courseService;

    //根据课程id查询课程信息
    @ApiOperation("根据ID查询课程")
    @GetMapping("inner/getById/{courseId}")
    public Course getById(
            @ApiParam(value = "课程ID", required = true)
            @PathVariable Long courseId){
        Course course = courseService.getById(courseId);
        return course;
    }

    //根据课程分类查询课程列表(分页)
    @ApiOperation("根据课程分类查询课程列表")
    @GetMapping("{subjectParentId}/{page}/{limit}")
    public Result findPageCourse(@ApiParam(value = "课程一级分类ID", required = true) @PathVariable Long subjectParentId,
                                 @ApiParam(name = "page", value = "当前页码", required = true) @PathVariable Long page,
                                 @ApiParam(name = "limit", value = "每页记录数", required = true) @PathVariable Long limit){
        
        //封装条件
        CourseQueryVo courseQueryVo = new CourseQueryVo();
        courseQueryVo.setSubjectParentId(subjectParentId);
        
        //创建page对象
        Page<Course> pageParam = new Page<>(page, limit);
        Map<String,Object> map = courseService.findPage(pageParam,courseQueryVo);
        return Result.ok(map);
    }

    //根据课程id查询课程详情
    @ApiOperation("根据课程id查询课程详情")
    @GetMapping("getInfo/{courseId}")
    public Result getInfo(@PathVariable Long courseId){
        Map<String,Object> map = courseService.getInfoById(courseId);
        return Result.ok(map);
    }

    @ApiOperation("根据关键字查询课程")
    @GetMapping("inner/findByKeyword/{keyword}")
    public List<Course> findByKeyword(
            @ApiParam(value = "关键词",required = true)
            @PathVariable String keyword){
        QueryWrapper<Course> wrapper = new QueryWrapper<>();
        wrapper.like("title",keyword);
        List<Course> list = courseService.list(wrapper);
        return list;
    }
}

公众号消息接收和相关业务模块设计:

MessageController:

package com.lxl.ggkt.wechat.controller;

import com.alibaba.fastjson.JSONObject;
import com.lxl.ggkt.result.Result;
import com.lxl.ggkt.wechat.service.MessageService;
import com.lxl.ggkt.wechat.utils.SHA1;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.InputStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/wechat/message")
public class MessageController {

    private static final String token = "ggkt";

    @Autowired
    private MessageService messageService;

    @GetMapping("/pushPayMessage")
    public Result pushPayMessage() throws WxErrorException {
        messageService.pushPayMessage(1L);
        return Result.ok(null);
    }
    
    /**
     * 服务器有效性验证
     * @param request
     * @return
     */
    @GetMapping
    public String verifyToken(HttpServletRequest request) {
        String signature = request.getParameter("signature");
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        String echostr = request.getParameter("echostr");
        //log.info("signature: {} nonce: {} echostr: {} timestamp: {}", signature, nonce, echostr, timestamp);
        if (this.checkSignature(signature, timestamp, nonce)) {
           // log.info("token ok");
            return echostr;
        }
        return echostr;
    }

    private boolean checkSignature(String signature, String timestamp, String nonce) {
        String[] str = new String[]{token, timestamp, nonce};
        //排序
        Arrays.sort(str);
        //拼接字符串
        StringBuffer buffer = new StringBuffer();
        for (int i = 0; i < str.length; i++) {
            buffer.append(str[i]);
        }
        //进行sha1加密
        String temp = SHA1.encode(buffer.toString());
        //与微信提供的signature进行匹对
        return signature.equals(temp);
    }

    /**
     * 接收微信服务器发送来的消息
     * @param request
     * @return
     * @throws Exception
     */
    @PostMapping
    public String receiveMessage(HttpServletRequest request) throws Exception {

//        WxMpXmlMessage wxMpXmlMessage = WxMpXmlMessage.fromXml(request.getInputStream());
//        System.out.println(JSONObject.toJSONString(wxMpXmlMessage));

        Map<String, String> param = this.parseXml(request);
        String message = messageService.receiveMessage(param);
        return message;
    }

    private Map<String, String> parseXml(HttpServletRequest request) throws Exception {
        Map<String, String> map = new HashMap<String, String>();
        InputStream inputStream = request.getInputStream();
        SAXReader reader = new SAXReader();
        Document document = reader.read(inputStream);
        Element root = document.getRootElement();
        List<Element> elementList = root.elements();
        for (Element e : elementList) {
            map.put(e.getName(), e.getText());
        }
        inputStream.close();
        inputStream = null;
        return map;
    }
}

MessageServiceImpl:

package com.lxl.ggkt.wechat.service.impl;

import com.lxl.ggkt.client.course.CourseFeignClient;
import com.lxl.ggkt.model.vod.Course;
import com.lxl.ggkt.wechat.service.MessageService;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Random;

@Service
public class MessageServiceImpl implements MessageService {

    @Autowired
    private CourseFeignClient courseFeignClient;

    @Autowired
    private WxMpService wxMpService;

    //接收消息
    @Override
    public String receiveMessage(Map<String, String> param) {
        String content = "";
        try {
            String msgType = param.get("MsgType");
            switch(msgType){
                case "text" :
                    content = this.search(param);
                    break;
                case "event" :
                    String event = param.get("Event");
                    String eventKey = param.get("EventKey");
                    if("subscribe".equals(event)) {//关注公众号
                        content = this.subscribe(param);
                    } else if("unsubscribe".equals(event)) {//取消关注公众号
                        content = this.unsubscribe(param);
                    } else if("CLICK".equals(event) && "aboutUs".equals(eventKey)){
                        content = this.aboutUs(param);
                    } else {
                        content = "success";
                    }
                    break;
                default:
                    content = "success";
            }
        } catch (Exception e) {
            e.printStackTrace();
            content = this.text(param, "请重新输入关键字,没有匹配到相关视频课程").toString();
        }
        return content;
    }

    @Override
    public void pushPayMessage(long id) {

        String openid = "oYtdy6gjiie2TF8o74YJbeJItpCA";
        WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
                .toUser(openid)//要推送的用户openid
                .templateId("ivOxy9PfqDONOWOqOqjvppO-YYebxVbPLBog1e-4nEU")//模板id
                .url("http://ggkt2.vipgz1.91tunnel.com/#/pay/"+id)//点击模板消息要访问的网址
                .build();
        //3,如果是正式版发送消息,,这里需要配置你的信息
        templateMessage.addData(new WxMpTemplateData("first", "亲爱的用户:您有一笔订单支付成功。", "#272727"));
        templateMessage.addData(new WxMpTemplateData("keyword1", "1314520", "#272727"));
        templateMessage.addData(new WxMpTemplateData("keyword2", "java基础课程", "#272727"));
        templateMessage.addData(new WxMpTemplateData("keyword3", "2022-01-11", "#272727"));
        templateMessage.addData(new WxMpTemplateData("keyword4", "100", "#272727"));
        templateMessage.addData(new WxMpTemplateData("remark", "感谢你购买课程,如有疑问,随时咨询!", "#272727"));
        try {
            String msg = wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage);
        } catch (WxErrorException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 关于我们
     * @param param
     * @return
     */
    private String aboutUs(Map<String, String> param) {
        return this.text(param, "硅谷课堂现开设Java、HTML5前端+全栈、大数据、全链路UI/UE设计、人工智能、大数据运维+Python自动化、Android+HTML5混合开发等多门课程;同时,通过视频分享、谷粒学苑在线课堂、大厂学苑直播课堂等多种方式,满足了全国编程爱好者对多样化学习场景的需求,已经为行业输送了大量IT技术人才。").toString();
    }

    /**
     * 处理关注事件
     * @param param
     * @return
     */
    private String subscribe(Map<String, String> param) {
        //处理业务
        return this.text(param, "感谢你关注“硅谷课堂”,可以根据关键字搜索您想看的视频教程,如:JAVA基础、Spring boot、大数据等").toString();
    }

    /**
     * 处理取消关注事件
     * @param param
     * @return
     */
    private String unsubscribe(Map<String, String> param) {
        //处理业务
        return "success";
    }

    /**
     * 处理关键字搜索事件
     * 图文消息个数;当用户发送文本、图片、语音、视频、图文、地理位置这六种消息时,开发者只能回复1条图文消息;其余场景最多可回复8条图文消息
     * @param param
     * @return
     */
    private String search(Map<String, String> param) {
        String fromusername = param.get("FromUserName");
        String tousername = param.get("ToUserName");
        String content = param.get("Content");
        //单位为秒,不是毫秒
        Long createTime = new Date().getTime() / 1000;
        StringBuffer text = new StringBuffer();
        List<Course> courseList = courseFeignClient.findByKeyword(content);
        if(CollectionUtils.isEmpty(courseList)) {
            text = this.text(param, "请重新输入关键字,没有匹配到相关视频课程");
        } else {
            //一次只能返回一个
            Random random = new Random();
            int num = random.nextInt(courseList.size());
            Course course = courseList.get(num);
            StringBuffer articles = new StringBuffer();
            articles.append("<item>");
            articles.append("<Title><![CDATA["+course.getTitle()+"]]></Title>");
            articles.append("<Description><![CDATA["+course.getTitle()+"]]></Description>");
            articles.append("<PicUrl><![CDATA["+course.getCover()+"]]></PicUrl>");
            articles.append("<Url><![CDATA[http://glkt.atguigu.cn/#/liveInfo/"+course.getId()+"]]></Url>");
            articles.append("</item>");

            text.append("<xml>");
            text.append("<ToUserName><![CDATA["+fromusername+"]]></ToUserName>");
            text.append("<FromUserName><![CDATA["+tousername+"]]></FromUserName>");
            text.append("<CreateTime><![CDATA["+createTime+"]]></CreateTime>");
            text.append("<MsgType><![CDATA[news]]></MsgType>");
            text.append("<ArticleCount><![CDATA[1]]></ArticleCount>");
            text.append("<Articles>");
            text.append(articles);
            text.append("</Articles>");
            text.append("</xml>");
        }
        return text.toString();
    }

    /**
     * 回复文本
     * @param param
     * @param content
     * @return
     */
    private StringBuffer text(Map<String, String> param, String content) {
        String fromusername = param.get("FromUserName");
        String tousername = param.get("ToUserName");
        //单位为秒,不是毫秒
        Long createTime = new Date().getTime() / 1000;
        StringBuffer text = new StringBuffer();
        text.append("<xml>");
        text.append("<ToUserName><![CDATA["+fromusername+"]]></ToUserName>");
        text.append("<FromUserName><![CDATA["+tousername+"]]></FromUserName>");
        text.append("<CreateTime><![CDATA["+createTime+"]]></CreateTime>");
        text.append("<MsgType><![CDATA[text]]></MsgType>");
        text.append("<Content><![CDATA["+content+"]]></Content>");
        text.append("</xml>");
        return text;
    }
}

测试号申请模版消息展示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r2UK5NLj-1684737630544)(/upload/2022/08/image-1659578887278.png)]

微信授权登录:

测试号配置网页授权获取用户基本信息:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JMgy1gyQ-1684737630544)(/upload/2022/08/image-1659579163289.png)]

完成前端之后引入微信工具包:

<dependencies>
    <dependency>
        <groupId>com.github.binarywang</groupId>
        <artifactId>weixin-java-mp</artifactId>
        <version>2.7.0</version>
    </dependency>

    <dependency>
        <groupId>dom4j</groupId>
        <artifactId>dom4j</artifactId>
        <version>1.1</version>
    </dependency>

    <dependency>
        <groupId>com.aliyun</groupId>
        <artifactId>aliyun-java-sdk-core</artifactId>
    </dependency>
</dependencies>

同时配置微信公众号的id和密钥

wechat.mpAppId: wxd4e0bcc0aa6b50d0

wechat.mpAppSecret: ad5712c888df46205b11fb77cddd0f0a

wechat.userInfoUrl: http://ggktlxl.free.idcfengye.com/api/user/wechat/userInfo

工具类ConstantPropertiesUtil和WeChatMpConfig配置见前章。

使用token实现用户信息传递:

导入jwt的依赖:

<dependencies>
	<dependency>
		<groupId>org.apache.httpcomponents</groupId>
		<artifactId>httpclient</artifactId>
	</dependency>
	<dependency>
		<groupId>io.jsonwebtoken</groupId>
		<artifactId>jjwt</artifactId>
	</dependency>
	<dependency>
		<groupId>joda-time</groupId>
		<artifactId>joda-time</artifactId>
	</dependency>
</dependencies>

增加JWT工具类:

package com.lxl.ggkt.utils;

import io.jsonwebtoken.*;
import org.springframework.util.StringUtils;

import java.util.Date;

public class JwtHelper {
    //token字符串有效时间
    private static long tokenExpiration = 24*60*60*1000;
    //加密编码秘钥
    private static String tokenSignKey = "123456";

    //根据userid  和  username 生成token字符串
    public static String createToken(Long userId, String userName) {
        String token = Jwts.builder()
                //设置token分类
                .setSubject("GGKT-USER")
                //token字符串有效时长
                .setExpiration(new Date(System.currentTimeMillis() + tokenExpiration))
                //私有部分(用户信息)
                .claim("userId", userId)
                .claim("userName", userName)
                //根据秘钥使用加密编码方式进行加密,对字符串压缩
                .signWith(SignatureAlgorithm.HS512, tokenSignKey)
                .compressWith(CompressionCodecs.GZIP)
                .compact();
        return token;
    }

    //从token字符串获取userid
    public static Long getUserId(String token) {
        if(StringUtils.isEmpty(token)) return null;
        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);
        Claims claims = claimsJws.getBody();
        Integer userId = (Integer)claims.get("userId");
        return userId.longValue();
    }

    //从token字符串获取getUserName
    public static String getUserName(String token) {
        if(StringUtils.isEmpty(token)) return "";
        Jws<Claims> claimsJws
                = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);
        Claims claims = claimsJws.getBody();
        return (String)claims.get("userName");
    }

    public static void main(String[] args) {
        String token = JwtHelper.createToken(1L, "lucy");
        System.out.println(token);
        System.out.println(JwtHelper.getUserId(token));
        System.out.println(JwtHelper.getUserName(token));
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/554975.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023年认证杯SPSSPRO杯数学建模D题(第一阶段)立体车库的自动调度问题全过程文档及程序

2023年认证杯SPSSPRO杯数学建模 D题 立体车库的自动调度问题 原题再现&#xff1a; 随着人们生活水平的提高&#xff0c;汽车保有量日益增加&#xff0c;而城市土地资源有限&#xff0c;传统平面停车场土地面积利用率低, 这样便形成了交通拥挤、停车困难的现象。为解决该问题…

资深测试老鸟整理,超全自动化测试用例详解-小技巧总结...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 Python自动化测试&…

PCA的数学原理和python实现

最近学习了一下PCA&#xff0c;具体原理网址如下&#xff1a; CodingLabs - PCA的数学原理 主要原理是通过线性变换将原始数据变换为一组各维度线性无关的表示&#xff0c;其中将方差最大的方向作为主要特征。提取数据的主要特征分量&#xff0c;可用于高维数据的降维 主要算…

工作3年裸辞,从18K到38K,面试也····

现在的面试好像也不是那么的难 工作3年&#xff0c;换了好几份工作&#xff08;行业流行性大&#xff09;&#xff0c;每次工作都是裸辞。朋友都觉得不可思议。因为我一直对自己很有信心&#xff0c;而且特别不喜欢请假面试&#xff0c;对自己负责也对公司负责。 但是这次没想…

Axure 教程:动态分组条形图(中继器)

本文将教大家如何用AXURE中的中继器动态分组条形图 一、效果介绍 如图&#xff1a; 预览地址&#xff1a;https://v7cmdp.axshare.com 下载地址&#xff1a;https://download.csdn.net/download/weixin_43516258/87807121?spm1001.2014.3001.5503 二、功能介绍 简单填写中继…

Lucene(4):Field域类型

1 Field属性 Field是文档中的域&#xff0c;包括Field名和Field值两部分&#xff0c;一个文档可以包括多个Field&#xff0c;Document只是Field的一个承载体&#xff0c;Field值即为要索引的内容&#xff0c;也是要搜索的内容。 是否分词(tokenized) 是&#xff1a;作分词处理…

requests爬虫

目录 一、爬虫概念及分类 二、requests模块 1、网页地址内容获取 2、图片爬取 3、UA伪装 三、动态加载数据 一、爬虫概念及分类 爬虫: 通过编写代码&#xff0c;让其模拟浏览器上网&#xff0c;然后在互联网中抓取数据的过程 分类&#xff1a;1、通用爬虫&#xff1a;要…

Linux: ARM32各CPU模式下栈配置

文章目录 1. 前言2. 背景3. ARM32 中断向量表 和 中断处理流程3.1 ARM32 中断向量表3.2 ARM32 中断处理流程 4. ARM32 各CPU模式下的栈配置4.1 SVC模式下各CPU栈配置(内核栈配置)4.1.1 BOOT CPU SVC模式栈配置(内核栈配置)4.1.2 非 BOOT CPU SVC模式栈配置(内核栈配置) 4.2 中断…

实现快速多点触控,让App自动化测试操作更方便

目录 前言&#xff1a; PyAutoGUI简介&#xff1a; 代码示例&#xff1a; 总结&#xff1a; 前言&#xff1a; 随着智能设备的普及&#xff0c;触摸点的数量和触摸操作的复杂度也在不断增加。要想在触控界面上获得更高效率和更好的体验&#xff0c;多点触控操作是必不可少的…

历经70+场面试,我发现了大厂面试的套路都是···

今年的金三银四刚刚过去&#xff0c;我又想起了我在去年春招时面试了50余家&#xff0c;加上暑期实习面试了20余家&#xff0c;加起来也面试了70余场的面试场景了。 基本把国内有名的互联网公司都面了一遍&#xff0c;不敢说自己的面试经验很丰富&#xff0c;但也是不差的。 …

【JAVAEE】认识网络及网络通信

目录 1.网络发展史 1.1独立模式 1.2网络互连 1.2.1局域网 1.2.2广域网 2.网络通信基础 2.1IP地址 2.2端口号 2.3协议 2.4五元组 2.5协议分层 2.5.1什么是协议分层 2.5.2协议分层的作用 2.5.3TCP/IP五层&#xff08;或四层&#xff09;模型 3.封装和分用 1.网络发…

调用百度API自动生成春联

目录 1、作者介绍2、百度智能春联介绍录2.1 功能介绍2.2 技术特色 3、智能春联API接口介绍3.1 请求参数3.2 返回参数 4. 操作流程5. 代码实现 1、作者介绍 范宇帅&#xff0c;男&#xff0c;西安工程大学电子信息学院&#xff0c;2022级研究生 研究方向&#xff1a;多机器人协…

〖C++11〗线程库详解

「前言」文章是关于C11线程库相关的 「归属专栏」C嘎嘎 「笔者」枫叶先生(fy) 「座右铭」前行路上修真我 「枫叶先生有点文青病」 「每篇一句」 请不要把陌生人的些许善意&#xff0c; 视为珍稀的瑰宝&#xff0c; 却把身边亲近人的全部付出&#xff0c; 当做天经地义的事情&am…

比赛记录:Codeforces Round 874 (Div. 3) A~G

传送门:CF 前题提要:赛时A出了5道题,并且都是一遍过的,F题也已经找到了解决方法,但是没时间完成了.以为应该能上分,但是没想到赛后E题被hack掉了…绝了.然后打完这场 d i v 3 div3 div3后立马阳了,加上一大堆烦心事(包括但不限于各类考试).就导致现在才写出这篇题解. A题:A. …

移动机器人 | 火星探矿机器人

01、需求分析 “火星探矿机器人”旨在要开发若干个自主机器人&#xff0c;将其送到火星上去搜寻和采集火星上的矿产资源。 火星环境对于开发者和自主机器人而言事先不可知&#xff0c;但是可以想象火星表面会有多样化的地形情况&#xff0c;如河流、巨石、凹坑等&#xff0c;机…

公司从字节招来一个28K的测试工程师,让我见识到了什么才是真正的测试天花板

今天上班开早会就是新人见面仪式&#xff0c;听说来了个很厉害的大佬&#xff0c;年纪还不大&#xff0c;是上家公司离职过来的&#xff0c;薪资已经达到中高等水平&#xff0c;很多人都好奇不已&#xff0c;能拿到这个薪资应该人不简单&#xff0c;果然&#xff0c;自我介绍的…

队列——“数据结构与算法”

各位CSDN的uu们你们好呀&#xff0c;又好久不见啦&#xff0c;最近有点摆烂&#xff0c;甚是惭愧&#xff01;&#xff01;&#xff01;&#xff01;今天&#xff0c;小雅兰的内容是队列&#xff0c;下面&#xff0c;让我们进入队列的世界吧&#xff01;&#xff01;&#xff0…

Trigger +Pipeline 完整实战案例

2.4.1 案例环境说明 示例项目&#xff1a;http://code.icloud2native.com/root/spring-boot-helloWorld.git 触发机制: 用户推送代码至项目仓库由Push Hook 自东触发pipeline的流水线的执行 2.4.2 项目实现 1、在k8s上部署一个gitlab&#xff0c;前面上节已经完成。 2、运…

海睿思分享 | 类chatgpt模型在信息抽取领域的应用

大语言模型&#xff08;LLM&#xff0c;Large Language Model&#xff09;是指能够处理海量数据、拥有百亿级参数的深度学习模型&#xff0c;它已成为⼈⼯智能领域中的新热点。2022 年 11 ⽉ 30 号 ChatGPT 发布&#xff0c;其卓越的性能表现给整个⾏业带来了巨⼤的冲击。⼈们不…

2023年春季期末网球理论复习资料

&#xff08;含2023/2022/2021时事题&#xff0c;基于2012年期末网球理论复习资料修改&#xff09; 目录 网球的起源 网球的主要赛事 三大网球协会 大满贯 网球的场地 1. 球场线 2. 网球的球网 3.场地的类型 网球的规则 1.发球规则 2.计分方法 3.通则 4.赛…