问题:页面展示信息是报错,因为数据库中某时间戳的列值为0000-00-00 00:00:00,所有报错原因:不知道建表时默认还是自己无意插入的,其中有行记录时间戳的默认值为0000-00-00 00:00:00, 将其删除即可
依赖:<dependency> <groupId>com.overzealous</groupId> <artifactId>remark</artifactId> <version>1.1.0</version></dependency>示例:Remark remark = new Remark(Options.github()); //以github模式String markdown = remark.convertFragment("### 办公网络\n"); //这里填markdown内容System.out.println(markdown);支持 PHP Markdown Extra MultiMarkdown Github Flavored Markdown Pegdown 等多种扩展格式的mardown。// PHP Markdown ExtraRemark markdownExtraRemark = new Remark(Options.markdownExtra());// MultiMarkdownRemark multiMarkdownRemark = new Remark(Options.multiMarkdown());// Github Flavored MarkdownRemark githubMarkdown = new Remark(Options.github());// Pegdown with all extensions enabledRemark pegdownMarkdown = new Remark(Options.pegdownAllExtensions());
所需依赖:<dependency> <groupId>com.atlassian.commonmark</groupId> <artifactId>commonmark</artifactId> <version>0.11.0</version></dependency>代码示例:import org.commonmark.node.Image;import org.commonmark.node.Link;import org.commonmark.node.Node;import org.commonmark.parser.Parser;import org.commonmark.renderer.html.AttributeProvider;import org.commonmark.renderer.html.AttributeProviderContext;import org.commonmark.renderer.html.AttributeProviderFactory;import org.commonmark.renderer.html.HtmlRenderer;import java.util.Map;public class Md2Html { public static void main(String[] args){ Parser parser = Parser.builder().build(); Node document = parser.parse("```java\n" + " //根据id获取课程\n" + " @Override\n" + " @GetMapping(\"/coursebase/get/{courseId}\")\n" + " public CourseBase getCourseBaseById(@PathVariable(\"courseId\") String courseId) throws RuntimeException {\n" + " return courseService.getCourseBaseById(courseId);\n" + " }\n" + "```"); HtmlRenderer renderer = HtmlRenderer.builder(). attributeProviderFactory(new AttributeProviderFactory() { @Override public AttributeProvider create(AttributeProviderContext attributeProviderContext) { return new AttributeProvider() { // 自定义标签属性 可用单独类继承AttributeProvider接口 @Override public void setAttributes(Node node, String s, Map<String, String> map) { if (node instanceof Image) { map.put("style", "width:150px;height:200px;position:relative;left:50%;margin-left:-100px;"); } if (node instanceof Link) { map.put("target", "_blank"); } } }; } }). build(); /* lamada改写 * HtmlRenderer renderer = HtmlRenderer.builder(). attributeProviderFactory(attributeProviderContext -> (node, s, map) -> { if (node instanceof Image) { map.put("style", "width:150px;height:200px;position:relative;left:50%;margin-left:-100px;"); } if (node instanceof Link) { map.put("target", "_blank"); } }). build(); * */ String mdHtml = renderer.render(document); mdHtml=mdHtml.replace("<pre>", "<pre class=\"fy-prettyprint linenums\">"); System.out.println(mdHtml); }}效果:<pre class="fy-prettyprint linenums"><code class="language-java"> //根据id获取课程 @Override @GetMapping("/coursebase/get/{courseId}") public CourseBase getCourseBaseById(@PathVariable("courseId") String courseId) throws RuntimeException { return courseService.getCourseBaseById(courseId); }</code></pre>
可能有些会失效,请大家选择需要的:http://tool.oschina.net/regex/ https://tool.xinke.org.cn/regexp.html http://tools.jb51.net/regex/create_reg https://www.regexpal.com/
Hexo官网:https://hexo.io/zh-cn/与Jekyll 一样是一款优秀快速的开源博客框架框架,安装方案参考官网文档,我就不再赘述:https://hexo.io/zh-cn/docs/同时Hexo也提供多彩的主题下载,官方就有相应的主题模块:https://hexo.io/themes/第一步:搭建局域网blog环境介绍作者使用系统:Deepin Linux 15.3桌面版软件环境:node+npm安装Hexonpm install hexo-cli -g初始化blog$ hexo init blog启动blog$ cd blog$ hexo server至此,本地blog已经创建完成,默认通过127.0.0.1:4000访问,简单到没朋友如果你不喜欢默认主题,可根据下面介绍换上其他漂亮的皮肤选择主题在hexo官网查看自己喜欢的主题通过git clone [url] themes/xxx 将主题克隆到本地,修改 _config.yml 中的theme:xxx以hexo-theme-3-hexo这个主题为例:先在git BASH控制台进入博客目录,使用git命令下载主题到主题文件夹git clone https://github.com/yelog/hexo-theme-3-hexo.git themes/3-hexo修改hexo根目录的_config.yml,如下:theme: 3-hexo如果想更新主题的话也很简单,先进入主题目录然后执行pull命令即可cd themes/3-hexogit pull# 安装后重启服务器 重新渲染页面$ hexo clean && hexo g && hexo s常用命令#创建一个新的文章$ hexo new "文章名"#生成静态文件$ hexo generate#讲一个草稿发布出去$ hexo publish [layout] <filename>#启动一个本地服务器$ hexo server更多命令移步官方文档第二步:搭建github pages局域网blog已经搭建完成,但是我们想让网上所有人都可以看到我们的文章,怎么办呢?又不想自己搭建服务器,别急,这时候就轮到github pages出场了注册github账户到github官网注册一个github账户配置SSH登录免密码许多Git服务器都支持使用SSH公钥进行认证,当然也包括github。首先你需要确认一下自己是否已经拥有密钥了,默认情况下,用户的 SSH 密钥存储在其 ~/.ssh 目录下。~即代表用户目录,Windows系统的话也在其用户目录内。进入该目录并列出其中内容,你便可以快速确认自己是否已经拥有密钥:$ cd ~/.ssh$ lsauthorized_keys2 id_rsa known_hostsconfig id_rsa.pub我们需要寻找一对 id_rsa 或 id_dsa 命名的文件,其中一个带 .pub 扩展名。 '.pub'文件是你的公钥,另一个则是私钥。如果没有找不到这样的文件(或者根本就没有.ssh目录),我们可以通过 ssh-keygen 程序来创建它们。#邮箱可以随便填$ ssh-keygen -t rsa -C "xx@xx.com"先 ssh-keygen 会确认密钥的存储位置和文件名(默认是 .ssh/id_rsa),然后他会要求你输入两次密钥口令,留空即可。所以一般选用默认,全部回车即可。接下来我们登陆到GitHub上,右上角小头像->Setting->SSH and GPG keys中,点击new SSH key。Title:可以随便填写,但最好起的名字能让自己知道这个公钥是哪个设备的。Key:将上面生成的.pub文件中的所有内容复制到这里。点击下面的Add SSH key即可。然后你就会发现可以免密码访问了。如果服务端是自己搭建的git服务器,生成密钥公钥对的步骤是一样的。然后将生成的 .pub 文件内容,导入到git服务器 /home/git/.ssh/authorized_keys 文件内,一行一个。然后你就会发现git push 不再需要密码了以上是其中一种连接方式,当然您使用HTTPS方式连接也可以,无需密钥但是首次使用可能需要密码。创建github远程仓库在github上创建一个仓库 xxx.github.io xxx为自己的github用户名配置Hexo修改 _comfig.yml,xxx为你的用户名,前一个是SSH方式,后一个是HTTPS:deploy: type: git repo: git@github.com:xxx/xxx.github.io.git branch: masterdeploy: type: git repo: https://github.com/xxx/xxx.github.io.git branch: master注意上述配置文件中:后面有空格。安装git部署插件$ npm install hexo-deployer-git --save推送服务器$ hexo deploy或者简写$ hexo d最后访问xxx.github.io就可以测试你的网站咯!文章参考:https://www.jianshu.com/p/50e796e038cbhttps://www.jianshu.com/p/3f2fe426edff码云方法同理,可参考:https://blog.csdn.net/wrp0101/article/details/79139996
//根据id获取课程 @Override @GetMapping("/coursebase/get/{courseId}") public CourseBase getCourseBaseById(@PathVariable("courseId") String courseId) throws RuntimeException { return courseService.getCourseBaseById(courseId); } //更新课程基本信息 @Override @PutMapping("/coursebase/update/{id}") public ResponseResult updateCourseBase(@PathVariable("id") String id, @RequestBody CourseBase courseBase) { return courseService.updateCourseBase(id,courseBase); }
一般操作都是在实体类中按Alt+Insert,然后选择Getter and Setter一键生成,但其实在选择生成时候有自带的Build模板可供选择,选择后可以一键生成可链式set的方法,位置如图:生成好后的代码:public class Coldknow { private Integer Id; private String Title; public Integer getId() { return Id; } public Coldknow setId(Integer id) { Id = id; return this; } public String getTitle() { return Title; } public Coldknow setTitle(String title) { Title = title; return this; }}让我们对比下与普通setter方法的异同(注释部分为普通方式,this修饰的表当前类变量):public class Coldknow { private Integer id;/* public Integer getId() { return id; } public void setId(Integer id) { this.id = id; }*/ public Integer getId() { return id; } public Coldknow setId(Integer id) { this.id = id; return this; }}可以看出,普通方式只是更改了属性,而Build方式在更改属性后还返回了当前对象,因此可以实现链式set这种操作。
在实体类上使用该注解,例如:@Data@EqualsAndHashCode(callSuper = false)@Accessors(fluent = true)@AllArgsConstructor@NoArgsConstructorpublic class Coldknow extends Model<Coldknow> { private static final long serialVersionUID = 1L; @TableId(value = "id", type = IdType.AUTO) private Integer id; private String title; private String img; private String text; @Override protected Serializable pkVal() { return this.id; }}@Accessors(fluent = true)使用后可以让你在get/set时候省去get/set例如: Coldknow coldknow = new Coldknow();// set设置属性 coldknow.title("标题"); coldknow.img("http://cway.top/1.png");// get属性 System.out.println(coldknow.title());@Accessors(chain = true)使用后支持链式set,即:Coldknow coldknow = new Coldknow().setTitle("标题").setImg("http://cway.top/1.png") .setText("内容");System.out.println(coldknow);@Accessors(prefix="t")生成getter/setter时忽略指定字符前缀,但前缀后必须是小驼峰命名,例如 fName,生成的get/set方法则变成getName()而非getFName(),具体观察下图:
主要用注解方式来简化Java实体类的书写,使代码更简洁清晰,所需依赖,例如:<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.20</version> <scope>provided</scope></dependency>@Data注解在类上,会为类的所有属性自动生成setter/getter、equals、canEqual、hashCode、toString方法@ToString、@EqualsAndHashCode、@Getter/@Setter、@RequiredArgsConstructor的所有特性(),如为final属性,则不会为该属性生成setter方法。@Getter/@Setter注解,此注解在属性上,可以为相应的属性自动生成Getter/Setter方法@NonNull该注解用在属性或构造器上,Lombok会生成一个非空的声明,可用于校验参数,能帮助避免空指针。@Cleanup该注解能帮助我们自动调用close()方法,很大的简化了代码,例如:import lombok.Cleanup;import java.io.*;public class CleanupExample { public static void main(String[] args) throws IOException { @Cleanup InputStream in = new FileInputStream(args[0]); @Cleanup OutputStream out = new FileOutputStream(args[1]); byte[] b = new byte[10000]; while (true) { int r = in.read(b); if (r == -1) break; out.write(b, 0, r); } }}@EqualsAndHashCode默认情况下,会使用所有非静态(non-static)和非瞬态(non-transient)属性来生成equals和hasCode,也能通过exclude注解来排除一些属性。示例:import lombok.EqualsAndHashCode;@EqualsAndHashCode(exclude={"id", "shape"})public class EqualsAndHashCodeExample { private transient int transientVar = 10; private String name; private double score; private Shape shape = new Square(5, 10); private String[] tags; private int id; public String getName() { return this.name; } @EqualsAndHashCode(callSuper=true) public static class Square extends Shape { private final int width, height; public Square(int width, int height) { this.width = width; this.height = height; } }}@ToString注解,Lombok会生成一个toString()方法,默认情况下,会输出类名、所有属性(会按照属性定义顺序),用逗号来分割。通过将includeFieldNames参数设为true,就能明确的输出toString()属性。这一点是不是有点绕口,通过代码来看会更清晰些。示例:import lombok.ToString;@ToString(exclude="id")public class ToStringExample { private static final int STATIC_VAR = 10; private String name; private Shape shape = new Square(5, 10); private String[] tags; private int id; public String getName() { return this.getName(); } @ToString(callSuper=true, includeFieldNames=true) public static class Square extends Shape { private final int width, height; public Square(int width, int height) { this.width = width; this.height = height; } }}@NoArgsConstructor, @RequiredArgsConstructor and @AllArgsConstructor无参构造器、部分参数构造器、全参构造器。Lombok没法实现多种参数构造器的重载。 Lombok的优缺点优点:能通过注解的形式自动生成构造器、getter/setter、equals、hashcode、toString等方法,提高了一定的开发效率让代码变得简洁,不用过多的去关注相应的方法属性做修改时,也简化了维护为这些属性所生成的getter/setter方法等缺点:不支持多种参数构造器的重载虽然省去了手动创建getter/setter方法的麻烦,但大大降低了源代码的可读性和完整性,降低了阅读源代码的舒适度总结Lombok虽然有很多优点,但Lombok更类似于一种IDE插件,项目也需要依赖相应的jar包。Lombok依赖jar包是因为编译时要用它的注解,为什么说它又类似插件?因为在使用时,eclipse或IntelliJ IDEA都需要安装相应的插件,在编译器编译时通过操作AST(抽象语法树)改变字节码生成,变向的就是说它在改变java语法。它不像spring的依赖注入或者mybatis的ORM一样是运行时的特性,而是编译时的特性。这里我个人最感觉不爽的地方就是对插件的依赖!因为Lombok只是省去了一些人工生成代码的麻烦,但IDE都有快捷键来协助生成getter/setter等方法,也非常方便。知乎上有位大神发表过对Lombok的一些看法:这是一种低级趣味的插件,不建议使用。JAVA发展到今天,各种插件层出不穷,如何甄别各种插件的优劣?能从架构上优化你的设计的,能提高应用程序性能的 ,实现高度封装可扩展的..., 像lombok这种,像这种插件,已经不仅仅是插件了,改变了你如何编写源码,事实上,少去了代码你写上去又如何? 如果JAVA家族到处充斥这样的东西,那只不过是一坨披着金属颜色的屎,迟早会被其它的语言取代。虽然话糙但理确实不糙,试想一个项目有非常多类似Lombok这样的插件,个人觉得真的会极大的降低阅读源代码的舒适度。虽然非常不建议在属性的getter/setter写一些业务代码,但在多年项目的实战中,有时通过给getter/setter加一点点业务代码,能极大的简化某些业务场景的代码。所谓取舍,也许就是这时的舍弃一定的规范,取得极大的方便。我现在非常坚信一条理念,任何编程语言或插件,都仅仅只是工具而已,即使工具再强大也在于用的人,就如同小米加步枪照样能赢飞机大炮的道理一样。结合具体业务场景和项目实际情况,无需一味追求高大上的技术,适合的才是王道。Lombok有它的得天独厚的优点,也有它避之不及的缺点,熟知其优缺点,在实战中灵活运用才是王道。参考:https://projectlombok.org/features/https://github.com/rzwitserloot/lombok?spm=a2c4e.11153940.blogcont59972.5.2aeb6d32hayLHvhttps://www.zhihu.com/question/42348457https://blog.csdn.net/ghsau/article/details/52334762转载:https://www.cnblogs.com/heyonggang/p/8638374.html
需要自己设置bduss,bduss设置方法:登录百度后在首页按F12,在调试窗口左上角Filter中填www.baidu.com 在Headers选项卡中Request Headers中找到BDUSS=复制其后的字符 赋值给代码中的bduss即可所需依赖:<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.8</version></dependency><dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpcore</artifactId> <version>4.4.6</version></dependency><dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.8.1</version></dependency><dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.58</version></dependency>或者直接用commons-httpclient的依赖,commons-httpclient包含httpclient与httpcore包里部分内容 <dependency> <groupId>commons-httpclient</groupId> <artifactId>commons-httpclient</artifactId> <version>3.1</version> </dependency>如果你使用普通导jar包的Java项目,则需要的jar包除了以上之外还需要的jar有:commons-logging、commons-codec,可自行在Maven仓库下载代码:/** * Author: https://cway.top * Date: 2019/7/9 * Time: 10:35 * Description: 百度签到 */class BaiduSigner { /** * 百度签到 */ public static void main(String[] args) throws Exception { PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(); cm.setMaxTotal(200); // 设置最大连接数 cm.setDefaultMaxPerRoute(10); // 设置每个主机的并发数// String bduss=args[0]; String bduss = ""; // 设置自己的bduss字符 或者从args获取 JSONObject tbs = (JSONObject) JSON.parse(getTbs(bduss, cm)); if (!tbs.getString("is_login").equals("1")) { System.out.println("可能cookie失效咯"); return; } System.out.println("登录成功>>>>>"); String tbstr = tbs.getString("tbs");// System.out.println(vipSign(tbstr, bduss, cm)); //vip一键签到 一般不需要 JSONObject jo = (JSONObject) JSON.parse(getForums(bduss, cm)); JSONObject forum_list = jo.getJSONObject("forum_list"); JSONArray jsonArray = forum_list.getJSONArray("non-gconforum"); System.out.println("获取列表成功>>>>>"); int n = 0; int count = 0; for (Object o : jsonArray) { System.out.println("==========第" + ++n + "个=========="); JSONObject forum = (JSONObject) JSON.toJSON(o); String id = forum.getString("id"); String name = forum.getString("name"); System.out.println("正在签到" + name + ":"); String signResult = signForums(name, id, tbstr, bduss, cm); JSONObject result = (JSONObject) JSON.parse(signResult); if (signResult.contains("error_code") && signResult.contains("error_msg")) { System.out.println(result.getString("error_msg")); continue; } JSONObject user_info = result.getJSONObject("user_info"); System.out.println("签到成功!经验+" + user_info.getString("sign_bonus_point") + ",今天第" + user_info.getString("user_sign_rank") + "个签到"); count++; } System.out.println("共签到成功" + count + "个贴吧"); } /** * 获取贴吧状态码 tbs */ public static String getTbs(String bduss, PoolingHttpClientConnectionManager cm) throws Exception { String header = "Cookie=" + "BDUSS=" + bduss; return postClient("http://tieba.baidu.com/dc/common/tbs", header, "", cm).getResponseStr(); } /** * 获取所有关注贴吧 */ public static String getForums(String bduss, PoolingHttpClientConnectionManager cm) throws Exception { String header = new StringBuilder().append("Cookie=BDUSS=").append(bduss).append("&") .append("Content-Type=application/x-www-form-urlencoded&Charset=UTF-8&net=3&") .append("User-Agent=bdtb for Android 8.4.0.1&Connection=Keep-Alive&Accept-Encoding=gzip&") .append("Host=c.tieba.baidu.com").toString(); String md5Hex = DigestUtils.md5Hex(new StringBuilder().append("BDUSS=").append(bduss) .append("_client_version=8.1.0.4page_no=1page_size=100tiebaclient!!!") .toString()); String body = new StringBuilder().append("BDUSS=").append(bduss).append("&") .append("_client_version=8.1.0.4&page_no=1&page_size=100&sign=") .append(md5Hex).toString(); return postClient("http://c.tieba.baidu.com/c/f/forum/like", header, body, cm).getResponseStr(); } /** * 签到 */ public static String signForums(String name, String id, String tbs, String bduss, PoolingHttpClientConnectionManager cm) throws Exception { String header = new StringBuilder().append("Cookie=BDUSS=").append(bduss).append("&") .append("Content-Type=application/x-www-form-urlencoded&Charset=UTF-8&net=3&") .append("User-Agent=bdtb for Android 8.4.0.1&Connection=Keep-Alive&Accept-Encoding=gzip&") .append("Host=c.tieba.baidu.com").toString(); String md5Hex = DigestUtils.md5Hex(new StringBuilder().append("BDUSS=").append(bduss) .append("fid=" + id + "kw=" + name + "tbs=" + tbs + "tiebaclient!!!") .toString()); String body = new StringBuilder().append("BDUSS=").append(bduss) .append("&fid=").append(id).append("&kw=").append(name) .append("&sign=").append(md5Hex).append("&tbs=").append(tbs).toString(); return postClient("http://c.tieba.baidu.com/c/c/forum/sign", header, body, cm).getResponseStr(); } /** * VIP签到 */ public static String vipSign(String tbs, String bduss, PoolingHttpClientConnectionManager cm) throws Exception { String firefoxHeader = "Content-Type: application/x-www-form-urlencoded\n" + "Charset: UTF-8\n" + "net: 3\n" + "User-Agent: bdtb for Android 8.4.0.1\n" + "Connection: Keep-Alive\n" + "Accept-Encoding: gzip\n" + "Host: c.tieba.baidu.com"; firefoxHeader = firefoxHeader.replaceAll(": ", "=").replaceAll("\n", "&"); System.out.println("火狐:" + firefoxHeader); String header = new StringBuilder().append("Cookie=BDUSS=").append(bduss).append("&") .append(firefoxHeader).toString(); String body = new StringBuilder().append("ie=utf-8&tbs=").append(tbs).toString(); return postClient("http://tieba.baidu.com/tbmall/onekeySignin1", header, body, cm).getResponseStr(); } /** * post封装 * * @param url 请求URL * @param header 请求头 * @param body 请求体 * @param cm cm连接池 * @return 返回Response与页面字符 * @throws Exception */ public static ResponseVo postClient(String url, String header, String body, PoolingHttpClientConnectionManager cm) throws Exception { CloseableHttpClient client = HttpClients.custom().setConnectionManager(cm).build(); HttpPost httpPost = new HttpPost(url); if (StringUtils.isNotBlank(header)) { for (Map.Entry<String, String> entry : covertParam(header)) { httpPost.addHeader(entry.getKey(), entry.getValue()); } } List<NameValuePair> pairs = new ArrayList<>(); if (StringUtils.isNotBlank(body)) { for (Map.Entry<String, String> entry : covertParam(body)) { pairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); } } UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(pairs, "utf-8"); httpPost.setEntity(formEntity); String content = null; CloseableHttpResponse response = null; ResponseVo responseVo = null; try { //使用HttpClient发起请求 response = client.execute(httpPost); //判断响应状态码是否为200 if (response.getStatusLine().getStatusCode() == 200) { //如果为200表示请求成功,获取返回数据 content = EntityUtils.toString(response.getEntity(), "UTF-8"); responseVo = new ResponseVo().setResponse(response).setResponseStr(content); } } catch (Exception e) { e.printStackTrace(); } finally { //释放连接 if (response == null) { try { response.close(); } catch (IOException e) { e.printStackTrace(); } } } return responseVo; } /** * 校验、转换参数 */ public static Set<Map.Entry<String, String>> covertParam(String params) throws Exception { String[] paramses; if (params.contains("=") && params.contains("&")) { paramses = params.split("&"); } else if (params.contains("=") && !params.contains("&")) { paramses = new String[1]; paramses[0] = params; } else { throw new Exception("参数请确保都为键值对形式"); } Map<String, String> map = new HashMap<>(); for (String s : paramses) { String[] ss = s.split("="); map.put(ss[0], s.substring(ss[0].length() + 1)); } return map.entrySet(); }}/** * 响应结果实体类 */class ResponseVo { private String responseStr; private CloseableHttpResponse response; public ResponseVo(String responseStr, CloseableHttpResponse response) { this.responseStr = responseStr; this.response = response; } public ResponseVo() { } public String getResponseStr() { return responseStr; } public ResponseVo setResponseStr(String responseStr) { this.responseStr = responseStr; return this; } public CloseableHttpResponse getResponse() { return response; } public ResponseVo setResponse(CloseableHttpResponse response) { this.response = response; return this; }}以下是非Maven版,即导jar包的版本,可以用cmd启动,试用期请编辑cmd文件中内容,另附源码:链接:https://pan.baidu.com/s/1mqWEYzYrxBYVqxrq-wON3g 提取码:fq91 复制这段内容后打开百度网盘手机App,操作更方便哦