个人整体项目:今日诊股(今日指数)后端代码开发(day01)

(当前开源个人项目正在开发,请关注个人项目专栏。需要源码请关注留言哦!!!)
(怀玉是一名一年的后端,前端目前不太精通,前端代码是直接写好的)

首先我们先看一张图:

在这里插入图片描述
这大概就是我需要写的效果一部分,接下来我会介绍一下股票的一些基础知识。
注意:

一、概念介绍

1.1什么是股票:

股票是股份公司发给股东证明其所入股份的一种有价证券(有效凭证),它可以作为买卖对象和抵押品,是资金市场中主要的信用工具之一。

1.2股票的分类

A股:★★★

即人民币普通股票,是由中国境内注册公司发行,在境内上市,以人民币标明面值,供境内机构、组织或个人(2013年4月1日起,境内港澳台居民可开立A股账户)以人民币认购和交易的普通股股票。
英文字母A没有实际意义,只是用来区分人民币普通股票和人民币特种股票。

A股中的股票分类

-绩优股:绩优股就是业绩优良公司的股票;
-垃圾股:与绩优股相对应,垃圾股指的是业绩较差的公司的股票;
-蓝筹股:指在其所属行业内占有重要支配性地位业绩优良成交活跃、红利优厚的大公司股票;

B股

也称为人民币特种股票。是指那些在中国大陆注册、在中国大陆上市的特种股票。以人民币标明面值,只能以外币认购和交易;部分股票也开放港元交易;

H股

也称为国企股,是指国有企业在香港 (Hong Kong) 上市的股票;

N股

是指那些在中国大陆注册、在纽约(New York)上市的外资股;

SCA股

是指那些主要生产或者经营等核心业务在中国大陆、而企业的注册地在新加坡(Singapore)或者其他国家和地区,但是在新加坡交易所上市挂牌的企业股票;

1.3股票核心参数介绍

在这里插入图片描述
开盘价

是指证券交易所在每个交易日开市后的第一笔股票买卖成交的价格; 中国股市的开盘价格是由市场集合竞价所产生的。
在A股市场中,股票的开盘价是由集合竞价的9点15分至9点25分买卖双方的撮合,股票价格在有效价格范围内选取成交量最大的价位所产生的,也是证券交易所每个交易日开市后的第一笔每股买卖成交价格。如果集合竞价的时间内股票没有买卖或没有成交,则股票前一日的收盘价作为当日股票的开盘价。
一般状况:开盘参考价=前一买卖日收盘价。

收盘价

又称收市价,是指某只股票在证券交易所每个交易日里的【最后一笔买卖成交价格】; 如果某只股票当日没有成交,则采用最近一次的成交价作为收盘价;

涨跌值

当前股票的价格与前一天的收盘价比价,来反应股票的实时涨跌情况; 计算公式为:最新价格-前收盘价格
注意:一般在交易台上用“+”或“-”号表示,单位是元,正值为涨,负值为跌,否则为持平;

涨跌幅

是对涨跌值的描绘; 计算公式为:股票涨跌幅计算公式:(最新成交价-前收盘价)÷前收盘价×100% 也就是(涨跌值)÷前收盘价×100%

涨停与跌停

就是一种对股市涨跌幅的限制;
证券交易所为了抑制过度投机行为,防止市场出现过分的暴涨暴跌,强制约定在每天的交易中股票的涨跌幅必须在规定的区间内上下波动。如果股票价格上升到该限制幅度的最高限价为涨停板,而下跌至该限制幅度的最低限度为跌停板。
1、涨停指的是价格涨到一定幅度,价格会被限制,不再变动,但是可以继续交易。
2、跌停指的是价格跌到一定幅度,价格会被限制,不在变动,但是可以继续交易。
3、在中国A股市场,均设有涨幅和跌幅的限制,他们都是【涨跌幅10%】的限制,即所谓的涨停和跌停。 注意事项: 涨停和跌停适用中国所有A股,但是对于第一次上市交易股票当天是没有涨停限制的,第二天才有限制(打新);
股票交易采用T+1机制,也就是当日买进,那么最快第二个交易日才可卖出;

振幅

股票振幅是指股票开盘后的当日最高价和最低价之间的差的绝对值与昨日收盘价的百分比,它在一定程度上表现股票的活跃程度。
计算公式为:(当日最高价-当日最低价)÷ 前收盘价 ×100%

成交量

成交量指当天成交的股票总手数(1手=100股); 计算则是由交易所直接进行计算;

成家金额

股票成交额是指某一特定时期内,成交某种股票的金额,其单位以人民币"元"计算; 成交金额就是每股价格乘交易的手数,再乘上100。
例如:投资者以每股10元的价格买入50手,10X50X100=50000,此时的5万就是成交额。
注意:
成交总金额又称总额,总额是指当天开盘以来总成交金额,单位以人民币"元"计算。
简单的说,这个总金额是反应当日有多少资金进行了成交操作。

股票编码

1、创业板 :创业板的代码是300打头的股票代码;
2、沪市A股 :沪市A股的代码是以600、601或603打头;★★★
3、沪市B股:沪市B股的代码是以900打头;
4、深市A股 :深市A股的代码是以000打头;★★★
5、中小板 :中小板的代码是002打头;
6、深圳B股: 深圳B股的代码是以200打头;
7、新股申购 :沪市新股申购的代码是以730打头 深市新股申购的代码与深市股票买卖代码一样;
8、配股代码:沪市以700打头,深市以080打头 权证,沪市是580打头 深市是031打头。
9、 400开头的股票是三板市场股票。
注意:国内上市公司可选择在上海证券交易所(上证)、深证证券交易所(深证)挂牌上市,中小型企业可选择北交所上市;

K线

K线图(Candlestick
Charts)又称蜡烛图、日本线、【阴阳线】、棒线等,常用说法是“K线”,起源于日本十八世纪德川幕府时代(1603~1867年)的米市交易,用来计算米价每天的涨跌。
它是以每个交易日(或每个分析周期,甚至是月年)的开盘价、最高价、最低价、和收盘价绘制而成,结构上可分为上影线、下影线及中间实体三部分。

k线图
在这里插入图片描述
示例

在这里插入图片描述

二、项目架构

2.1今日指数技术选型
2.1.1 前端技术
名称技术场景
基本股价vue-cli+vue+element+axios
报表echartsjs【百度,百度共享出去开源了】
前端支持node webpack 等
2.1.2 后端技术栈
名称技术场景
基础框架springboot、mybatis-springboot、springMVC项目基础骨架
安全框架boot-security+jwt认证与授权
缓存redis缓存
excel表格导出easyexcel 【国产阿里巴巴】
小组件jode-date【日期】 、gson【json】 、guava 、httpClient | restTemplate 【模拟浏览器发送http请求】、线程池
定时任务xxljob 【大众点评】
文档框架swagger【生成接口文档】
分库分表sharding-JDBC【apache】
部署nginx
2.1.3整体概览

在这里插入图片描述

2.2核心业务介绍
2.2.1业务结构预览

在这里插入图片描述

2.2.2 业务功能简介

1.定时任务调度服务,XXL-JOB通过RestTemplate+多线程动态拉去股票接口数据,刷入数据库;
2.国内指数服务;
3.板块指数服务;
4.涨幅榜展示功能;
5.涨停跌停数展示功能;
6.成交量对比展示功能;
7.个股涨停服务展示功能;
8.个股详情展示功能,包含分时行情、日k线、周K线图等;
9.个股描述服务;
10.报表导出服务.

三、软件开发流程说明

3.1软件开发流程

在这里插入图片描述
第1阶段: 需求分析

完成产品原型、需求规格说明书|| 需求说明书的编写。

产品原型:一般是通过网页(html)的形式展示业务功能,。比如包含页面的布局是什么样子的,点击某个菜单,打开什么页面,点击某个按钮,出现什么效果,都可以通过产品原型看到。

需求规格说明书, 一般来说就是使用 Word 文档来描述当前项目有哪些功能,每一项功能的需求及业务流程是什么样的,都会在文档中描述。

产品!

企业中给你原型:某个图片或者文字

第2阶段: 设计

设计的内容包含 产品设计、UI界面设计、概要设计、详细设计(接口设计是其中一个部分)、数据库设计。

在设计阶段,会出具相关的UI界面、及相关的设计文档。比如数据库设计,需要设计当前项目中涉及到哪些数据库,每一个数据库里面包含哪些表,这些表结构之间的关系是什么样的,表结构中包含哪些字段,字段类型都会在文档中描述清楚。

在该阶段查出:UI界面(纯静态的html页面)、概要设计文档(涵盖笼统的核心模块)、详细设计(具体功能的设计,包含接口设计产出:接口文档说明书)、数据库设计(设计业务关联的表、表与表之间的关系、表中的字段、字段的类型、索引等等)

第3阶段: 编码

项目管理人员或者项目组长|架构师任务分发;【日报,周报】

编写项目代码、并完成单元测试;

作为软件开发工程师,我们主要的工作就是在该阶段, 对分配给我们的模块功能,进行编码实现。编码实现完毕后,进行单元测试,单元测试通过后再进入到下一阶段;

第4阶段: 测试

在该阶段中主要由测试人员, 对部署在测试环境的项目进行功能测试, 并出具测试报告。(测试外包,外包提供测试报告,缺陷报告)

第5阶段: 上线运维

4个9999 保证全年99.9999%;

在项目上线之前, 会由运维人员准备服务器上的软件环境安装、配置, 配置完毕后, 再将我们开发好的项目,部署在服务器上运行。

沙箱环境 | 准生产环境:最大程度模拟生产环境,又不是生产环境;

注意:

我们作为软件开发工程师, 我们主要的任务是在编码阶段, 但是在一些小的项目组当中, 也会涉及到数据库的设计、测试等方面的工作。

3.2 软件开发角色分工

在这里插入图片描述

3.3 软件开发环境

在我们日常的软件开发中,会涉及到软件开发中的三套环境, 那么这三套环境分别是: 开发环境、测试环境、生产环境。
接下来,我们分别介绍一下这三套环境的作用和特点。

开发环境(development)

我们作为软件开发人员,在开发阶段使用的环境,就是开发环境,一般外部用户无法访问。

比如,我们在开发中使用的MySQL数据库和其他的一些常用软件,我们可以安装在本地, 也可以安装在一台专门的服务器中, 这些应用软件仅仅在软件开发过程中使用, 项目测试、上线时,我们不会使用这套环境了,这个环境就是开发环境。

测试环境(testing)

当软件开发工程师,将项目的功能模块开发完毕,并且单元测试通过后,就需要将项目部署到测试服务器上,让测试人员对项目进行测试。那这台测试服务器就是专门给测试人员使用的环境, 也就是测试环境,用于项目测试,一般外部用户无法访问。

生产环境(production)

当项目开发完毕,并且由测试人员测试通过之后,就可以上线项目,将项目部署到线上环境,并正式对外提供服务,这个线上环境也称之为生产环境。

拓展知识:

准生产环境: 对于有的公司来说,项目功能开发好, 并测试通过以后,并不是直接就上生产环境。为了保证我们开发的项目在上线之后能够完全满足要求,就需要把项目部署在真实的环境中, 测试一下是否完全符合要求啊,这时候就诞生了准生产环境,你可以把他当做生产环境的克隆体,准生产环境的服务器配置, 安装的应用软件(JDK、Tomcat、数据库、中间件 …) 的版本都一样,这种环境也称为 “仿真环境”。

​ ps:(postscript 补充)由于项目的性质和类型不同,有的项目可能不需要这个环境

四、后端开发环境搭建

开发工具版本要求
在这里插入图片描述

4.1 数据库环境搭建
4.1.1 表结构介绍

在这里插入图片描述
在这里插入图片描述

4.1.2 数据导入

在这里插入图片描述
在这里插入图片描述
或者执行SQL脚本:

CREATE DATABASE `db_stock` CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_general_ci';

在这里插入图片描述
在这里插入图片描述
说明

上述的表结构, 我们先简单的了解一下,大概有那些表, 每张表结构中存储什么样的数据, 有一个印象;
对于具体的表结构, 以及表结构中的字段, 在讲解具体的功能开发时, 我们再详细介绍;

4.2后端工程搭建
4.2.1 构建stock_parent父工程

在这里插入图片描述
构建stock_parent maven工程:
在这里插入图片描述
pom.xml(可以直接复制)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.itheima.stock</groupId><artifactId>stock_parent</artifactId><version>1.0.0</version><properties><!--锁定项目字符集为UTF-8--><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.encoding>UTF-8</maven.compiler.encoding><!--锁定Java版本为1.8--><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><maven.test.skip>true</maven.test.skip><spring-boot.version>2.7.4</spring-boot.version><mybatis-spring-boot-starter.version>2.2.2</mybatis-spring-boot-starter.version><pagehelper-spring-boot-starter.version>1.4.5</pagehelper-spring-boot-starter.version><druid-spring-boot-starter.version>1.2.12</druid-spring-boot-starter.version><sharding-jdbc-spring-boot-starter.version>4.0.0-RC1</sharding-jdbc-spring-boot-starter.version><mysql.version>8.0.30</mysql.version><fastjson.version>1.2.83</fastjson.version><joda-time.version>2.11.2</joda-time.version><springfox-swagger2.version>3.0.0</springfox-swagger2.version><jjwt.version>0.9.1</jjwt.version><xxl-job-core.version>2.3.1</xxl-job-core.version><easyexcel.version>3.1.1</easyexcel.version><druid.version>1.2.12</druid.version><guava.version>31.1-jre</guava.version><maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version></properties><dependencyManagement><dependencies><!--声明springboot 依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope></dependency><!--声明mybatis 起步依赖--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>${mybatis-spring-boot-starter.version}</version></dependency><!--声明pageHelper 起步依赖--><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>${pagehelper-spring-boot-starter.version}</version></dependency><!--声明druid 起步依赖--><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>${druid-spring-boot-starter.version}</version></dependency><!--声明sharding jdbc 起步依赖--><dependency><groupId>org.apache.shardingsphere</groupId><artifactId>sharding-jdbc-spring-boot-starter</artifactId><version>${sharding-jdbc-spring-boot-starter.version}</version></dependency><!--声明mysql驱动依赖--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql.version}</version></dependency><!--声明fastjson 依赖--><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>${fastjson.version}</version></dependency><!--声明druid 依赖--><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>${druid.version}</version></dependency><!--声明 swagger依赖--><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>${springfox-swagger2.version}</version></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>${springfox-swagger2.version}</version></dependency><!--声明jwt依赖--><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>${jjwt.version}</version></dependency><!--声明easyexcel依赖 --><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>${easyexcel.version}</version></dependency><!--声明xxl-job依赖--><dependency><groupId>com.xuxueli</groupId><artifactId>xxl-job-core</artifactId><version>${xxl-job-core.version}</version></dependency><!--声明joda-time依赖--><dependency><groupId>joda-time</groupId><artifactId>joda-time</artifactId><version>${joda-time.version}</version></dependency><!--声明guava依赖--><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>${guava.version}</version></dependency><!--开发的时候,频繁重启项目测试,提升重启速度--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><version>${spring-boot.version}</version></dependency></dependencies></dependencyManagement><build><pluginManagement><plugins><!--Springboot核心插件--><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>${spring-boot.version}</version><configuration><excludes><!--插件运行时排除依赖:这两个依赖都是在编译期间有作用,运行期间用,打包时候排除掉--><exclude><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId></exclude><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin><!--打包跳过test --><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>${maven-surefire-plugin.version}</version><configuration><skip>${maven.test.skip}</skip></configuration></plugin></plugins></pluginManagement></build></project>

注意事项

1.通过dependencyManagement、pluginManagement锁定开发中的依赖和插件的版本;
2.复制pom文件中内容到你的工程中可能会报错,不要紧张,是因为你的仓库中没有对应的依赖。继续往后学习

4.2.2 构建stock_backendj基础工程

创建stock_paren的maven子工程stock_backend
在这里插入图片描述
stock_backend工程创建完成以后,stock_parent工程中pom文件变化:
在这里插入图片描述

4.2.3 引入依赖

stock_backend工程被stock_parent父工程,pom配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><!--继承父工程stock_parent--><parent><artifactId>stock_parent</artifactId><groupId>com.itheima.stock</groupId><version>1.0.0</version></parent><modelVersion>4.0.0</modelVersion><artifactId>stock_backend</artifactId><dependencies><!-- web 起步依赖:提供web开发基本功能 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--aop 起步依赖:提供aop开发基本功能--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency><!--test 起步依赖:提供测试相关功能--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!--mybatis起步依赖:提供mybatis功能--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId></dependency><!--pagehelper 起步依赖:基于分页插件为mybatis提供分页功能--><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId></dependency><!--druid 起步依赖:提供连接数据库数据源功能--><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId></dependency><!--mysql 依赖:提供连接MySQL数据库功能--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><!--配置提示依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency><!--时间小工具joda依赖--><dependency><groupId>joda-time</groupId><artifactId>joda-time</artifactId></dependency><!--lombok依赖:提供简化pojo类编写的功能比如生成get和set方法--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><scope>provided</scope><optional>true</optional></dependency><!--springboot 开发工具依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency></dependencies><build><!--打包名称--><finalName>${project.artifactId}</finalName><plugins><!--打成可执行jar包插件--><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin><!-- 打包跳过test --><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId></plugin></plugins></build></project>
4.2.4 配置yml

在src/main/resources 创建application.yml

# web定义
server:port: 8081spring:# 配置mysql数据源datasource:druid:username: rootpassword: rooturl: jdbc:mysql://127.0.0.1:3306/db_stock?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false&serverTimezone=Asia/Shanghaidriver-class-name: com.mysql.cj.jdbc.Driver# 初始化时建立物理连接的个数。初始化发生在显示调用 init 方法,或者第一次 getConnection 时initialSize: 6# 最小连接池数量minIdle: 2# 最大连接池数量maxActive: 20# 获取连接时最大等待时间,单位毫秒。配置了 maxWait 之后,缺省启用公平锁,# 并发效率会有所下降,如果需要可以通过配置 useUnfairLock 属性为 true 使用非公平锁。maxWait: 60000# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒timeBetweenEvictionRunsMillis: 60000# 配置一个连接在池中最小生存的时间,单位是毫秒minEvictableIdleTimeMillis: 300000# 用来检测连接是否有效的 sql 因数据库方言而差, 例如 oracle 应该写成 SELECT 1 FROM DUALvalidationQuery: SELECT 1 FROM DUAL# 建议配置为 true,不影响性能,并且保证安全性。申请连接的时候检测,# 如果空闲时间大于 timeBetweenEvictionRunsMillis,执行 validationQuery 检测连接是否有效。testWhileIdle: true# 申请连接时执行 validationQuery 检测连接是否有效,做了这个配置会降低性能。testOnBorrow: false# 归还连接时执行 validationQuery 检测连接是否有效,做了这个配置会降低性能。testOnReturn: false# 是否自动回收超时连接poolPreparedStatements: truemaxPoolPreparedStatementPerConnectionSize: 20# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙filters: stat,wall# 通过connectProperties属性来打开mergeSql功能;慢SQL记录connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000# 配置mybatis
mybatis:type-aliases-package: com.itheima.stock.pojomapper-locations: classpath:mapper/*.xmlconfiguration:map-underscore-to-camel-case: truecache-enabled: false #使全局的映射器启用或禁用缓存。lazy-loading-enabled: false #全局启用或禁用延迟加载。当禁用时,所有关联对象都会即时加载。aggressive-lazy-loading: true #当启用时,有延迟加载属性的对象在被调用时将会完全加载任意属性。否则,每种属性将会按需要加载。# pagehelper配置
pagehelper:helper-dialect: mysql #指定分页数据库类型(方言)reasonable: true #合理查询超过最大也,则查询最后一页support-methods-arguments: true # 支持通过Mapper接口参数来传递分页参数,默认falseparams: pacount=countSql # POJO或者Map中发现了countSql属性,就会作为count参数使用returnPageInfo: check # always总是返回PageInfo类型,check检查返回类型是否为PageInfo,none返回Page
4.2.5 定义main启动类
package com.itheima.stock;import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;/*** @author ghy* @version 1.0* @description 引导类* @date 2022/10/1 19:47:04*/
@Slf4j
@SpringBootApplication
@MapperScan(basePackages = {"com.itheima.stock.mapper"})
public class StockApp {public static void main(String[] args) {SpringApplication.run(StockApp.class,args);log.info("项目启动成功......");}
}
4.2.6 定义web测试接口
package com.itheima.stock.controller;import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** @author ghy* @version 1.0* @description 用户表现层* @date 2022/10/1 19:50:29*/
@RestController
@RequestMapping(path = "/api")
public class UserController {@GetMapping(path = "/test")public String getName() {return "itheima";}
}
4.2.7 测试环境搭建

在这里插入图片描述
到这儿,工程基础环境就搭建完毕了

4.3 快速构建mybatis业务开发环境
4.3.1 mybatis逆向工程使用

借助mybatisX工具生成基础代码

第一步:通过idea自带的database组件连接数据库:
在这里插入图片描述
第二步:配置pojo实体类选项
在这里插入图片描述
第三步:配置mapper接口和xml选项:
在这里插入图片描述

4.3.2 集成mybatis的工程结构

在这里插入图片描述

4.3.3 环境整体测试

目的:我们通过一个简单的web接口访问数据库,验证工程搭建情况
接口功能说明:查询所有上市公司主营业务数据(阅读理解能力!)
思考:
(查询(select)表(stock_business))
技术mybatis
mapper接口
mapper映射
实体类
接口url:/api/quot/stock/business/all
思考:
web层controller 方法 :参数 返回值(集合)

定义mapper接口方法
StockBusinessMapper接口和xml定义查询所有股票业务信息的接口方法:

   /*** 查询所有股票主营业务数据** @return*/List<StockBusiness> selectAllStockBusiness();
     <!--1.查询所有股票主营业务数据--><select id="selectAllStockBusiness" resultMap="BaseResultMap">        select        <include refid="Base_Column_List"/>        from stock_business    </select>

定义服务接口及实现

package com.itheima.stock.service;import com.itheima.stock.pojo.StockBusiness;import java.util.List;/*** @author ghy* @version 1.0* @description 股票服务接口* @date 2022/10/1 21:05:44*/
public interface StockService {/*** 获取所有股票主营业务数据** @return*/List<StockBusiness> getAllStockBusiness();
}

定义服务接口实现

package com.itheima.stock.service.impl;import com.itheima.stock.common.domain.InnerMarketDomain;
import com.itheima.stock.common.domain.StockInfoConfig;
import com.itheima.stock.mapper.StockBusinessMapper;
import com.itheima.stock.mapper.StockMarketIndexInfoMapper;
import com.itheima.stock.pojo.StockBusiness;
import com.itheima.stock.service.StockService;
import com.itheima.stock.vo.resp.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;/*** @author ghy* @version 1.0* @description 股票服务接口实现类* @date 2022/10/1 21:09:30*/
@Service
public class StockServiceImpl implements StockService {@Autowiredprivate StockBusinessMapper stockBusinessMapper;@Overridepublic List<StockBusiness> getAllStockBusiness() {return stockBusinessMapper.selectAllStockBusiness();}
}

定义web访问接口

package com.itheima.stock.controller;import com.itheima.stock.pojo.StockBusiness;
import com.itheima.stock.service.StockService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.List;/*** @author ghy* @version 1.0* @description 股票访问层* @date 2022/10/1 21:17:30*/
@RestController
@RequestMapping(path = "/api/quot")
@CrossOrigin
public class StockController {@Autowiredprivate StockService stockService;@GetMapping(path = "/stock/business/all")public List<StockBusiness> getAllBusiness() {return stockService.getAllStockBusiness();}}

启动项目测试
在这里插入图片描述

五、前端开发环境搭建

5.1前端环境准备
5.1.1 node安装

安装完成在cmd中会返回如下内容:
在这里插入图片描述

(前端的代码过于复杂,我已经上传了代码文件到资料)

六、登录功能实现

6.1 需求分析
6.1.1 页面原型效果

在这里插入图片描述

6.1.2 相关的表结构

sys_user表如下:
在这里插入图片描述

6.1.3 访问接口定义

请求接口:/api/login
请求方式:POST
请求数据示例:
{
username:‘zhangsan’,//用户名
password:‘666’,//密码
code:‘1234’ //校验码
}
响应数据:
{
“code”: 1,//成功1 失败0
“data”: {
“id”:“1237365636208922624”,
“username”:“zhangsan”,
“nickName”:“xiaozhang”,
“phone”:“1886702304”
}
}

6.1.4封装请求和响应VO

请求VO封装

package com.itheima.stock.vo.req;import lombok.Data;/*** 登录请求Vo ,这个对象封装的就是登录接口的请求数据*/
@Data
public class LoginReqVo {/*** 用户名*/private String username;/*** 密码*/private String password;/*** 验证码*/private String code;
}

响应VO

package com.itheima.stock.vo.resp;import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;/***  登录接口响应Vo*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class LoginRespVo {/*** 用户ID*/private String id;/*** 电话*/private String phone;/*** 用户名*/private String username;/*** 昵称*/private String nickName;}

定义公共响应VO

package com.itheima.stock.vo.resp;import com.fasterxml.jackson.annotation.JsonInclude;import java.io.Serializable;/*** @author ghy* @version 1.0* @description 统一响应数据格式类* @date 2022/10/1 22:38:39*/
@JsonInclude(JsonInclude.Include.NON_NULL)
public class R<T> implements Serializable {private static final long serialVersionUID = 7735505903525411467L;// 成功值private static final int SUCCESS_CODE = 1;// 失败值private static final int ERROR_CODE = 0;//状态码private int code;//消息private String msg;//返回数据private T data;private R(int code){this.code = code;}private R(int code, T data){this.code = code;this.data = data;}private R(int code, String msg){this.code = code;this.msg = msg;}private R(int code, String msg, T data){this.code = code;this.msg = msg;this.data = data;}public static <T> R<T> ok(){return new R<T>(SUCCESS_CODE,"success");}public static <T> R<T> ok(String msg){return new R<T>(SUCCESS_CODE,msg);}public static <T> R<T> ok(T data){return new R<T>(SUCCESS_CODE,data);}public static <T> R<T> ok(String msg, T data){return new R<T>(SUCCESS_CODE,msg,data);}public static <T> R<T> error(){return new R<T>(ERROR_CODE,"error");}public static <T> R<T> error(String msg){return new R<T>(ERROR_CODE,msg);}public static <T> R<T> error(int code, String msg){return new R<T>(code,msg);}public int getCode(){return code;}public String getMsg(){return msg;}public T getData(){return data;}
}

定义响应状态枚举

package com.itheima.stock.common.enums;/*** @author ghy* @version 1.0* @description 响应状态枚举类* @date 2022/10/1 22:42:28*/
public enum ResponseCode {ERROR(0, "操作失败"),SUCCESS(1, "操作成功"),DATA_ERROR(0, "参数异常"),NO_RESPONSE_DATA(0, "无响应数据"),SYSTEM_VERIFY_CODE_NOT_EMPTY(0, "验证码不能为空"),SYSTEM_VERIFY_CODE_ERROR(0, "验证码错误"),SYSTEM_USERNAME_NOT_EMPTY(0, "账号不能为空"),SYSTEM_USERNAME_NOT_EXISTS(0, "账号不存在"),SYSTEM_USERNAME_EXPIRED(0, "账户过期"),SYSTEM_USERNAME_LOCKED(0, "账户被锁"),SYSTEM_USERNAME_DISABLED(0, "账户被禁用"),SYSTEM_PASSWORD_ERROR(0, "账号或密码错误"),SYSTEM_PASSWORD_EXPIRED(0, "密码过期"),SYSTEM_USERNAME_OFFLINE(0, "已下线,请重新登录"),SYSTEM_ERROR(0, "系统异常请稍后再试"),ACCOUNT_EXISTS_ERROR(0, "该账号已存在"),TOKEN_ERROR(2, "用户未登录,请先登录"),NOT_PERMISSION(3, "没有权限访问该资源"),TOKEN_NOT_NULL(-1, "token 不能为空"),TOKEN_NO_AVAIL(-1, "token无效或过期"),TOKEN_PAST_DUE(-1, "登录失效,请重新登录"),TOKEN_EXISTS(-1, "账号异地登录,你已被迫退出"),OPERATION_MENU_PERMISSION_CATALOG_ERROR(0, "操作后的菜单类型是目录,所属菜单必须为默认顶级菜单或者目录"),OPERATION_MENU_PERMISSION_MENU_ERROR(0, "操作后的菜单类型是菜单,所属菜单必须为目录类型"),OPERATION_MENU_PERMISSION_BTN_ERROR(0, "操作后的菜单类型是按钮,所属菜单必须为菜单类型"),OPERATION_MENU_PERMISSION_URL_NOT_NULL(0, "菜单权限的url不能为空"),OPERATION_MENU_PERMISSION_URL_PERMS_NULL(0, "菜单权限的标识符不能为空"),OPERATION_MENU_PERMISSION_URL_METHOD_NULL(0, "菜单权限的请求方式不能为空"),OPERATION_MENU_PERMISSION_URL_CODE_NULL(0, "菜单权限的按钮标识不能为空"),OPERATION_MENU_PERMISSION_UPDATE(0, "操作的菜单权限存在子集关联不允许变更"),ROLE_PERMISSION_RELATION(0, "该菜单权限存在子集关联,不允许删除"),OLD_PASSWORD_ERROR(0, "旧密码不匹配");/*** 状态码*/private int code;/*** 消息*/private String message;private ResponseCode(int code, String message) {this.code = code;this.message = message;}public int getCode() {return this.code;}public String getMessage() {return this.message;}
}
6.2 登录功能开发实现
6.2.1 stock_backend导入依赖资源
<!--apache工具包:java.lang 包中类的工具类,String -->
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId>
</dependency>
<!--密码加密和校验工具包:安全相关功能,比如密码加密器-->
<dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-crypto</artifactId>
</dependency>
<!--guava工具包 Java开发过程工具类,比如项目中使用的Strings-->
<dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId>
</dependency>
6.2.2 配置密码加密服务
package com.itheima.stock.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;/*** @author ghy* @version 1.0* @description 公共配置类* @date 2022/10/1 21:54:41*/
@Configuration
public class CommonConfig {/***  密码加密器  BCryptPasswordEncoder 采用 SHA-256 算法* @return*/@Beanpublic PasswordEncoder passwordEncoder(){BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();return bCryptPasswordEncoder;}}

密码加密测试

创建测试基类:在src/test拆功能键Base Test.java

package com.itheima.stock;import org.springframework.boot.test.context.SpringBootTest;/*** @author ghy* @version 1.0* @description 单元测试基类* @date 2022/10/1 19:59:12*/
@SpringBootTest
public class BaseTest {}

创建测试类

package com.itheima.stock.config;import com.itheima.stock.BaseTest;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;/*** @author ghy* @version 1.0* @description* @date 2022/10/1 22:08:19*/
public class CommonConfigTest extends BaseTest {@Autowiredprivate PasswordEncoder passwordEncoder;/*** 测试 密码加密/比对*/@Testpublic void testEncodePassword() {// 模拟未加密的密码String rawPassword = "123456";// 对密码加密得到加密后的密码:$2a$10$PWfx6UNdiUMEnqr.Y0UiP.NUFOTjQmG6wU9SSlbY5lXGBIB1C9XwS// 注意:统一个密码使用encode方法多次加密的密文是并不一样String encodePassword = passwordEncoder.encode(rawPassword);// 输出加密后的密码System.out.println(encodePassword);// 使用未加密的密码和加密后的密码比对,比对成功返回true,否则返回falseboolean matches = passwordEncoder.matches(rawPassword, encodePassword);System.out.println(matches);}
}
6.2.3 登录接口方法定义
package com.itheima.stock.controller;import com.itheima.stock.service.UserService;
import com.itheima.stock.vo.req.LoginReqVo;
import com.itheima.stock.vo.resp.LoginRespVo;
import com.itheima.stock.vo.resp.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;/*** @author by itheima* @Date 2021/12/29* @Description 定义用户访问层*/
@RestController
@RequestMapping("/api")
@CrossOrigin
public class UserController {@Autowiredprivate UserService userService;/*** 用户登录功能实现* @param vo* @return*/@PostMapping("/login")public R<LoginRespVo> login(@RequestBody LoginReqVo vo){R<LoginRespVo> r= this.userService.login(vo);return r;}//    @GetMapping("/test")
//    public String getName(){
//        return "itheima";
//    }
}
6.2.4 定义登录服务接口和实现

服务接口:

package com.itheima.stock.service;import com.itheima.stock.vo.req.LoginReqVo;
import com.itheima.stock.vo.resp.LoginRespVo;
import com.itheima.stock.vo.resp.R;/*** @author by itheima* @Date 2021/12/30* @Description 用户服务*/
public interface UserService {/*** 用户登录功能实现* @param vo* @return*/R<LoginRespVo> login(LoginReqVo vo);
}

服务接口实现:

package com.itheima.stock.service.impl;import com.google.common.base.Strings;
import com.itheima.stock.common.enums.ResponseCode;
import com.itheima.stock.mapper.SysUserMapper;
import com.itheima.stock.pojo.SysUser;
import com.itheima.stock.service.UserService;
import com.itheima.stock.vo.req.LoginReqVo;
import com.itheima.stock.vo.resp.LoginRespVo;
import com.itheima.stock.vo.resp.R;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;/*** @author by itheima* @Date 2021/12/30* @Description 定义服务接口实现*/
@Service("userService")
public class UserServiceImpl implements UserService {@Autowiredprivate SysUserMapper sysUserMapper;@Autowiredprivate PasswordEncoder passwordEncoder;@Overridepublic R<LoginRespVo> login(LoginReqVo vo) {if (vo==null || Strings.isNullOrEmpty(vo.getUsername()) || Strings.isNullOrEmpty(vo.getPassword())){return R.error(ResponseCode.DATA_ERROR.getMessage());}//根据用户名查询用户信息SysUser user=this.sysUserMapper.findByUserName(vo.getUsername());//判断用户是否存在,存在则密码校验比对if (user==null || !passwordEncoder.matches(vo.getPassword(),user.getPassword())){return R.error(ResponseCode.SYSTEM_PASSWORD_ERROR.getMessage());}//组装登录成功数据LoginRespVo respVo = new LoginRespVo();//属性名称与类型必须相同,否则copy不到BeanUtils.copyProperties(user,respVo);return  R.ok(respVo);}
}
6.2.5 定义mapper方法

在SysUserMapper下定义接口方法:

    /*** 根据用户名查询用户信息* @param username* @return*/SysUser findByUserName(@Param("username") String username);

绑定xml:

    <select id="findByUserName" resultMap="BaseResultMap">select <include refid="Base_Column_List"/> from sys_user whereusername=#{username}</select>
6.2.6 Postman测试结果

(后续会继续更新项目代码和项目进度,请关注个人项目专栏)

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python版股市情感分析源代码,提取投资者情绪,为决策提供参考

情绪与股市关系的研究由来已久&#xff0c;情绪是市场的一个重要影响因素已成为共识。 15年股灾时&#xff0c;亲历了一次交易灾难&#xff0c;眼见朋友的数千万在一周不到的时间内灰飞烟灭。那段时间市场的疯狂&#xff0c;让人深刻地明白&#xff1a;某些时候&#xff0c;股票…

干货全拿走-用Excel获取上证指数等50+股指行情及历史数据

一、 前言 二、 实现思路 三、 核心代码 四、 注意事项 一、前言 大数据时代&#xff0c;数据分析的价值愈发凸显&#xff0c;数据对于金融市场亦如是。现在越来越多的金融机构和个人借助专业的软件去做数据分析和获取数据&#xff0c;但是显然对于普通人来说&#xff0c;…

程序员能用大数据分析,用脚本测算股市的状况吗?

星期一的基金收益更新&#xff0c;没想到竟然… 8月2日的支付宝基金收益收益为2443元&#xff0c;今日收益为负值&#xff0c;上个星期暴跌4天&#xff0c;大盘很大大浮动。细看一下我的仓位&#xff0c;从上星期到现在都一直是这几个&#xff0c;没变过&#xff0c;医疗板块&a…

【Android】最新主流新闻app功能实现。仿网易,搜狐等新闻客户端实现展示

最新主流新闻app功能实现。仿网易,搜狐等新闻客户端 作者&#xff1a;程序员小冰 欢迎点击关注微博 (原创作品&#xff0c;转载请说明出处)先给大家看一下效果图&#xff1a; 这个项目总体来说虽然不是特别难&#xff0c;但是确实非常常用的功能。是业余时间自己写的一个小…

Safari 安装 Tampermonkey(油猴)插件

Safari 安装 Tampermonkey&#xff08;油猴&#xff09;插件 一、软件介绍 今天给大家推荐的一款”神器插件”叫 油猴&#xff0c;英文为Tampermonkey&#xff0c;是一款适用于Safari用户的脚本管理器&#xff0c;能够方便管理不同的脚本。虽然有些受支持的浏览器拥有原生的用…

使用Tampermonkey(油猴) 插件,重新实现了,百度搜索热点过滤功能

昨天晚上&#xff0c;花了点时间学习了Chrome插件的制作方法&#xff0c;并书写了《Chrome 百度搜索热点过滤插件 - 开源软件》这一文章&#xff0c;简单地介绍自己实现的百度搜索热点过滤神器的原理和使用方式&#xff0c;并进行了开源&#xff08;https://github.com/yaowenx…

Mac的Safari安装油猴插件(Tampermonkey)

Mac的Safari安装油猴插件&#xff08;Tampermonkey&#xff09; 官方的AppStore是没有油猴插件&#xff08;Tampermonkey&#xff09;的&#xff0c;官方插件不仅少&#xff0c;功能被阉割&#xff0c;相对弱小&#xff0c;还收费。嗯&#xff0c;这很苹果第三方拓展。 这是油…

油猴插件: AC-百度-重定向优化

在日常使用搜索引擎时, 会遇到有些问题 1.搜索结果 网址重定向问题, 导致的打开很慢(每次跳转浪费1-2秒钟) 2.搜索结果里面的 垃圾网站, 比如某些 爬虫采集网站 重复出现(频繁出现, 一次浪费5秒左右) 改了之后记得点保存 ps: 不仅仅是百度, google, bing也会出现 垃圾答案网…

uniApp 新闻详情页语音播报,百度语音合成app端、H5端语音播报实例

非常轻便的语音合成接口&#xff0c;可以用于新闻详情页语音播报&#xff0c;实例功能&#xff1a; 点击“播放”按钮播放新闻详情页面的内容&#xff0c;播放按钮文字也图标变为“暂停”&#xff0c;再点击重新播放。 实例用到uniApp插件&#xff1a;百度语音合成接口 - DCl…

编写一个油猴脚本,去除百度首页的广告卡片(亲测有效)

1、去除前 2、去除后 3、脚本实现 // UserScript // name 隐藏百度首页的卡片 // namespace http://tampermonkey.net/ // version 0.2 // description try to take over the world! // author You // match *://www.baidu.com/?tn* // grant …

哪些手机浏览器可以安装油猴插件(Tampermonkey)

哪些手机浏览器可以安装油猴 安装 Tampermonkey 一、可以安装油猴的手机浏览器 火狐浏览器&#xff08;Firefox&#xff09; Kiwi 浏览器 Yandex 浏览器 二、优点与缺点 火狐浏览器 UI 互动效果差一些&#xff0c;Kiwi 浏览器 UI 互动更爽一些Yandex 浏览器俄式风格&…

利用浏览器的油猴插件下载网页视频

1. 油猴介绍 油猴是一个浏览器的插件&#xff0c;该插件用于管理&#xff08;安装和卸载&#xff09;浏览器的功能脚本&#xff0c;实现浏览器附加功能的添加。 众所周知&#xff0c;浏览器可以添加扩展程序插件&#xff0c;以扩展浏览器的功能。但是&#xff0c;有些扩展程序…

【自动化】初见 - 最强浏览器插件 《油猴Tampermonkey》 开发和发布

▒ 目录 ▒ &#x1f6eb; 导读需求开发环境 1️⃣ 油猴插件基本使用安装油猴插件安装用户脚本使用用户脚本 2️⃣ 脚本开发-自定义baidu搜索框新建脚本修改元数据编写脚本 3️⃣ 脚本发布注册账号发布脚本 &#x1f6ec; 文章小结&#x1f4d6; 参考资料 &#x1f6eb; 导读 …

让iOS Safari浏览器支持油猴脚本

Userscripts 是一款免费 iOS Safari 浏览器插件&#xff0c;可以兼容油猴脚本&#xff0c;但如果油猴脚本代码没有对手机进行适配的话可能不会生效。 1、首先 打开设置 找到 Safari 浏览器 选择 扩展 然后 勾选 Userscripts 所有网站中 选择 允许 然后打开 Userscripts 后按照…

Tampermonkey[油猴插件]开发者的神级工具!

油猴插件在项目开发中的应用 油猴插件介绍和使用插件介绍输出Hello world 实战应用文档生成代码 油猴插件介绍和使用 插件介绍 Tampermonkey是一款免费的浏览器扩展和最为流行的用户脚本管理器&#xff0c;它适用于 Chrome, Microsoft Edge, Safari, Opera Next, 和 Firefox。…

利用油猴插件 Tampermonkey 编写脚本以屏蔽网页指定元素——以屏蔽百度搜索右边的百度热榜为例

一、起因 一直使用 Tampermonkey 中的 AC-baidu-重定向优化百度搜狗谷歌必应搜索_favicon_双列 这个插件屏蔽好好的&#xff0c;今天突然屏蔽不了&#xff0c;正好自己编写一个简单的插件试试完成这一效果&#xff0c;如下图 二、过程 Tampermonkey 版本 v4.11 直接进入油…

哪些安卓手机和IPhone手机浏览器可以安装油猴Tampermonkey插件

油猴官网&#xff1a;Greasy Fork - 安全、实用的用户脚本大全 Android手机浏览器&#xff1a; Firefox&#xff1a;Greasemonkey、Tampermonkey 或 Violentmonkey Maxthon&#xff1a;Violentmonkey Dolphin&#xff1a;Tampermonkey UC&#xff1a;Tampermonkey Kiwi&#…

保姆级教程!如何在安卓手机上安装使用油猴脚本

浏览器插件成千上万&#xff0c;但是大家都有一个共识&#xff0c;那就是油猴无插件能敌&#xff0c;原因就在于它一个插件就可以实现众多插件的功能。 首先需要明确一点的是&#xff0c;油猴插件本身是没有任何功能的&#xff0c;它需要依靠脚本来实现功能。至于脚本&#xf…

【关键词排名点击软件】网站关键词挖掘常用的五个工具

很多SEO站长朋友明明每天都在进行优化&#xff0c;为什么就是没有好的排名呢&#xff1f;这是因为一个主关键词的优化&#xff0c;需要看你网站多方面的优化配合&#xff0c;而一般能选择成为你网站主关键词一般竞争都比较大&#xff0c;其他方面的优化如果没做好的话&#xff…

关键词挖掘与筛选(流量+权重必备)

seo如果你做到一定程度的时候&#xff0c;你自然就会发现&#xff0c;seo永远是围绕两个话题 一个是收录话题&#xff0c;一个是词的话题 为什么这么说呢&#xff0c;收录可以帮你解决展现量与点击量 &#xff0c;词可以帮你解决流量 &#xff0c;这也是我们做seo的目的所在。…