基层教学组织评估系统5_系统管理员数据维护模块功能完善,优化教学组织名称的输入提示补全,项目打包部署篇

目录


  • 一、完善
  • 二、项目打包
  • 三、部署
  • 四、报错解决
  • 五、数据初始

一、完善
  • 系统管理员数据维护模块功能完善
  • 优化教学组织名称的输入提示补全
  • 数据对应格式bug修复
1.系统管理员数据维护模块功能完善

系统管理员可以对数据进行维护,例如添加学院、添加导入基层教学组织名称(为了规范用户输入的数据格式,提示补全输入内容)

实现思路就是一般的增,点击增加学院按钮、教学组织名称按钮,将输入的学院、教学组织名称传入后端进行保存

其中需要注意的地方:

  • Restful风格或者一般的RequestBody请求方式,是无法将中文字符传入后端的,因为中文字符 会 变成乱码,后端取不出来,干脆直接在后端创建对应实体,将 学院名称、基层教学组织名称、批量导入的基层教学组织名称数组 作为 属性,进而逐个处理
  • 异步请求和 填入对话框内容的清空 需要有先后顺序,默认的循序是 清空先执行(执行的速度快),携带表单数据的请求在后面,导致传入的数据为 "",解决办法就是将 清空对话框数据的 语句放到 请求成功 之后。
  • 对于批量添加后端的处理,MongodbTemplate并没有批量添加内嵌数组数据的方法,采用的是循环逐个添加
2.优化教学组织名称的输入提示补全

为了输入数据格式的控制,规范教学组织名称,需要加上 内容下拉提示补全 功能,在输入的时候,下方下拉框显示匹配的 完整内容

主要的就是前端的实现,大致实现逻辑

		<el-col :span="7">
              <el-form-item class="el-form-item_label" label="教学组织名称">
                <el-autocomplete
                  style="width: 250px"
                  v-model="form.info.organization"
                  :fetch-suggestions="querySearch"
                  placeholder="请输入内容"
                  :trigger-on-focus="false"
                  @select="handleSelect"
                ></el-autocomplete>
              </el-form-item>
            </el-col>

data() {
    return {
      //基层组织列表,从后端拿数据
      arrayOfGrassRootsTeachingSystemName: [
        // {
        //   value: 'aaa'
        // },
        // {
        //   value: 'bbb'
        // },
        // {
        //   value: 'ccc'
        // },
        // {
        //   value: 'csccc'
        // }
      ]
		....
		....
     }
  }


// 方法
//显示搜索内容
    handleSelect(item) {
      console.log(item);
    },
    //基层教学组织输入框查找相关输入内容
    querySearch(queryString, cb) {
      var arrayOfGrassRootsTeachingSystemName = this
        .arrayOfGrassRootsTeachingSystemName;
      var results = queryString
        ? arrayOfGrassRootsTeachingSystemName.filter(
            this.createFilter(queryString)
          )
        : arrayOfGrassRootsTeachingSystemName;
      // 调用 callback 返回建议列表的数据
      cb(results);
    },
    //过滤出相关输入内容
    createFilter(queryString) {
      return (arrayOfGrassRootsTeachingSystemName) => {
        return (
          arrayOfGrassRootsTeachingSystemName.value
            .toLowerCase()
            .indexOf(queryString.toLowerCase()) !== -1
        );
      };
    },


二、项目打包
1.前端项目打包

前后端分离的项目部署方式很多种,可以使用多个服务器部署,也可以前后端放在一起部署,这里我就一块部署

设置好生产环境的url,前端执行 npm run build:prod,生成dist目录,将里面二段内容复制(不含dist文件夹)放在后端的resource/static 目录

其中打包的过程遇到控制台报错,参考解决:Vue解决报错8_打包时TyeError: Class extends value undefined is not a constructor or null

然后开启后端测试

2.后端项目打包

因为前后端是放在一起的,直接打成jar包就行,使用mvn 的packge命令

最终在target目录下生成 jar文件,稍后直接ftp到服务器,配置完相关环境后就可以运行

三、部署

准备一台服务器,使用xShell连接,接着就是服务器环境的配置

参考:SpringBoot项目部署到阿里云linux服务器全流程

3.1安装jdk11及环境配置

一、下载tar包解压安装

下载jdk11 的linux版tar包,官网下载很慢,自行选择

链接:https://pan.baidu.com/s/1yCObT1mCQWuTpXSS60YMOg
提取码:nsk9
复制这段内容后打开百度网盘手机App,操作更方便哦

之后ssh连接服务器,上传tar包

  • 执行yum install lrzsz

  • 创建文件夹,执行rz选中文件上传至服务器,速度可能会比较慢

  • 执行 tar -zxvf xxx.tar.gz解压jdk文件

  • 配置jdk环境变量

    找到文件 /etc/profile ,向其中添加如下代码:

    export JAVA_HOME=/usr/java/你安装的jdk名称
    export CLASSPATH=$JAVA_HOME/lib/
    export PATH=$PATH:$JAVA_HOME/bin
    export PATH JAVA_HOME CLASSPATH
    
    

    然后执行source /etc/profile使配置生效

二、直接使用yum安装

[root@ecs-2e99-0104593 /]# cd /usr/local/
[root@ecs-2e99-0104593 local]# ls
bin  etc  games  include  lib  lib64  libexec  sbin  share  src
[root@ecs-2e99-0104593 local]# mkdir mydata

[root@ecs-2e99-0104593 local]# cd ./mydata/
[root@ecs-2e99-0104593 mydata]# mkdir jdk
[root@ecs-2e99-0104593 mydata]# cd ./jdk/

[root@ecs-2e99-0104593 jdk]# clear
[root@ecs-2e99-0104593 jdk]# yum search java

# 选择版本安装
yum install java-11-openjdk-devel.x86_64

3.2配置MongoDB环境

参考:云服务器环境安装与配置:mongodb

方法一:下载tar包安装

  • 下载mongodb:执行wget http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-2.4.9.tgz,然后解压

  • 创建db、log文件夹,mongod.conf配置文件,编辑配置文件

  • 尝试启动:/usr/mongodb/mongodb-linux-x86_64-2.4.9/bin/mongo --dbpath=/usr/mongodb/mongodb-linux-x86_64-2.4.9/db --logpath=/usr/mongodb/mongodb-linux-x86_64-2.4.9/log/mongodb.log --fork

  • 重新绑定ip和配置文件:/usr/mongodb/mongodb-linux-x86_64-2.4.9/bin/mongod --dbpath=/usr/mongodb/mongodb-linux-x86_64-2.4.9/db --logpath=/usr/mongodb/mongodb-linux-x86_64-2.4.9/log/mongodb.log --bind_ip 172.25.204.157 -f /usr/mongodb/mongodb-linux-x86_64-2.4.9/bin/mongodb.conf

  • 设置开机自启:vi /etc/rc.d/rc.local ,然后将 上一步的代码复制 添加保存即可

  • 测试启动:/usr/mongodb/mongodb-linux-x86_64-2.4.9/bin/mongo 172.25.204.157

提示:这里的版本是2.4.9,springboot可能对于mongodb的版本又要求,选择合适的版本进行安装使用,这里我安装的版本就太低,需要重新安装更高的版本,详情见下文。

方法二:使用docker安装

# 首先需要安装docker,参考官网:https://docs.docker.com/engine/install/centos/


sudo yum install -y yum-utils

sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo
    
sudo yum install docker-ce docker-ce-cli containerd.io


sudo systemctl start docker



docker search mongo

docker  pull mongo

[root@ecs-2e99-0104593 mydata]# mkdir mongo
[root@ecs-2e99-0104593 mydata]# ls
jdk  mongo
[root@ecs-2e99-0104593 mydata]# cd ./mongo/
[root@ecs-2e99-0104593 mongo]# ls
[root@ecs-2e99-0104593 mongo]# mkdir data
[root@ecs-2e99-0104593 mongo]# mkdir conf
[root@ecs-2e99-0104593 mongo]# mkdir backup
[root@ecs-2e99-0104593 mongo]# clear
[root@ecs-2e99-0104593 mongo]# 

docker run --name=mongodb -v /usr/local/mydata/mongo/data:/data/db \
-v /usr/local/mydata/mongo/backup:/data/backup \
-v /usr/local/mydata/mongo/conf:/data/configdb \
--restart=on-failure:3 \
-p 27017:27017 -d mongo --auth


# 进入
[root@ecs-2e99-0104593 mongo]# docker exec -it mongodb mongo admin
MongoDB shell version v5.0.5
connecting to: mongodb://127.0.0.1:27017/admin?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("fca3b7f9-62ba-4df1-bbd5-92ceee14ccf8") }
MongoDB server version: 5.0.5
================
Warning: the "mongo" shell has been superseded by "mongosh",
which delivers improved usability and compatibility.The "mongo" shell has been deprecated and will be removed in
an upcoming release.
For installation instructions, see
https://docs.mongodb.com/mongodb-shell/install/
================
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
	https://docs.mongodb.com/
Questions? Try the MongoDB Developer Community Forums
	https://community.mongodb.com


# 添加账户,便于远程连接
db.createUser({ user: 'root', pwd: 'root', roles: [ { role: "userAdminAnyDatabase", db: "admin" } ] });




3.3配置Redis环境

方法一

参考:阿里云centos服务器安装redis并配置远程连接

大致步骤:

  • 下载、解压、编译安装
  • 测试启动redis:在当前的 /usr/local/redis-4.0.6/src 目录下启动,./redis-server,这种需要页面一直打开,需要配置服务后台开启
  • 以后台进程方式启动redis
  • 设置redis开机自启动
  • 启动redis:service redisd start

方法二

# 创建挂载文件夹
[root@ecs-2e99-0104593 redis]# clear
[root@ecs-2e99-0104593 redis]# cd ./redis

[root@ecs-2e99-0104593 redis]# mkdir conf
[root@ecs-2e99-0104593 redis]# mkdir data
[root@ecs-2e99-0104593 redis]# ls
conf  data
[root@ecs-2e99-0104593 redis]# 

# 新建redis.conf文件
[root@ecs-2e99-0104593 conf]# touch redis.conf

docker run -p 6379:6379 --name redis \
-v /usr/local/mydata/redis/data:/data \
-v /usr/local/mydata/redis/conf/redis.conf:/etc/redis/redis.conf \
-d redis redis-server /etc/redis/redis.conf





3.4安装Nginx

# 创建文件夹
[root@ecs-2e99-0104593 mydata]# ls
jdk  mongo  redis
[root@ecs-2e99-0104593 mydata]# mkdir nginx
[root@ecs-2e99-0104593 mydata]# cd ./nginx/
[root@ecs-2e99-0104593 nginx]# ls
[root@ecs-2e99-0104593 nginx]# mkdir html
[root@ecs-2e99-0104593 nginx]# mkdir conf
[root@ecs-2e99-0104593 nginx]# mkdir logs
[root@ecs-2e99-0104593 nginx]# 

docker run --name nginx -p 80:80 \
-v /usr/local/mydata/nginx/html:/usr/share/nginx/html \
-v /usr/local/mydata/nginx/logs:/var/log/nginx \
-v /usr/local/mydata/nginx/conf:/etc/nginx \
-d nginx


如果浏览器不能访问,但是curl 可以访问,需要开发下端口

iptables -I IN_public_allow -p tcp --dport 80 -j ACCEPT
iptables -I INPUT -p tcp --dport 80 -j ACCEPT
3.5上传jar包

java jar xxx.jar 运行,需要一直打开命令行,后台进程运行 nohup java jar xxx.jar

查看进程 ps -ef | grep java 是否正常开启

测试访问xxxx:8080,注意需要打开设置安全组策略开启系列服务端口


四、报错解决
1报错解决

测试发现登录页面能显示,但是登录不进去,检查redis和mongodb的服务都开启了,而且服务器客户端都能正常打开访问

然后配置文件也看了一遍应该没问题,检查不出来。

1.1只好在本机测试,现在本机测试mongodb,使用本机连接服务器的mongodb

开始一直连接不上,后来发现 安全组策略没放行,加上27017测试,能访问得到了,但是又报了错

1.2服务器mongodb版本太低

在这里插入图片描述

err:Server at 47.108.148.53:27017 reports wire version 0, but this version of the driver requires at least 2 (MongoDB 2.6).; nested exception is com.mongodb.MongoIncompatibleDriverException: Server at 47.108.148.53:27017 reports wire version 0, but this version of the driver requires at least 2 (MongoDB 2.6).

解决的话就是 删除旧的版本,重新安装新的版本

  • 下载:wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel62-3.6.4.tgz

  • 解压安装:tar -zxvf mongodb-linux-x86_64-rhel62-3.6.4.tgz

  • 移动:mv mongodb-linux-x86_64-rhel62-3.6.4/ /usr/local/mongodb

  • 系统profile配置:vi /etc/profile,加上环境变量
    export MONGODB_HOME=/usr/local/mongodb
    export PATH=$PATH:$MONGODB_HOME/bin

  • 重启系统配置:source /etc/profile

  • mongodb启动配置

    // 第一步
    cd /usr/local/mongodb/bin  
    
    
    // 第二步
    vi mongodb.conf 
    
    
    // 下面内容添加到配置文件
    dbpath = /usr/local/mongodb/data/db #数据文件存放目录  
    
    logpath = /usr/local/mongodb/logs/mongodb.log #日志文件存放目录  
    
    port = 27017  #端口  
    
    fork = true  #以守护程序的方式启用,即在后台运行  
    
    #nohttpinterface = true  #先注释掉 有的版本不需要 加上反而启不来 报错
    
    
    
  • 启动mongodb

/usr/local/mongodb/bin/mongod -f /usr/local/mongodb/bin/mongodb.conf发现报错

1.2.1注意配置文件一定要写好,空格也需要注意,这个就是dbpath后面加了一个空格报错

在这里插入图片描述

1.2.1配置文件格式正确后,还是无法启动,报错

about to fork child process, waiting until server is ready for connections.
forked process: 1620
ERROR: child process failed, exited with error number 1
To see additional information in this output, start without the "--fork" option.

原因是 logpath配置的 logs/mongodb.log文件还没创建

在这里插入图片描述

2.redis连接失败解决

上述redis的配置基本完成,以为没什么问题,运行web系统

MongoDB应该是没什么问题了

但是一直跑不起来,开始找错…

  • 本地windows的项目跑起来,打开redis,然后竟然服务器端和本地都能跑了,关掉本地idea开发环境,只打开redis却不行,推测出是服务器的redis有问题
  • 改springboot的application.yaml配置文件的redis的host,没什么用
  • 修改redis的配置文件,改bind的ip 为 0.0.0.0,保护模式为no,一系列操作发现远程能连接redis了,但是项目就是跑不起来
  • 卸载redis,准备使用yum进行安装,但是yum不能用,只好去官网下载tar包,然后rz到服务器(这里我总结三点…),然后又重装了一个6.0.2版本最新的redis,然后老一套配置

快奔溃的时候,我通过浏览器控制台点进去失败的请求,发现地址栏显示 localhost:8080/user/login

前端忘记改地址了(明明记得改过了,可能是忘记保存了…),然后改好地址(不要忘记加8080端口号!!!),重新打包、rz,运行

在这里插入图片描述

这次终于不是network error,而且token已经生成了,证明redis没什么大问题了,而是又报了一个500服务端的错(终于跳出了大坑,可喜可贺可口可乐~)

服务端报错,说redis需要密码,springboot里面已经设置过密码了

在这里插入图片描述

详细报错信息

Mar 30, 2021 12:42:52 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [redis.clients.jedis.exceptions.JedisDataException: NOAUTH Authentication required.] with root cause
redis.clients.jedis.exceptions.JedisDataException: NOAUTH Authentication required.
	at redis.clients.jedis.Protocol.processError(Protocol.java:132)
	at redis.clients.jedis.Protocol.process(Protocol.java:166)
	at redis.clients.jedis.Protocol.read(Protocol.java:220)
	at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:278)
	at redis.clients.jedis.Connection.getStatusCodeReply(Connection.java:196)
	at redis.clients.jedis.BinaryJedis.set(BinaryJedis.java:226)
	at org.crazycake.shiro.WorkAloneRedisManager.set(WorkAloneRedisManager.java:73)
	at org.crazycake.shiro.RedisSessionDAO.saveSession(RedisSessionDAO.java:73)
	at org.crazycake.shiro.RedisSessionDAO.doCreate(RedisSessionDAO.java:124)
	at org.apache.shiro.session.mgt.eis.AbstractSessionDAO.create(AbstractSessionDAO.java:116)
	at org.apache.shiro.session.mgt.DefaultSessionManager.create(DefaultSessionManager.java:177)
	at org.apache.shiro.session.mgt.DefaultSessionManager.doCreateSession(DefaultSessionManager.java:158)
	at org.apache.shiro.session.mgt.AbstractValidatingSessionManager.createSession(AbstractValidatingSessionManager.java:136)
	at org.apache.shiro.session.mgt.AbstractNativeSessionManager.start(AbstractNativeSessionManager.java:99)
	at org.apache.shiro.mgt.SessionsSecurityManager.start(SessionsSecurityManager.java:152)
	at org.apache.shiro.subject.support.DelegatingSubject.getSession(DelegatingSubject.java:340)
	at org.apache.shiro.subject.support.DelegatingSubject.getSession(DelegatingSubject.java:316)
	at org.apache.shiro.mgt.DefaultSubjectDAO.mergePrincipals(DefaultSubjectDAO.java:207)
	at org.apache.shiro.mgt.DefaultSubjectDAO.saveToSession(DefaultSubjectDAO.java:165)
	at org.apache.shiro.mgt.DefaultSubjectDAO.save(DefaultSubjectDAO.java:146)
	at org.apache.shiro.mgt.DefaultSecurityManager.save(DefaultSecurityManager.java:387)
	at org.apache.shiro.mgt.DefaultSecurityManager.createSubject(DefaultSecurityManager.java:354)
	at org.apache.shiro.mgt.DefaultSecurityManager.createSubject(DefaultSecurityManager.java:187)
	at org.apache.shiro.mgt.DefaultSecurityManager.login(DefaultSecurityManager.java:287)
	at org.apache.shiro.subject.support.DelegatingSubject.login(DelegatingSubject.java:260)
	at org.apache.shiro.web.filter.authc.AuthenticatingFilter.executeLogin(AuthenticatingFilter.java:53)
	at henu.soft.xiaosi.shiro.ShiroFilter.onAccessDenied(ShiroFilter.java:91)
	at org.apache.shiro.web.filter.AccessControlFilter.onAccessDenied(AccessControlFilter.java:133)
	at org.apache.shiro.web.filter.AccessControlFilter.onPreHandle(AccessControlFilter.java:162)
	at org.apache.shiro.web.filter.PathMatchingFilter.isFilterChainContinued(PathMatchingFilter.java:203)
	at org.apache.shiro.web.filter.PathMatchingFilter.preHandle(PathMatchingFilter.java:178)
	at henu.soft.xiaosi.shiro.ShiroFilter.preHandle(ShiroFilter.java:56)
	at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:131)
	at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
	at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
	at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)
	at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
	at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
	at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
	at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:387)
	at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
	at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:888)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1597)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.base/java.lang.Thread.run(Thread.java:834)

干脆直接改bind 127.0.0.1,发现requirepass前面有个空格,删去试试

在这里插入图片描述

发现还是不行,既然设置了bind 127.0.0.1,直接取消密码

在这里插入图片描述

终终终于能跑起来了,心累。

五、数据初始

mongodb的部分数据初始,后端需要调整更新mongodb自动生成ObjectId 对应的 service 里面的业务逻辑 表id(因为不同机器的ObjectId是不同的,而且时间戳也不同)

  • 学院表college
  • 角色表role
  • 基层教学组织名称表organization_name

其实可以单独设置一个字段来作为动态生成的ObjectId,可以方便部署,不过多次部署的情况好像也并不需要,方便这来吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

scl、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值