预见猿份
主题
首页面试题在线工具关于我们老苗一对一私教学员评价
实战项目
项目前置基础创新WMS项目Java微服务框架与实战云岚到家项目闪聚支付项目学成在线项目青橙电商项目JVM原理与实战调优分布式事务专题Java高频面试题MySQL从入门到精通Java数据结构与算法老苗一对一私教学员评价blog
blog
  • 云岚到家项目

    • 项目介绍
    • 项目安装配置
    • 安装配置-第三方软件安装说明
    • 安装配置-OSS配置文档
    • 安装配置-高德地图web服务配置文档
    • 第一章如何熟悉新项目
    • 运营服务管理模块需求文档v1.0
    • 第二章运营服务管理模块
    • 第三章用户认证
    • 第四章小程序首页
    • 第五章搜索模块
    • 第五章配置ES索引同步环境
    • 第六章优惠券模块
    • 项目实战说明文档
    • 第七章订单模块
    • 第八章支付模块
    • 第八章微信支付调研
    • 第九章系统优化
    • 第九章EasyExcel入门
    • 第十章秒杀抢购模块
    • 第十一章派单调度
    • 第十二章项目总结&部署
    • 第十三章云岚到家100问







----- 到底线了 -----

×

欢迎来到预见猿份,本站项目均为站长原创,学习中有问题可直接提交给站长老苗解决(微信:mrt_0607)。

苗润土老师,20余年一线项目经验,2014年加入黑马,星辰wms、云岚到家、学成在线项目作者,历任高级讲师、教学主管及课程研究员。 b站老苗

第三方软件安装说明 ​

以下软件已安装不用重新安装。

MySQL ​

拉取镜像:

docker pull mysql:8.0.26

创建以下目录:

sudo mkdir -p /usr/mysql/conf /usr/mysql/data /var/log/mysql

sudo chmod -R 777 /usr/mysql/ /var/log/mysql

创建配置文件

vim /usr/mysql/conf/my.cnf

添加以下内容到上述创建的配置文件中

Java
 
[client]
#socket = /usr/mysql/mysqld.sock
default-character-set = utf8mb4
 
[mysqld]
#pid-file        = /var/run/mysqld/mysqld.pid
#socket          = /var/run/mysqld/mysqld.sock
#datadir         = /var/lib/mysql
#socket = /usr/mysql/mysqld.sock
#pid-file = /usr/mysql/mysqld.pid
 
datadir  = /usr/mysql/data
 
general_log = 1
general_log_file = /var/log/mysql/access.log
log-error = /var/log/mysql/error.log
 
character_set_server = utf8mb4
collation_server = utf8mb4_bin
secure-file-priv= NULL

#Disabling symbolic-links is recommended to prevent assorted security risks
#symbolic-links=0

#Custom config should go here
#!includedir /etc/mysql/conf.d/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

创建启动容器

Java
docker run -itd --name=mysql -v /usr/mysql/conf/my.cnf:/etc/mysql/my.cnf -v /usr/mysql/data:/usr/mysql/data -v /var/log/mysql:/var/log/mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=mysql mysql:8.0.26
1

说明: -v : 挂载宿主机目录和 docker容器中的目录,前面是宿主机目录,后面是容器内部目录 -d : 后台运行容器 -p 映射容器端口号和宿主机端口号 -e 环境参数,MYSQL_ROOT_PASSWORD设置root用户的密码

下边修改mysql的访问权限为所有客户端可以访问:

进入容器内部

sudo docker exec -it mysql /bin/bash

连接mysql

mysql -uroot -pmysql

使用mysql库

use mysql;

修改访问主机以及密码等,设置为所有主机可访问

Java
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'mysql';
flush privileges;
1
2

Nacos ​

安装数据库 ​

我们基于Docker来部署Nacos的注册中心,首先我们要准备MySQL数据库表,用来存储Nacos的数据。由于是Docker部署,所以大家需要将资料中的SQL文件导入到你Docker中的MySQL容器中:

SFC3bmVwCoozTrxdwFmcH3Asnvg

最终表结构如下:

B5hdbwdlMo8A7Nxg78jcoKJyngh

创建容器 ​

然后,找到课前资料下的nacos文件夹和nacos.2.4.tar,全部上传到/root下:

nacos.2.4.tar是nacos的镜像文件,nacos文件夹下是nacos配置文件。

QhtRbbxPxol83axJDfLcbK0Fn7d

其中的nacos/custom.env文件中,注意:有一个MYSQL_SERVICE_HOST也就是mysql地址,需要修改为你自己的虚拟机IP地址:

RbfTbcYpXoN1PpxltuPc20RGn8f

然后,将课前资料中的nacos目录上传至虚拟机的/root目录。

首先导入nacos.tar镜像文件:

JavaScript
docker load -i nacos.2.4.tar
1

进入root目录,然后执行下面的docker命令:

PowerShell
docker run -d \
--name nacos \
--env-file ./nacos/custom.env \
-p 8848:8848 \
-p 9848:9848 \
-p 9849:9849 \
--restart=always \
nacos/nacos-server:v2.4.0.1
1
2
3
4
5
6
7
8

访问nacos ​

启动完成后,访问下面地址:http://192.168.101.68:8848/nacos/,注意将192.168.101.68替换为你自己的虚拟机IP地址。

进入首页:

PLMhbULYFogwKGxYLtycvTygnEe

注意:2.4版本开始nacos默认不进行认证直接进入首页,以前的版本首次访问会跳转到登录页,账号密码都是nacos

I1uubwLtmob7uxxsc2RclOWCnbf

xxl-job ​

拉取镜像:

docker pull xuxueli/xxl-job-admin:2.3.1

创建目录:

/data/soft/xxl-job

/data/soft/xxl-job/applogs

创建配置文件:/data/soft/xxl-job/application.properties,内容如下:

Java
### web
server.port=8080
server.servlet.context-path=/xxl-job-admin

### actuator
management.server.servlet.context-path=/actuator
management.health.mail.enabled=false

### resources
spring.mvc.servlet.load-on-startup=0
spring.mvc.static-path-pattern=/static/**
spring.resources.static-locations=classpath:/static/

### freemarker
spring.freemarker.templateLoaderPath=classpath:/templates/
spring.freemarker.suffix=.ftl
spring.freemarker.charset=UTF-8
spring.freemarker.request-context-attribute=request
spring.freemarker.settings.number_format=0.##########

### mybatis
mybatis.mapper-locations=classpath:/mybatis-mapper/*Mapper.xml
#mybatis.type-aliases-package=com.xxl.job.admin.core.model

### xxl-job, datasource
spring.datasource.url=jdbc:mysql://192.168.101.68:3306/xxl_job_2.3.1?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=mysql
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

### datasource-pool
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.hikari.minimum-idle=10
spring.datasource.hikari.maximum-pool-size=30
spring.datasource.hikari.auto-commit=true
spring.datasource.hikari.idle-timeout=30000
spring.datasource.hikari.pool-name=HikariCP
spring.datasource.hikari.max-lifetime=900000
spring.datasource.hikari.connection-timeout=10000
spring.datasource.hikari.connection-test-query=SELECT 1
spring.datasource.hikari.validation-timeout=1000

### xxl-job, email
spring.mail.host=smtp.qq.com
spring.mail.port=25
spring.mail.username=xxx@qq.com
spring.mail.from=xxx@qq.com
spring.mail.password=xxx
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory

### xxl-job, access token
xxl.job.accessToken=default_token

### xxl-job, i18n (default is zh_CN, and you can choose "zh_CN", "zh_TC" and "en")
xxl.job.i18n=zh_CN

## xxl-job, triggerpool max size
xxl.job.triggerpool.fast.max=200
xxl.job.triggerpool.slow.max=100

### xxl-job, log retention days
xxl.job.logretentiondays=30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

创建数据库:xxl_job_2.3.1

导入xxl_job_2.3.1.sql,如下:

Y5KCbOUPworMxOxjEcUc60r0nWb

创建容器:

Java
docker run -d -e \
  --restart=always \
  -v /data/soft/xxl-job/applogs:/data/applogs \
  -v /data/soft/xxl-job/application.properties:/application.properties \
  -p 8088:8080 \
  --name xxl-job-admin \
  xuxueli/xxl-job-admin:2.3.1
1
2
3
4
5
6
7

启动成功进入管理界面:

http://192.168.101.68:8088/xxl-job-admin

账号/密码:admin/123456

Elasticsearch7.17.7 ​

拉取镜像

docker pull elasticsearch:7.17.7

创建文件夹:

mkdir -p /data/soft/es7.17.7/xzb

在/data/soft/es7.17.7/xzb下创建data目录并且修改权限为777

Java
mkdir data
chmod 777 data
1
2

将课程资料下的"ES安装"目录中的 es.zip上传到/data/soft/es7.17.7/xzb下,并进行解压

Java
 unzip es.zip
1

解压成功如下图:

KZmabhRi3oK7X9xox2rcKEbVnQe

创建容器

Java
docker run -d \
--name elasticsearch7.17.7 \
--restart always \
-p 9200:9200 \
-p 9300:9300 \
-e "discovery.type=single-node" \
-e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \
-v /data/soft/es7.17.7/xzb/data:/usr/share/elasticsearch/data \
-v /data/soft/es7.17.7/xzb/plugins:/usr/share/elasticsearch/plugins \
-v /data/soft/es7.17.7/xzb/config:/usr/share/elasticsearch/config \
elasticsearch:7.17.7
1
2
3
4
5
6
7
8
9
10
11

访问http://192.168.101.68:9200/,如下图说明启动成功:

VrCzbIvZBoGqIBxVvZic3PZvnpx

kibana7.17.7 ​

拉取镜像

docker pull kibana:7.17.7

创建容器:

注意修改es的地址

Java
docker run --name kibana7.17.7 \
-e ELASTICSEARCH_HOSTS=http://192.168.101.68:9200 \
-p 5601:5601 \
-d kibana:7.17.7
1
2
3
4

下边启动容器,先保证Elasticsearch启动成功。

启动kibana容器成功,在浏览器输入地址访问:http://192.168.101.68:5601,进入DevTools,如下图:

C2hxb2zZgoBpBpxNMbWcW6mfnFe

执行:GET /_cat/indices?v 查询索引信息

LbKUbNLNDowLjvxebUoccKlRnBg

创建项目所需要的索引 ​

启动ES和kibana:

如果没有安装参考本文档 安装elasticsearch7.17.7 和 kibana7.17.7。

安装完成后进行启动:

JSON
docker start elasticsearch7.17.7 
docker start kibana7.17.7
1
2

本项目共需创建下边三个索引结构:

首先通过下边的命令查询索引

JSON
GET /_cat/indices?v
1

TP1ZbKSz1oJo40xXvfEcWgBsnMc

创建orders_seize和serve_provider_info(已经存在无法重复创建)

Java
PUT /serve_provider_info
{
    "mappings" : {
      "properties" : {
        "acceptance_num" : {
          "type" : "integer"
        },
        "city_code" : {
          "type" : "keyword"
        },
        "evaluation_score" : {
          "type" : "double"
        },
        "id" : {
          "type" : "long"
        },
        "location" : {
          "type" : "geo_point"
        },
        "pick_up" : {
          "type" : "integer"
        },
        "serve_item_ids" : {
          "type" : "long"
        },
        "serve_provider_type" : {
          "type" : "integer"
        },
        "serve_times" : {
          "type" : "integer"
        },
        "setting_status" : {
          "type" : "long"
        },
        "settting_status" : {
          "type" : "integer"
        },
        "skills" : {
          "type" : "long"
        }
      }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

如果需要修改索引结构需要删除重新创建:

JSON
DELETE 索引名
1
2

查询索引结构

JSON
GET /索引名/_mapping
1

下边继续创建其它索引:

创建:orders_seize (已经存在无法重复创建)

Java
PUT /orders_seize
{
"mappings" : {
      "properties" : {
        "city_code" : {
          "type" : "keyword"
        },
        "id" : {
          "type" : "long"
        },
        "key_words" : {
          "type" : "text",
          "analyzer" : "ik_max_word",
          "search_analyzer" : "ik_smart"
        },
        "location" : {
          "type" : "geo_point"
        },
        "orders_amount" : {
          "type" : "float"
        },
        "pur_num" : {
          "type" : "integer"
        },
        "serve_address" : {
          "type" : "text",
          "index" : false
        },
        "serve_item_id" : {
          "type" : "long"
        },
        "serve_item_img" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "serve_item_name" : {
          "type" : "text",
          "index" : false
        },
        "serve_start_time" : {
          "type" : "text",
          "index" : false
        },
        "serve_time" : {
          "type" : "integer"
        },
        "serve_type_id" : {
          "type" : "long"
        },
        "serve_type_name" : {
          "type" : "text",
          "index" : false
        },
        "total_amount" : {
          "type" : "double"
        }
      }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

创建serve_aggregation索引 (已经存在无法重复创建)

Java
PUT /serve_aggregation
{
   "mappings" : {
      "properties" : {
        "city_code" : {
          "type" : "keyword"
        },
        "detail_img" : {
          "type" : "text",
          "index" : false
        },
        "hot_time_stamp" : {
          "type" : "long"
        },
        "id" : {
          "type" : "keyword"
        },
        "is_hot" : {
          "type" : "short"
        },
        "price" : {
          "type" : "double"
        },
        "serve_item_icon" : {
          "type" : "text",
          "index" : false
        },
        "serve_item_id" : {
          "type" : "keyword"
        },
        "serve_item_img" : {
          "type" : "text",
          "index" : false
        },
        "serve_item_name" : {
          "type" : "text",
          "analyzer": "ik_max_word",
          "search_analyzer":"ik_smart"
          
        },
        "serve_item_sort_num" : {
          "type" : "short"
        },
        "serve_type_icon" : {
          "type" : "text",
          "index" : false
        },
        "serve_type_id" : {
          "type" : "keyword"
        },
        "serve_type_img" : {
          "type" : "text",
          "index" : false
        },
        "serve_type_name" : {
          "type" : "text",
          "analyzer": "ik_max_word",
          "search_analyzer":"ik_smart"
        },
        "serve_type_sort_num" : {
          "type" : "short"
        }
      }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65

sentinel ​

安装 ​

从课程资料--》开发环境配置目录找到“sentinel”目录获取sentinel.zip,并上传至/data/soft目录下

解压sentinel.zip:

JSON
unzip sentinel.zip
1

注意:

如果unzip命令不可用则需要安装unzip:

JSON
sudo yum install unzip
1

进入/data/soft/sentinel目录,如下所示:

MRW7bD6eooEorExunw6cZmM7nPd

注意修改docker-compose.yml中的nacos的地址及nacos的账号和密码:

JSON
version: "3.8"
services:
  sentinel:
    container_name: sentinel-dashboard
    image: sentinel-dashboard:latest
    ports:
        - "8080:8080"
    environment:
        - "TZ=Asia/Shanghai" 
        # nacos访问地址+端口号
        - SENTINEL_NACOS_SERVER_ADDR=192.168.101.68:8848
        # nacos访问账号
        - SENTINEL_NACOS_USERNAME=nacos
        # nacos访问密码
        - SENTINEL_NACOS_PASSWORD=nacos
        # nacos访问命名空间
        - SENTINEL_NACOS_NAMESPACE=75a593f5-33e6-4c65-b2a0-18c403d20f63
        # sentinel dashboard平台登录账号
        - SENTINEL_USERNAME=sentinel
        # sentinel dashboard平台登录密码
        - SENTINEL_PASSWORD=sentinel
        # sentinel dashboard 访问端口号
        - SENTINEL_PORT=8080
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

执行下边的命令创建镜像,如下:

Shell
docker build -t sentinel-dashboard .
1

下边启动容器:

Shell
docker-compose up -d
1

启动容器成功,通过docker ps命令查看容器:

XWyQbUZWUoFUpfxDUEfcH1ZInzf

接下来访问sentinel ,地址:http://192.168.101.68:8080/#/login

Ok2ibO7uHoDUZux9eYWcdRxHnMh

需要输入账号和密码,默认都是:sentinel

Hz3fbYXbxo6Xz0xom01cFeXtnch

项目集成sentinel ​

  1. 添加nacos配置文件shared-sentinel.yaml,如下:
YAML
spring:
  cloud:
    sentinel:
      transport:
        # 供sentinel dashboard平台访问端口
        port: 8719
        # sentinel控制台
        dashboard: 192.168.101.68:8080
        #服务启动直接建立心跳连接
      eager: true
1
2
3
4
5
6
7
8
9
10

注意:

1)、spring.cloud.sentinel.transport.port端口可以无需修改,如果多个微服务运行在同一个物理机时,同时都要占用8719端口,记得修改端口号,保证sentinel.transport.port端口不冲突,如果使用docker部署一定要将该端口开放

2)、spring.cloud.sentinel.transport.dashboard需要配置成自己sentinel-dashboard的访问地址

  1. 在项目中引入shared-sentinel.yaml配置文件

YgnLbnM1kot3v0xbJ53cPw4wnZg

只需要在远程调用的调用方(客户端)配置sentinel即可,订单管理服务调用 客户管理服务,只需要在订单管理服务配置sentienl。

  1. 项目代码中添加依赖
XML
<dependency>
    <groupId>com.jzo2o</groupId>
    <artifactId>jzo2o-sentinel</artifactId>
</dependency>
1
2
3
4

注意:

1)、hibernate-validator版本不要高于6,sentinel 1.8.5版本对于hibernate-validator 6以上版本存在不兼容问题。

2)、sentinel-dashboard注册中心和配置中心一定要和微服务保持一致,不然读不到熔断配置。

Seata ​

拉取镜像:

docker pull seataio/seata-server:1.5.2

创建目录:

mkdir -p /data/soft/seata-jzo2o/data /data/soft/seata-jzo2o/config

将配置resources.tar 上传到服务器解压到/data/soft/seata-jzo2o/config

解压resources.tar : tar xvf resources.tar

注意修改resources中application.yml中nacos的配置

Java
server:
  port: 7091

spring:
  application:
    name: seata-server

console:
  user:
    username: seata
    password: seata

logging:
  config: classpath:logback-spring.xml
  file:
    path: ${user.home}/logs/seata

seata:
  config:
    # support: nacos 、 consul 、 apollo 、 zk  、 etcd3
    type: nacos
    nacos:
      server-addr: 192.168.101.68:8848
      namespace: 75a593f5-33e6-4c65-b2a0-18c403d20f63
      group: DEFAULT_GROUP
      username: nacos
      password: nacos
      ##if use MSE Nacos with auth, mutex with username/password attribute
      #access-key: ""
      #secret-key: ""
      data-id: seata-server.properties
  registry:
    # support: nacos 、 eureka 、 redis 、 zk  、 consul 、 etcd3 、 sofa
    type: nacos
    #preferred-networks: 30.240.*
    nacos:
      application: seata-server
      server-addr: 192.168.101.68:8848
      group: DEFAULT_GROUP
      namespace: 75a593f5-33e6-4c65-b2a0-18c403d20f63
      cluster: default
      username: nacos
      password: nacos
      ##if use MSE Nacos with auth, mutex with username/password attribute
      #access-key: ""
      #secret-key: ""
      
  server:
    service-port: 8091 #If not configured, the default is '${server.port} + 1000'
    max-commit-retry-timeout: -1
    max-rollback-retry-timeout: -1
    rollback-retry-timeout-unlock-enable: false
    enableCheckAuth: true
    retryDeadThreshold: 130000
    xaerNotaRetryTimeout: 60000
    recovery:
      handle-all-session-period: 1000
    undo:
      log-save-days: 7
      log-delete-period: 86400000
    session:
      branch-async-queue-size: 5000 #branch async remove queue size
      enable-branch-async-remove: false #enable to asynchronous remove branchSession
      
  metrics:
    enabled: false
    registry-type: compact
    exporter-list: prometheus
    exporter-prometheus-port: 9898
  transport:
    rpc-tc-request-timeout: 30000
    enable-tc-server-batch-send-response: false
    shutdown:
      wait: 3
    thread-factory:
      boss-thread-prefix: NettyBoss
      worker-thread-prefix: NettyServerNIOWorker
      boss-thread-size: 1
  security:
    secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017
    tokenValidityInMilliseconds: 1800000
    ignore:
      urls: /,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/api/v1/auth/login
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84

创建seata数据库,导入seata.sql

WRzzbaUjJoNDgdxhuxec4cKCnrd

登录nacos配置seata-server.properties配置文件,内容如下:

Java
store.mode = db
store.db.datasource = druid
store.db.dbType = mysql
store.db.driverClassName = com.mysql.cj.jdbc.Driver
store.db.url = jdbc:mysql://192.168.101.68:3306/seata?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true&useSSL=false
store.db.user = root
store.db.password = mysql
store.db.minConn = 5
store.db.maxConn = 100
store.db.globalTable = global_table
store.db.branchTable = branch_table
store.db.lockTable = lock_table
store.db.distributedLockTable = distributed_lock
store.db.queryLimit = 100
store.db.maxWait = 5000
#seata.tm.global_transaction_timeout = 60000
#seata.tm.beginTimeout = 5000
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

创建容器,seata端口号:8091(程序交互端口,根据情况进行修改),7091(管理端工具端口,根据情况进行修改)

Shell
docker run -d \
--name seata-server \
--restart always \
-p 8091:8091 \
-p 7091:7091 \
-v /data/soft/seata-jzo2o/config/resources:/seata-server/resources  \
-e SEATA_IP=192.168.101.65 \
seataio/seata-server:1.5.2
1
2
3
4
5
6
7
8

测试,登录地址http://192.168.101.68:7091,账号和密码均为seata/seata,首次登录可能会慢稍等1-2分钟

ESxYbpBreoykvPxh8sucOz7SnCg

← 项目安装配置安装配置-OSS配置文档 →








如果发现文档内容有错误或排版错乱,请及时联系站长老苗修改,不胜感激。联系方式
关于我们 | 隐私政策 | 豫ICP备2026003386号-4 | 豫公网安备41010202004008号
目录

本页无章节