Full Code of SmacUL/NewsRecommend for AI

main ea694c194a9c cached
156 files
348.3 KB
95.5k tokens
598 symbols
1 requests
Download .txt
Showing preview only (404K chars total). Download the full file or copy to clipboard to get everything.
Repository: SmacUL/NewsRecommend
Branch: main
Commit: ea694c194a9c
Files: 156
Total size: 348.3 KB

Directory structure:
gitextract_jxucev3e/

├── .gitattributes
├── .gitignore
├── LICENSE
├── NewsRecommend.sql
├── README.md
├── back/
│   ├── .gitignore
│   ├── .mvn/
│   │   └── wrapper/
│   │       ├── MavenWrapperDownloader.java
│   │       ├── maven-wrapper.jar
│   │       └── maven-wrapper.properties
│   ├── mvnw
│   ├── mvnw.cmd
│   ├── pom.xml
│   └── src/
│       ├── main/
│       │   ├── .DS_Store
│       │   ├── java/
│       │   │   └── com/
│       │   │       └── smacul/
│       │   │           └── demo/
│       │   │               ├── DemoApplication.java
│       │   │               ├── bean/
│       │   │               │   ├── ArtFeatureCount.java
│       │   │               │   ├── ArtScoreList.java
│       │   │               │   ├── ArtTimeList.java
│       │   │               │   ├── Article.java
│       │   │               │   ├── Comment.java
│       │   │               │   ├── CusBehaviorRecord.java
│       │   │               │   ├── CusFeatureCount.java
│       │   │               │   ├── Customer.java
│       │   │               │   └── Reply.java
│       │   │               ├── controller/
│       │   │               │   ├── DiscussController.java
│       │   │               │   ├── EditController.java
│       │   │               │   ├── LoadController.java
│       │   │               │   ├── SearchController.java
│       │   │               │   └── SelfController.java
│       │   │               ├── dao/
│       │   │               │   ├── ArtDao.java
│       │   │               │   ├── ArtFeatureCountDao.java
│       │   │               │   ├── ArtScoreListDao.java
│       │   │               │   ├── ArtTimeList.java
│       │   │               │   ├── ComDao.java
│       │   │               │   ├── CusBehaviorRecordDao.java
│       │   │               │   ├── CusDao.java
│       │   │               │   ├── CusFeatureCountDao.java
│       │   │               │   ├── CusRecommendRecordDao.java
│       │   │               │   └── RepDao.java
│       │   │               ├── model/
│       │   │               │   ├── ArtFullMod.java
│       │   │               │   ├── ComFullMod.java
│       │   │               │   ├── CusArtBehaviorMod.java
│       │   │               │   ├── CusDynamicMod.java
│       │   │               │   ├── CusFeatureFullMod.java
│       │   │               │   └── RepFullMod.java
│       │   │               ├── service/
│       │   │               │   ├── .DS_Store
│       │   │               │   ├── DiscussService.java
│       │   │               │   ├── EditService.java
│       │   │               │   ├── LoadService.java
│       │   │               │   ├── SearchService.java
│       │   │               │   ├── SelfService.java
│       │   │               │   ├── SessionService.java
│       │   │               │   ├── ShapeService.java
│       │   │               │   └── impl/
│       │   │               │       ├── .DS_Store
│       │   │               │       ├── DiscussServiceImpl.java
│       │   │               │       ├── EditServiceImpl.java
│       │   │               │       ├── LoadServiceImpl.java
│       │   │               │       ├── SearchServiceImpl.java
│       │   │               │       ├── SelfServiceImpl.java
│       │   │               │       ├── SessionServiceImpl.java
│       │   │               │       └── ShapeServiceImpl.java
│       │   │               └── util/
│       │   │                   ├── MD5.java
│       │   │                   ├── PageHandler.java
│       │   │                   └── TypeHandler.java
│       │   └── resources/
│       │       ├── .DS_Store
│       │       ├── mapper/
│       │       │   ├── .DS_Store
│       │       │   ├── ArtFeatureCountMap.xml
│       │       │   ├── ArtMap.xml
│       │       │   ├── ArtScoreListMap.xml
│       │       │   ├── ArtTimeListMap.xml
│       │       │   ├── ComMap.xml
│       │       │   ├── CusBehaviorRecordMap.xml
│       │       │   ├── CusFeatureCountMap.xml
│       │       │   ├── CusMap.xml
│       │       │   ├── CusRecommendRecordDao.xml
│       │       │   └── RepMap.xml
│       │       ├── static/
│       │       │   └── .DS_Store
│       │       └── templates/
│       │           └── application.properties.template
│       └── test/
│           └── java/
│               └── com/
│                   └── smacul/
│                       └── demo/
│                           └── DemoApplicationTests.java
├── front/
│   ├── .gitignore
│   ├── README.md
│   ├── babel.config.js
│   ├── package.json
│   ├── public/
│   │   └── index.html
│   ├── src/
│   │   ├── App.vue
│   │   ├── assets/
│   │   │   └── css/
│   │   │       ├── Narrow.css
│   │   │       └── Normal.css
│   │   ├── components/
│   │   │   ├── HelloWorld.vue
│   │   │   ├── app/
│   │   │   │   └── HelloWorld.vue
│   │   │   ├── article/
│   │   │   │   ├── ArticleCenter.vue
│   │   │   │   ├── CommentReplyCenter.vue
│   │   │   │   ├── RightMenu.vue
│   │   │   │   ├── TopBar.vue
│   │   │   │   └── comment-reply-main/
│   │   │   │       ├── CommentReplyInput.vue
│   │   │   │       └── ReplyMain.vue
│   │   │   ├── common/
│   │   │   │   ├── DarkCard.vue
│   │   │   │   ├── EditEntrance.vue
│   │   │   │   ├── EditorBrief.vue
│   │   │   │   ├── FloatCard.vue
│   │   │   │   ├── HotArticle.vue
│   │   │   │   ├── SearchPanel.vue
│   │   │   │   └── TinyArticle.vue
│   │   │   ├── edit/
│   │   │   │   └── TopBar.vue
│   │   │   ├── index/
│   │   │   │   ├── LeftMenu.vue
│   │   │   │   └── TopBar.vue
│   │   │   ├── port/
│   │   │   │   ├── LoginPart.vue
│   │   │   │   └── RegisterPart.vue
│   │   │   ├── search/
│   │   │   │   ├── RightMenu.vue
│   │   │   │   ├── TinyCenter.vue
│   │   │   │   └── TopBar.vue
│   │   │   └── self/
│   │   │       ├── EditorMain.vue
│   │   │       ├── RightMenu.vue
│   │   │       ├── TinyCenter.vue
│   │   │       └── TopBar.vue
│   │   ├── control/
│   │   │   ├── Discuss.js
│   │   │   ├── Edit.js
│   │   │   ├── Load.js
│   │   │   ├── Search.js
│   │   │   └── Self.js
│   │   ├── main.js
│   │   ├── plugins/
│   │   │   └── axios.js
│   │   ├── router/
│   │   │   └── index.js
│   │   ├── styles.scss
│   │   ├── util/
│   │   │   ├── PageJump.js
│   │   │   └── TimeHandler.js
│   │   └── views/
│   │       ├── About.vue
│   │       ├── ArticleView.vue
│   │       ├── EditView.vue
│   │       ├── Home.vue
│   │       ├── IndexView.vue
│   │       ├── PortView.vue
│   │       ├── SearchView.vue
│   │       └── SelfView.vue
│   └── vue.config.js
└── spider/
    ├── Main.py
    ├── dao/
    │   ├── ArticleDao.py
    │   ├── CommentDao.py
    │   ├── CustomerDao.py
    │   ├── ReplyDao.py
    │   └── __init__.py
    ├── model/
    │   ├── ArticleModel.py
    │   ├── CommentModel.py
    │   ├── CustomerModel.py
    │   ├── ReplyModel.py
    │   └── __init__.py
    ├── process/
    │   ├── ArticleProcess.py
    │   ├── CommentProcess.py
    │   ├── CustomerProcess.py
    │   ├── ReplyProcess.py
    │   └── __init__.py
    └── util/
        ├── Driver.py
        ├── Json.py
        ├── Md5.py
        ├── MySql.py
        ├── Request.py
        ├── Time.py
        └── __init__.py

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitattributes
================================================
# Auto detect text files and perform LF normalization
* text=auto


================================================
FILE: .gitignore
================================================

# crawler/.idea/*
# crawler/__pycache__/*
# crawler/database-properties.json
.DS_Store

/back/lib/*.jar
back/src/main/resources/application.properties

*.pyc
spider/log/*.txt
spider/.idea/*
spider/experiment/*
spider/properties/database.json
spider/debug.log


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2019 SmacUL

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: NewsRecommend.sql
================================================
DROP DATABASE IF EXISTS NR;
CREATE DATABASE IF NOT EXISTS NR CHARACTER SET utf8mb4;


-- cus 用户
DROP TABLE IF EXISTS NR.Customer;
CREATE TABLE NR.Customer (
    cus_id INT UNSIGNED NOT NULL auto_increment,
    cus_name VARCHAR(64) UNIQUE,
    cus_pass VARCHAR(255),
    -- 爬虫中用于识别用户
    cus_spider VARCHAR(64) default '',
    -- 用户头像的 url
    cus_avatar_url VARCHAR(255) default 'http://localhost:8080/img/Man.png',
    -- 用户的个人描述
    cus_style VARCHAR(255) default '这个人很懒, 什么都没写',
    -- cus_gender 为 0 时性别未知, 为 1 时为男, 为 -1 时为女
    cus_gender TINYINT DEFAULT 0,
    -- 用户的创建时间
    cus_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    -- cus_legal 为 0 时待审核, 为 1 时合法, 为 -1 不合法
    cus_legal TINYINT default 0,

    -- cus_type 为 0 时是普通用户, 为 1 时是可编辑用户 ABANDON
    -- cus_type TINYINT default 0,
    -- 用户背景墙的图片 url ABANDON
    -- cus_background_url VARCHAR(255) default '',
    -- 此用户的关注的用户数量 ABANDON
    -- cus_follow_num int UNSIGNED default 0,
    -- 此用户的粉丝 ABANDON
    -- cus_fan_num int UNSIGNED default 0, 
    -- 此用户的文章数量 ABANDON
    -- cus_article_num int UNSIGNED default 0,
    -- 用户评分 ABANDON
    -- cus_scope int UNSIGNED default 0,
	
    primary key(cus_id)
);


-- art 新闻
DROP TABLE IF EXISTS NR.Article;
CREATE TABLE NR.Article (
    art_id INT UNSIGNED NOT NULL auto_increment,
    art_title VARCHAR(255) default '',
    art_content TEXT,
    -- 在爬虫中分辨文章
    art_spider VARCHAR(64) default '',
    -- 文章的分类
    art_type VARCHAR(32),
    -- 文章的标签 应该以 & 分隔
    art_tags VARCHAR(128) default '',
    -- 文章缩略图的信息
    art_image_url VARCHAR(255) default '',
    art_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    art_legal tinyint default 0,
    art_cus_id INT UNSIGNED,

    -- 文章的点赞数量 ABANDON
    -- art_like_num INT UNSIGNED default 0,
    -- 文章的点踩数量 ABANDON
    -- art_dislike_num INT UNSIGNED default 0,
    -- 文章的评论数量 ABANDON
    -- art_comment_num INT UNSIGNED default 0,
    -- 文章的分数 ABANDON
	-- art_scope int UNSIGNED default 0,
    
    primary key(art_id),
	foreign key(art_cus_id) references Customer(cus_id)
);


-- com 评论 
DROP TABLE IF EXISTS NR.Comment;
CREATE TABLE NR.Comment (
    com_id INT UNSIGNED NOT NULL auto_increment,
    com_content TEXT,
    com_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    com_legal tinyint default 0,
    -- 爬虫过程中的评论标识
    com_spider varchar(64) default '',
    com_cus_id INT UNSIGNED,
    com_art_id INT UNSIGNED, 

    -- ABANDON
    -- com_like_num INT UNSIGNED default 0,
    -- ABANDON
    -- com_dislike_num INT UNSIGNED default 0,
	-- 评论的回复数量 ABANDON
    -- com_reply_num INT UNSIGNED default 0,
    -- 评论的分数 ABANDON
	-- com_scope int UNSIGNED default 0,

	primary key(com_id),
    foreign key(com_cus_id) references Customer(cus_id),
	foreign key(com_art_id) references Article(art_id)
);


-- rep 回复
DROP TABLE IF EXISTS NR.Reply;
CREATE TABLE NR.Reply (
    rep_id INT UNSIGNED NOT NULL auto_increment,
    rep_content TEXT,
    -- 回复的类型, 0 是对评论的回复, 1 是对回复的回复
    rep_type tinyint default 0, 
    rep_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
	rep_legal tinyint default 0,
    -- 爬虫过程中的评论标识
    rep_spider varchar(64) default '',
    rep_cus_id INT UNSIGNED,
    rep_art_id INT UNSIGNED,
    rep_com_id INT UNSIGNED, 
    rep_rep_id INT UNSIGNED,

    -- ABANDON
    -- rep_like_num INT UNSIGNED default 0,
    -- ABANDON
    -- rep_dislike_num INT UNSIGNED default 0,
	-- 回复的回复数量 ABANDON
    -- rep_reply_num INT UNSIGNED default 0,
    -- 回复的分数 ABANDON
	-- rep_scope int UNSIGNED default 0,

    primary key(rep_id),
    foreign key(rep_cus_id) references Customer(cus_id),
	foreign key(rep_art_id) references Article(art_id),
    foreign key(rep_com_id) references Comment(com_id),
    foreign key(rep_rep_id) references Reply(rep_id)
);


-- adm 管理员
DROP TABLE IF EXISTS NR.Administrator;
CREATE TABLE NR.Administrator (
    adm_id INT UNSIGNED NOT NULL auto_increment,
    adm_name VARCHAR(64),
    adm_pass VARCHAR(255),
    adm_email VARCHAR(64),
    adm_phone VARCHAR(64),
    adm_address VARCHAR(255),
    adm_avatar_url VARCHAR(255),
    adm_gender TINYINT DEFAULT 0,
    adm_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    
    primary key(adm_id)
);



-- ccf 用户的关注情况记录
-- follower -> followee
-- DROP TABLE IF EXISTS NewsRecommend.CustomerCustomerFollow;
-- CREATE TABLE NewsRecommend.CustomerCustomerFollow (
--     ccf_id INT UNSIGNED NOT NULL auto_increment,
--     ccf_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,

--     ccf_follower_id INT UNSIGNED,
--     ccf_followee_id INT UNSIGNED,
-- 	primary key(ccf_id),
--     foreign key(ccf_follower_id) references Customers(cus_id),
--     foreign key(ccf_followee_id) references Customers(cus_id)
-- );



-- cbr 用户的行为记录
-- 此表比较复杂, 用户之间的关注, 用户对文章, 用户对评论, 用户对回复. 
DROP TABLE IF EXISTS NR.CusBehaviorRecord;
CREATE TABLE NR.CusBehaviorRecord (
    cbr_id INT UNSIGNED NOT NULL auto_increment,
    -- 用户 攻
    cbr_cus_id_from INT UNSIGNED,
    -- 用户 受
    cbr_cus_id_to INT UNSIGNED,
    -- 行为类别
    cbr_behavior INT default 0,
    -- 行为时间
    cbr_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    -- 行为发生的文章 ID
    cbr_art_id INT UNSIGNED,
    -- 行为发生的位置代号, 0: 无发生, 1: 文章, 2: 评论, 3:回复
    cbr_type TINYINT DEFAULT 0,
    -- target ID
    cbr_target_id INT UNSIGNED,
    
	primary key(cbr_id),
    foreign key(cbr_art_id) references Article(art_id),
    foreign key(cbr_cus_id_from) references Customer(cus_id),
    foreign key(cbr_cus_id_to) references Customer(cus_id)
);

-- afc 文章特征统计表
DROP TABLE IF EXISTS NR.ArtFeatureCount;
CREATE TABLE NR.ArtFeatureCount (
    afc_id INT UNSIGNED NOT NULL auto_increment,
    afc_art_id INT UNSIGNED NOT NULL,

    afc_like_num INT UNSIGNED default 0,
    afc_dislike_num INT UNSIGNED default 0,
    afc_com_num INT UNSIGNED default 0,
    afc_rep_num INT UNSIGNED default 0,
    afc_read_num INT UNSIGNED default 0,
    afc_art_time TIMESTAMP,

	primary key(afc_id),
    foreign key(afc_art_id) references Article(art_id)
);


-- cfc 用户特征统计表
DROP TABLE IF EXISTS NR.CusFeatureCount;
CREATE TABLE NR.CusFeatureCount (
    cfc_id INT UNSIGNED NOT NULL auto_increment,

    cfc_cus_id INT UNSIGNED NOT NULL,

    cfc_news_society INT UNSIGNED default 0,
    cfc_news_entertainment INT UNSIGNED default 0,
    cfc_news_tech INT UNSIGNED default 0,
    cfc_news_military INT UNSIGNED default 0,
    cfc_news_sports INT UNSIGNED default 0,
    cfc_news_finance INT UNSIGNED default 0,
    cfc_news_world INT UNSIGNED default 0,
    cfc_news_fashion INT UNSIGNED default 0,
    cfc_news_travel INT UNSIGNED default 0,
    cfc_news_discovery INT UNSIGNED default 0,
    cfc_news_baby INT UNSIGNED default 0,
    cfc_news_regimen INT UNSIGNED default 0,
    cfc_news_story INT UNSIGNED default 0,
    cfc_news_essay INT UNSIGNED default 0,
    cfc_news_game INT UNSIGNED default 0,
    cfc_news_history INT UNSIGNED default 0,
    cfc_news_food INT UNSIGNED default 0,
    cfc_news_car INT UNSIGNED default 0,

	primary key(cfc_id),
    foreign key(cfc_cus_id) references Customer(cus_id)
);

-- crr 推荐内容记录表
DROP TABLE IF EXISTS NR.CusRecommendRecord;
CREATE TABLE NR.CusRecommendRecord (
    crr_id INT UNSIGNED NOT NULL auto_increment,
    crr_cus_id INT UNSIGNED NOT NULL,
    crr_art_id INT UNSIGNED NOT NULL,
    crr_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,

	primary key(crr_id),
    foreign key(crr_cus_id) references Customer(cus_id),
    foreign key(crr_art_id) references Article(art_id)
);


-- 新闻 分数 for tiny 列表 asl
DROP VIEW IF EXISTS NR.ArtScoreList;
create view NR.ArtScoreList(asl_art_id, asl_art_score) as
    select
        afc_art_id,
        timestampdiff(HOUR,now(),afc_art_time)*20+cast(afc_like_num as signed)*4+cast(afc_dislike_num as signed)*(-6)+cast(afc_com_num as signed)*3+cast(afc_read_num as signed )*1+cast(afc_rep_num as signed )*2 as afc_art_socre
    from NR.ArtFeatureCount
    order by afc_art_socre desc;

-- 新闻 分数 for hot 列表 atl
DROP VIEW IF EXISTS NR.ArtTimeList;
create view NR.ArtTimeList(atl_art_id, atl_art_score) as 
    SELECT
        afc_art_id,
        timestampdiff(HOUR,now(),afc_art_time)*32+cast(afc_like_num as signed)*4+cast(afc_dislike_num as signed)*(-6)+cast(afc_com_num as signed)*3+cast(afc_read_num as signed )*1+cast(afc_rep_num as signed )*2 as atl_art_score
    from NR.ArtFeatureCount left join NR.Article on NR.ArtFeatureCount.afc_art_id = NR.Article.art_id
    where
        NR.Article.art_type in ("news_society", "news_military", "news_finance", "news_entertainment",
                                "news_game", "news_sports", "news_world", "news_tech", "news_car", "news_fashion") and
        abs(timestampdiff(HOUR,now(),afc_art_time)) < 72
    order by atl_art_score desc;


================================================
FILE: README.md
================================================
# NewsRecommend

基于协同过滤算法的新闻推荐系统, 项目分前后端与爬虫. 

实现热点新闻推荐以及个性化新闻推荐.

[项目的具体说明](https://smacul.github.io/log/news_recommend/)

喜欢的话, 可以点个 star 奥. 

## 项目分支

- main: 主分支, 保存最新的可预览状态.
- dev: Mac 上的开发分支
- dev-win: Win 上的开发分支

**不同分支使用的数据库名称可能并不一致, 以各个分支中的 `NewsRecommend.sql` 文件为准**

## 数据库 NewsRecommend.sql
MySQL 导入自动建库

## 爬虫 spider

### 运行
爬虫独立运行获取数据后写入数据库, 数据来源为 今日头条, 需要 python 3 环境.

在 `spider` 目录下创建 `properties/database.json`.   
*database.json* 模板:
``` json
{
  "name": "NewsRecommend",
  "user": "your name",
  "pass": "your pass",
  "host": "your host",
  "charset": "utf8mb4"
}
```

并在 `spider` 目录下创建 `log` 目录,用于存放日志文件 (我懒得写)

正确安装 webdriver 后执行:

``` sh
cd spider
python Main.py
```

## 前端 front

前端利用 Vue Cli 3 脚手架. 需要 node.js yarn.

应该需要先装 wangeditor (富文本编辑工具) `npm install wangeditor`

### 运行
``` sh
cd front
yarn install
yarn serve
```

<!-- ### 页面浏览
``` sh
localhost:8071/         # 首页
localhost:8071/article  # 文章阅读页
localhost:8071/self     # 个人中心
localhost:8071/search   # 搜索页面
# ...
​``` -->

## 后端 back

后端基于 SpringBoot 与 MyBatis. 

现在工程目录下的 `src/main/resources` 中创建 application.properties 文件, 内容大致如下: 

``` shell   
spring.datasource.driverClassName = com.mysql.jdbc.Driver
spring.datasource.url = jdbc:mysql://[主机名]:3306/[数据库名称]?useUnicode=true&characterEncoding=utf8&useSSL=true
spring.datasource.username = [用户名]
spring.datasource.password = [密码]
mybatis.configuration.map-underscore-to-camel-case=true
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
```

## 预览

![首页](./index.png)



================================================
FILE: back/.gitignore
================================================
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**
!**/src/test/**

### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache

### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/

### VS Code ###
.vscode/

/src/main/resources/application.properties


================================================
FILE: back/.mvn/wrapper/MavenWrapperDownloader.java
================================================
/*
 * Copyright 2012-2019 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import java.net.*;
import java.io.*;
import java.nio.channels.*;
import java.util.Properties;

public class MavenWrapperDownloader {

    private static final String WRAPPER_VERSION = "0.5.5";
    /**
     * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
     */
    private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
            + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";

    /**
     * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
     * use instead of the default one.
     */
    private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
            ".mvn/wrapper/maven-wrapper.properties";

    /**
     * Path where the maven-wrapper.jar will be saved to.
     */
    private static final String MAVEN_WRAPPER_JAR_PATH =
            ".mvn/wrapper/maven-wrapper.jar";

    /**
     * Name of the property which should be used to override the default download url for the wrapper.
     */
    private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";

    public static void main(String args[]) {
        System.out.println("- Downloader started");
        File baseDirectory = new File(args[0]);
        System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());

        // If the maven-wrapper.properties exists, read it and check if it contains a custom
        // wrapperUrl parameter.
        File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
        String url = DEFAULT_DOWNLOAD_URL;
        if (mavenWrapperPropertyFile.exists()) {
            FileInputStream mavenWrapperPropertyFileInputStream = null;
            try {
                mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
                Properties mavenWrapperProperties = new Properties();
                mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
                url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
            } catch (IOException e) {
                System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
            } finally {
                try {
                    if (mavenWrapperPropertyFileInputStream != null) {
                        mavenWrapperPropertyFileInputStream.close();
                    }
                } catch (IOException e) {
                    // Ignore ...
                }
            }
        }
        System.out.println("- Downloading from: " + url);

        File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
        if (!outputFile.getParentFile().exists()) {
            if (!outputFile.getParentFile().mkdirs()) {
                System.out.println(
                        "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
            }
        }
        System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
        try {
            downloadFileFromURL(url, outputFile);
            System.out.println("Done");
            System.exit(0);
        } catch (Throwable e) {
            System.out.println("- Error downloading");
            e.printStackTrace();
            System.exit(1);
        }
    }

    private static void downloadFileFromURL(String urlString, File destination) throws Exception {
        if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
            String username = System.getenv("MVNW_USERNAME");
            char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
            Authenticator.setDefault(new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(username, password);
                }
            });
        }
        URL website = new URL(urlString);
        ReadableByteChannel rbc;
        rbc = Channels.newChannel(website.openStream());
        FileOutputStream fos = new FileOutputStream(destination);
        fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
        fos.close();
        rbc.close();
    }

}


================================================
FILE: back/.mvn/wrapper/maven-wrapper.properties
================================================
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.2/apache-maven-3.6.2-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar


================================================
FILE: back/mvnw
================================================
#!/bin/sh
# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#    https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------

# ----------------------------------------------------------------------------
# Maven2 Start Up Batch script
#
# Required ENV vars:
# ------------------
#   JAVA_HOME - location of a JDK home dir
#
# Optional ENV vars
# -----------------
#   M2_HOME - location of maven2's installed home dir
#   MAVEN_OPTS - parameters passed to the Java VM when running Maven
#     e.g. to debug Maven itself, use
#       set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
#   MAVEN_SKIP_RC - flag to disable loading of mavenrc files
# ----------------------------------------------------------------------------

if [ -z "$MAVEN_SKIP_RC" ] ; then

  if [ -f /etc/mavenrc ] ; then
    . /etc/mavenrc
  fi

  if [ -f "$HOME/.mavenrc" ] ; then
    . "$HOME/.mavenrc"
  fi

fi

# OS specific support.  $var _must_ be set to either true or false.
cygwin=false;
darwin=false;
mingw=false
case "`uname`" in
  CYGWIN*) cygwin=true ;;
  MINGW*) mingw=true;;
  Darwin*) darwin=true
    # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
    # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
    if [ -z "$JAVA_HOME" ]; then
      if [ -x "/usr/libexec/java_home" ]; then
        export JAVA_HOME="`/usr/libexec/java_home`"
      else
        export JAVA_HOME="/Library/Java/Home"
      fi
    fi
    ;;
esac

if [ -z "$JAVA_HOME" ] ; then
  if [ -r /etc/gentoo-release ] ; then
    JAVA_HOME=`java-config --jre-home`
  fi
fi

if [ -z "$M2_HOME" ] ; then
  ## resolve links - $0 may be a link to maven's home
  PRG="$0"

  # need this for relative symlinks
  while [ -h "$PRG" ] ; do
    ls=`ls -ld "$PRG"`
    link=`expr "$ls" : '.*-> \(.*\)$'`
    if expr "$link" : '/.*' > /dev/null; then
      PRG="$link"
    else
      PRG="`dirname "$PRG"`/$link"
    fi
  done

  saveddir=`pwd`

  M2_HOME=`dirname "$PRG"`/..

  # make it fully qualified
  M2_HOME=`cd "$M2_HOME" && pwd`

  cd "$saveddir"
  # echo Using m2 at $M2_HOME
fi

# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
  [ -n "$M2_HOME" ] &&
    M2_HOME=`cygpath --unix "$M2_HOME"`
  [ -n "$JAVA_HOME" ] &&
    JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
  [ -n "$CLASSPATH" ] &&
    CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
fi

# For Mingw, ensure paths are in UNIX format before anything is touched
if $mingw ; then
  [ -n "$M2_HOME" ] &&
    M2_HOME="`(cd "$M2_HOME"; pwd)`"
  [ -n "$JAVA_HOME" ] &&
    JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
fi

if [ -z "$JAVA_HOME" ]; then
  javaExecutable="`which javac`"
  if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
    # readlink(1) is not available as standard on Solaris 10.
    readLink=`which readlink`
    if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
      if $darwin ; then
        javaHome="`dirname \"$javaExecutable\"`"
        javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
      else
        javaExecutable="`readlink -f \"$javaExecutable\"`"
      fi
      javaHome="`dirname \"$javaExecutable\"`"
      javaHome=`expr "$javaHome" : '\(.*\)/bin'`
      JAVA_HOME="$javaHome"
      export JAVA_HOME
    fi
  fi
fi

if [ -z "$JAVACMD" ] ; then
  if [ -n "$JAVA_HOME"  ] ; then
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
      # IBM's JDK on AIX uses strange locations for the executables
      JAVACMD="$JAVA_HOME/jre/sh/java"
    else
      JAVACMD="$JAVA_HOME/bin/java"
    fi
  else
    JAVACMD="`which java`"
  fi
fi

if [ ! -x "$JAVACMD" ] ; then
  echo "Error: JAVA_HOME is not defined correctly." >&2
  echo "  We cannot execute $JAVACMD" >&2
  exit 1
fi

if [ -z "$JAVA_HOME" ] ; then
  echo "Warning: JAVA_HOME environment variable is not set."
fi

CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher

# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {

  if [ -z "$1" ]
  then
    echo "Path not specified to find_maven_basedir"
    return 1
  fi

  basedir="$1"
  wdir="$1"
  while [ "$wdir" != '/' ] ; do
    if [ -d "$wdir"/.mvn ] ; then
      basedir=$wdir
      break
    fi
    # workaround for JBEAP-8937 (on Solaris 10/Sparc)
    if [ -d "${wdir}" ]; then
      wdir=`cd "$wdir/.."; pwd`
    fi
    # end of workaround
  done
  echo "${basedir}"
}

# concatenates all lines of a file
concat_lines() {
  if [ -f "$1" ]; then
    echo "$(tr -s '\n' ' ' < "$1")"
  fi
}

BASE_DIR=`find_maven_basedir "$(pwd)"`
if [ -z "$BASE_DIR" ]; then
  exit 1;
fi

##########################################################################################
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
# This allows using the maven wrapper in projects that prohibit checking in binary data.
##########################################################################################
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
    if [ "$MVNW_VERBOSE" = true ]; then
      echo "Found .mvn/wrapper/maven-wrapper.jar"
    fi
else
    if [ "$MVNW_VERBOSE" = true ]; then
      echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
    fi
    if [ -n "$MVNW_REPOURL" ]; then
      jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar"
    else
      jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar"
    fi
    while IFS="=" read key value; do
      case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
      esac
    done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
    if [ "$MVNW_VERBOSE" = true ]; then
      echo "Downloading from: $jarUrl"
    fi
    wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
    if $cygwin; then
      wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
    fi

    if command -v wget > /dev/null; then
        if [ "$MVNW_VERBOSE" = true ]; then
          echo "Found wget ... using wget"
        fi
        if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
            wget "$jarUrl" -O "$wrapperJarPath"
        else
            wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
        fi
    elif command -v curl > /dev/null; then
        if [ "$MVNW_VERBOSE" = true ]; then
          echo "Found curl ... using curl"
        fi
        if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
            curl -o "$wrapperJarPath" "$jarUrl" -f
        else
            curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
        fi
        
    else
        if [ "$MVNW_VERBOSE" = true ]; then
          echo "Falling back to using Java to download"
        fi
        javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
        # For Cygwin, switch paths to Windows format before running javac
        if $cygwin; then
          javaClass=`cygpath --path --windows "$javaClass"`
        fi
        if [ -e "$javaClass" ]; then
            if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
                if [ "$MVNW_VERBOSE" = true ]; then
                  echo " - Compiling MavenWrapperDownloader.java ..."
                fi
                # Compiling the Java class
                ("$JAVA_HOME/bin/javac" "$javaClass")
            fi
            if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
                # Running the downloader
                if [ "$MVNW_VERBOSE" = true ]; then
                  echo " - Running MavenWrapperDownloader.java ..."
                fi
                ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
            fi
        fi
    fi
fi
##########################################################################################
# End of extension
##########################################################################################

export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
if [ "$MVNW_VERBOSE" = true ]; then
  echo $MAVEN_PROJECTBASEDIR
fi
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"

# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
  [ -n "$M2_HOME" ] &&
    M2_HOME=`cygpath --path --windows "$M2_HOME"`
  [ -n "$JAVA_HOME" ] &&
    JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
  [ -n "$CLASSPATH" ] &&
    CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
  [ -n "$MAVEN_PROJECTBASEDIR" ] &&
    MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
fi

# Provide a "standardized" way to retrieve the CLI args that will
# work with both Windows and non-Windows executions.
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
export MAVEN_CMD_LINE_ARGS

WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain

exec "$JAVACMD" \
  $MAVEN_OPTS \
  -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
  "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
  ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"


================================================
FILE: back/mvnw.cmd
================================================
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements.  See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership.  The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License.  You may obtain a copy of the License at
@REM
@REM    https://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied.  See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------

@REM ----------------------------------------------------------------------------
@REM Maven2 Start Up Batch script
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM
@REM Optional ENV vars
@REM M2_HOME - location of maven2's installed home dir
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM     e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM ----------------------------------------------------------------------------

@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM set title of command window
title %0
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on"  echo %MAVEN_BATCH_ECHO%

@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")

@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
:skipRcPre

@setlocal

set ERROR_CODE=0

@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal

@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome

echo.
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error

:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init

echo.
echo Error: JAVA_HOME is set to an invalid directory. >&2
echo JAVA_HOME = "%JAVA_HOME%" >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error

@REM ==== END VALIDATION ====

:init

@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.

set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir

set EXEC_DIR=%CD%
set WDIR=%EXEC_DIR%
:findBaseDir
IF EXIST "%WDIR%"\.mvn goto baseDirFound
cd ..
IF "%WDIR%"=="%CD%" goto baseDirNotFound
set WDIR=%CD%
goto findBaseDir

:baseDirFound
set MAVEN_PROJECTBASEDIR=%WDIR%
cd "%EXEC_DIR%"
goto endDetectBaseDir

:baseDirNotFound
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
cd "%EXEC_DIR%"

:endDetectBaseDir

IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig

@setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%

:endReadAdditionalConfig

SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain

set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar"

FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
    IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
)

@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
if exist %WRAPPER_JAR% (
    if "%MVNW_VERBOSE%" == "true" (
        echo Found %WRAPPER_JAR%
    )
) else (
    if not "%MVNW_REPOURL%" == "" (
        SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar"
    )
    if "%MVNW_VERBOSE%" == "true" (
        echo Couldn't find %WRAPPER_JAR%, downloading it ...
        echo Downloading from: %DOWNLOAD_URL%
    )

    powershell -Command "&{"^
		"$webclient = new-object System.Net.WebClient;"^
		"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
		"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
		"}"^
		"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
		"}"
    if "%MVNW_VERBOSE%" == "true" (
        echo Finished downloading %WRAPPER_JAR%
    )
)
@REM End of extension

@REM Provide a "standardized" way to retrieve the CLI args that will
@REM work with both Windows and non-Windows executions.
set MAVEN_CMD_LINE_ARGS=%*

%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
if ERRORLEVEL 1 goto error
goto end

:error
set ERROR_CODE=1

:end
@endlocal & set ERROR_CODE=%ERROR_CODE%

if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
:skipRcPost

@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%" == "on" pause

if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%

exit /B %ERROR_CODE%


================================================
FILE: back/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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.smacul</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot</artifactId>
            <version>2.2.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.2.0.RELEASE</version>
        </dependency>


        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.38</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13-beta-3</version>
        </dependency>
        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>RELEASE</version>
            <scope>compile</scope>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>


================================================
FILE: back/src/main/java/com/smacul/demo/DemoApplication.java
================================================
package com.smacul.demo;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Import;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@EnableTransactionManagement
@SpringBootApplication
@MapperScan("com.smacul.demo.dao")
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}


================================================
FILE: back/src/main/java/com/smacul/demo/bean/ArtFeatureCount.java
================================================
package com.smacul.demo.bean;

public class ArtFeatureCount {

    private Integer afcId;
    private Integer afcArtId;
    private Integer afcLikeNum;
    private Integer afcDislikeNum;

    private Integer afcComNum;
    private Integer afcRepNum;
    private Integer afcReadNum;
    private Integer afcArtTime;

    public Integer getAfcId() {
        return afcId;
    }

    public void setAfcId(Integer afcId) {
        this.afcId = afcId;
    }

    public Integer getAfcArtId() {
        return afcArtId;
    }

    public void setAfcArtId(Integer afcArtId) {
        this.afcArtId = afcArtId;
    }

    public Integer getAfcLikeNum() {
        return afcLikeNum;
    }

    public void setAfcLikeNum(Integer afcLikeNum) {
        this.afcLikeNum = afcLikeNum;
    }

    public Integer getAfcDislikeNum() {
        return afcDislikeNum;
    }

    public void setAfcDislikeNum(Integer afcDislikeNum) {
        this.afcDislikeNum = afcDislikeNum;
    }

    public Integer getAfcComNum() {
        return afcComNum;
    }

    public void setAfcComNum(Integer afcComNum) {
        this.afcComNum = afcComNum;
    }

    public Integer getAfcRepNum() {
        return afcRepNum;
    }

    public void setAfcRepNum(Integer afcRepNum) {
        this.afcRepNum = afcRepNum;
    }

    public Integer getAfcReadNum() {
        return afcReadNum;
    }

    public void setAfcReadNum(Integer afcReadNum) {
        this.afcReadNum = afcReadNum;
    }

    public Integer getAfcArtTime() {
        return afcArtTime;
    }

    public void setAfcArtTime(Integer afcArtTime) {
        this.afcArtTime = afcArtTime;
    }
}


================================================
FILE: back/src/main/java/com/smacul/demo/bean/ArtScoreList.java
================================================
package com.smacul.demo.bean;

public class ArtScoreList {

    private Integer aslArtId;
    private Integer aslArtScore;

    public Integer getAslArtId() {
        return aslArtId;
    }

    public void setAslArtId(Integer aslArtId) {
        this.aslArtId = aslArtId;
    }

    public Integer getAslArtScore() {
        return aslArtScore;
    }

    public void setAslArtScore(Integer aslArtScore) {
        this.aslArtScore = aslArtScore;
    }

}


================================================
FILE: back/src/main/java/com/smacul/demo/bean/ArtTimeList.java
================================================
package com.smacul.demo.bean;

public class ArtTimeList {

    private Integer atlId;
    private Integer atlArtScore;

    public Integer getAtlId() {
        return atlId;
    }

    public void setAtlId(Integer atlId) {
        this.atlId = atlId;
    }

    public Integer getAtlArtScore() {
        return atlArtScore;
    }

    public void setAtlArtScore(Integer atlArtScore) {
        this.atlArtScore = atlArtScore;
    }
}


================================================
FILE: back/src/main/java/com/smacul/demo/bean/Article.java
================================================
package com.smacul.demo.bean;

import java.sql.Timestamp;

public class Article {
    private Integer artId;
    private String artTitle;
    private String artContent;
    private String artSpider;

    private String artType;
    private String artTags;
    private String artImageUrl;
    private Timestamp artTime;

    private Integer artLegal;
    private Integer artCusId;

    public Integer getArtId() {
        return artId;
    }

    public void setArtId(Integer artId) {
        this.artId = artId;
    }

    public String getArtTitle() {
        return artTitle;
    }

    public void setArtTitle(String artTitle) {
        this.artTitle = artTitle;
    }

    public String getArtContent() {
        return artContent;
    }

    public void setArtContent(String artContent) {
        this.artContent = artContent;
    }

    public String getArtSpider() {
        return artSpider;
    }

    public void setArtSpider(String artSpider) {
        this.artSpider = artSpider;
    }

    public String getArtType() {
        return artType;
    }

    public void setArtType(String artType) {
        this.artType = artType;
    }

    public String getArtTags() {
        return artTags;
    }

    public void setArtTags(String artTags) {
        this.artTags = artTags;
    }

    public String getArtImageUrl() {
        return artImageUrl;
    }

    public void setArtImageUrl(String artImageUrl) {
        this.artImageUrl = artImageUrl;
    }

    public Timestamp getArtTime() {
        return artTime;
    }

    public void setArtTime(Timestamp artTime) {
        this.artTime = artTime;
    }

    public Integer getArtLegal() {
        return artLegal;
    }

    public void setArtLegal(Integer artLegal) {
        this.artLegal = artLegal;
    }

    public Integer getArtCusId() {
        return artCusId;
    }

    public void setArtCusId(Integer artCusId) {
        this.artCusId = artCusId;
    }
}


================================================
FILE: back/src/main/java/com/smacul/demo/bean/Comment.java
================================================
package com.smacul.demo.bean;

import java.sql.Timestamp;

public class Comment {

    private Integer comId;
    private String comContent;
    private Timestamp comTime;
    private Integer comLegal;
    private String comSpider;

    private Integer comCusId;
    private  Integer comArtId;

    public Integer getComId() {
        return comId;
    }

    public void setComId(Integer comId) {
        this.comId = comId;
    }

    public String getComContent() {
        return comContent;
    }

    public void setComContent(String comContent) {
        this.comContent = comContent;
    }

    public Timestamp getComTime() {
        return comTime;
    }

    public void setComTime(Timestamp comTime) {
        this.comTime = comTime;
    }

    public Integer getComLegal() {
        return comLegal;
    }

    public void setComLegal(Integer comLegal) {
        this.comLegal = comLegal;
    }

    public String getComSpider() {
        return comSpider;
    }

    public void setComSpider(String comSpider) {
        this.comSpider = comSpider;
    }

    public Integer getComCusId() {
        return comCusId;
    }

    public void setComCusId(Integer comCusId) {
        this.comCusId = comCusId;
    }

    public Integer getComArtId() {
        return comArtId;
    }

    public void setComArtId(Integer comArtId) {
        this.comArtId = comArtId;
    }
}


================================================
FILE: back/src/main/java/com/smacul/demo/bean/CusBehaviorRecord.java
================================================
package com.smacul.demo.bean;

import java.sql.Timestamp;

public class CusBehaviorRecord {

    private Integer cbrId;
    private Integer cbrCusIdFrom;
    private Integer cbrCusIdTo;
    private Integer cbrBehavior;

    private Timestamp cbrTime;
    private Integer cbrArtId;
    // 行为发生的位置代号, 0: 默认, 1: 文章, 2: 评论, 3:回复
    private Integer cbrType;
    private Integer cbrTargetId;

    public Integer getCbrId() {
        return cbrId;
    }

    public void setCbrId(Integer cbrId) {
        this.cbrId = cbrId;
    }

    public Integer getCbrCusIdFrom() {
        return cbrCusIdFrom;
    }

    public void setCbrCusIdFrom(Integer cbrCusIdFrom) {
        this.cbrCusIdFrom = cbrCusIdFrom;
    }

    public Integer getCbrCusIdTo() {
        return cbrCusIdTo;
    }

    public void setCbrCusIdTo(Integer cbrCusIdTo) {
        this.cbrCusIdTo = cbrCusIdTo;
    }

    public Integer getCbrBehavior() {
        return cbrBehavior;
    }

    public void setCbrBehavior(Integer cbrBehavior) {
        this.cbrBehavior = cbrBehavior;
    }

    public Timestamp getCbrTime() {
        return cbrTime;
    }

    public void setCbrTime(Timestamp cbrTime) {
        this.cbrTime = cbrTime;
    }

    public Integer getCbrArtId() {
        return cbrArtId;
    }

    public void setCbrArtId(Integer cbrArtId) {
        this.cbrArtId = cbrArtId;
    }

    public Integer getCbrType() {
        return cbrType;
    }

    public void setCbrType(Integer cbrType) {
        this.cbrType = cbrType;
    }

    public Integer getCbrTargetId() {
        return cbrTargetId;
    }

    public void setCbrTargetId(Integer cbrTargetId) {
        this.cbrTargetId = cbrTargetId;
    }
}


================================================
FILE: back/src/main/java/com/smacul/demo/bean/CusFeatureCount.java
================================================
package com.smacul.demo.bean;

public class CusFeatureCount {
    private Integer cfcId;
    private Integer cfcCusId;

    private Integer cfcNewsSociety;
    private Integer cfcNewsEntertainment;
    private Integer cfcNewsTech;

    private Integer cfcNewsMilitary;
    private Integer cfcNewsSports;
    private Integer cfcNewsFinance;

    private Integer cfcNewsWorld;
    private Integer cfcNewsFashion;
    private Integer cfcNewsTravel;

    private Integer cfcNewsDiscovery;
    private Integer cfcNewsBaby;
    private Integer cfcNewsRegimen;

    private Integer cfcNewsStory;
    private Integer cfcNewsEssay;
    private Integer cfcNewsGame;

    private Integer cfcNewsHistory;
    private Integer cfcNewsFood;
    private Integer cfcNewsCar;

    public Integer getCfcId() {
        return cfcId;
    }

    public void setCfcId(Integer cfcId) {
        this.cfcId = cfcId;
    }

    public Integer getCfcCusId() {
        return cfcCusId;
    }

    public void setCfcCusId(Integer cfcCusId) {
        this.cfcCusId = cfcCusId;
    }

    public Integer getCfcNewsSociety() {
        return cfcNewsSociety;
    }

    public void setCfcNewsSociety(Integer cfcNewsSociety) {
        this.cfcNewsSociety = cfcNewsSociety;
    }

    public Integer getCfcNewsEntertainment() {
        return cfcNewsEntertainment;
    }

    public void setCfcNewsEntertainment(Integer cfcNewsEntertainment) {
        this.cfcNewsEntertainment = cfcNewsEntertainment;
    }

    public Integer getCfcNewsTech() {
        return cfcNewsTech;
    }

    public void setCfcNewsTech(Integer cfcNewsTech) {
        this.cfcNewsTech = cfcNewsTech;
    }

    public Integer getCfcNewsMilitary() {
        return cfcNewsMilitary;
    }

    public void setCfcNewsMilitary(Integer cfcNewsMilitary) {
        this.cfcNewsMilitary = cfcNewsMilitary;
    }

    public Integer getCfcNewsSports() {
        return cfcNewsSports;
    }

    public void setCfcNewsSports(Integer cfcNewsSports) {
        this.cfcNewsSports = cfcNewsSports;
    }

    public Integer getCfcNewsFinance() {
        return cfcNewsFinance;
    }

    public void setCfcNewsFinance(Integer cfcNewsFinance) {
        this.cfcNewsFinance = cfcNewsFinance;
    }

    public Integer getCfcNewsWorld() {
        return cfcNewsWorld;
    }

    public void setCfcNewsWorld(Integer cfcNewsWorld) {
        this.cfcNewsWorld = cfcNewsWorld;
    }

    public Integer getCfcNewsFashion() {
        return cfcNewsFashion;
    }

    public void setCfcNewsFashion(Integer cfcNewsFashion) {
        this.cfcNewsFashion = cfcNewsFashion;
    }

    public Integer getCfcNewsTravel() {
        return cfcNewsTravel;
    }

    public void setCfcNewsTravel(Integer cfcNewsTravel) {
        this.cfcNewsTravel = cfcNewsTravel;
    }

    public Integer getCfcNewsDiscovery() {
        return cfcNewsDiscovery;
    }

    public void setCfcNewsDiscovery(Integer cfcNewsDiscovery) {
        this.cfcNewsDiscovery = cfcNewsDiscovery;
    }

    public Integer getCfcNewsBaby() {
        return cfcNewsBaby;
    }

    public void setCfcNewsBaby(Integer cfcNewsBaby) {
        this.cfcNewsBaby = cfcNewsBaby;
    }

    public Integer getCfcNewsRegimen() {
        return cfcNewsRegimen;
    }

    public void setCfcNewsRegimen(Integer cfcNewsRegimen) {
        this.cfcNewsRegimen = cfcNewsRegimen;
    }

    public Integer getCfcNewsStory() {
        return cfcNewsStory;
    }

    public void setCfcNewsStory(Integer cfcNewsStory) {
        this.cfcNewsStory = cfcNewsStory;
    }

    public Integer getCfcNewsEssay() {
        return cfcNewsEssay;
    }

    public void setCfcNewsEssay(Integer cfcNewsEssay) {
        this.cfcNewsEssay = cfcNewsEssay;
    }

    public Integer getCfcNewsGame() {
        return cfcNewsGame;
    }

    public void setCfcNewsGame(Integer cfcNewsGame) {
        this.cfcNewsGame = cfcNewsGame;
    }

    public Integer getCfcNewsHistory() {
        return cfcNewsHistory;
    }

    public void setCfcNewsHistory(Integer cfcNewsHistory) {
        this.cfcNewsHistory = cfcNewsHistory;
    }

    public Integer getCfcNewsFood() {
        return cfcNewsFood;
    }

    public void setCfcNewsFood(Integer cfcNewsFood) {
        this.cfcNewsFood = cfcNewsFood;
    }

    public Integer getCfcNewsCar() {
        return cfcNewsCar;
    }

    public void setCfcNewsCar(Integer cfcNewsCar) {
        this.cfcNewsCar = cfcNewsCar;
    }
}


================================================
FILE: back/src/main/java/com/smacul/demo/bean/Customer.java
================================================
package com.smacul.demo.bean;


import java.sql.Timestamp;

public class Customer {
    private Integer cusId;
    private String cusName;
    private String cusPass;
    private String cusSpider;

    private String cusAvatarUrl;
    private String cusStyle;
    private Integer cusGender;
    private Timestamp cusTime;
    // cusLegal 默认为 0, 1 为合法, -1 为非法
    private Integer cusLegal;

    public Integer getCusId() {
        return cusId;
    }

    public void setCusId(Integer cusId) {
        this.cusId = cusId;
    }

    public String getCusName() {
        return cusName;
    }

    public void setCusName(String cusName) {
        this.cusName = cusName;
    }

    public String getCusPass() {
        return cusPass;
    }

    public void setCusPass(String cusPass) {
        this.cusPass = cusPass;
    }

    public String getCusSpider() {
        return cusSpider;
    }

    public void setCusSpider(String cusSpider) {
        this.cusSpider = cusSpider;
    }

    public String getCusAvatarUrl() {
        return cusAvatarUrl;
    }

    public void setCusAvatarUrl(String cusAvatarUrl) {
        this.cusAvatarUrl = cusAvatarUrl;
    }

    public String getCusStyle() {
        return cusStyle;
    }

    public void setCusStyle(String cusStyle) {
        this.cusStyle = cusStyle;
    }

    public Integer getCusGender() {
        return cusGender;
    }

    public void setCusGender(Integer cusGender) {
        this.cusGender = cusGender;
    }

    public Timestamp getCusTime() {
        return cusTime;
    }

    public void setCusTime(Timestamp cusTime) {
        this.cusTime = cusTime;
    }

    public Integer getCusLegal() {
        return cusLegal;
    }

    public void setCusLegal(Integer cusLegal) {
        this.cusLegal = cusLegal;
    }
}


================================================
FILE: back/src/main/java/com/smacul/demo/bean/Reply.java
================================================
package com.smacul.demo.bean;

import java.sql.Timestamp;

public class Reply {

    private Integer repId;
    private String repContent;

    private Integer repType;
    private Timestamp repTime;
    private Integer repLegal;
    private String repSpider;

    private Integer repCusId;
    private Integer repArtId;
    private Integer repComId;
    private Integer repRepId;

    public Integer getRepId() {
        return repId;
    }

    public void setRepId(Integer repId) {
        this.repId = repId;
    }

    public String getRepContent() {
        return repContent;
    }

    public void setRepContent(String repContent) {
        this.repContent = repContent;
    }

    public Integer getRepType() {
        return repType;
    }

    public void setRepType(Integer repType) {
        this.repType = repType;
    }

    public Timestamp getRepTime() {
        return repTime;
    }

    public void setRepTime(Timestamp repTime) {
        this.repTime = repTime;
    }

    public Integer getRepLegal() {
        return repLegal;
    }

    public void setRepLegal(Integer repLegal) {
        this.repLegal = repLegal;
    }

    public String getRepSpider() {
        return repSpider;
    }

    public void setRepSpider(String repSpider) {
        this.repSpider = repSpider;
    }

    public Integer getRepCusId() {
        return repCusId;
    }

    public void setRepCusId(Integer repCusId) {
        this.repCusId = repCusId;
    }

    public Integer getRepArtId() {
        return repArtId;
    }

    public void setRepArtId(Integer repArtId) {
        this.repArtId = repArtId;
    }

    public Integer getRepComId() {
        return repComId;
    }

    public void setRepComId(Integer repComId) {
        this.repComId = repComId;
    }

    public Integer getRepRepId() {
        return repRepId;
    }

    public void setRepRepId(Integer repRepId) {
        this.repRepId = repRepId;
    }
}


================================================
FILE: back/src/main/java/com/smacul/demo/controller/DiscussController.java
================================================
package com.smacul.demo.controller;

import com.smacul.demo.bean.Comment;
import com.smacul.demo.bean.Customer;
import com.smacul.demo.bean.Reply;
import com.smacul.demo.model.ComFullMod;
import com.smacul.demo.service.DiscussService;
import com.smacul.demo.service.ShapeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpSession;
import java.util.List;

@RestController
@RequestMapping("/discuss")
public class DiscussController {

    @Autowired
    DiscussService discussService;
    @Autowired
    ShapeService shapeService;
    @Autowired
    HttpSession session;

    /**
     * 获取完整的评论列表
     * 20-04-20 方法创建
     * @param artId
     * @return
     */
    @RequestMapping("/page")
    public List<ComFullMod> getComList(@RequestParam Integer artId) {
        Customer customer = (Customer) session.getAttribute("customer");
        if (customer == null) {
            return null;
        }
        return discussService.getComList(artId);
    }

    /**
     * 添加评论
     * 20-04-20 添加方法
     * 20-05-04 在插入用户行为数据之前, 对 result 的内容进行检查
     * @param comment
     * @return
     */
    @RequestMapping("/com")
    public String addNewCom(@RequestBody Comment comment) {
        Customer customer = (Customer) session.getAttribute("customer");
        if (customer == null) {
            return "评论失败";
        }
        String result = discussService.addNewCom(comment);
        if (result.equals("评论成功")) {
            shapeService.setCusBehaviorComEdit(customer.getCusId(), comment.getComArtId(), comment.getComId());
        }
        return result;
    }

    /**
     * 添加回复
     * 20-04-20 添加方法
     * 20-05-04 在插入用户行为数据之前, 对 result 的内容进行检查
     * @param reply
     * @return
     */
    @RequestMapping("/rep")
    public String addNewRep(@RequestBody Reply reply) {
        Customer customer = (Customer) session.getAttribute("customer");
        if (customer == null) {
            return "评论失败";
        }
        String result = discussService.addNewRep(reply);
        if (result.equals("评论成功")) {
            shapeService.setCusBehaviorRepEdit(customer.getCusId(), reply.getRepArtId(), reply.getRepId());
        }
        return result;
    }

}


================================================
FILE: back/src/main/java/com/smacul/demo/controller/EditController.java
================================================
package com.smacul.demo.controller;

import com.smacul.demo.bean.Article;
import com.smacul.demo.bean.Customer;
import com.smacul.demo.service.EditService;
import com.smacul.demo.service.ShapeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpSession;

@RestController
@RequestMapping("/edit")
public class EditController {

    @Autowired
    EditService editService;
    @Autowired
    ShapeService shapeService;
    @Autowired
    HttpSession session;

    /**
     * 用户添加新的文章
     * 20-05-04 添加方法
     * @param article
     * @return
     */
    @RequestMapping("/add")
    public Integer addNewArt(@RequestBody Article article) {
        Customer customer = (Customer) session.getAttribute("customer");
        if (customer == null) {
            return 0;
        }

        String result = editService.addNewArt(article);
        if (result.equals("文章添加成功")) {
            shapeService.setCusBehaviorArtEdit(customer.getCusId(), article.getArtId());
        }
        return article.getArtId();
    }

}


================================================
FILE: back/src/main/java/com/smacul/demo/controller/LoadController.java
================================================
package com.smacul.demo.controller;

import com.smacul.demo.bean.Customer;
import com.smacul.demo.model.ArtFullMod;
import com.smacul.demo.service.LoadService;
import com.smacul.demo.service.SelfService;
import com.smacul.demo.service.SessionService;
import com.smacul.demo.service.ShapeService;
import com.smacul.demo.util.TypeHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/load")
public class LoadController {

    @Autowired
    LoadService loadService;
    @Autowired
    ShapeService shapeService;
    @Autowired
    SelfService selfService;
    @Autowired
    SessionService session;

    /**
     * 获取新闻类别(英文)
     * 20-04-19 创建方法 TODO 老用户的处理逻辑还没完成
     * @return
     */
    @RequestMapping("/type")
    public List<String> getArtTypes() {
        Customer customer = session.getCusSession();
        if (customer == null) {
            return null;
        }
        if (selfService.checkIsNewUser(customer.getCusId())) {
            return loadService.getArtTypesForNew();
        } else {
            return loadService.getArtTypesForOld(customer.getCusId());
        }
    }

    /**
     * 按照类别获取一页文章
     * 20-04-19 创建方法
     * 20-05-02 添加老用户推荐逻辑
     * 20-05-18 修改逻辑, 在新用户切换成老用户时添加计算相似用户的逻辑
     * 20-05-19 推荐逻辑修改, 在相似用户用完之后, 重新计算相似用户
     * 20-05-24 方法修改, 接受 artType 后转换为英文.
     * @param artType
     * @param page
     * @param pageSize
     * @return
     */
    @RequestMapping("/tiny")
    public List<ArtFullMod> getTinyArtOnePageByType(
            @RequestParam String artType, @RequestParam Integer page, @RequestParam Integer pageSize) {
        artType = TypeHandler.typeTransSingleChToEn(artType);
        Customer customer = session.getCusSession();
        if (customer == null) {
            return null;
        }
        List<ArtFullMod> recommendList = null;
        // 新用户推荐
        if (selfService.checkIsNewUser(customer.getCusId())) {
            recommendList = loadService.getTinyArtOnePageByTypeForNew(customer.getCusId(), artType, session.getPagThenAddOne(artType), pageSize);
            shapeService.recordRecommendList(customer.getCusId(), recommendList);
            return recommendList;
        }

        // 老用户推荐
        List<Integer> relativeCusList = session.getRelSession();

        // 当前用户变为老用户, session 中相似用户的记录为空
        if (relativeCusList == null || relativeCusList.size() == 0) {
            relativeCusList = selfService.getRelativeCusList(customer.getCusId(), 10);
            session.setRelSession(relativeCusList);
            session.getSetPagAfterCusChange(artType);
        }
        //获取推荐内容
        recommendList = loadService.getTinyArtOnePageByTypeForOld(
                customer.getCusId(), relativeCusList, artType, session.getPagThenAddOne(artType), pageSize);
        // 如果 getTinyArtOnePageByTypeForOld 方法返回内容长度为 0, 说明本批次相似用户推荐结束. 重新计算相似用户
        // getTinyArtOnePageByTypeForOld 方法返回内容长度为 0, 系统利用新一批相似用户再次尝试推荐
        if (recommendList.size() == 0) {
            if ("news_global".equals(artType)) {
                relativeCusList = selfService.getRelativeCusList(customer.getCusId(), 10);
                session.setRelSession(relativeCusList);
                session.getSetPagAfterCusChange(artType);
                recommendList = loadService.getTinyArtOnePageByTypeForOld(customer.getCusId(), relativeCusList, artType, session.getPagThenAddOne(artType), pageSize);
            }
            // 如果再次推荐的结果内容长度为 0, 切换至新用户推荐
            if (recommendList.size() == 0) {
                if ("news_global".equals(artType)) {
                    session.setRelSession(new ArrayList<>());
                    session.getSetPagAfterCusChange(artType);
                }
                recommendList = loadService.getTinyArtOnePageByTypeForNew(customer.getCusId(), artType, session.getPagThenAddOne(artType), pageSize);
            }
        }
        shapeService.recordRecommendList(customer.getCusId(), recommendList);
        return recommendList;
    }

    /**
     * 提供一页的热点新闻
     * 20-04-19 创建方法
     * @param page
     * @param pageSize
     * @return
     */
    @RequestMapping("/hot")
    public List<ArtFullMod> getHotArtOnePage(@RequestParam Integer page, @RequestParam Integer pageSize) {
        Customer customer = session.getCusSession();
        if (customer == null) {
            return null;
        }
        return loadService.getHotArtOnePage(session.getPagThenAddOne("news_hot"), pageSize);
    }

    /**
     * 获取文章的主体内容, 包括文章内容, 文章作者, 文章的特征信息, 当前用户与文章的关系.
     * 20-04-19 创建方法
     * @param artId
     * @return
     */
    @RequestMapping("/main")
    public ArtFullMod getFullArt(@RequestParam Integer artId) {
        Customer customer = session.getCusSession();
        if (customer == null) {
            return null;
        }
        ArtFullMod artFullMod = loadService.getFullArt(customer.getCusId(), artId);
        shapeService.setCusBehaviorArtRead(customer.getCusId(), artId);
        return artFullMod;
    }

    /**
     * 文章点赞/点踩控制, 包括取消
     * 20-04-19 创建方法
     * @param artId
     * @param type  1: 点赞, 2: 点踩, -1: 取消点赞, -2: 取消点踩
     * @return
     */
    @RequestMapping("/prefer")
    public String setArtPreference(@RequestParam Integer artId, @RequestParam Integer type) {
        Customer customer = session.getCusSession();
        if (customer == null) {
            return "操作失败";
        }
        Boolean result = false;
        switch (type){
            case 1:
                result = shapeService.setCusBehaviorArtLike(customer.getCusId(), artId, true);
                break;
            case 2:
                result = shapeService.setCusBehaviorArtDislike(customer.getCusId(), artId, true);
                break;
            case -1:
                result = shapeService.setCusBehaviorArtLike(customer.getCusId(), artId, false);
                break;
            case -2:
                result = shapeService.setCusBehaviorArtDislike(customer.getCusId(), artId, false);
                break;
        }
        if (result) {
            return "操作成功";
        } else {
            return "操作失败";
        }
    }

}


================================================
FILE: back/src/main/java/com/smacul/demo/controller/SearchController.java
================================================
package com.smacul.demo.controller;

import com.smacul.demo.bean.Customer;
import com.smacul.demo.model.ArtFullMod;
import com.smacul.demo.service.SearchService;
import com.smacul.demo.service.ShapeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpSession;
import java.util.List;

@RestController
@RequestMapping("/search")
public class SearchController {

    @Autowired
    SearchService searchService;
    @Autowired
    ShapeService shapeService;
    @Autowired
    HttpSession session;

    @RequestMapping("/simple")
    public List<ArtFullMod> searchContentSimple(
            @RequestParam String key, @RequestParam Integer page, @RequestParam Integer pageSize) {
        Customer customer = (Customer) session.getAttribute("customer");
        if (customer == null) {
            return null;
        }
        return searchService.searchContentSimple(key, page, pageSize);
    }
}


================================================
FILE: back/src/main/java/com/smacul/demo/controller/SelfController.java
================================================
package com.smacul.demo.controller;

import com.smacul.demo.bean.Customer;
import com.smacul.demo.dao.CusDao;
import com.smacul.demo.model.CusDynamicMod;
import com.smacul.demo.model.CusFeatureFullMod;
import com.smacul.demo.service.SearchService;
import com.smacul.demo.service.SelfService;
import com.smacul.demo.service.SessionService;
import com.smacul.demo.service.ShapeService;
import com.sun.org.apache.xpath.internal.operations.Bool;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpSession;
import java.security.NoSuchAlgorithmException;
import java.util.List;

@RestController
@RequestMapping("/self")
public class SelfController {

    @Autowired
    SelfService selfService;
    @Autowired
    ShapeService shapeService;
    @Autowired
    SessionService session;

    /**
     * 用户登录
     * 20-04-18 创建方法
     * 20-05-02 添加获取相似用户的逻辑
     * @param cusName
     * @param cusPass
     * @return
     */
    @RequestMapping("/login")
    public String cusLogin(@RequestParam String cusName, @RequestParam String cusPass) {
        if (session.getCusSession() != null) {
            return "您已登录";
        }
        try {
            Customer customer = selfService.checkCusForLogin(cusName, cusPass);
            if (customer != null) {
                customer.setCusPass(null);
                session.setCusSession(customer);
                List<Integer> cusList = selfService.getRelativeCusList(customer.getCusId(), 10);
                session.setRelSession(cusList);
                session.initPagSession();
                return "登录成功";
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "登录失败";
    }

    /**
     * 用户退出登录
     * 20-04-24 创建方法
     * @return
     */
    @RequestMapping("/quit")
    public String quitLogin() {
        session.setCusSession(null);
        return "退出成功";
    }

    /**
     * 用户注册
     * 20-04-18 创建方法
     * 20-04-24 逻辑修改, 在注册时清空 session 中的用户
     * @param cusName
     * @param cusPass
     * @return
     */
    @RequestMapping("/register")
    public String cusRegister(@RequestParam String cusName, @RequestParam String cusPass) {
        try {
            session.setCusSession(null);
            return selfService.setNewCus(cusName, cusPass);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "注册失败";
    }

    /**
     * 通过 ID 获取用户基本信息
     * 20-04-18 创建方法
     * @param cusId
     * @return
     */
    @RequestMapping("/basic")
    public Customer getCusBasicInfo(@RequestParam Integer cusId) {
        if (session.getCusSession() == null) {
            return null;
        }
        if (cusId == null || cusId <= 0) {
            return session.getCusSession();
        } else {
            return selfService.getCusBasicInfo(cusId);
        }
    }

    /**
     * 修改用户的基本信息
     * 20-04-18 创建方法
     * @param customer
     * @return
     */
    @RequestMapping("/modify")
    public String setCusBasicInfo(@RequestBody Customer customer) {
        if (session.getCusSession() == null) {
            return "修改失败";
        }
        try {
            if (selfService.setCusBasicInfo(customer)) {
                session.setCusSession(customer);
                return "修改成功";
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "修改失败";
    }

    /**
     * 处理用户关注与取消关注
     * 20-04-18 创建方法
     * 20-04-26 修改逻辑, 防止用户关注自己
     * 20-05-17 补上用户关注后, 更新后台三个表信息.
     * @param cusId 关注或取消关注的用户的 ID
     * @return
     */
    @RequestMapping("/follow")
    public String setCusFollow(@RequestParam Integer cusId) {
        if (session.getCusSession() == null) {
            return "关注失败";
        }
        Customer cusFrom = session.getCusSession();
        Integer cusIdFrom = cusFrom.getCusId();
        if (cusId.equals(cusIdFrom)) {
            return "不能关注自己";
        }
        if (selfService.setCusFollow(cusIdFrom, cusId)) {
            shapeService.setCusBehaviorCusFollow(cusIdFrom, cusId);
            return "关注成功";
        } else {
            return "关注失败";
        }
    }

    /**
     * 获取用户完成的特征数据
     * 20-04-18 创建方法
     * @param cusId
     * @return
     */
    @RequestMapping("/feature")
    public CusFeatureFullMod getCusFeatureInfo(@RequestParam Integer cusId) {
        return selfService.getCusFeatureInfo(cusId);
    }

    /**
     * 获取指定用户的动态
     * 20-04-24 创建方法
     * @param cusId
     * @param page
     * @param pageSize
     * @return
     */
    @RequestMapping("/dynamic")
    public List<CusDynamicMod> getCusDynamic(
            @RequestParam Integer cusId, @RequestParam Integer page, @RequestParam Integer pageSize) {
        if (session.getCusSession() == null) {
            return null;
        }
        return selfService.getCusDynamic(cusId, page, pageSize);
    }

    /**
     * 检查用户之间是否存在关注关系
     * 20-04-26 创建方法
     * @param cusId
     * @return
     */
    @RequestMapping("/chefollow")
    public Boolean checkCusFollow(@RequestParam Integer cusId) {
        Customer cusFrom = session.getCusSession();
        if (cusFrom == null) {
            return false;
        }
        return selfService.checkCusFollow(cusFrom.getCusId(), cusId);
    }

}


================================================
FILE: back/src/main/java/com/smacul/demo/dao/ArtDao.java
================================================
package com.smacul.demo.dao;

import com.smacul.demo.bean.Article;
import com.smacul.demo.model.ArtFullMod;
import org.springframework.stereotype.Repository;

import java.util.Collection;
import java.util.List;

@Repository
public interface ArtDao {

    /**
     * 获取文章类别列表并按照数量排序
     * 20-04-18 创建方法
     * @return
     */
    List<String> getArtTypesOrderByTypeNum();

    /**
     * 全局获取一页文章缩略内容, 包括文章基本信息, 文章作者基本信息, 文章的特征统计信息
     * 20-04-19 创建方法
     * 20-04-23 BUG 修改, SQL 多了一个逗号
     * 20-04-24 方法修改, 替换了排序方式
     * 20-04-28 方法修改, 添加了用户浏览内容去重
     * 20-05-02 修改方法名称, 添加了 New 的后缀
     * @param start
     * @param pageSize
     * @return
     */
    @Deprecated
    List<ArtFullMod> getTinyArtOnePageFromGlobalNew(Integer cusId, Integer start, Integer pageSize);

    /**
     * 按照类别获取一页文章缩略内容, 包括文章基本信息, 文章作者基本信息, 文章的特征统计信息
     * 20-04-19 创建方法
     * 20-04-23 BUG 修改, SQL 多了一个逗号; 参数 type 修改为 artType
     * 20-04-24 方法修改, 替换了排序方式
     * 20-04-28 方法修改, 添加了用户浏览内容去重
     * 20-05-02 修改方法名称, 添加了 New 的后缀
     * @param artType
     * @param start
     * @param pageSize
     * @return
     */
    List<ArtFullMod> getTinyArtOnePageByTypeNew(String artType, Integer cusId, Integer start, Integer pageSize);

    /**
     * 获取一页热点新闻的文章缩略信息, 包括文章基本信息, 文章作者基本信息, 文章的特征统计信息
     * 20-04-19 创建方法
     * 20-04-23 BUG 修改, SQL 多了一个逗号
     * 20-04-24 方法修改, 替换了排序方式
     * @param start
     * @param pageSize
     * @return
     */
    List<ArtFullMod> getHotArtOnePage(Integer start, Integer pageSize);

    /**
     * 获取一篇文章的信息, 包括文章基本信息(包含 content), 文章作者基本信息, 文章的特征统计信息
     * 20-04-19 创建方法
     * @param artId
     * @return
     */
    ArtFullMod getArtFull(Integer artId);

    /**
     * 通过文章 ID 获取文章作者的 ID
     * 20-04-19 创建方法
     * @param artId
     * @return
     */
    Integer getArtCusIdByArtId(Integer artId);

    /**
     * 通过文章 ID 获取文章类别
     * 20-04-19 创建方法
     * @param artId
     * @return
     */
    String getArtTypeByArtId(Integer artId);

    /**
     * 简单的搜索功能
     * 20-04-20 创建方法
     * 20-04-23 BUG 修改, SQL 多了一个逗号; 删除了 SQL 中不必要的字段.
     * 20-04-24 方法修改, 替换了排序方式
     * @param key
     * @param start
     * @param pageSize
     * @return
     */
    List<ArtFullMod> searchContentSimple(String key, Integer start, Integer pageSize);

    /**
     * 返回一篇文章的基本信息
     * 20-04-24 创建方法
     * @param flag      用来判断此查询是否要生效, 生效值 非 11.
     * @param artId
     * @return
     */
    ArtFullMod getSingleArt(Integer flag, Integer artId);

    /**
     * 通过相似用户获取推荐内容
     * 20-05-02 创建方法
     * @param cusId
     * @param cusIdListStr
     * @param start
     * @param pageSize
     * @return
     */
    List<ArtFullMod> getTinyArtOnePageFromGlobalOld
            (Integer cusId, String cusIdListStr, Integer start, Integer pageSize);

    /**
     * 通过相似用户获取推荐内容, 按照类别
     * 20-05-02 创建方法
     * @param artType
     * @param cusId
     * @param cusIdListStr
     * @param start
     * @param pageSize
     * @return
     */
    List<ArtFullMod> getTinyArtOnePageByTypeOld
            (String artType, Integer cusId, String cusIdListStr, Integer start, Integer pageSize);

    /**
     * 添加新闻
     * 20-05-04 创建方法
     * 20-05-11 Bug 修改, 添加插入 artLegal
     * @param article
     * @return
     */
    Integer addArt(Article article);

    /**
     * 全局获取一页新(new)文章缩略内容, 包括文章基本信息, 文章作者基本信息, 文章的特征统计信息
     * 直接依据新闻的发布时间排序推荐.
     * 20-05-13 创建方法
     * @param cusId
     * @param start
     * @param pageSize
     * @return
     */
    List<ArtFullMod> getTinyNewArtFromGlobalForNew(Integer cusId, Integer start, Integer pageSize);

    /**
     * 全局获取一页核心(hot)文章缩略内容, 包括文章基本信息, 文章作者基本信息, 文章的特征统计信息
     * 通过文章类别来判断是否属于核心文章
     * 20-05-13 创建方法
     * @param cusId
     * @param start
     * @param pageSize
     * @return
     */
    List<ArtFullMod> getTinyHotArtFromGlobalForNew(Integer cusId, Integer start, Integer pageSize);

    /**
     * 全局获取一页咨询类(info)文章缩略内容, 包括文章基本信息, 文章作者基本信息, 文章的特征统计信息
     * 通过文章类别来判断是否属于核心文章
     * 20-05-13 创建方法
     * @param cusId
     * @param start
     * @param pageSize
     * @return
     */
    List<ArtFullMod> getTinyInfoArtFromGlobalForNew(Integer cusId, Integer start, Integer pageSize);

    /**
     * 按照类别获取一页新(new)文章缩略内容, 包括文章基本信息, 文章作者基本信息, 文章的特征统计信息
     * 直接按照新闻发布的时间排序, 推荐最新的文章
     * 20-05-13 创建方法
     * @param artType
     * @param cusId
     * @param start
     * @param pageSize
     * @return
     */
    List<ArtFullMod> getTinyNewArtByTypeForNew(String artType, Integer cusId, Integer start, Integer pageSize);

    /**
     * 此方法功能和 getTinyNewArtFromGlobalForNew 一致, 只是名字不同
     * 20-05-13 创建方法
     * @param cusId
     * @param start
     * @param pageSize
     * @return
     */
    List<ArtFullMod> getTinyNewArtFromGlobalForOld(Integer cusId, Integer start, Integer pageSize);

    /**
     * 此方法功能和 getTinyNewArtByTypeForNew 一致, 只是名字不同
     * 20-05-13 创建方法
     * @param artType
     * @param cusId
     * @param start
     * @param pageSize
     * @return
     */
    List<ArtFullMod> getTinyNewArtByTypeForOld(String artType, Integer cusId, Integer start, Integer pageSize);
}


================================================
FILE: back/src/main/java/com/smacul/demo/dao/ArtFeatureCountDao.java
================================================
package com.smacul.demo.dao;

import com.smacul.demo.bean.ArtFeatureCount;
import org.springframework.stereotype.Repository;

@Repository
public interface ArtFeatureCountDao {

    /**
     * 获取文章的特征统计数据
     * 20-04-18 创建方法
     * @param artId
     * @return
     */
    ArtFeatureCount getArtFeatureCountByArtId(Integer artId);

    /**
     * 更新文章指定字段的特征数据
     * 20-04-19 创建方法
     * 20-05-28 补丁, 数据库表缺陷
     * @param artId
     * @param column    特征字段, 保证 afc 前缀, 下划线
     * @param num
     * @return
     */
    Integer updateArtFeature(Integer artId, String column, Integer num);

}


================================================
FILE: back/src/main/java/com/smacul/demo/dao/ArtScoreListDao.java
================================================
package com.smacul.demo.dao;

import org.springframework.stereotype.Repository;

@Repository
public interface ArtScoreListDao {
}


================================================
FILE: back/src/main/java/com/smacul/demo/dao/ArtTimeList.java
================================================
package com.smacul.demo.dao;

import org.springframework.stereotype.Repository;

@Repository
public interface ArtTimeList {
}


================================================
FILE: back/src/main/java/com/smacul/demo/dao/ComDao.java
================================================
package com.smacul.demo.dao;

import com.smacul.demo.bean.Comment;
import com.smacul.demo.model.ComFullMod;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface ComDao {

    /**
     * 获取评论列表
     * 20-04-20 创建方法
     * @param artId
     * @return
     */
    List<ComFullMod> getComFullList(Integer artId);

    /**
     * 添加评论
     * 20-04-10 创建方法
     * 20-04-24 允许评论后返回自增主键
     * @param comment
     * @return
     */
    Integer addCom(Comment comment);

    /**
     * 获取单一一条评论, 不包括其回复
     * 20-04-24 创建方法
     * @param flag      用来判断是否需要查询, 生效值为 2
     * @param comId
     * @return
     */
    ComFullMod getSingleCom(Integer flag, Integer comId);

}


================================================
FILE: back/src/main/java/com/smacul/demo/dao/CusBehaviorRecordDao.java
================================================
package com.smacul.demo.dao;

import com.smacul.demo.bean.CusBehaviorRecord;
import com.smacul.demo.model.CusDynamicMod;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface CusBehaviorRecordDao {

    /**
     * 统计指定两个用户之间关注行为记录的数量
     * 20-04-18 添加方法
     * @param cusIdFrom
     * @param cusIdTo
     * @return
     */
    Integer countTargetCusFollowBehavior(Integer cusIdFrom, Integer cusIdTo);

    /**
     * 删除指定两个用户之间的关注行为记录
     * 20-04-18 添加方法
     * @param cusIdFrom
     * @param cusIdTo
     * @return
     */
    Integer deleteTargetCusFollowBehavior(Integer cusIdFrom, Integer cusIdTo);

    /**
     * 添加指定两个用户之间的关注行为记录
     * 20-04-18 添加方法
     * @param cusIdFrom
     * @param cusIdTo
     * @return
     */
    Integer addTargetCusFollowBehavior(Integer cusIdFrom, Integer cusIdTo);

    /**
     * 统计指定 from 用户指定行为的记录数量
     * 20-04-18 添加方法
     * @param cusIdFrom
     * @param behavior
     * @return
     */
    Integer countCusBehaviorFrom(Integer cusIdFrom, Integer behavior);

    /**
     * 统计指定 to 用户指定行为的记录数量
     * 20-04-18 添加方法
     * @param cusIdTo
     * @param behavior
     * @return
     */
    Integer countCusBehaviorTo(Integer cusIdTo, Integer behavior);

    /**
     * 统计指定 from 用户与指定文章之间指定行为的记录数量
     * 20-04-19 创建方法
     * 20-04-23 BUG 修复 SQL 参数错误
     * @param cusIdFrom
     * @param artId
     * @param behavior
     * @return
     */
    Integer countTargetCusArtBehaviorFrom(Integer cusIdFrom, Integer artId, Integer behavior);

    /**
     * 统计指定 to 用户与指定文章之间指定行为的记录数量
     * 20-04-19 成绩方法
     * 20-04-23 BUG 修复 SQL 参数错误
     * @param cusIdTo
     * @param artId
     * @param behavior
     * @return
     */
    Integer countTargetCusArtBehaviorTo(Integer cusIdTo, Integer artId, Integer behavior);

    /**
     * 插入用户行为记录
     * 本质上, 这个方法可以取代 addTargetCusFollowBehavior
     * 20-04-19 创建方法
     * @param cusIdFrom
     * @param cusIdTo
     * @param behavior
     * @param artId
     * @param type
     * @param targetId
     * @return
     */
    Integer addCusBehavior(
            Integer cusIdFrom, Integer cusIdTo, Integer behavior, Integer artId, Integer type, Integer targetId);

    /**
     * 删除用户行为记录
     * 本质上, 这个方法可以取代 deleteTargetCusFollowBehavior
     * 20-04-19 创建方法
     * @param cusIdFrom
     * @param cusIdTo
     * @param behavior
     * @param artId
     * @param type
     * @param targetId
     * @return
     */
    Integer deleteCusBehavior(
            Integer cusIdFrom, Integer cusIdTo, Integer behavior, Integer artId, Integer type, Integer targetId);

    /**
     * 分页获取指定用户动态
     * 20-04-24 创建方法
     * 20-05-06 修改排序时间
     * @param cusId
     * @param start
     * @param pageSize
     * @return
     */
    List<CusDynamicMod> getCusDynamicByCusId(Integer cusId, Integer start, Integer pageSize);


    /**
     * 获取指定用户所有的关注用户的列表
     * 20-05-02 创建方法
     * @param cusId
     * @return
     */
    List<Integer> getFollowCus(Integer cusId);
}


================================================
FILE: back/src/main/java/com/smacul/demo/dao/CusDao.java
================================================
package com.smacul.demo.dao;

import com.smacul.demo.bean.Customer;
import org.springframework.stereotype.Repository;

@Repository
public interface CusDao {

    /**
     * 通过用户名获取用户基本信息
     * 20-04-18 创建方法
     * 20-04-21 获取内容中添加密码
     * @param cusName
     * @return
     */
    Customer getCusByName(String cusName);

    /**
     * 通过统计用户数判断用户是否存在
     * 20-04-18 创建方法
     * @param cusName
     * @return
     */
    Integer countCusByName(String cusName);

    /**
     * 在用户注册时插入用户
     * 20-04-18 创建方法
     * 20-04-21 参数名修改
     * @param cusName
     * @param cusPass   MD5 加密后的密码
     * @return
     */
    Integer insertCusForRegister(String cusName, String cusPass);

    /**
     * 通过 ID 获取用户基本信息
     * 20-04-18 创建方法
     * @param cusId
     * @return
     */
    Customer getCusById(Integer cusId);

    /**
     * 更新用户基本信息, 不包括密码.
     * 20-04-18 创建方法
     * @param customer
     * @return
     */
    Integer updateCusBasicInfo(Customer customer);

    /**
     * 更新用户基本信息, 包括密码
     * 20-04-18 创建方法
     * @param customer
     * @return
     */
    Integer updateCusBasicInfoWithPass(Customer customer);
}


================================================
FILE: back/src/main/java/com/smacul/demo/dao/CusFeatureCountDao.java
================================================
package com.smacul.demo.dao;

import com.smacul.demo.bean.CusFeatureCount;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface CusFeatureCountDao {

    /**
     * 获取指定 ID 用户在所有类别下的操作次数总和
     * 20-04-18 创建方法
     * @param cusId
     * @return
     */
    Integer countBehaviorNum(Integer cusId);

    /**
     * 获取指定 ID 用户的类别统计数据.
     * 20-04-18 创建方法
     * @param cusId
     * @return
     */
    CusFeatureCount getCusFeatureCountByCusId(Integer cusId);

    /**
     * 获取指定 ID 用户的类别统计数据(仅 18 个类别的数据)以及所有类别数据总和
     * 20-04-18 创建方法
     * @param cusId
     * @return
     */
    List<Integer> getCusArtTypesBehaviorNums(Integer cusId);

    /**
     * 更新用户特征
     * 20-04-19 创建方法
     * @param cusId
     * @param column    字段名, 先保证 cfc 前缀, 下划线
     * @param num
     * @return
     */
    Integer updateCusFeature(Integer cusId, String column, Integer num);

    /**
     * 初始化指定用户的特征数据记录, 即所有种类统计归 0
     * 20-04-23 创建方法
     * @param cusId
     * @return
     */
    Integer initialCusFeature(Integer cusId);

    /**
     * 获取用户的相似用户
     * 20-05-02 创建方法
     * @param cusId
     * @param num
     * @return
     */
    List<Integer> getRelativeCusList(Integer cusId, Integer num);
}


================================================
FILE: back/src/main/java/com/smacul/demo/dao/CusRecommendRecordDao.java
================================================
package com.smacul.demo.dao;

import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface CusRecommendRecordDao {

    /**
     * 记录系统为用户推荐的内容
     * 20-06-03 创建方法
     * @param cusId
     * @param list
     * @return
     */
    Integer addRecommendList(Integer cusId, List<Integer> list);

    /**
     * 删除历史推荐记录
     * 20-06-03 创建方法
     * @param cusId
     */
    void deleteOldCommentList(Integer cusId);
}


================================================
FILE: back/src/main/java/com/smacul/demo/dao/RepDao.java
================================================
package com.smacul.demo.dao;

import com.smacul.demo.bean.Reply;
import com.smacul.demo.model.RepFullMod;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface RepDao {

    /**
     * 通过评论 ID 来获取此评论下所有的回复
     * 20-04-19 创建方法
     * 20-04-23 BUG 修复, SQL 逗号问题
     * @param comId
     * @return
     */
    List<RepFullMod> getRepFullList(Integer comId);

    /**
     * 添加回复
     * 20-04-19 创建方法
     * 20-04-24 允许插入后返回自增主键
     * @param reply
     * @return
     */
    Integer addRep(Reply reply);

    /**
     * 获取单一一条回复
     * 20-04-24 创建方法
     * @param flag      用于判断查询是否生效, 生效值位 3
     * @param repId
     * @return
     */
    RepFullMod getSingleRep(Integer flag, Integer repId);

}


================================================
FILE: back/src/main/java/com/smacul/demo/model/ArtFullMod.java
================================================
package com.smacul.demo.model;

import com.smacul.demo.bean.ArtFeatureCount;
import com.smacul.demo.bean.Customer;

import java.sql.Timestamp;

public class ArtFullMod {
    private Integer artId;
    private String artTitle;
    private String artContent;
    private String artSpider;

    private String artType;
    private String artTags;
    private String artImageUrl;
    private Timestamp artTime;

    private Integer artLegal;
    private Integer artCusId;

    // 文章作者
    private Customer customer;
    private ArtFeatureCount artFeature;
    // 浏览者-文章的行为
    private CusArtBehaviorMod cusArtBehavior;

    public Integer getArtId() {
        return artId;
    }

    public void setArtId(Integer artId) {
        this.artId = artId;
    }

    public String getArtTitle() {
        return artTitle;
    }

    public void setArtTitle(String artTitle) {
        this.artTitle = artTitle;
    }

    public String getArtContent() {
        return artContent;
    }

    public void setArtContent(String artContent) {
        this.artContent = artContent;
    }

    public String getArtSpider() {
        return artSpider;
    }

    public void setArtSpider(String artSpider) {
        this.artSpider = artSpider;
    }

    public String getArtType() {
        return artType;
    }

    public void setArtType(String artType) {
        this.artType = artType;
    }

    public String getArtTags() {
        return artTags;
    }

    public void setArtTags(String artTags) {
        this.artTags = artTags;
    }

    public String getArtImageUrl() {
        return artImageUrl;
    }

    public void setArtImageUrl(String artImageUrl) {
        this.artImageUrl = artImageUrl;
    }

    public Timestamp getArtTime() {
        return artTime;
    }

    public void setArtTime(Timestamp artTime) {
        this.artTime = artTime;
    }

    public Integer getArtLegal() {
        return artLegal;
    }

    public void setArtLegal(Integer artLegal) {
        this.artLegal = artLegal;
    }

    public Integer getArtCusId() {
        return artCusId;
    }

    public void setArtCusId(Integer artCusId) {
        this.artCusId = artCusId;
    }

    public Customer getCustomer() {
        return customer;
    }

    public void setCustomer(Customer customer) {
        this.customer = customer;
    }

    public ArtFeatureCount getArtFeature() {
        return artFeature;
    }

    public void setArtFeature(ArtFeatureCount artFeature) {
        this.artFeature = artFeature;
    }

    public CusArtBehaviorMod getCusArtBehavior() {
        return cusArtBehavior;
    }

    public void setCusArtBehavior(CusArtBehaviorMod cusArtBehavior) {
        this.cusArtBehavior = cusArtBehavior;
    }
}


================================================
FILE: back/src/main/java/com/smacul/demo/model/ComFullMod.java
================================================
package com.smacul.demo.model;

import com.smacul.demo.bean.Customer;
//import com.smacul.demo.bean.Reply;

import java.sql.Timestamp;
import java.util.List;

public class ComFullMod {
    private Integer comId;
    private String comContent;
    private Timestamp comTime;
    private Integer comLegal;
    private String comSpider;

    private Integer comCusId;
    private Integer comArtId;

    private Customer customer;
    private List<RepFullMod> replys;

    public Integer getComId() {
        return comId;
    }

    public void setComId(Integer comId) {
        this.comId = comId;
    }

    public String getComContent() {
        return comContent;
    }

    public void setComContent(String comContent) {
        this.comContent = comContent;
    }

    public Timestamp getComTime() {
        return comTime;
    }

    public void setComTime(Timestamp comTime) {
        this.comTime = comTime;
    }

    public Integer getComLegal() {
        return comLegal;
    }

    public void setComLegal(Integer comLegal) {
        this.comLegal = comLegal;
    }

    public String getComSpider() {
        return comSpider;
    }

    public void setComSpider(String comSpider) {
        this.comSpider = comSpider;
    }

    public Integer getComCusId() {
        return comCusId;
    }

    public void setComCusId(Integer comCusId) {
        this.comCusId = comCusId;
    }

    public Integer getComArtId() {
        return comArtId;
    }

    public void setComArtId(Integer comArtId) {
        this.comArtId = comArtId;
    }

    public Customer getCustomer() {
        return customer;
    }

    public void setCustomer(Customer customer) {
        this.customer = customer;
    }

    public List<RepFullMod> getReplys() {
        return replys;
    }

    public void setReplys(List<RepFullMod> replys) {
        this.replys = replys;
    }
}


================================================
FILE: back/src/main/java/com/smacul/demo/model/CusArtBehaviorMod.java
================================================
package com.smacul.demo.model;

public class CusArtBehaviorMod {
    private Integer cusId;
    private Integer artId;
    private Integer preference;
    private Boolean isFollow;
    private Boolean isRead;
    private Boolean isArtAuthor;

    public Integer getCusId() {
        return cusId;
    }

    public void setCusId(Integer cusId) {
        this.cusId = cusId;
    }

    public Integer getArtId() {
        return artId;
    }

    public void setArtId(Integer artId) {
        this.artId = artId;
    }

    public Integer getPreference() {
        return preference;
    }

    public void setPreference(Integer preference) {
        this.preference = preference;
    }

    public Boolean getFollow() {
        return isFollow;
    }

    public void setFollow(Boolean follow) {
        isFollow = follow;
    }

    public Boolean getRead() {
        return isRead;
    }

    public void setRead(Boolean read) {
        isRead = read;
    }

    public Boolean getArtAuthor() {
        return isArtAuthor;
    }

    public void setArtAuthor(Boolean artAuthor) {
        isArtAuthor = artAuthor;
    }
}


================================================
FILE: back/src/main/java/com/smacul/demo/model/CusDynamicMod.java
================================================
package com.smacul.demo.model;

import com.smacul.demo.bean.Customer;

import java.sql.Timestamp;

public class CusDynamicMod {

    private Integer cbrId;
    private Integer cbrCusIdFrom;
    private Integer cbrCusIdTo;
    private Integer cbrBehavior;
    private Timestamp cbrTime;
    // 行为发生的位置代号, 0: 默认, 1: 文章, 2: 评论, 3:回复
    private Integer cbrType;
    private Integer cbrArtId;

    private Customer cusFrom;
    private Customer cusTo;
    private ArtFullMod article;
    private ComFullMod comment;
    private RepFullMod reply;

    public Integer getCbrId() {
        return cbrId;
    }

    public void setCbrId(Integer cbrId) {
        this.cbrId = cbrId;
    }

    public Integer getCbrCusIdFrom() {
        return cbrCusIdFrom;
    }

    public void setCbrCusIdFrom(Integer cbrCusIdFrom) {
        this.cbrCusIdFrom = cbrCusIdFrom;
    }

    public Integer getCbrCusIdTo() {
        return cbrCusIdTo;
    }

    public void setCbrCusIdTo(Integer cbrCusIdTo) {
        this.cbrCusIdTo = cbrCusIdTo;
    }

    public Integer getCbrBehavior() {
        return cbrBehavior;
    }

    public void setCbrBehavior(Integer cbrBehavior) {
        this.cbrBehavior = cbrBehavior;
    }

    public Timestamp getCbrTime() {
        return cbrTime;
    }

    public void setCbrTime(Timestamp cbrTime) {
        this.cbrTime = cbrTime;
    }

    public Integer getCbrType() {
        return cbrType;
    }

    public void setCbrType(Integer cbrType) {
        this.cbrType = cbrType;
    }

    public Customer getCusFrom() {
        return cusFrom;
    }

    public void setCusFrom(Customer cusFrom) {
        this.cusFrom = cusFrom;
    }

    public Customer getCusTo() {
        return cusTo;
    }

    public void setCusTo(Customer cusTo) {
        this.cusTo = cusTo;
    }

    public ArtFullMod getArticle() {
        return article;
    }

    public void setArticle(ArtFullMod article) {
        this.article = article;
    }

    public ComFullMod getComment() {
        return comment;
    }

    public void setComment(ComFullMod comment) {
        this.comment = comment;
    }

    public RepFullMod getReply() {
        return reply;
    }

    public void setReply(RepFullMod reply) {
        this.reply = reply;
    }

    public Integer getCbrArtId() {
        return cbrArtId;
    }

    public void setCbrArtId(Integer cbrArtId) {
        this.cbrArtId = cbrArtId;
    }
}


================================================
FILE: back/src/main/java/com/smacul/demo/model/CusFeatureFullMod.java
================================================
package com.smacul.demo.model;

import com.smacul.demo.bean.CusFeatureCount;

public class CusFeatureFullMod {
    private Integer cusId;
    private Integer readNum;
    private Integer fanNum;
    private Integer followNum;

    private Integer artEditNum;
    private Integer comEditNum;
    private Integer repEditNum;

    private CusFeatureCount featureCount;

    public Integer getCusId() {
        return cusId;
    }

    public void setCusId(Integer cusId) {
        this.cusId = cusId;
    }

    public Integer getReadNum() {
        return readNum;
    }

    public void setReadNum(Integer readNum) {
        this.readNum = readNum;
    }

    public Integer getFanNum() {
        return fanNum;
    }

    public void setFanNum(Integer fanNum) {
        this.fanNum = fanNum;
    }

    public Integer getFollowNum() {
        return followNum;
    }

    public void setFollowNum(Integer followNum) {
        this.followNum = followNum;
    }

    public Integer getArtEditNum() {
        return artEditNum;
    }

    public void setArtEditNum(Integer artEditNum) {
        this.artEditNum = artEditNum;
    }

    public Integer getComEditNum() {
        return comEditNum;
    }

    public void setComEditNum(Integer comEditNum) {
        this.comEditNum = comEditNum;
    }

    public Integer getRepEditNum() {
        return repEditNum;
    }

    public void setRepEditNum(Integer repEditNum) {
        this.repEditNum = repEditNum;
    }

    public CusFeatureCount getFeatureCount() {
        return featureCount;
    }

    public void setFeatureCount(CusFeatureCount featureCount) {
        this.featureCount = featureCount;
    }
}


================================================
FILE: back/src/main/java/com/smacul/demo/model/RepFullMod.java
================================================
package com.smacul.demo.model;

import com.smacul.demo.bean.Customer;

import java.sql.Timestamp;

public class RepFullMod {

    private Integer repId;
    private String repContent;

    private Integer repType;
    private Timestamp repTime;
    private Integer repLegal;
    private String repSpider;

    private Integer repCusId;
    private Integer repArtId;
    private Integer repComId;
    private Integer repRepId;

    private Customer customer;

    public Integer getRepId() {
        return repId;
    }

    public void setRepId(Integer repId) {
        this.repId = repId;
    }

    public String getRepContent() {
        return repContent;
    }

    public void setRepContent(String repContent) {
        this.repContent = repContent;
    }

    public Integer getRepType() {
        return repType;
    }

    public void setRepType(Integer repType) {
        this.repType = repType;
    }

    public Timestamp getRepTime() {
        return repTime;
    }

    public void setRepTime(Timestamp repTime) {
        this.repTime = repTime;
    }

    public Integer getRepLegal() {
        return repLegal;
    }

    public void setRepLegal(Integer repLegal) {
        this.repLegal = repLegal;
    }

    public String getRepSpider() {
        return repSpider;
    }

    public void setRepSpider(String repSpider) {
        this.repSpider = repSpider;
    }

    public Integer getRepCusId() {
        return repCusId;
    }

    public void setRepCusId(Integer repCusId) {
        this.repCusId = repCusId;
    }

    public Integer getRepArtId() {
        return repArtId;
    }

    public void setRepArtId(Integer repArtId) {
        this.repArtId = repArtId;
    }

    public Integer getRepComId() {
        return repComId;
    }

    public void setRepComId(Integer repComId) {
        this.repComId = repComId;
    }

    public Integer getRepRepId() {
        return repRepId;
    }

    public void setRepRepId(Integer repRepId) {
        this.repRepId = repRepId;
    }

    public Customer getCustomer() {
        return customer;
    }

    public void setCustomer(Customer customer) {
        this.customer = customer;
    }
}


================================================
FILE: back/src/main/java/com/smacul/demo/service/DiscussService.java
================================================
package com.smacul.demo.service;

import com.smacul.demo.bean.Comment;
import com.smacul.demo.bean.Reply;
import com.smacul.demo.model.ComFullMod;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.List;

public interface DiscussService {

    /**
     * 获取完整的评论列表
     * 20-04-20 创建方法
     * @param artId
     * @return
     */
    List<ComFullMod> getComList(Integer artId);

    /**
     * 添加评论
     * 20-04-20 创建方法
     * @param comment
     * @return
     */
    String addNewCom(Comment comment);

    /**
     * 添加回复, 包括回复的回复
     * 20-04-20 创建方法
     * @param reply
     * @return
     */
    String addNewRep(Reply reply);

}


================================================
FILE: back/src/main/java/com/smacul/demo/service/EditService.java
================================================
package com.smacul.demo.service;

import com.smacul.demo.bean.Article;

public interface EditService {

    /**
     * 用户添加新文章
     * 20-05-04 创建方法
     * 20-05-11 方法修改, 添加 artLegal
     * @param article
     * @return
     */
    String addNewArt(Article article);

}


================================================
FILE: back/src/main/java/com/smacul/demo/service/LoadService.java
================================================
package com.smacul.demo.service;

import com.smacul.demo.model.ArtFullMod;

import java.util.List;

public interface LoadService {

    /**
     * 为新用户提供文章类别列表
     * 20-04-18 创建方法
     * @return
     */
    List<String> getArtTypesForNew();

    /**
     * 为老用户提供文章类别列表
     * 20-04-19 创建方法, TODO 功能上和 getArtTypesForNew 没有区别, 需要跟换
     * @param cusId
     * @return
     */
    List<String> getArtTypesForOld(Integer cusId);

    /**
     * 为新用户提供一页指定类别的新闻缩率信息
     * 20-04-19 创建方法
     * 20-04-28 方法修改, 添加用户浏览内容去重
     * 20-05-06 方法修改, 返回时将文章类别从英文翻译成中文
     * 20-05-13 修改文章推荐方式, 核心文章 pageSize-3: 资讯文章 2: 新生文章 1
     * 20-05-24 方法修改, artType 接受英文
     * @param artType
     * @param page
     * @param pageSize
     * @return
     */
    List<ArtFullMod> getTinyArtOnePageByTypeForNew(Integer cusId, String artType, Integer page, Integer pageSize);

    /**
     * 为老用户提供一页指定类别的新闻缩率信息
     * 如果相似用户的内容推荐完毕, 就切换到新用户的推荐逻辑上.
     * 20-04-19 创建方法
     * 20-04-28 方法修改, 添加用户浏览内容去重
     * 20-05-02 添加对老用户的推荐
     * 20-05-06 方法修改, 返回时将文章类别从英文翻译成中文
     * 20-05-13 修改文章推荐方式, 协同推荐文章 pageSize-1: 新生文章 1
     * 20-05-19 方法修改, 当相似用户推荐低于 10 的时候, 返回长度为 0 的列表
     * 20-05-24 方法修改, artType 接受英文
     * @param artType
     * @param cusList   相似用户列表
     * @param page
     * @param pageSize
     * @return
     */
    List<ArtFullMod> getTinyArtOnePageByTypeForOld(
            Integer cusId, List<Integer> cusList, String artType, Integer page, Integer pageSize);

    /**
     * 提供一页的热点新闻的缩略信息
     * 20-04-19 创建方法
     * @param page
     * @param pageSize
     * @return
     */
    List<ArtFullMod> getHotArtOnePage(Integer page, Integer pageSize);

    /**
     * 获取一篇文章的完整信息, 包括文章, 文章作者, 文章特征统计数据, 当前用户与文章的关系
     * 20-04-19 创建方法
     * 20-05-06 修改方法, 获取文章时返回文章的中文类别
     * @param cusId
     * @param artId
     * @return
     */
    ArtFullMod getFullArt(Integer cusId, Integer artId);

}


================================================
FILE: back/src/main/java/com/smacul/demo/service/SearchService.java
================================================
package com.smacul.demo.service;

import com.smacul.demo.model.ArtFullMod;

import java.util.List;

public interface SearchService {

    /**
     * 简单的搜索 % %
     * 20-04-20 创建方法
     * 20-05-06
     * @param key
     * @param page
     * @param pageSize
     * @return
     */
    List<ArtFullMod> searchContentSimple(String key, Integer page, Integer pageSize);

}


================================================
FILE: back/src/main/java/com/smacul/demo/service/SelfService.java
================================================
package com.smacul.demo.service;

import com.smacul.demo.bean.Customer;
import com.smacul.demo.model.CusDynamicMod;
import com.smacul.demo.model.CusFeatureFullMod;

import java.security.NoSuchAlgorithmException;
import java.util.List;

public interface SelfService {

    /**
     * 检查用户是否为新用户.
     * 20-04-18 创建方法
     * @param cusId
     * @return
     */
    Boolean checkIsNewUser(Integer cusId);

    /**
     * 在用户登录时检查用户是否存在, 如果存在, 返回用户基本信息, 否则返回空.
     * 20-04-28 创建方法
     * @param cusName
     * @param cusPass
     * @return
     * @throws NoSuchAlgorithmException
     */
    Customer checkCusForLogin(String cusName, String cusPass) throws NoSuchAlgorithmException;

    /**
     * 在用户注册时插入用户.
     * 20-04-18 创建方法
     * 20-04-23 方法逻辑修改, 在添加用户时, 添加用户的特征统计数据记录.
     * @param cusName
     * @param cusPass
     * @return
     * @throws NoSuchAlgorithmException
     */
    String setNewCus(String cusName, String cusPass) throws NoSuchAlgorithmException;

    /**
     * 获取用户基本数据, 不包括密码
     * 20-04-18 创建方法
     * @param cusId
     * @return
     */
    Customer getCusBasicInfo(Integer cusId);

    /**
     * 设置用户基本数据, 可包括密码
     * 20-04-18 创建方法
     * @param customer
     * @return
     * @throws NoSuchAlgorithmException
     */
    Boolean setCusBasicInfo(Customer customer) throws NoSuchAlgorithmException;

    /**
     * 处理用户关注, 行为代码: 11
     * 20-04-18 创建方法
     * 20-04-26 修改方法, 只有当用户关注关系创建时, 才返回 true.
     * @param cusIdFrom
     * @param cusIdTo
     * @return
     */
    Boolean setCusFollow(Integer cusIdFrom, Integer cusIdTo);

    /**
     * 获取用户完整的特征数据
     * 20-04-18 创建方法
     * @param cusId
     * @return
     */
    CusFeatureFullMod getCusFeatureInfo(Integer cusId);

    /**
     * 分页获取指定用户的动态
     * 20-04-24 创建方法
     * 20-05-06 修改方法, 用户动态如果有文章, 则将文章的类别由英文改为中文
     * @param cusId
     * @param page
     * @param pageSize
     * @return
     */
    List<CusDynamicMod> getCusDynamic(Integer cusId, Integer page, Integer pageSize);

    /**
     * 检查用户之间是否存在关注关系
     * 20-04-26 创建方法
     * @param cusIdFrom
     * @param cusIdTo
     * @return
     */
    Boolean checkCusFollow(Integer cusIdFrom, Integer cusIdTo);

    /**
     * 获取指定用户的相似用户
     * 如果用户是新用户则不计算相似用户, 直接返回空的 ArrayList;
     * 如果用户是老用户, 优先考虑他关注的用户, 再计算相似用户.
     * 返回 10 个吧先
     * 20-05-02 创建方法
     * 20-05-19 删除关注用户的添加逻辑
     * @param cusId
     * @param num
     * @return
     */
    List<Integer> getRelativeCusList(Integer cusId, Integer num);
}


================================================
FILE: back/src/main/java/com/smacul/demo/service/SessionService.java
================================================
package com.smacul.demo.service;

import com.smacul.demo.bean.Customer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpSession;
import java.util.List;

public interface SessionService {

    void setCusSession(Customer cus);

    void setRelSession(List<Integer> rel);

    Customer getCusSession();

    List<Integer> getRelSession();

    Integer getPagThenAddOne(String category);

    Integer getSetPagAfterCusChange(String category);

    void initPagSession();

}


================================================
FILE: back/src/main/java/com/smacul/demo/service/ShapeService.java
================================================
package com.smacul.demo.service;

import com.smacul.demo.model.ArtFullMod;
import com.sun.org.apache.xpath.internal.operations.Bool;

import java.util.List;

public interface ShapeService {

    /**
     * 文章编辑 1
     * cbrCusIdFrom | cbrCusIdTo | cbrBehavior |   cbrTime   | cbrArtId | cbrType | cbrTargetId
     *    cusId     |    cusId   |       1     |   artTime   |   artId  |    1    |     artId
     * 20-04-19 创建方法
     * @param cusId
     * @param artId
     * @return
     */
    Boolean setCusBehaviorArtEdit(Integer cusId, Integer artId);

    /**
     * 文章阅读 2
     * cbrCusIdFrom | cbrCusIdTo | cbrBehavior |   cbrTime   | cbrArtId | cbrType | cbrTargetId
     *    cusId     |  artCusId  |       2     |   readTime  |   artId  |    1    |     artId
     * 20-04-19 创建方法
     * 20-04-28 修改方法, 防止同一个用户重复阅读
     * @param cusId
     * @param artId
     * @return
     */
    Boolean setCusBehaviorArtRead(Integer cusId, Integer artId);

    /**
     * 文章点赞 3
     * cbrCusIdFrom | cbrCusIdTo | cbrBehavior |   cbrTime   | cbrArtId | cbrType | cbrTargetId
     *    cusId     |  artCusId  |       3     |   likeTime  |   artId  |    1    |     artId
     * 20-04-19 创建方法
     * @param cusId
     * @param artId
     * @param type  true: 点上, false: 取消
     * @return
     */
    Boolean setCusBehaviorArtLike(Integer cusId, Integer artId, Boolean type);

    /**
     * 文章点踩 4
     * cbrCusIdFrom | cbrCusIdTo | cbrBehavior |   cbrTime   | cbrArtId | cbrType | cbrTargetId
     *    cusId     |  artCusId  |       4     | dislikeTime |   artId  |    1    |     artId
     * 20-04-19 创建方法
     * @param cusId
     * @param artId
     * @param type  true: 点上, false: 取消
     * @return
     */
    Boolean setCusBehaviorArtDislike(Integer cusId, Integer artId, Boolean type);

    /**
     * 评论编辑 5
     * cbrCusIdFrom | cbrCusIdTo | cbrBehavior |   cbrTime   | cbrArtId | cbrType | cbrTargetId
     *    cusId     | artCusId   |       5     |   comTime   |   artId  |    2    |     comId
     * @param cusId
     * @param artId
     * @param comId
     * @return
     */
    Boolean setCusBehaviorComEdit(Integer cusId, Integer artId, Integer comId);

    /**
     * 评论点赞 6
     * @param cusId
     * @param comCusId
     * @param artId
     * @param comId
     * @return
     */
    Boolean setCusBehaviorComLike(Integer cusId, Integer comCusId, Integer artId, Integer comId);

    /**
     * 评论点踩 7
     * @param cusId
     * @param comCusId
     * @param artId
     * @param comId
     * @return
     */
    Boolean setCusBehaviorComDislike(Integer cusId, Integer comCusId, Integer artId, Integer comId);

    /**
     * 回复编辑(包括回复与回复的回复) 8
     * cbrCusIdFrom | cbrCusIdTo | cbrBehavior |   cbrTime   | cbrArtId | cbrType | cbrTargetId
     *    cusId     | artCusId   |       8     |   repTime   |   artId  |    3    |     repId
     * 20-04-19 创建方法
     * @param cusId
     * @param artId
     * @param repId
     * @return
     */
    Boolean setCusBehaviorRepEdit(Integer cusId, Integer artId, Integer repId);

    /**
     * 回复点赞 9
     * @param cusId
     * @param repCusId
     * @param artId
     * @param repId
     * @return
     */
    Boolean setCusBehaviorRepLike(Integer cusId, Integer repCusId, Integer artId, Integer repId);

    /**
     * 回复点踩 10
     * @param cusId
     * @param repCusId
     * @param artId
     * @param repId
     * @return
     */
    Boolean setCusBehaviorRepDislike(Integer cusId, Integer repCusId, Integer artId, Integer repId);

    /**
     * 用户 follow 11
     * cbrCusIdFrom | cbrCusIdTo | cbrBehavior |   cbrTime   | cbrArtId | cbrType | cbrTargetId
     *   cusIdFrom  |   cusIdTo  |      11     | followTime  |    null  |    0    |     null
     * 20-04-19 创建方法
     * @param cusIdFrom
     * @param cusIdTo
     * @return
     */
    Boolean setCusBehaviorCusFollow(Integer cusIdFrom, Integer cusIdTo);

    /**
     * 记录系统推荐内容, 并删除指定用户历史 72 小时的推荐内容
     * 20-06-03
     * @param list
     * @return
     */
    Boolean recordRecommendList(Integer cusId, List<ArtFullMod> list);

}


================================================
FILE: back/src/main/java/com/smacul/demo/service/impl/DiscussServiceImpl.java
================================================
package com.smacul.demo.service.impl;

import com.smacul.demo.bean.Comment;
import com.smacul.demo.bean.Reply;
import com.smacul.demo.dao.ComDao;
import com.smacul.demo.dao.RepDao;
import com.smacul.demo.model.ComFullMod;
import com.smacul.demo.service.DiscussService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class DiscussServiceImpl implements DiscussService {

    @Autowired
    ComDao comDao;
    @Autowired
    RepDao repDao;

    @Override
    public List<ComFullMod> getComList(Integer artId) {
        return comDao.getComFullList(artId);
    }

    @Override
    public String addNewCom(Comment comment) {
        if (comDao.addCom(comment) == 1) {
            return "评论成功";
        } else {
            return "评论失败";
        }
    }

    @Override
    public String addNewRep(Reply reply) {
        if (repDao.addRep(reply) == 1) {
            return "评论成功";
        } else {
            return "评论失败";
        }
    }
}


================================================
FILE: back/src/main/java/com/smacul/demo/service/impl/EditServiceImpl.java
================================================
package com.smacul.demo.service.impl;

import com.smacul.demo.bean.Article;
import com.smacul.demo.dao.ArtDao;
import com.smacul.demo.service.EditService;
import com.smacul.demo.util.TypeHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class EditServiceImpl implements EditService {

    @Autowired
    ArtDao artDao;

    @Override
    public String addNewArt(Article article) {
        String type = article.getArtType();
        article.setArtType(TypeHandler.typeTransSingleChToEn(type));
        article.setArtLegal(1);
        if (artDao.addArt(article) == 1) {
            return "文章添加成功";
        } else {
            return "文章添加失败";
        }
    }
}


================================================
FILE: back/src/main/java/com/smacul/demo/service/impl/LoadServiceImpl.java
================================================
package com.smacul.demo.service.impl;

import com.smacul.demo.dao.ArtDao;
import com.smacul.demo.dao.ArtFeatureCountDao;
import com.smacul.demo.dao.CusBehaviorRecordDao;
import com.smacul.demo.dao.CusFeatureCountDao;
import com.smacul.demo.model.ArtFullMod;
import com.smacul.demo.model.CusArtBehaviorMod;
import com.smacul.demo.service.LoadService;
import com.smacul.demo.util.PageHandler;
import com.smacul.demo.util.TypeHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.swing.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TransferQueue;

@Service
public class LoadServiceImpl implements LoadService {

    @Autowired
    ArtDao artDao;
    @Autowired
    CusFeatureCountDao cusFeatureCountDao;
    @Autowired
    ArtFeatureCountDao artFeatureCountDao;
    @Autowired
    CusBehaviorRecordDao cusBehaviorRecordDao;

    @Override
    public List<String> getArtTypesForNew() {
        List<String> result = artDao.getArtTypesOrderByTypeNum();
        return TypeHandler.typeTransAllEnToCh(result);
    }

    @Override
    public List<String> getArtTypesForOld(Integer cusId) {
        List<String> result = artDao.getArtTypesOrderByTypeNum();
        return TypeHandler.typeTransAllEnToCh(result);
    }

    @Override
    public List<ArtFullMod> getTinyArtOnePageByTypeForNew(
            Integer cusId, String artType, Integer page, Integer pageSize) {
        Integer start = PageHandler.calcuStartNO(page, pageSize);
        List<ArtFullMod> resultList = null;
        if (artType.equals("news_global")) {
            resultList = artDao.getTinyInfoArtFromGlobalForNew(cusId, start, 2);
            resultList.addAll(artDao.getTinyHotArtFromGlobalForNew(cusId, start, pageSize-1-2));
            resultList.addAll(artDao.getTinyNewArtFromGlobalForNew(cusId, start, 1));
        } else {
            resultList = artDao.getTinyNewArtByTypeForNew(artType, cusId, start, 1);
            resultList.addAll(artDao.getTinyArtOnePageByTypeNew(artType, cusId, start, pageSize-1));
        }
        for (ArtFullMod result: resultList) {
            result.setArtType(TypeHandler.typeTransSingleEnToCh(result.getArtType()));
        }
        return resultList;
    }

    @Override
    public List<ArtFullMod> getTinyArtOnePageByTypeForOld(
            Integer cusId, List<Integer> cusList, String artType, Integer page, Integer pageSize) {
        Integer start = PageHandler.calcuStartNO(page, pageSize);
        String cusIdListStr = "";
        for (int i = 0; i < cusList.size(); i++) {
            if (i != (cusList.size() - 1)) {
                cusIdListStr += cusList.get(i) + ", ";
            } else {
                cusIdListStr += cusList.get(i);
            }
        }
        List<ArtFullMod> resultList = null;
        if (artType.equals("news_global")) {
            resultList = artDao.getTinyHotArtFromGlobalForNew(cusId, start, 3);
            resultList.addAll(artDao.getTinyArtOnePageFromGlobalOld(cusId, cusIdListStr, start, pageSize-1-3));
            resultList.addAll(artDao.getTinyNewArtFromGlobalForOld(cusId, start, 1));
        } else {
            resultList = artDao.getTinyArtOnePageByTypeOld(artType, cusId, cusIdListStr, start, pageSize-1);
            resultList.addAll(artDao.getTinyNewArtByTypeForOld(artType, cusId, start, 1));
        }
        // 如果相似用户的推荐内容数量不足 10, 则返回长度为 0 的列表.
        if (resultList.size() < 10) {
            return new ArrayList<>();
        } else {
            for (ArtFullMod result: resultList) {
                result.setArtType(TypeHandler.typeTransSingleEnToCh(result.getArtType()));
            }
            return resultList;
        }
    }

    @Override
    public List<ArtFullMod> getHotArtOnePage(Integer page, Integer pageSize) {
        Integer start = PageHandler.calcuStartNO(page, pageSize);
        //if (page <= 4) {
        //    start = PageHandler.calcuStartNO(page, pageSize);
        //}
        return artDao.getHotArtOnePage(start, pageSize);
    }

    @Override
    public ArtFullMod getFullArt(Integer cusId, Integer artId) {
        ArtFullMod artFullMod = artDao.getArtFull(artId);
        artFullMod.setArtType(TypeHandler.typeTransSingleEnToCh(artFullMod.getArtType()));
        CusArtBehaviorMod behaviorMod = new CusArtBehaviorMod();
        behaviorMod.setArtId(artId);
        behaviorMod.setCusId(cusId);
        // 是否阅读过此文章
        if (cusBehaviorRecordDao.countTargetCusArtBehaviorFrom(cusId, artId, 2) >= 1) {
            behaviorMod.setRead(true);
        } else {
            behaviorMod.setRead(false);
        }
        // 是否点赞
        if (cusBehaviorRecordDao.countTargetCusArtBehaviorFrom(cusId, artId, 3) == 1) {
            behaviorMod.setPreference(1);
        } else if (cusBehaviorRecordDao.countTargetCusArtBehaviorFrom(cusId, artId, 4) == 1) {
            behaviorMod.setPreference(-1);
        } else {
            behaviorMod.setPreference(0);
        }
        // 是否是文章作者
        if (cusBehaviorRecordDao.countTargetCusArtBehaviorFrom(cusId, artId, 1) == 1) {
            behaviorMod.setArtAuthor(true);
        } else {
            behaviorMod.setArtAuthor(false);
        }
        // 是否关注了文章作者
        if (cusBehaviorRecordDao.countTargetCusFollowBehavior(cusId, artFullMod.getArtCusId()) == 1) {
            behaviorMod.setFollow(true);
        } else {
            behaviorMod.setRead(false);
        }
        artFullMod.setCusArtBehavior(behaviorMod);
        return artFullMod;
    }

}


================================================
FILE: back/src/main/java/com/smacul/demo/service/impl/SearchServiceImpl.java
================================================
package com.smacul.demo.service.impl;

import com.smacul.demo.dao.ArtDao;
import com.smacul.demo.model.ArtFullMod;
import com.smacul.demo.service.SearchService;
import com.smacul.demo.util.PageHandler;
import com.smacul.demo.util.TypeHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class SearchServiceImpl implements SearchService {

    @Autowired
    ArtDao artDao;

    @Override
    public List<ArtFullMod> searchContentSimple(String key, Integer page, Integer pageSize) {
        Integer start = PageHandler.calcuStartNO(page, pageSize);
        List<ArtFullMod> resultList = artDao.searchContentSimple(key, start, pageSize);
        for (ArtFullMod result: resultList) {
            result.setArtType(TypeHandler.typeTransSingleEnToCh(result.getArtType()));
        }
        return resultList;
    }
}


================================================
FILE: back/src/main/java/com/smacul/demo/service/impl/SelfServiceImpl.java
================================================
package com.smacul.demo.service.impl;

import com.smacul.demo.bean.CusBehaviorRecord;
import com.smacul.demo.bean.Customer;
import com.smacul.demo.dao.CusBehaviorRecordDao;
import com.smacul.demo.dao.CusDao;
import com.smacul.demo.dao.CusFeatureCountDao;
import com.smacul.demo.model.CusDynamicMod;
import com.smacul.demo.model.CusFeatureFullMod;
import com.smacul.demo.service.SelfService;
import com.smacul.demo.util.MD5;
import com.smacul.demo.util.PageHandler;
import com.smacul.demo.util.TypeHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;

@Service
public class SelfServiceImpl implements SelfService {

    @Autowired
    CusDao cusDao;
    @Autowired
    CusFeatureCountDao cusFeatureCountDao;
    @Autowired
    CusBehaviorRecordDao cusBehaviorRecordDao;

    @Override
    public Boolean checkIsNewUser(Integer cusId) {
        Integer behaviorNum = cusFeatureCountDao.countBehaviorNum(cusId);
        if (behaviorNum > 20) {
            return false;
        } else {
            return true;
        }
    }

    @Override
    public Customer checkCusForLogin(String cusName, String cusPass) throws NoSuchAlgorithmException {
        String cryptString = MD5.MD5Creator(cusPass);
        Customer customer = cusDao.getCusByName(cusName);
        if (customer != null && cryptString.equals(customer.getCusPass())) {
            return customer;
        } else {
            return null;
        }
    }

    @Override
    public String setNewCus(String cusName, String cusPass) throws NoSuchAlgorithmException {
        String cryptString = MD5.MD5Creator(cusPass);
        if (cusDao.countCusByName(cusName) != 0) {
            return "当前用户名已被注册";
        }
        Integer cusResult = cusDao.insertCusForRegister(cusName, cryptString);
        Customer customer = cusDao.getCusByName(cusName);
        Integer cusFeature = 0;
        if (customer != null) {
            cusFeature = cusFeatureCountDao.initialCusFeature(customer.getCusId());
        }
        if (cusResult == 1 && cusFeature == 1) {
            return "注册成功";
        } else {
            return "注册失败";
        }
    }

    @Override
    public Customer getCusBasicInfo(Integer cusId) {
        Customer customer = cusDao.getCusById(cusId);
        customer.setCusPass(null);
        return customer;
    }

    @Override
    public Boolean setCusBasicInfo(Customer customer) throws NoSuchAlgorithmException {
        if (customer.getCusPass() == null) {
            if (cusDao.updateCusBasicInfoWithPass(customer) == 1) {
                return true;
            }
        } else {
            customer.setCusPass(MD5.MD5Creator(customer.getCusPass()));
            if (cusDao.updateCusBasicInfo(customer) == 1) {
                return true;
            }
        }
        return false;
    }

    @Override
    public Boolean setCusFollow(Integer cusIdFrom, Integer cusIdTo) {
        if (cusBehaviorRecordDao.countTargetCusFollowBehavior(cusIdFrom, cusIdTo) == 1) {
            if (cusBehaviorRecordDao.deleteTargetCusFollowBehavior(cusIdFrom, cusIdTo) == 1) {
                return false;
            }
        } else {
            if (cusBehaviorRecordDao.addTargetCusFollowBehavior(cusIdFrom, cusIdTo) == 1) {
                return true;
            }
        }
        return false;
    }

    @Override
    public CusFeatureFullMod getCusFeatureInfo(Integer cusId) {
        CusFeatureFullMod cusFeatureFullMod = new CusFeatureFullMod();
        cusFeatureFullMod.setCusId(cusId);
        cusFeatureFullMod.setReadNum(cusBehaviorRecordDao.countCusBehaviorFrom(cusId, 2));
        cusFeatureFullMod.setFanNum(cusBehaviorRecordDao.countCusBehaviorTo(cusId, 11));
        cusFeatureFullMod.setFollowNum(cusBehaviorRecordDao.countCusBehaviorFrom(cusId, 11));
        cusFeatureFullMod.setArtEditNum(cusBehaviorRecordDao.countCusBehaviorFrom(cusId, 1));
        cusFeatureFullMod.setComEditNum(cusBehaviorRecordDao.countCusBehaviorFrom(cusId, 5));
        cusFeatureFullMod.setRepEditNum(cusBehaviorRecordDao.countCusBehaviorFrom(cusId, 8));
        cusFeatureFullMod.setFeatureCount(cusFeatureCountDao.getCusFeatureCountByCusId(cusId));
        return cusFeatureFullMod;
    }

    @Override
    public List<CusDynamicMod> getCusDynamic(Integer cusId, Integer page, Integer pageSize) {
        Integer start = PageHandler.calcuStartNO(page, pageSize);
        List<CusDynamicMod> resultList = cusBehaviorRecordDao.getCusDynamicByCusId(cusId, start, pageSize);
        for (CusDynamicMod result: resultList) {
            if (result.getCbrType() != 0) {
                result.getArticle().setArtType(TypeHandler.typeTransSingleEnToCh(result.getArticle().getArtType()));
            }
        }
        return resultList;
    }

    @Override
    public Boolean checkCusFollow(Integer cusIdFrom, Integer cusIdTo) {
        if (cusBehaviorRecordDao.countTargetCusFollowBehavior(cusIdFrom, cusIdTo) == 1) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public List<Integer> getRelativeCusList(Integer cusId, Integer num) {
        // 判断用户类型
        if (checkIsNewUser(cusId)) {
            return new ArrayList<>();
        }
        // 是老用户获取关注用户
        //List<Integer> followCusList = cusBehaviorRecordDao.getFollowCus(cusId);
        //if (followCusList.size() >= 10) {
        //    return followCusList.subList(0, 10);
        //}
        // 是老用户获取相似用户
        //Integer leftNum = num - followCusList.size();
        Integer leftNum = 10;
        List<Integer> followCusList = cusFeatureCountDao.getRelativeCusList(cusId, leftNum);
        return followCusList;
    }
}


================================================
FILE: back/src/main/java/com/smacul/demo/service/impl/SessionServiceImpl.java
================================================
package com.smacul.demo.service.impl;

import com.smacul.demo.bean.Customer;
import com.smacul.demo.service.SessionService;
import com.smacul.demo.util.PageHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.Locale;
import java.util.Map;

@Service
public class SessionServiceImpl implements SessionService {

    @Autowired
    HttpSession session;

    private static final String CUS = "customer";
    private static final String REL = "relative";
    private static final String PAG = "pages";

    @Override
    public void setCusSession(Customer cus) {
        session.setAttribute(CUS, cus);
    }

    @Override
    public void setRelSession(List<Integer> rel) {
        session.setAttribute(REL, rel);
    }

    @Override
    public Customer getCusSession() {
        return (Customer) session.getAttribute(CUS);
    }

    @Override
    public List<Integer> getRelSession() {
        return (List<Integer>) session.getAttribute(REL);
    }

    @Override
    public void initPagSession() {
        session.setAttribute(PAG, PageHandler.initPageList());
    }

    @Override
    public Integer getPagThenAddOne(String category) {
        Map<String, Integer> pages = (Map<String, Integer>)session.getAttribute(PAG);
        Integer pag = 0;
        if (category.equals("news_hot")) {
            pag = pages.get("news_hot");
            if (pag > 4) {
                pages.replace("news_hot", 0);
            } else {
                pages.replace("news_hot", pag+1);
            }
        } else {
            pag = pages.get(category);
            pages.replace(category, pag+1);
        }
        session.setAttribute(PAG, pages);
        return pag;
    }

    @Override
    public Integer getSetPagAfterCusChange(String category) {
        Map<String, Integer> pages = (Map<String, Integer>)session.getAttribute(PAG);
        pages.replace(category, 0);
        session.setAttribute(PAG, pages);
        return 0;
    }

    //public void setSession(String name, Object object) {
    //    switch (name) {
    //        case CUS:
    //            session.setAttribute(CUS, object);
    //            break;
    //        case REL:
    //            session.setAttribute(REL, object);
    //            break ;
    //
    //    }
    //}
    //
    //public Object getSession(String name) {
    //    switch (name) {
    //        case CUS:
    //            session.getAttribute(CUS);
    //            break;
    //        case REL:
    //            session.getAttribute(REL);
    //            break ;
    //    }
    //}
    //

}


================================================
FILE: back/src/main/java/com/smacul/demo/service/impl/ShapeServiceImpl.java
================================================
package com.smacul.demo.service.impl;

import com.smacul.demo.bean.Customer;
import com.smacul.demo.dao.*;
import com.smacul.demo.model.ArtFullMod;
import com.smacul.demo.service.ShapeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class ShapeServiceImpl implements ShapeService {

    @Autowired
    ArtDao artDao;
    @Autowired
    CusBehaviorRecordDao cbrDao;
    @Autowired
    CusFeatureCountDao cusFeatureCountDao;
    @Autowired
    ArtFeatureCountDao artFeatureCountDao;
    @Autowired
    CusRecommendRecordDao cusRecommendRecordDao;

    @Override
    public Boolean setCusBehaviorArtEdit(Integer cusId, Integer artId) {
        String artType = artDao.getArtTypeByArtId(artId);
        Integer cbr = cbrDao.addCusBehavior(cusId, cusId, 1, artId, 1, artId);
        Integer cfc = cusFeatureCountDao.updateCusFeature(cusId, "cfc_" + artType, 1);
        if (cbr == 1 && cfc == 1) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public Boolean setCusBehaviorArtRead(Integer cusId, Integer artId) {
        String artType = artDao.getArtTypeByArtId(artId);
        Integer artCusId = artDao.getArtCusIdByArtId(artId);
        Integer cbr = 0;
        Integer cfc = 0;
        Integer afc = 0;
        Integer readNum = cbrDao.countTargetCusArtBehaviorFrom(cusId, artId, 2);
        if (readNum < 1) {
            cbr = cbrDao.addCusBehavior(cusId, artCusId, 2, artId, 1, artId);
            cfc = cusFeatureCountDao.updateCusFeature(cusId, "cfc_" + artType, 1);
            afc = artFeatureCountDao.updateArtFeature(artId, "afc_read_num", 1);
        }
        if (readNum >=1 || (cbr == 1 && cfc == 1 && afc == 1)) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public Boolean setCusBehaviorArtLike(Integer cusId, Integer artId, Boolean type) {
        String artType = artDao.getArtTypeByArtId(artId);
        Integer artCusId = artDao.getArtCusIdByArtId(artId);
        if (type) {
            Integer cbr = cbrDao.addCusBehavior(cusId, artCusId, 3, artId, 1, artId);
            Integer cfc = cusFeatureCountDao.updateCusFeature(cusId, "cfc_" + artType, 1);
            Integer afc = artFeatureCountDao.updateArtFeature(artId, "afc_like_num", 1);
            if (cbr == 1 && cfc == 1 && afc == 1) {
                return true;
            }
        } else {
            Integer cbr = cbrDao.deleteCusBehavior(cusId, artCusId, 3, artId, 1, artId);
            Integer cfc = cusFeatureCountDao.updateCusFeature(cusId, "cfc_" + artType, -1);
            Integer afc = artFeatureCountDao.updateArtFeature(artId, "afc_like_num", -1);
            if (cbr == 1 && cfc == 1 && afc == 1) {
                return true;
            }
        }
        return false;
    }

    @Override
    public Boolean setCusBehaviorArtDislike(Integer cusId, Integer artId, Boolean type) {
        String artType = artDao.getArtTypeByArtId(artId);
        Integer artCusId = artDao.getArtCusIdByArtId(artId);
        if (type) {
            Integer cbr = cbrDao.addCusBehavior(cusId, artCusId, 4, artId, 1, artId);
            Integer cfc = cusFeatureCountDao.updateCusFeature(cusId, "cfc_" + artType, 1);
            Integer afc = artFeatureCountDao.updateArtFeature(artId, "afc_dislike_num", 1);
            if (cbr == 1 && cfc == 1 && afc == 1) {
                return true;
            }
        } else {
            Integer cbr = cbrDao.deleteCusBehavior(cusId, artCusId, 4, artId, 1, artId);
            Integer cfc = cusFeatureCountDao.updateCusFeature(cusId, "cfc_" + artType, -1);
            Integer afc = artFeatureCountDao.updateArtFeature(artId, "afc_dislike_num", -1);
            if (cbr == 1 && cfc == 1 && afc == 1) {
                return true;
            }
        }
        return false;
    }

    @Override
    public Boolean setCusBehaviorComEdit(Integer cusId, Integer artId, Integer comId) {
        ArtFullMod artFull = artDao.getArtFull(artId);
        Integer cbr = cbrDao.addCusBehavior(cusId, artFull.getArtCusId(), 5, artId, 2, comId);
        Integer cfc = cusFeatureCountDao.updateCusFeature(cusId, "cfc_" + artFull.getArtType(), 1);
        Integer afc = artFeatureCountDao.updateArtFeature(artId, "afc_com_num", 1);
        if (cbr == 1 && cfc == 1 && afc == 1) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public Boolean setCusBehaviorComLike(Integer cusId, Integer comCusId, Integer artId, Integer comId) {
        return null;
    }

    @Override
    public Boolean setCusBehaviorComDislike(Integer cusId, Integer comCusId, Integer artId, Integer comId) {
        return null;
    }

    @Override
    public Boolean setCusBehaviorRepEdit(Integer cusId, Integer artId, Integer repId) {
        ArtFullMod artFull = artDao.getArtFull(artId);
        Integer cbr = cbrDao.addCusBehavior(cusId, artFull.getArtCusId(), 8, artId, 3, repId);
        Integer cfc = cusFeatureCountDao.updateCusFeature(cusId, "cfc_" + artFull.getArtType(), 1);
        Integer afc = artFeatureCountDao.updateArtFeature(artId, "afc_rep_num", 1);
        if (cbr == 1 && cfc == 1 && afc == 1) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public Boolean setCusBehaviorRepLike(Integer cusId, Integer repCusId, Integer artId, Integer repId) {
        return null;
    }

    @Override
    public Boolean setCusBehaviorRepDislike(Integer cusId, Integer repCusId, Integer artId, Integer repId) {
        return null;
    }

    @Override
    public Boolean setCusBehaviorCusFollow(Integer cusIdFrom, Integer cusIdTo) {
        if (cbrDao.addCusBehavior(cusIdFrom, cusIdTo, 9, null, 0, null) == 1) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public Boolean recordRecommendList(Integer cusId, List<ArtFullMod> list) {
        List<Integer> idList = new ArrayList<>();
        for (ArtFullMod tar: list) {
            idList.add(tar.getArtId());
        }
        cusRecommendRecordDao.deleteOldCommentList(cusId);
        cusRecommendRecordDao.addRecommendList(cusId, idList);
        return null;
    }


}


================================================
FILE: back/src/main/java/com/smacul/demo/util/MD5.java
================================================
package com.smacul.demo.util;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5 {

    public static String MD5Creator(String plainString) throws NoSuchAlgorithmException {
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        byte b[] = md5.digest(plainString.getBytes());
        int i;
        StringBuffer buf = new StringBuffer("");
        for(int offset = 0; offset < b.length; offset ++){
            i = b[offset];
            if(i < 0){
                i += 256;
            }
            if(i < 16){
                buf.append("0");
            }
            buf.append(Integer.toHexString(i));
        }

        return buf.toString();
    }

}


================================================
FILE: back/src/main/java/com/smacul/demo/util/PageHandler.java
================================================
package com.smacul.demo.util;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class PageHandler {

    public static Integer calcuStartNO(Integer page, Integer pageSize) {
        return page * pageSize;
    }

    public static Map<String, Integer> initPageList() {
        Map<String, Integer> pages = new HashMap<>();
        pages.put("news_global", 0);
        pages.put("news_hot", 0);

        pages.put("news_society", 0);
        pages.put("news_entertainment", 0);
        pages.put("news_tech", 0);
        pages.put("news_military", 0);
        pages.put("news_sports", 0);
        pages.put("news_car", 0);

        pages.put("news_finance", 0);
        pages.put("news_world", 0);
        pages.put("news_fashion", 0);
        pages.put("news_travel", 0);
        pages.put("news_discovery", 0);
        pages.put("news_baby", 0);

        pages.put("news_regimen", 0);
        pages.put("news_story", 0);
        pages.put("news_essay", 0);
        pages.put("news_game", 0);
        pages.put("news_history", 0);
        pages.put("news_food", 0);

        return pages;
    }

    //public static void hotArtPageCheck(Map<String, Integer> pages) {
    //    if (pages.get("hot") > 4) {
    //        pages.replace("hot", 0);
    //    }
    //}
    //
    //public static void pageChange(Map<String, Integer> pages, String category, Integer num) {
    //    pages.replace(category, num);
    //}
}


================================================
FILE: back/src/main/java/com/smacul/demo/util/TypeHandler.java
================================================
package com.smacul.demo.util;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class TypeHandler {

    private static final String[] ch = {"综合", "社会", "娱乐", "科技", "军事", "体育", "汽车", "财经", "国际", "时尚", "旅游", "探索",
            "育儿", "养生", "故事", "美文", "游戏", "历史", "美食"};
    private static final String[] en = {"news_global", "news_society", "news_entertainment", "news_tech", "news_military", "news_sports",
            "news_car", "news_finance", "news_world", "news_fashion", "news_travel",
            "news_discovery", "news_baby", "news_regimen", "news_story", "news_essay",
            "news_game", "news_history", "news_food"};

    //public static List<String> sortTypeEn(List<Integer> nums) {
    //    Map<String, Integer> dictionary = new HashMap<>();
    //    for (int i = 0; i < nums.size(); i++) {
    //        dictionary.put(en[i+1], nums.get(i));
    //    }
    //
    //}

    //public static List<String> sortTypeCh(List<Integer> nums) {
    //
    //}

    public static List<String> typeTransAllEnToCh(List<String> enTypes) {
        for (int i = 0; i < enTypes.size(); i++) {
            for (int j = 0; j < en.length; j++) {
                if (enTypes.get(i).equals(en[j])) {
                    enTypes.set(i, ch[j]);
                }
            }
        }
        enTypes.add(0, "综合");
        return enTypes;
    }

    /**
     * 不出意外的话, 这个方法应该用不到.
     *
     * @param chTypes
     * @return
     */
    public static List<String> typeTransAllChToEn(List<String> chTypes) {
        for (int i = 0; i < chTypes.size(); i++) {
            for (int j = 0; j < ch.length; j++) {
                if (chTypes.get(i).equals(ch[j])) {
                    chTypes.set(i, en[j]);
                }
            }
        }
        chTypes.add(0, "news_global");
        return chTypes;
    }
    
    public static String typeTransSingleEnToCh(String enType) {
        for (int i = 0; i < en.length; i++) {
            if (enType.equals(en[i])) {
                return ch[i];
            }
        }
        return null;
    }
    
    public static String typeTransSingleChToEn(String chType) {
        for (int i = 0; i < ch.length; i++) {
            if (chType.equals(ch[i])) {
                return en[i];
            }
        }
        return null;
    }
    
}


================================================
FILE: back/src/main/resources/mapper/ArtFeatureCountMap.xml
================================================
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.smacul.demo.dao.ArtFeatureCountDao">

    <update id="updateArtFeature">
        update ArtFeatureCount
        set ${column} = ${column} + 1, afc_art_time=afc_art_time
        where afc_art_id = #{artId}
    </update>

    <select id="getArtFeatureCountByArtId" resultType="com.smacul.demo.bean.ArtFeatureCount">
        select *
        from ArtFeatureCount
        where afc_art_id = #{artId}
    </select>
</mapper>

================================================
FILE: back/src/main/resources/mapper/ArtMap.xml
================================================
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.smacul.demo.dao.ArtDao">

    <insert id="addArt" useGeneratedKeys="true" keyProperty="artId" parameterType="com.smacul.demo.bean.Article">
        insert into Article(art_title, art_cus_id, art_content, art_image_url, art_type, art_legal)
        values(#{artTitle}, #{artCusId}, #{artContent}, #{artImageUrl}, #{artType}, #{artLegal})
    </insert>

    <select id="getArtTypesOrderByTypeNum" resultType="java.lang.String">
        select art_type from Article group by art_type order by count(art_type) desc
    </select>

    <select id="getTinyArtOnePageFromGlobalNew" resultMap="artFullModRM">
        select art_id, art_title, art_spider, art_type, art_tags, art_image_url, art_time, art_legal, art_cus_id
        from Article left join artscorelist on Article.art_id = artscorelist.asl_art_id
        where art_id not in (select cbr_art_id from CusBehaviorRecord where cbr_cus_id_from = #{cusId} and cbr_behavior = 2)
        order by artscorelist.asl_art_score desc
        limit #{start}, #{pageSize}
    </select>

    <select id="getTinyArtOnePageByTypeNew" resultMap="artFullModRM">
        select art_id, art_title, art_spider, art_type, art_tags, art_image_url, art_time, art_legal, art_cus_id
        from Article left join artscorelist on Article.art_id = artscorelist.asl_art_id
        where art_type = #{artType} and
        art_id not in (select cbr_art_id from CusBehaviorRecord where cbr_cus_id_from = #{cusId} and cbr_behavior = 2) and
        art_id not in (select crr_art_id from CusRecommendRecord where crr_cus_id = #{cusId})
        order by artscorelist.asl_art_score desc
        limit #{start}, #{pageSize}
    </select>

    <select id="getHotArtOnePage" resultMap="artFullModRM">
        select
            art_id, art_title, art_spider, art_type, art_tags, art_image_url, art_time, art_legal, art_cus_id
        from Article left join ArtTimeList on Article.art_id = ArtTimeList.atl_art_id
        order by ArtTimeList.atl_art_score desc
        limit #{start}, #{pageSize}
    </select>

    <select id="getArtFull" resultMap="artFullModRM">
        select *
        from Article
        where art_id = #{artId}
    </select>

    <select id="getArtCusIdByArtId" resultType="java.lang.Integer">
        select art_cus_id from Article where art_id = #{artId}
    </select>

    <select id="getArtTypeByArtId" resultType="java.lang.String">
        select art_type from Article where art_id = #{artId}
    </select>

    <select id="searchContentSimple" resultMap="artFullModRM">
        select
            art_id, art_title, art_spider, art_type, art_tags, art_image_url, art_time, art_legal, art_cus_id
        from Article left join artscorelist on Article.art_id = artscorelist.asl_art_id
        where art_title like concat('%', #{key}, '%') or art_content like concat('%', #{key}, '%')
        order by artscorelist.asl_art_score desc
        limit #{start}, #{pageSize}
    </select>

    <select id="getSingleArt" resultType="com.smacul.demo.model.ArtFullMod">
        select *
        from Article
        where 11 != #{flag} and art_id = #{artId}
    </select>

    <select id="getTinyArtOnePageFromGlobalOld" resultMap="artFullModRM">
        select art_id, art_title, art_spider, art_type, art_tags, art_image_url, art_time, art_legal, art_cus_id
        from Article left join artscorelist on Article.art_id = artscorelist.asl_art_id
        where
            art_id not in (select cbr_art_id from CusBehaviorRecord where cbr_cus_id_from = #{cusId} and cbr_behavior = 2)
            and art_id in (select cbr_art_id from CusBehaviorRecord where cbr_behavior = 2 and cbr_cus_id_from in (${cusIdListStr}))
            and art_id not in (select crr_art_id from CusRecommendRecord where crr_cus_id = #{cusId})
        order by artscorelist.asl_art_score desc
        limit #{start}, #{pageSize}
    </select>

    <select id="getTinyArtOnePageByTypeOld" resultMap="artFullModRM">
        select art_id, art_title, art_spider, art_type, art_tags, art_image_url, art_time, art_legal, art_cus_id
        from Article left join artscorelist on Article.art_id = artscorelist.asl_art_id
        where
            art_type = #{artType}
            and art_id not in (select cbr_art_id from CusBehaviorRecord where cbr_cus_id_from = #{cusId} and cbr_behavior = 2)
            and art_id in (select cbr_art_id from CusBehaviorRecord where cbr_behavior = 2 and cbr_cus_id_from in (${cusIdListStr}))
            and art_id not in (select crr_art_id from CusRecommendRecord where crr_cus_id = #{cusId})
        order by artscorelist.asl_art_score desc
        limit #{start}, #{pageSize}
    </select>

    <select id="getTinyNewArtFromGlobalForNew" resultMap="artFullModRM">
        select art_id, art_title, art_spider, art_type, art_tags, art_image_url, art_time, art_legal, art_cus_id
        from Article
        where
            art_id not in (select cbr_art_id from CusBehaviorRecord where cbr_cus_id_from = #{cusId} and cbr_behavior = 2) and
            art_id not in (select crr_art_id from CusRecommendRecord where crr_cus_id = #{cusId})
        order by art_time desc
        limit #{start}, #{pageSize}
    </select>

    <select id="getTinyHotArtFromGlobalForNew" resultMap="artFullModRM">
        select art_id, art_title, art_spider, art_type, art_tags, art_image_url, art_time, art_legal, art_cus_id
        from Article left join artscorelist on Article.art_id = artscorelist.asl_art_id
        where
            art_id not in (select cbr_art_id from CusBehaviorRecord where cbr_cus_id_from = #{cusId} and cbr_behavior = 2) and
            art_id not in (select crr_art_id from CusRecommendRecord where crr_cus_id = #{cusId}) and
            art_type not in ('news_travel', 'news_regimen', 'news_story', 'news_history', 'news_baby' 'news_essay', 'news_food', 'news_discovery')
        order by artscorelist.asl_art_score desc
        limit #{start}, #{pageSize}
    </select>

    <select id="getTinyInfoArtFromGlobalForNew" resultMap="artFullModRM">
        select art_id, art_title, art_spider, art_type, art_tags, art_image_url, art_time, art_legal, art_cus_id
        from Article left join artscorelist on Article.art_id = artscorelist.asl_art_id
        where
            art_id not in (select cbr_art_id from CusBehaviorRecord where cbr_cus_id_from = #{cusId} and cbr_behavior = 2) and
            art_id not in (select crr_art_id from CusRecommendRecord where crr_cus_id = #{cusId}) and
            art_type in ('news_travel', 'news_regimen', 'news_story', 'news_history', 'news_baby' 'news_essay', 'news_food', 'news_discovery')
        order by artscorelist.asl_art_score desc
        limit #{start}, #{pageSize}
    </select>

    <select id="getTinyNewArtByTypeForNew" resultMap="artFullModRM">
        select art_id, art_title, art_spider, art_type, art_tags, art_image_url, art_time, art_legal, art_cus_id
        from Article
        where art_type = #{artType} and
        art_id not in (select cbr_art_id from CusBehaviorRecord where cbr_cus_id_from = #{cusId} and cbr_behavior = 2) and
        art_id not in (select crr_art_id from CusRecommendRecord where crr_cus_id = #{cusId})
        order by art_time desc
        limit #{start}, #{pageSize}
    </select>

    <select id="getTinyNewArtFromGlobalForOld" resultMap="artFullModRM">
        select art_id, art_title, art_spider, art_type, art_tags, art_image_url, art_time, art_legal, art_cus_id
        from Article
        where
            art_id not in (select cbr_art_id from CusBehaviorRecord where cbr_cus_id_from = #{cusId} and cbr_behavior = 2)
        order by art_time desc
        limit #{start}, #{pageSize}
    </select>

    <select id="getTinyNewArtByTypeForOld" resultMap="artFullModRM">
        select art_id, art_title, art_spider, art_type, art_tags, art_image_url, art_time, art_legal, art_cus_id
        from Article
        where art_type = #{artType} and
        art_id not in (select cbr_art_id from CusBehaviorRecord where cbr_cus_id_from = #{cusId} and cbr_behavior = 2) and
        art_id not in (select crr_art_id from CusRecommendRecord where crr_cus_id = #{cusId})
        order by art_time desc
        limit #{start}, #{pageSize}
    </select>

    <resultMap id="artFullModRM" type="com.smacul.demo.model.ArtFullMod">
        <id property="artId" column="art_id"></id>
        <result property="artTitle" column="art_title"></result>
        <result property="artTime" column="art_time"></result>
        <result property="artImageUrl" column="art_image_url"></result>
        <result property="artCusId" column="art_cus_id"></result>
        <result property="artContent" column="art_content"></result>
        <result property="artSpider" column="art_spider"></result>
        <result property="artLegal" column="art_legal"></result>
        <result property="artTags" column="art_tags"></result>
        <result property="artType" column="art_type"></result>
        <collection property="customer" select="com.smacul.demo.dao.CusDao.getCusById"
                    column="cusId=art_cus_id" javaType="com.smacul.demo.bean.Customer"></collection>
        <collection property="artFeature" select="com.smacul.demo.dao.ArtFeatureCountDao.getArtFeatureCountByArtId"
                    column="artId=art_id" javaType="com.smacul.demo.bean.ArtFeatureCount"></collection>
    </resultMap>
</mapper>

================================================
FILE: back/src/main/resources/mapper/ArtScoreListMap.xml
================================================
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.smacul.demo.dao.ArtScoreListDao">

</mapper>

================================================
FILE: back/src/main/resources/mapper/ArtTimeListMap.xml
================================================
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.smacul.demo.dao.ArtTimeList">

</mapper>

================================================
FILE: back/src/main/resources/mapper/ComMap.xml
================================================
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.smacul.demo.dao.ComDao">
    <insert id="addCom" useGeneratedKeys="true" keyProperty="comId" parameterType="com.smacul.demo.bean.Comment">
        insert into Comment(com_content, com_legal, com_cus_id, com_art_id)
        values(#{comContent}, #{comLegal}, #{comCusId}, #{comArtId})
    </insert>

    <select id="getComFullList" resultMap="searchCommentsRM">
        select *
        from Comment
        where com_art_id = #{artId}
        order by com_time desc
    </select>

    <select id="getSingleCom" resultType="com.smacul.demo.model.ComFullMod">
        select *
        from Comment
        where 2 = #{flag} and com_id = #{comId}
    </select>

    <resultMap id="searchCommentsRM" type="com.smacul.demo.model.ComFullMod">
        <id property="comId" column="com_id"></id>
        <result property="comArtId" column="com_art_id"></result>
        <result property="comContent" column="com_content"></result>
        <result property="comCusId" column="com_cus_id"></result>
        <result property="comLegal" column="com_legal"></result>
        <result property="comSpider" column="com_spider"></result>
        <result property="comTime" column="com_time"></result>
        <collection property="customer" select="com.smacul.demo.dao.CusDao.getCusById"
                    column="cusId=com_cus_id" javaType="com.smacul.demo.bean.Customer"></collection>
        <collection property="replys" select="com.smacul.demo.dao.RepDao.getRepFullList"
                    column="comId=com_id" javaType="java.util.ArrayList"></collection>
    </resultMap>

</mapper>

================================================
FILE: back/src/main/resources/mapper/CusBehaviorRecordMap.xml
================================================
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.smacul.demo.dao.CusBehaviorRecordDao">

    <insert id="addTargetCusFollowBehavior">
        insert into CusBehaviorRecord(cbr_cus_id_from, cbr_cus_id_to, cbr_behavior)
        values (#{param1}, #{param2}, 11)
    </insert>

    <insert id="addCusBehavior">
        insert into CusBehaviorRecord(cbr_cus_id_from, cbr_cus_id_to, cbr_behavior, cbr_art_id, cbr_type, cbr_target_id)
        values (#{cusIdFrom}, #{cusIdTo}, #{behavior}, #{artId}, #{type}, #{targetId})
    </insert>

    <delete id="deleteTargetCusFollowBehavior">
        delete from CusBehaviorRecord
        where cbr_behavior = 11 and cbr_cus_id_from = #{param1} and cbr_cus_id_to = #{param2};
    </delete>

    <delete id="deleteCusBehavior">
        delete from CusBehaviorRecord
        where
            cbr_cus_id_from = #{cusIdFrom} and cbr_cus_id_to = #{cusIdTo} and cbr_behavior = #{behavior} and
            cbr_art_id = #{artId} and cbr_type = #{type} and cbr_target_id = #{targetId}
    </delete>


    <select id="countTargetCusFollowBehavior" resultType="java.lang.Integer">
        select count(*)
        from CusBehaviorRecord
        where cbr_behavior = 11 and cbr_cus_id_from = #{param1} and cbr_cus_id_to = #{param2};
    </select>

    <select id="countCusBehaviorFrom" resultType="java.lang.Integer">
        select count(*)
        from CusBehaviorRecord
        where cbr_cus_id_from = #{param1} and cbr_behavior = #{param2}
    </select>

    <select id="countCusBehaviorTo" resultType="java.lang.Integer">
        select count(*)
        from CusBehaviorRecord
        where cbr_cus_id_to = #{param1} and cbr_behavior = #{param2}
    </select>

    <select id="countTargetCusArtBehaviorFrom" resultType="java.lang.Integer">
        select count(*)
        from CusBehaviorRecord
        where
            cbr_cus_id_from = #{cusIdFrom} and cbr_art_id = #{artId}
            and cbr_behavior = #{behavior} and cbr_type = 1 and cbr_target_id = #{artId}
    </select>

    <select id="countTargetCusArtBehaviorTo" resultType="java.lang.Integer">
        select count(*)
        from CusBehaviorRecord
        where
            cbr_cus_id_to = #{cusIdTo} and cbr_art_id = #{artId}
            and cbr_behavior = #{behavior} and cbr_type = 1 and cbr_target_id = #{artId}
    </select>

    <select id="getCusDynamicByCusId" resultMap="cusDynamicRM">
        select *
        from CusBehaviorRecord
        where cbr_cus_id_from = #{cusId} and cbr_behavior != 2
        order by cbr_time desc
        limit #{start}, #{pageSize}
    </select>

    <select id="getFollowCus" resultType="java.lang.Integer">
        select cbr_cus_id_to
        from CusBehaviorRecord
        where cbr_cus_id_from = #{cusId} and cbr_behavior = 11
    </select>

    <resultMap id="cusDynamicRM" type="com.smacul.demo.model.CusDynamicMod">
        <id property="cbrId" column="cbr_id"></id>
        <result property="cbrCusIdFrom" column="cbr_cus_id_from"></result>
        <result property="cbrCusIdTo" column="cbr_cus_id_to"></result>
        <result property="cbrBehavior" column="cbr_behavior"></result>
        <result property="cbrTime" column="cbr_time"></result>
        <result property="cbrType" column="cbr_type"></result>
        <result property="cbrArtId" column="cbr_art_id"></result>
        <collection property="cusFrom" select="com.smacul.demo.dao.CusDao.getCusById"
                    column="cusId=cbr_cus_id_from"
                    javaType="com.smacul.demo.bean.Customer"></collection>
        <collection property="cusTo" select="com.smacul.demo.dao.CusDao.getCusById"
                    column="cusId=cbr_cus_id_to"
                    javaType="com.smacul.demo.bean.Customer"></collection>
        <collection property="article" select="com.smacul.demo.dao.ArtDao.getSingleArt"
                    column="{flag=cbr_type, artId=cbr_art_id}"
                    javaType="com.smacul.demo.model.ArtFullMod"></collection>
        <collection property="comment" select="com.smacul.demo.dao.ComDao.getSingleCom"
                    column="{flag=cbr_type, comId=cbr_target_id}" javaType="com.smacul.demo.model.ComFullMod"></collection>
        <collection property="reply" select="com.smacul.demo.dao.RepDao.getSingleRep"
                    column="{flag=cbr_type, repId=cbr_target_id}" javaType="com.smacul.demo.model.RepFullMod"></collection>
    </resultMap>


</mapper>

================================================
FILE: back/src/main/resources/mapper/CusFeatureCountMap.xml
================================================
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.smacul.demo.dao.CusFeatureCountDao">

    <insert id="initialCusFeature">
        insert into CusFeatureCount (cfc_cus_id) value(#{cusId})
    </insert>

    <update id="updateCusFeature">
        update CusFeatureCount
        set ${column} = ${column} + #{num}
        where cfc_cus_id = #{cusId}
    </update>

    <select id="countBehaviorNum" resultType="java.lang.Integer">
        select
            cfc_news_society + cfc_news_entertainment + cfc_news_tech + cfc_news_military + cfc_news_sports + cfc_news_finance +
            cfc_news_world + cfc_news_fashion + cfc_news_travel + cfc_news_discovery + cfc_news_baby + cfc_news_regimen +
            cfc_news_story + cfc_news_essay + cfc_news_game + cfc_news_history + cfc_news_food + cfc_news_car
        from CusFeatureCount
        where cfc_cus_id = #{cusId}
    </select>

    <select id="getCusFeatureCountByCusId" resultType="com.smacul.demo.bean.CusFeatureCount">
        select *
        from CusFeatureCount
        where cfc_cus_id = #{cusId}
    </select>

    <select id="getCusArtTypesBehaviorNums" resultType="java.lang.Integer">
        select
--             cfc_news_society + cfc_news_entertainment + cfc_news_tech + cfc_news_military + cfc_news_sports + cfc_news_finance +
--             cfc_news_world + cfc_news_fashion + cfc_news_travel + cfc_news_discovery + cfc_news_baby + cfc_news_regimen +
--             cfc_news_story + cfc_news_essay + cfc_news_game + cfc_news_history + cfc_news_food + cfc_news_car as cfc_news_global,
            cfc_news_society, cfc_news_entertainment, cfc_news_tech, cfc_news_military, cfc_news_sports, cfc_news_car,
            cfc_news_finance, cfc_news_world, cfc_news_fashion, cfc_news_travel, cfc_news_discovery, cfc_news_baby,
            cfc_news_regimen, cfc_news_story, cfc_news_essay, cfc_news_game, cfc_news_history, cfc_news_food,
        from CusFeatureCount
        where cfc_cus_id = #{cusId}
    </select>

    <select id="getRelativeCusList" resultType="java.lang.Integer">
        select
            a.cfc_cus_id
        from CusFeatureCount as a,
             (select
                  cfc_news_society, cfc_news_entertainment, cfc_news_tech, cfc_news_military, cfc_news_sports, cfc_news_finance,
                  cfc_news_world, cfc_news_fashion, cfc_news_travel, cfc_news_discovery, cfc_news_baby, cfc_news_regimen,
                  cfc_news_story, cfc_news_essay, cfc_news_game, cfc_news_history, cfc_news_food, cfc_news_car
              from CusFeatureCount where cfc_cus_id = #{cusId}) as b
        where a.cfc_cus_id != #{cusId}
        order by
            SQRT(
                        POW((cast(a.cfc_news_society as signed) - cast(b.cfc_news_society as signed)), 2) +
                        POW((cast(a.cfc_news_entertainment as signed) - cast(b.cfc_news_entertainment as signed)), 2) +
                        POW((cast(a.cfc_news_tech as signed) - cast(b.cfc_news_tech as signed)), 2) +
                        POW((cast(a.cfc_news_military as signed) - cast(b.cfc_news_military as signed)), 2) +
                        POW((cast(a.cfc_news_sports as signed) - cast(b.cfc_news_sports as signed)), 2) +
                        POW((cast(a.cfc_news_finance as signed) - cast(b.cfc_news_finance as signed)), 2) +

                        POW((cast(a.cfc_news_world as signed) - cast(b.cfc_news_world as signed)), 2) +
                        POW((cast(a.cfc_news_fashion as signed) - cast(b.cfc_news_fashion as signed)), 2) +
                        POW((cast(a.cfc_news_travel as signed) - cast(b.cfc_news_travel as signed)), 2) +
                        POW((cast(a.cfc_news_discovery as signed) - cast(b.cfc_news_discovery as signed)), 2) +
                        POW((cast(a.cfc_news_baby as signed) - cast(b.cfc_news_baby as signed)), 2) +
                        POW((cast(a.cfc_news_regimen as signed) - cast(b.cfc_news_regimen as signed)), 2) +

                        POW((cast(a.cfc_news_story as signed) - cast(b.cfc_news_story as signed)), 2) +
                        POW((cast(a.cfc_news_essay as signed) - cast(b.cfc_news_essay as signed)), 2) +
                        POW((cast(a.cfc_news_game as signed) - cast(b.cfc_news_game as signed)), 2) +
                        POW((cast(a.cfc_news_history as signed) - cast(b.cfc_news_history as signed)), 2) +
                        POW((cast(a.cfc_news_food as signed) - cast(b.cfc_news_food as signed)), 2) +
                        POW((cast(a.cfc_news_car as signed) - cast(b.cfc_news_car as signed)), 2)
                )
        limit #{num};
    </select>

</mapper>

================================================
FILE: back/src/main/resources/mapper/CusMap.xml
================================================
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.smacul.demo.dao.CusDao">

    <insert id="insertCusForRegister">
        insert into Customer(cus_name, cus_pass) values(#{cusName}, #{cusPass});
    </insert>

    <insert id="updateCusBasicInfo" parameterType="com.smacul.demo.bean.Customer">
        update Customer
        set cus_name = #{cusName}, cus_avatar_url = #{cusAvatarUrl}, cus_style = #{cusStyle}, cus_gender = #{cusGender}
        where cus_id = #{cusId}
    </insert>

    <update id="updateCusBasicInfoWithPass">
        update Customer
        set cus_name = #{cusName}, cus_avatar_url = #{cusAvatarUrl}, cus_style = #{cusStyle}, cus_gender = #{cusGender},
            cus_pass = #{cusPass}
        where cus_id = #{cusId}
    </update>

    <select id="getCusByName" resultType="com.smacul.demo.bean.Customer">
        select cus_id, cus_name, cus_spider, cus_avatar_url, cus_style, cus_gender, cus_time, cus_legal, cus_pass
        from Customer where cus_name = #{cusName};
    </select>

    <select id="countCusByName" resultType="java.lang.Integer">
        select count(*) from Customer where cus_name = #{cusName};
    </select>

    <select id="getCusById" resultType="com.smacul.demo.bean.Customer">
        select
            cus_id, cus_name, cus_spider, cus_avatar_url, cus_style, cus_gender, cus_time, cus_legal
        from Customer where cus_id = #{cusId};
    </select>


</mapper>

================================================
FILE: back/src/main/resources/mapper/CusRecommendRecordDao.xml
================================================
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.smacul.demo.dao.CusRecommendRecordDao">


    <insert id="addRecommendList">
        INSERT INTO CusRecommendRecord(crr_cus_id, crr_art_id)
        VALUES
        <foreach collection="list" item="tar" separator=",">
            (#{cusId}, #{tar})
        </foreach>
    </insert>

    <delete id="deleteOldCommentList">
        delete from CusRecommendRecord WHERE crr_cus_id = #{cusId} and timestampdiff(HOUR, crr_time, now()) >= 72
    </delete>

</mapper>

================================================
FILE: back/src/main/resources/mapper/RepMap.xml
================================================
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.smacul.demo.dao.RepDao">

    <insert id="addRep" useGeneratedKeys="true" keyProperty="repId" parameterType="com.smacul.demo.bean.Reply">
        insert into Reply(rep_content, rep_type, rep_legal, rep_cus_id, rep_art_id, rep_com_id, rep_rep_id)
        values (#{repContent}, #{repType}, #{repLegal}, #{repCusId}, #{repArtId}, #{repComId}, #{repRepId})
    </insert>

    <select id="getRepFullList" resultType="com.smacul.demo.model.RepFullMod">
        select R.*,
            C.cus_avatar_url as 'customer.cusAvatarUrl',
            C.cus_id as 'customer.cusId',
            C.cus_name as 'customer.cusName'
        from Reply as R, Customer as C
        where R.rep_com_id = #{comId} and R.rep_cus_id = C.cus_id
        order by rep_time desc
    </select>

    <select id="getSingleRep" resultType="com.smacul.demo.model.RepFullMod">
        select *
        from Reply
        where 3 = #{flag} and rep_id = #{repId}
    </select>

</mapper>

================================================
FILE: back/src/main/resources/templates/application.properties.template
================================================
spring.datasource.driverClassName = com.mysql.jdbc.Driver
spring.datasource.url = jdbc:mysql://
spring.datasource.username =
spring.datasource.password =
mybatis.configuration.map-underscore-to-camel-case=true
mybatis.mapper-locations=classpath:mapper/*.xml

================================================
FILE: back/src/test/java/com/smacul/demo/DemoApplicationTests.java
================================================
package com.smacul.demo;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class DemoApplicationTests {

    @Test
    void contextLoads() {
    }

}


================================================
FILE: front/.gitignore
================================================
.DS_Store
node_modules
/dist

# local env files
.env.local
.env.*.local

# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?


================================================
FILE: front/README.md
================================================
# front

## Project setup
```
yarn install
```

### Compiles and hot-reloads for development
```
yarn serve
```

### Compiles and minifies for production
```
yarn build
```

### Lints and fixes files
```
yarn lint
```

### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).


================================================
FILE: front/babel.config.js
================================================
module.exports = {
  presets: [
    '@vue/cli-plugin-babel/preset'
  ]
}


================================================
FILE: front/package.json
================================================
{
  "name": "front",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "core-js": "^3.4.4",
    "element-ui": "^2.3.6",
    "vue": "^2.6.10",
    "vue-blu": "^0.1.9",
    "vue-router": "^3.1.3",
    "wangeditor": "^3.1.1"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "^4.1.0",
    "@vue/cli-plugin-eslint": "^4.1.0",
    "@vue/cli-plugin-router": "^4.1.2",
    "@vue/cli-service": "^4.1.0",
    "axios": "^0.18.0",
    "babel-eslint": "^10.0.3",
    "eslint": "^5.16.0",
    "eslint-plugin-vue": "^5.0.0",
    "node-sass": "^4.13.1",
    "sass-loader": "^8.0.2",
    "vue-cli-plugin-axios": "^0.0.4",
    "vue-cli-plugin-element-ui": "^1.1.4",
    "vue-template-compiler": "^2.6.10"
  },
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/essential",
      "eslint:recommended"
    ],
    "rules": {},
    "parserOptions": {
      "parser": "babel-eslint"
    }
  },
  "browserslist": [
    "> 1%",
    "last 2 versions"
  ]
}


================================================
FILE: front/public/index.html
================================================
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title>front</title>
  </head>
  <body>
    <noscript>
      <strong>We're sorry but front doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>


================================================
FILE: front/src/App.vue
================================================
<template>
    <div id="app">
        <!--<div id="nav">-->
        <!--  <router-link to="/">Home</router-link> |-->
        <!--  <router-link to="/about">About</router-link>-->
        <!--</div>-->
        <router-view/>
    </div>
</template>

<style>
    #app {
        font-family: 'Avenir', Helvetica, Arial, sans-serif;
        -webkit-font-smoothing: antialiased;
        -moz-osx-font-smoothing: grayscale;
        text-align: center;
        color: #2c3e50;
    }

    #nav {
        padding: 30px;
    }

    #nav a {
        font-weight: bold;
        color: #2c3e50;
    }

    #nav a.router-link-exact-active {
        color: #42b983;
    }

    .clear-float:after {
        content: '.';
        display: block;
        height: 0;
        clear: both;
        visibility: hidden;
    }

    .clear-float {
        zoom: 1;
    }

</style>


================================================
FILE: front/src/assets/css/Narrow.css
================================================
body {
    margin: 0 auto;
}

header {
    height: 60px;
    margin-bottom: 10px;
    box-shadow: 0 1px 4px 0 rgba(0,0,0,.12);

    width: 1000000px;
    overflow: hidden;
    position: fixed;
    background-color: #fff;
    z-index: 10;
    top: 0;
}

main {
    width: 1030px;
    margin: 70px auto 10px;
    position: relative;
    z-index: 1;
    height: 1000px;
}

/*nav {*/
/*    width: 130px;*/
/*    position: fixed;*/
/*}*/

article {
    margin-left:0;
    width: 710px;
}

aside {
    width: 280px;
    position: fixed;
    top: 70px;
    margin-left: 750px;
}

.top-bar {
    width: 1030px;
    height: 40px;
    padding: 10px 0px 10px 0px;
    position: fixed;
    left: -515px;
    margin-left: 50%;
}

================================================
FILE: front/src/assets/css/Normal.css
================================================
body {
    margin: 0 auto;
}

header {
    height: 60px;
    margin-bottom: 10px;
    box-shadow: 0 1px 4px 0 rgba(0,0,0,.12);

    width: 1000000px;
    overflow: hidden;
    position: fixed;
    background-color: #fff;
    z-index: 10;
    top: 0;
}

main {
    width: 1180px;
    margin: 70px auto 10px;
    position: relative;
    z-index: 1;
    height: 1000px;
}

nav {
    width: 130px;
    position: fixed;
    z-index: 2;
}

article {
    margin-left:160px;
    width: 710px;
    z-index: 1;
}

aside {
    width: 280px;
    position: fixed;
    top: 70px;
    margin-left: 900px;
}

.top-bar {
    width: 1180px;
    height: 40px;
    padding: 10px 0px 10px 0px;
    position: fixed;
    left: -590px;
    margin-left: 50%;
}



================================================
FILE: front/src/components/HelloWorld.vue
================================================
<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <p>
      For a guide and recipes on how to configure / customize this project,<br>
      check out the
      <a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
    </p>
    <h3>Installed CLI Plugins</h3>
    <ul>
      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
    </ul>
    <h3>Essential Links</h3>
    <ul>
      <li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
      <li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
      <li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
      <li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
      <li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
    </ul>
    <h3>Ecosystem</h3>
    <ul>
      <li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
      <li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
      <li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
      <li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
      <li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
    </ul>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
  margin: 40px 0 0;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>


================================================
FILE: front/src/components/app/HelloWorld.vue
================================================
<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <p>
      For a guide and recipes on how to configure / customize this project,<br>
      check out the
      <a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
    </p>
    <h3>Installed CLI Plugins</h3>
    <ul>
      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
    </ul>
    <h3>Essential Links</h3>
    <ul>
      <li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
      <li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
      <li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
      <li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
      <li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
    </ul>
    <h3>Ecosystem</h3>
    <ul>
      <li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
      <li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
      <li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
      <li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
      <li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
    </ul>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
  h3 {
    margin: 40px 0 0;
  }
  ul {
    list-style-type: none;
    padding: 0;
  }
  li {
    display: inline-block;
    margin: 0 10px;
  }
  a {
    color: #42b983;
  }
</style>


================================================
FILE: front/src/components/article/ArticleCenter.vue
================================================
<template>
    <div class="article-main">
        <div class="title">{{articleMain.artTitle}}</div>
        <div class="article-info">
            <span class="type"> {{ articleMain.artType }}</span>
            <span style="margin-right: 5px;">{{ articleMain.cusName }}</span>
            <span>{{ dataTransfer }}</span>
        </div>
        <div class="content" v-html="articleMain.artContent"></div>
        <!--<div class="up-down clear-float">-->
        <!--    <div class="up">-->
        <!--        <img :src='control.art.up' @click="cusLikeArt"/>-->
        <!--        <span>{{ articleMain.artLikeNum }}</span>-->
        <!--    </div>-->
        <!--    <div class="down">-->
        <!--        <img :src="control.art.down" @click="cusDislikeArt"/>-->
        <!--        <span>{{ articleMain.artDislikeNum }}</span>-->
        <!--    </div>-->
        <!--</div>-->
    </div>
</template>

<script>
    export default {
        name: "ArticleCenter",
        props: ['articleMain'],
        computed: {
            dataTransfer: function () {
                return new Date(Date.parse(this.articleMain.artTime)).toLocaleString();
            }
        },
        methods: {
            cusLikeArt: function () {
                if (this.control.art.up === require('../../assets/icon/Like.png')) {
                    this.control.art.up = require('../../assets/icon/LikeFill.png');
                    this.control.art.down = require('../../assets/icon/Dislike.png');
                } else {
                    this.control.art.up = require('../../assets/icon/Like.png');
                }
            },
            cusDislikeArt: function () {
                if (this.control.art.down === require('../../assets/icon/Dislike.png')) {
                    this.control.art.down = require('../../assets/icon/DislikeFill.png');
                    this.control.art.up = require('../../assets/icon/Like.png');
                } else {
                    this.control.art.down = require('../../assets/icon/Dislike.png')
                }
            }
        },
        data: function() {
            return {
                control: {
                    art: {
                        up: require('../../assets/icon/Like.png'),
                        down: require('../../assets/icon/Dislike.png'),
                    }
                },
                // likeImg: require('../../assets/icon/Like.png'),
                // dislikeImg: require('../../assets/icon/Dislike.png'),
                // likeImgFill: require('../../assets/icon/LikeFill.png'),
                // dislikeImgFill: require('../../assets/icon/DislikeFill.png'),
            }
        }
    }
</script>

<style scoped>
    .title {
        font-size: 40px;
        font-weight: 800;
        text-align: left;
        line-height: 70px;
    }

    .article-info {
        text-align: left;
        margin-top: 10px;
        margin-bottom: 20px;
        color: #777777;
    }

    .content >>> p {
        text-align: left;
        font-size: 18px;
        margin: 10px;
    }

    .content >>> img {
        text-align: center;
    }

    .content {
        margin-bottom: 30px;
    }

    .up-down {
        width: 200px;
        margin: 0 auto;
        padding: 30px 0px
    }

    .up {
        float: left;
        height: 30px;
        width: 50px;
    }

    .up img {
        height: 30px;
        float: left;
    }

    .up span {
        display: inline-block;
        line-height: 30px;
        font-size: 20px;
        float: right;
    }

    /*.el-icon-success {*/
    /*    margin-right: 10px;*/
    /*}*/

    .down {
        float: right;
        height: 30px;
        width: 50px;
    }

    .down img {
        height: 30px;
        float: left;
    }

    .down span {
        display: inline-block;
        line-height: 30px;
        font-size: 20px;
        float: right;
    }

    /*.el-icon-error {*/
    /*    margin-right: 10px;*/
    /*}*/

    .article-info .type {
        margin-right: 10px;
        border: 1px;
        border-style: solid;
        border-radius: 3px;
        color: darkred;
    }
</style>

================================================
FILE: front/src/components/article/CommentReplyCenter.vue
================================================
<template>
    <div>
        <comment-reply-input :customer="customer" @messageHandler="addComment"></comment-reply-input>
        <div class="comments" v-for="(comment, i) in comments.slice((control.com.page-1)*control.com.pageSize, (control.com.page)*control.com.pageSize)" :key="i">
            <div class="clear-float">
                <div class="avatar">
                    <img :src='comment.customer.cusAvatarUrl'>
                </div>
                <div class="comment">
                    <div style="text-align: left; font-weight: 500; font-size: 18px;">
                        <el-button type="text" @click="jumpToCus(comment.customer.cusId)">{{comment.customer.cusName}}</el-button>
                    </div>
                    <!--<div class="content">{{comment.comContent}}</div>-->
                    <div class="content" v-html="comment.comContent"></div>
                    <div class="info">
                        <span>{{ date(comment.comTime) }}</span>
                        <!--<span>{{comment.comLikeNum}}</span>-->
                        <el-button type="text" @click="addCancelReply(comment.comId)">
                            <span v-show="control.add.type == 1 && control.add.id == comment.comId">收起</span>
                            <span v-show="control.add.type != 1 || control.add.id != comment.comId">评论</span>
                        </el-button>
                    </div>
                </div>
                <!-- 评论回复输入框 -->
                <comment-reply-input @readycancel="cancelMessage" @messageHandler="addReply"
                                     v-if="control.add.type == 1 && control.add.id == comment.comId"
                                     :heightKey=false :customer="customer">
                </comment-reply-input>
            </div>

            <reply-main :replys=comment.replys :commentId=comment.comId :add="control.add" :customer="customer"
                        @quickShow="$emit('quickShow')">
            </reply-main>
        </div>
        <el-pagination v-if="comments.length > control.com.pageSize"
                       background
                       layout="prev, pager, next"
                       @current-change="commentHandleCurrentChange"
                       :page-size="control.com.pageSize"
                       :current-page="control.com.page"
                       :total="comments.length"
                       class="page-switcher"
        >
        </el-pagination>
    </div>
</template>

<script>
    import CommentReplyInput from "./comment-reply-main/CommentReplyInput";
    import ReplyMain from "./comment-reply-main/ReplyMain";
    import {transUTCtoLocal} from "../../util/TimeHandler";
    import {addNewCom, cusAddReply} from "../../control/Discuss";
    import {jumpInNewPage} from "../../util/PageJump";

    /**
     * /src/components/article/comment-reply-main/ 路径下包含了 CommentReplyMain 模块需要的子组件
     */
    export default {
        name: "CommentReplyCenter",
        components: {ReplyMain, CommentReplyInput},
        props: ["comments", 'customer'],
        methods: {
            cancelMessage: function() {
                this.control.add.id = -1;
            },
            addCancelReply(comId) {
                if (this.control.add.type === 1 && this.control.add.id === comId) {
                    this.control.add.type = -1;
                    this.control.add.id = -1;
                } else {
                    this.control.add.type = 1;
                    this.control.add.id = comId;
                }
            },
            commentHandleCurrentChange(val) {
                this.control.com.page = val;
                this.control.type = -1;
                this.control.id = -1;
                let artHeight = document.getElementsByClassName('article-main')[0].offsetHeight;
                let otherHeight = 70 + 15;
                let scrollHeight = artHeight + otherHeight;
                window.scrollTo(0, scrollHeight);
            },
            date: function (time) {
                return transUTCtoLocal(time);
            },
            /**
             * 发表评论对文章
             *
             * @param message
             */
            addComment: function (message) {
                // let comment = new FormData();
                // comment.append('comContent', message);
                // comment.append('comCustomerId', this.customer.cusId);
                // comment.append('comArticleId', this.comments[0].comArticleId);

                let comment = {
                    comContent: message,
                    comCusId: this.customer.cusId,
                    comArtId: this.comments[0].comArtId,
                };
                addNewCom(comment)
                    .then((response) => {
                        if(response.data) {
                            this.$message.info("评论成功");
                            this.$emit('quickShow');
                            this.control.com.page = 1;
                        } else {
                            this.$message.info("评论失败");
                        }
                    })
            },

            /**
             * 添加回复
             *
             * @param message
             */
            addReply: function (message) {
                // let reply = new FormData();
                // reply.append('repContent', message);
                // reply.append('repType', 0);
                // reply.append('repCustomerId', this.customer.cusId);
                // reply.append('repArticleId', this.comments[0].comArticleId);
                // reply.append('repCommentId', this.control.add.id);
                let reply = {
                    repContent: message,
                    repType: 0,
                    repCusId: this.customer.cusId,
                    repArtId: this.comments[0].comArtId,
                    // 回复针对的评论的 id
                    repComId: this.control.add.id,
                };
                cusAddReply(reply)
                    .then((response) => {
                        if (response.data) {
                            this.$message.info("回复成功");
                            this.$emit('quickShow');
                            // todo 这个地方要重新计算一遍位置
                        } else {
                            this.$message.info("回复失败");
                        }
                    });
                this.control.add.type = -1;
                this.control.add.id = -1;
            },
            jumpToCus: function (cusId) {
                jumpInNewPage('/self/' + cusId);
            }
        },
        data: function() {
            return {
                control: {
                    com: {
                        page: 1,
                        pageSize: 8,
                    },
                    add: {
                        type: -1,
                        id: -1,
                    }
                }
            }
        },

    }
</script>

<style scoped>
    .comments {
        margin-bottom: 10px;
    }

    .reply-main {
        margin-left: 10%;
        margin-bottom: 5px;
    }

    .avatar {
        float: left;
        margin-right: 3%;
        width: 7%;
    }

    .avatar img{
        width: 100%;
    }

    .comment {
        float: left;
        width: 90%;
    }

    .name {
        font-size: 20px;
        font-weight: 600;
        text-align: left;
        margin-bottom: 5px;
        float: left;
    }

    .reply {
        float: left;
    }

    .content {
        font-size: 16px;
        line-height: 20px;
        text-align: left;
        word-wrap: break-word;
    }

    .info {
        font-size: 14px;
        color: #888888;
        text-align: left;
    }

    .info span {
        margin-right: 10px;
    }

    .content >>> p {
        margin: 0;
    }

    .page-switcher {
        float: left;
        padding-bottom: 50px;
    }
</style>

================================================
FILE: front/src/components/article/RightMenu.vue
================================================
<template>
    <div>
        <editor-brief class="editor-brief" :articleAuthor="articleAuthor"></editor-brief>
        <edit-entrance class="edit-entrance"></edit-entrance>
        <hot-article :title="hotArticle.title" :hot-articles="hotArticle.hotArticles"></hot-article>
    </div>
</template>


<script>
    import EditEntrance from '../common/EditEntrance'
    import HotArticle from '../common/HotArticle'

    import Logo from '../../assets/image/Logo.png'
    import EditorBrief from "../common/EditorBrief";

    export default {
        name: 'RightMenu',
        components: {
            EditorBrief,
            EditEntrance, HotArticle
        },
        data: function () {
            return {
                hotArticle: {
                    title: '相关新闻',
                    hotArticles: [
                        { artId: '1', artTitle: 'This is the template title of news', artImage: Logo},
                        { artId: '2', artTitle: 'This is the template title of news', artImage: ''},
                        { artId: '3', artTitle: 'This is the template title of news', artImage: ''},
                        { artId: '4', artTitle: 'This is the template title of news', artImage: Logo},
                        { artId: '5', artTitle: 'This is the template title of news', artImage: Logo},
                        { artId: '6', artTitle: 'This is the template title of news', artImage: Logo},
                    ]
                },
                articleAuthor: {
                    cusId: 6,
                    cusName: '中国新闻网',
                    cusAvatarUrl: 'https://p3.pstatp.com/large/97d001bf3f3cba72913',
                },
            }
        }
    }
</script>

<style scoped>
    .editor-brief, .edit-entrance {
        margin-bottom: 10px;
    }
</style>

================================================
FILE: front/src/components/article/TopBar.vue
================================================
<template>
    <div class="clear-float">
        <div class="body-image" v-on:click="jumpToIndex">
            <img src="@/assets/image/Logo.png"/>
        </div>
        <search-panel :tip="tip"  v-on:search="searchArticles"></search-panel>
        <div class="manage">
            <img v-if="customer.cusAvatarUrl !== ''" :src="customer.cusAvatarUrl" v-on:click="jumpToSelf"/>
            <img v-if="customer.cusAvatarUrl === ''" :src="manSrc" v-on:click="jumpToSelf"/>
            <el-button type="text" @click="loginOut">退出登录</el-button>
        </div>
    </div>
</template>

<script>
    import SearchPanel from '../common/SearchPanel'
    import Man from '../../assets/image/Man.png'
    import {jumpInCurPage, jumpInNewPage} from "../../util/PageJump";
    import {quitLogin} from "../../control/Self";

    export default {
        name: 'TopBar',
        props: ['message', 'customer'],
        components: {SearchPanel},
        methods: {
            jumpToIndex: function() {
                jumpInCurPage('/index/');
            },
            jumpToSelf: function() {
                jumpInNewPage('/self/' + this.customer.cusId)
            },
            searchArticles: function (message) {
                jumpInNewPage('/search/' + message )
                // searchContentByKeyAndTagTypePage(message, 'global', 'test', 0, 10)
            },
            loginOut: function () {
                quitLogin()
                    .then((response) => {
                        if (response.data === '退出成功') {
                            this.$router.push({path: '/port'});
                        }
                    })
            }
        },
        data: function() {
            return {
                tip: '搜索',
                manSrc: Man,
            }
        }
    }
</script>

<style scoped>


    .body-image {
        float: left;
        height: 40px;
        margin-top: 5px;
    }

    .body-image img {
        height: 30px;
        width: 130px;
    }

    .manage {
        float: right;
        height: 40px;
        padding-top: 5px;
    }

    .manage >>> .el-button {
        font-size: 16px;
        height: 40px;
        float: right;
    }

    .manage img {
        width: 30px;
        height: 30px;
        /*padding: 5px 10px;*/
        margin-right: 5px;
    }

</style>


================================================
FILE: front/src/components/article/comment-reply-main/CommentReplyInput.vue
================================================
<template>
    <div class="comment-reply-input">
        <div class="avatar">
            <img :src="customer.cusAvatarUrl" style="width: 100%"/>
        </div>
        <div style="width: 90%">
            <div ref="toolbar" class="toolbar">
                <div style="position: absolute; display: inherit; right: 0px; width: 120px;">
                    <el-button class="cancel" type="primary" @click="cancel">取消</el-button>
                    <el-button type="primary" @click="showMessage"
                               style="padding: 5px; width: 70px">发表</el-button>
                </div>
            </div>
            <div ref="textplace" class="textplace" :style="{height: height}" @click="changeHeight"></div>
        </div>
    </div>
</template>

<script>
    import WangEditor from 'wangeditor'
    // import Man from '../../../assets/image/Man.png'
    // import Man from '@/assets/image/Man.png'

    export default {
        name: "CommentReplyInput",
        props: ['heightKey', 'customer'],
        data: function() {
            return {
                height: '70px',

                DEFAULT_HEIGHT: '70px',
                EDIT_HEIGHT: '210px',

                menus: [
                    'source', 'bold', 'underline', 'italic', 'emotion', 'undo', 'redo', 'fullscreen', 'emoticon',
                ],
                editor: null,
                message: 'message',
                // manSrc: Man,
            }
        },
        mounted() {
            let editor = new WangEditor(this.$refs.toolbar, this.$refs.textplace);
            this.editor = editor;
            editor.customConfig.onchange = (html) => {
                this.message = html;
            };
            editor.customConfig.menus = this.menus;
            editor.create();
        },
        methods: {
            /**
             * 向上级组件返回用户输入的内容
             */
            showMessage() {
                // alert(this.message);
                this.$emit('messageHandler', this.message);
                this.editor.txt.clear();
            },
            changeHeight() {
                if (this.heightKey) {
                    this.height = this.EDIT_HEIGHT;
                }
            },
            cancel() {
                if (this.heightKey) {
                    this.height = this.DEFAULT_HEIGHT;
                    this.editor.txt.clear();
                } else {
                    this.editor.txt.clear();
                    this.$emit('readycancel');
                }

            }
        }
    }
</script>

<style scoped>
    .comment-reply-input {
        display: flex;
        width: 100%;
    }

    .avatar {
        width: 7%;
        margin-right: 3%;
    }

    .toolbar {
        height: 30px;
        border: 0px solid #f1f1f1;
        background-color:#f1f1f1;
        position: relative;
    }

    .toolbar .el-button {
        line-height: 20px;
    }

    .toolbar .el-button--primary {
        border: none;
        border-radius: 0px;
        margin: 0px;
    }

    /* 取消按钮 */
    .toolbar .el-button.cancel.el-button--primary {
        padding: 5px;
        width: 50px;
        background-color: #888888;
    }

    /* 取消按钮 */
    .toolbar .el-button.cancel.el-button--primary:hover {
 
Download .txt
gitextract_jxucev3e/

├── .gitattributes
├── .gitignore
├── LICENSE
├── NewsRecommend.sql
├── README.md
├── back/
│   ├── .gitignore
│   ├── .mvn/
│   │   └── wrapper/
│   │       ├── MavenWrapperDownloader.java
│   │       ├── maven-wrapper.jar
│   │       └── maven-wrapper.properties
│   ├── mvnw
│   ├── mvnw.cmd
│   ├── pom.xml
│   └── src/
│       ├── main/
│       │   ├── .DS_Store
│       │   ├── java/
│       │   │   └── com/
│       │   │       └── smacul/
│       │   │           └── demo/
│       │   │               ├── DemoApplication.java
│       │   │               ├── bean/
│       │   │               │   ├── ArtFeatureCount.java
│       │   │               │   ├── ArtScoreList.java
│       │   │               │   ├── ArtTimeList.java
│       │   │               │   ├── Article.java
│       │   │               │   ├── Comment.java
│       │   │               │   ├── CusBehaviorRecord.java
│       │   │               │   ├── CusFeatureCount.java
│       │   │               │   ├── Customer.java
│       │   │               │   └── Reply.java
│       │   │               ├── controller/
│       │   │               │   ├── DiscussController.java
│       │   │               │   ├── EditController.java
│       │   │               │   ├── LoadController.java
│       │   │               │   ├── SearchController.java
│       │   │               │   └── SelfController.java
│       │   │               ├── dao/
│       │   │               │   ├── ArtDao.java
│       │   │               │   ├── ArtFeatureCountDao.java
│       │   │               │   ├── ArtScoreListDao.java
│       │   │               │   ├── ArtTimeList.java
│       │   │               │   ├── ComDao.java
│       │   │               │   ├── CusBehaviorRecordDao.java
│       │   │               │   ├── CusDao.java
│       │   │               │   ├── CusFeatureCountDao.java
│       │   │               │   ├── CusRecommendRecordDao.java
│       │   │               │   └── RepDao.java
│       │   │               ├── model/
│       │   │               │   ├── ArtFullMod.java
│       │   │               │   ├── ComFullMod.java
│       │   │               │   ├── CusArtBehaviorMod.java
│       │   │               │   ├── CusDynamicMod.java
│       │   │               │   ├── CusFeatureFullMod.java
│       │   │               │   └── RepFullMod.java
│       │   │               ├── service/
│       │   │               │   ├── .DS_Store
│       │   │               │   ├── DiscussService.java
│       │   │               │   ├── EditService.java
│       │   │               │   ├── LoadService.java
│       │   │               │   ├── SearchService.java
│       │   │               │   ├── SelfService.java
│       │   │               │   ├── SessionService.java
│       │   │               │   ├── ShapeService.java
│       │   │               │   └── impl/
│       │   │               │       ├── .DS_Store
│       │   │               │       ├── DiscussServiceImpl.java
│       │   │               │       ├── EditServiceImpl.java
│       │   │               │       ├── LoadServiceImpl.java
│       │   │               │       ├── SearchServiceImpl.java
│       │   │               │       ├── SelfServiceImpl.java
│       │   │               │       ├── SessionServiceImpl.java
│       │   │               │       └── ShapeServiceImpl.java
│       │   │               └── util/
│       │   │                   ├── MD5.java
│       │   │                   ├── PageHandler.java
│       │   │                   └── TypeHandler.java
│       │   └── resources/
│       │       ├── .DS_Store
│       │       ├── mapper/
│       │       │   ├── .DS_Store
│       │       │   ├── ArtFeatureCountMap.xml
│       │       │   ├── ArtMap.xml
│       │       │   ├── ArtScoreListMap.xml
│       │       │   ├── ArtTimeListMap.xml
│       │       │   ├── ComMap.xml
│       │       │   ├── CusBehaviorRecordMap.xml
│       │       │   ├── CusFeatureCountMap.xml
│       │       │   ├── CusMap.xml
│       │       │   ├── CusRecommendRecordDao.xml
│       │       │   └── RepMap.xml
│       │       ├── static/
│       │       │   └── .DS_Store
│       │       └── templates/
│       │           └── application.properties.template
│       └── test/
│           └── java/
│               └── com/
│                   └── smacul/
│                       └── demo/
│                           └── DemoApplicationTests.java
├── front/
│   ├── .gitignore
│   ├── README.md
│   ├── babel.config.js
│   ├── package.json
│   ├── public/
│   │   └── index.html
│   ├── src/
│   │   ├── App.vue
│   │   ├── assets/
│   │   │   └── css/
│   │   │       ├── Narrow.css
│   │   │       └── Normal.css
│   │   ├── components/
│   │   │   ├── HelloWorld.vue
│   │   │   ├── app/
│   │   │   │   └── HelloWorld.vue
│   │   │   ├── article/
│   │   │   │   ├── ArticleCenter.vue
│   │   │   │   ├── CommentReplyCenter.vue
│   │   │   │   ├── RightMenu.vue
│   │   │   │   ├── TopBar.vue
│   │   │   │   └── comment-reply-main/
│   │   │   │       ├── CommentReplyInput.vue
│   │   │   │       └── ReplyMain.vue
│   │   │   ├── common/
│   │   │   │   ├── DarkCard.vue
│   │   │   │   ├── EditEntrance.vue
│   │   │   │   ├── EditorBrief.vue
│   │   │   │   ├── FloatCard.vue
│   │   │   │   ├── HotArticle.vue
│   │   │   │   ├── SearchPanel.vue
│   │   │   │   └── TinyArticle.vue
│   │   │   ├── edit/
│   │   │   │   └── TopBar.vue
│   │   │   ├── index/
│   │   │   │   ├── LeftMenu.vue
│   │   │   │   └── TopBar.vue
│   │   │   ├── port/
│   │   │   │   ├── LoginPart.vue
│   │   │   │   └── RegisterPart.vue
│   │   │   ├── search/
│   │   │   │   ├── RightMenu.vue
│   │   │   │   ├── TinyCenter.vue
│   │   │   │   └── TopBar.vue
│   │   │   └── self/
│   │   │       ├── EditorMain.vue
│   │   │       ├── RightMenu.vue
│   │   │       ├── TinyCenter.vue
│   │   │       └── TopBar.vue
│   │   ├── control/
│   │   │   ├── Discuss.js
│   │   │   ├── Edit.js
│   │   │   ├── Load.js
│   │   │   ├── Search.js
│   │   │   └── Self.js
│   │   ├── main.js
│   │   ├── plugins/
│   │   │   └── axios.js
│   │   ├── router/
│   │   │   └── index.js
│   │   ├── styles.scss
│   │   ├── util/
│   │   │   ├── PageJump.js
│   │   │   └── TimeHandler.js
│   │   └── views/
│   │       ├── About.vue
│   │       ├── ArticleView.vue
│   │       ├── EditView.vue
│   │       ├── Home.vue
│   │       ├── IndexView.vue
│   │       ├── PortView.vue
│   │       ├── SearchView.vue
│   │       └── SelfView.vue
│   └── vue.config.js
└── spider/
    ├── Main.py
    ├── dao/
    │   ├── ArticleDao.py
    │   ├── CommentDao.py
    │   ├── CustomerDao.py
    │   ├── ReplyDao.py
    │   └── __init__.py
    ├── model/
    │   ├── ArticleModel.py
    │   ├── CommentModel.py
    │   ├── CustomerModel.py
    │   ├── ReplyModel.py
    │   └── __init__.py
    ├── process/
    │   ├── ArticleProcess.py
    │   ├── CommentProcess.py
    │   ├── CustomerProcess.py
    │   ├── ReplyProcess.py
    │   └── __init__.py
    └── util/
        ├── Driver.py
        ├── Json.py
        ├── Md5.py
        ├── MySql.py
        ├── Request.py
        ├── Time.py
        └── __init__.py
Download .txt
SYMBOL INDEX (598 symbols across 78 files)

FILE: NewsRecommend.sql
  type NR (line 7) | CREATE TABLE NR.Customer (
  type NR (line 43) | CREATE TABLE NR.Article (
  type NR (line 75) | CREATE TABLE NR.Comment (
  type NR (line 102) | CREATE TABLE NR.Reply (
  type NR (line 135) | CREATE TABLE NR.Administrator (
  type NR (line 170) | CREATE TABLE NR.CusBehaviorRecord (
  type NR (line 195) | CREATE TABLE NR.ArtFeatureCount (
  type NR (line 213) | CREATE TABLE NR.CusFeatureCount (
  type NR (line 243) | CREATE TABLE NR.CusRecommendRecord (
  type NR (line 257) | create view NR.ArtScoreList(asl_art_id, asl_art_score) as
  type NR (line 266) | create view NR.ArtTimeList(atl_art_id, atl_art_score) as

FILE: back/.mvn/wrapper/MavenWrapperDownloader.java
  class MavenWrapperDownloader (line 22) | public class MavenWrapperDownloader {
    method main (line 49) | public static void main(String args[]) {
    method downloadFileFromURL (line 98) | private static void downloadFileFromURL(String urlString, File destina...

FILE: back/src/main/java/com/smacul/demo/DemoApplication.java
  class DemoApplication (line 9) | @EnableTransactionManagement
    method main (line 14) | public static void main(String[] args) {

FILE: back/src/main/java/com/smacul/demo/bean/ArtFeatureCount.java
  class ArtFeatureCount (line 3) | public class ArtFeatureCount {
    method getAfcId (line 15) | public Integer getAfcId() {
    method setAfcId (line 19) | public void setAfcId(Integer afcId) {
    method getAfcArtId (line 23) | public Integer getAfcArtId() {
    method setAfcArtId (line 27) | public void setAfcArtId(Integer afcArtId) {
    method getAfcLikeNum (line 31) | public Integer getAfcLikeNum() {
    method setAfcLikeNum (line 35) | public void setAfcLikeNum(Integer afcLikeNum) {
    method getAfcDislikeNum (line 39) | public Integer getAfcDislikeNum() {
    method setAfcDislikeNum (line 43) | public void setAfcDislikeNum(Integer afcDislikeNum) {
    method getAfcComNum (line 47) | public Integer getAfcComNum() {
    method setAfcComNum (line 51) | public void setAfcComNum(Integer afcComNum) {
    method getAfcRepNum (line 55) | public Integer getAfcRepNum() {
    method setAfcRepNum (line 59) | public void setAfcRepNum(Integer afcRepNum) {
    method getAfcReadNum (line 63) | public Integer getAfcReadNum() {
    method setAfcReadNum (line 67) | public void setAfcReadNum(Integer afcReadNum) {
    method getAfcArtTime (line 71) | public Integer getAfcArtTime() {
    method setAfcArtTime (line 75) | public void setAfcArtTime(Integer afcArtTime) {

FILE: back/src/main/java/com/smacul/demo/bean/ArtScoreList.java
  class ArtScoreList (line 3) | public class ArtScoreList {
    method getAslArtId (line 8) | public Integer getAslArtId() {
    method setAslArtId (line 12) | public void setAslArtId(Integer aslArtId) {
    method getAslArtScore (line 16) | public Integer getAslArtScore() {
    method setAslArtScore (line 20) | public void setAslArtScore(Integer aslArtScore) {

FILE: back/src/main/java/com/smacul/demo/bean/ArtTimeList.java
  class ArtTimeList (line 3) | public class ArtTimeList {
    method getAtlId (line 8) | public Integer getAtlId() {
    method setAtlId (line 12) | public void setAtlId(Integer atlId) {
    method getAtlArtScore (line 16) | public Integer getAtlArtScore() {
    method setAtlArtScore (line 20) | public void setAtlArtScore(Integer atlArtScore) {

FILE: back/src/main/java/com/smacul/demo/bean/Article.java
  class Article (line 5) | public class Article {
    method getArtId (line 19) | public Integer getArtId() {
    method setArtId (line 23) | public void setArtId(Integer artId) {
    method getArtTitle (line 27) | public String getArtTitle() {
    method setArtTitle (line 31) | public void setArtTitle(String artTitle) {
    method getArtContent (line 35) | public String getArtContent() {
    method setArtContent (line 39) | public void setArtContent(String artContent) {
    method getArtSpider (line 43) | public String getArtSpider() {
    method setArtSpider (line 47) | public void setArtSpider(String artSpider) {
    method getArtType (line 51) | public String getArtType() {
    method setArtType (line 55) | public void setArtType(String artType) {
    method getArtTags (line 59) | public String getArtTags() {
    method setArtTags (line 63) | public void setArtTags(String artTags) {
    method getArtImageUrl (line 67) | public String getArtImageUrl() {
    method setArtImageUrl (line 71) | public void setArtImageUrl(String artImageUrl) {
    method getArtTime (line 75) | public Timestamp getArtTime() {
    method setArtTime (line 79) | public void setArtTime(Timestamp artTime) {
    method getArtLegal (line 83) | public Integer getArtLegal() {
    method setArtLegal (line 87) | public void setArtLegal(Integer artLegal) {
    method getArtCusId (line 91) | public Integer getArtCusId() {
    method setArtCusId (line 95) | public void setArtCusId(Integer artCusId) {

FILE: back/src/main/java/com/smacul/demo/bean/Comment.java
  class Comment (line 5) | public class Comment {
    method getComId (line 16) | public Integer getComId() {
    method setComId (line 20) | public void setComId(Integer comId) {
    method getComContent (line 24) | public String getComContent() {
    method setComContent (line 28) | public void setComContent(String comContent) {
    method getComTime (line 32) | public Timestamp getComTime() {
    method setComTime (line 36) | public void setComTime(Timestamp comTime) {
    method getComLegal (line 40) | public Integer getComLegal() {
    method setComLegal (line 44) | public void setComLegal(Integer comLegal) {
    method getComSpider (line 48) | public String getComSpider() {
    method setComSpider (line 52) | public void setComSpider(String comSpider) {
    method getComCusId (line 56) | public Integer getComCusId() {
    method setComCusId (line 60) | public void setComCusId(Integer comCusId) {
    method getComArtId (line 64) | public Integer getComArtId() {
    method setComArtId (line 68) | public void setComArtId(Integer comArtId) {

FILE: back/src/main/java/com/smacul/demo/bean/CusBehaviorRecord.java
  class CusBehaviorRecord (line 5) | public class CusBehaviorRecord {
    method getCbrId (line 18) | public Integer getCbrId() {
    method setCbrId (line 22) | public void setCbrId(Integer cbrId) {
    method getCbrCusIdFrom (line 26) | public Integer getCbrCusIdFrom() {
    method setCbrCusIdFrom (line 30) | public void setCbrCusIdFrom(Integer cbrCusIdFrom) {
    method getCbrCusIdTo (line 34) | public Integer getCbrCusIdTo() {
    method setCbrCusIdTo (line 38) | public void setCbrCusIdTo(Integer cbrCusIdTo) {
    method getCbrBehavior (line 42) | public Integer getCbrBehavior() {
    method setCbrBehavior (line 46) | public void setCbrBehavior(Integer cbrBehavior) {
    method getCbrTime (line 50) | public Timestamp getCbrTime() {
    method setCbrTime (line 54) | public void setCbrTime(Timestamp cbrTime) {
    method getCbrArtId (line 58) | public Integer getCbrArtId() {
    method setCbrArtId (line 62) | public void setCbrArtId(Integer cbrArtId) {
    method getCbrType (line 66) | public Integer getCbrType() {
    method setCbrType (line 70) | public void setCbrType(Integer cbrType) {
    method getCbrTargetId (line 74) | public Integer getCbrTargetId() {
    method setCbrTargetId (line 78) | public void setCbrTargetId(Integer cbrTargetId) {

FILE: back/src/main/java/com/smacul/demo/bean/CusFeatureCount.java
  class CusFeatureCount (line 3) | public class CusFeatureCount {
    method getCfcId (line 31) | public Integer getCfcId() {
    method setCfcId (line 35) | public void setCfcId(Integer cfcId) {
    method getCfcCusId (line 39) | public Integer getCfcCusId() {
    method setCfcCusId (line 43) | public void setCfcCusId(Integer cfcCusId) {
    method getCfcNewsSociety (line 47) | public Integer getCfcNewsSociety() {
    method setCfcNewsSociety (line 51) | public void setCfcNewsSociety(Integer cfcNewsSociety) {
    method getCfcNewsEntertainment (line 55) | public Integer getCfcNewsEntertainment() {
    method setCfcNewsEntertainment (line 59) | public void setCfcNewsEntertainment(Integer cfcNewsEntertainment) {
    method getCfcNewsTech (line 63) | public Integer getCfcNewsTech() {
    method setCfcNewsTech (line 67) | public void setCfcNewsTech(Integer cfcNewsTech) {
    method getCfcNewsMilitary (line 71) | public Integer getCfcNewsMilitary() {
    method setCfcNewsMilitary (line 75) | public void setCfcNewsMilitary(Integer cfcNewsMilitary) {
    method getCfcNewsSports (line 79) | public Integer getCfcNewsSports() {
    method setCfcNewsSports (line 83) | public void setCfcNewsSports(Integer cfcNewsSports) {
    method getCfcNewsFinance (line 87) | public Integer getCfcNewsFinance() {
    method setCfcNewsFinance (line 91) | public void setCfcNewsFinance(Integer cfcNewsFinance) {
    method getCfcNewsWorld (line 95) | public Integer getCfcNewsWorld() {
    method setCfcNewsWorld (line 99) | public void setCfcNewsWorld(Integer cfcNewsWorld) {
    method getCfcNewsFashion (line 103) | public Integer getCfcNewsFashion() {
    method setCfcNewsFashion (line 107) | public void setCfcNewsFashion(Integer cfcNewsFashion) {
    method getCfcNewsTravel (line 111) | public Integer getCfcNewsTravel() {
    method setCfcNewsTravel (line 115) | public void setCfcNewsTravel(Integer cfcNewsTravel) {
    method getCfcNewsDiscovery (line 119) | public Integer getCfcNewsDiscovery() {
    method setCfcNewsDiscovery (line 123) | public void setCfcNewsDiscovery(Integer cfcNewsDiscovery) {
    method getCfcNewsBaby (line 127) | public Integer getCfcNewsBaby() {
    method setCfcNewsBaby (line 131) | public void setCfcNewsBaby(Integer cfcNewsBaby) {
    method getCfcNewsRegimen (line 135) | public Integer getCfcNewsRegimen() {
    method setCfcNewsRegimen (line 139) | public void setCfcNewsRegimen(Integer cfcNewsRegimen) {
    method getCfcNewsStory (line 143) | public Integer getCfcNewsStory() {
    method setCfcNewsStory (line 147) | public void setCfcNewsStory(Integer cfcNewsStory) {
    method getCfcNewsEssay (line 151) | public Integer getCfcNewsEssay() {
    method setCfcNewsEssay (line 155) | public void setCfcNewsEssay(Integer cfcNewsEssay) {
    method getCfcNewsGame (line 159) | public Integer getCfcNewsGame() {
    method setCfcNewsGame (line 163) | public void setCfcNewsGame(Integer cfcNewsGame) {
    method getCfcNewsHistory (line 167) | public Integer getCfcNewsHistory() {
    method setCfcNewsHistory (line 171) | public void setCfcNewsHistory(Integer cfcNewsHistory) {
    method getCfcNewsFood (line 175) | public Integer getCfcNewsFood() {
    method setCfcNewsFood (line 179) | public void setCfcNewsFood(Integer cfcNewsFood) {
    method getCfcNewsCar (line 183) | public Integer getCfcNewsCar() {
    method setCfcNewsCar (line 187) | public void setCfcNewsCar(Integer cfcNewsCar) {

FILE: back/src/main/java/com/smacul/demo/bean/Customer.java
  class Customer (line 6) | public class Customer {
    method getCusId (line 19) | public Integer getCusId() {
    method setCusId (line 23) | public void setCusId(Integer cusId) {
    method getCusName (line 27) | public String getCusName() {
    method setCusName (line 31) | public void setCusName(String cusName) {
    method getCusPass (line 35) | public String getCusPass() {
    method setCusPass (line 39) | public void setCusPass(String cusPass) {
    method getCusSpider (line 43) | public String getCusSpider() {
    method setCusSpider (line 47) | public void setCusSpider(String cusSpider) {
    method getCusAvatarUrl (line 51) | public String getCusAvatarUrl() {
    method setCusAvatarUrl (line 55) | public void setCusAvatarUrl(String cusAvatarUrl) {
    method getCusStyle (line 59) | public String getCusStyle() {
    method setCusStyle (line 63) | public void setCusStyle(String cusStyle) {
    method getCusGender (line 67) | public Integer getCusGender() {
    method setCusGender (line 71) | public void setCusGender(Integer cusGender) {
    method getCusTime (line 75) | public Timestamp getCusTime() {
    method setCusTime (line 79) | public void setCusTime(Timestamp cusTime) {
    method getCusLegal (line 83) | public Integer getCusLegal() {
    method setCusLegal (line 87) | public void setCusLegal(Integer cusLegal) {

FILE: back/src/main/java/com/smacul/demo/bean/Reply.java
  class Reply (line 5) | public class Reply {
    method getRepId (line 20) | public Integer getRepId() {
    method setRepId (line 24) | public void setRepId(Integer repId) {
    method getRepContent (line 28) | public String getRepContent() {
    method setRepContent (line 32) | public void setRepContent(String repContent) {
    method getRepType (line 36) | public Integer getRepType() {
    method setRepType (line 40) | public void setRepType(Integer repType) {
    method getRepTime (line 44) | public Timestamp getRepTime() {
    method setRepTime (line 48) | public void setRepTime(Timestamp repTime) {
    method getRepLegal (line 52) | public Integer getRepLegal() {
    method setRepLegal (line 56) | public void setRepLegal(Integer repLegal) {
    method getRepSpider (line 60) | public String getRepSpider() {
    method setRepSpider (line 64) | public void setRepSpider(String repSpider) {
    method getRepCusId (line 68) | public Integer getRepCusId() {
    method setRepCusId (line 72) | public void setRepCusId(Integer repCusId) {
    method getRepArtId (line 76) | public Integer getRepArtId() {
    method setRepArtId (line 80) | public void setRepArtId(Integer repArtId) {
    method getRepComId (line 84) | public Integer getRepComId() {
    method setRepComId (line 88) | public void setRepComId(Integer repComId) {
    method getRepRepId (line 92) | public Integer getRepRepId() {
    method setRepRepId (line 96) | public void setRepRepId(Integer repRepId) {

FILE: back/src/main/java/com/smacul/demo/controller/DiscussController.java
  class DiscussController (line 18) | @RestController
    method getComList (line 35) | @RequestMapping("/page")
    method addNewCom (line 51) | @RequestMapping("/com")
    method addNewRep (line 71) | @RequestMapping("/rep")

FILE: back/src/main/java/com/smacul/demo/controller/EditController.java
  class EditController (line 14) | @RestController
    method addNewArt (line 31) | @RequestMapping("/add")

FILE: back/src/main/java/com/smacul/demo/controller/LoadController.java
  class LoadController (line 19) | @RestController
    method getArtTypes (line 37) | @RequestMapping("/type")
    method getTinyArtOnePageByType (line 62) | @RequestMapping("/tiny")
    method getHotArtOnePage (line 119) | @RequestMapping("/hot")
    method getFullArt (line 134) | @RequestMapping("/main")
    method setArtPreference (line 152) | @RequestMapping("/prefer")

FILE: back/src/main/java/com/smacul/demo/controller/SearchController.java
  class SearchController (line 15) | @RestController
    method searchContentSimple (line 26) | @RequestMapping("/simple")

FILE: back/src/main/java/com/smacul/demo/controller/SelfController.java
  class SelfController (line 23) | @RestController
    method cusLogin (line 42) | @RequestMapping("/login")
    method quitLogin (line 68) | @RequestMapping("/quit")
    method cusRegister (line 82) | @RequestMapping("/register")
    method getCusBasicInfo (line 99) | @RequestMapping("/basic")
    method setCusBasicInfo (line 117) | @RequestMapping("/modify")
    method setCusFollow (line 141) | @RequestMapping("/follow")
    method getCusFeatureInfo (line 165) | @RequestMapping("/feature")
    method getCusDynamic (line 178) | @RequestMapping("/dynamic")
    method checkCusFollow (line 193) | @RequestMapping("/chefollow")

FILE: back/src/main/java/com/smacul/demo/dao/ArtDao.java
  type ArtDao (line 10) | @Repository
    method getArtTypesOrderByTypeNum (line 18) | List<String> getArtTypesOrderByTypeNum();
    method getTinyArtOnePageFromGlobalNew (line 31) | @Deprecated
    method getTinyArtOnePageByTypeNew (line 46) | List<ArtFullMod> getTinyArtOnePageByTypeNew(String artType, Integer cu...
    method getHotArtOnePage (line 57) | List<ArtFullMod> getHotArtOnePage(Integer start, Integer pageSize);
    method getArtFull (line 65) | ArtFullMod getArtFull(Integer artId);
    method getArtCusIdByArtId (line 73) | Integer getArtCusIdByArtId(Integer artId);
    method getArtTypeByArtId (line 81) | String getArtTypeByArtId(Integer artId);
    method searchContentSimple (line 93) | List<ArtFullMod> searchContentSimple(String key, Integer start, Intege...
    method getSingleArt (line 102) | ArtFullMod getSingleArt(Integer flag, Integer artId);
    method getTinyArtOnePageFromGlobalOld (line 113) | List<ArtFullMod> getTinyArtOnePageFromGlobalOld
    method getTinyArtOnePageByTypeOld (line 126) | List<ArtFullMod> getTinyArtOnePageByTypeOld
    method addArt (line 136) | Integer addArt(Article article);
    method getTinyNewArtFromGlobalForNew (line 147) | List<ArtFullMod> getTinyNewArtFromGlobalForNew(Integer cusId, Integer ...
    method getTinyHotArtFromGlobalForNew (line 158) | List<ArtFullMod> getTinyHotArtFromGlobalForNew(Integer cusId, Integer ...
    method getTinyInfoArtFromGlobalForNew (line 169) | List<ArtFullMod> getTinyInfoArtFromGlobalForNew(Integer cusId, Integer...
    method getTinyNewArtByTypeForNew (line 181) | List<ArtFullMod> getTinyNewArtByTypeForNew(String artType, Integer cus...
    method getTinyNewArtFromGlobalForOld (line 191) | List<ArtFullMod> getTinyNewArtFromGlobalForOld(Integer cusId, Integer ...
    method getTinyNewArtByTypeForOld (line 202) | List<ArtFullMod> getTinyNewArtByTypeForOld(String artType, Integer cus...

FILE: back/src/main/java/com/smacul/demo/dao/ArtFeatureCountDao.java
  type ArtFeatureCountDao (line 6) | @Repository
    method getArtFeatureCountByArtId (line 15) | ArtFeatureCount getArtFeatureCountByArtId(Integer artId);
    method updateArtFeature (line 26) | Integer updateArtFeature(Integer artId, String column, Integer num);

FILE: back/src/main/java/com/smacul/demo/dao/ArtScoreListDao.java
  type ArtScoreListDao (line 5) | @Repository

FILE: back/src/main/java/com/smacul/demo/dao/ArtTimeList.java
  type ArtTimeList (line 5) | @Repository

FILE: back/src/main/java/com/smacul/demo/dao/ComDao.java
  type ComDao (line 9) | @Repository
    method getComFullList (line 18) | List<ComFullMod> getComFullList(Integer artId);
    method addCom (line 27) | Integer addCom(Comment comment);
    method getSingleCom (line 36) | ComFullMod getSingleCom(Integer flag, Integer comId);

FILE: back/src/main/java/com/smacul/demo/dao/CusBehaviorRecordDao.java
  type CusBehaviorRecordDao (line 9) | @Repository
    method countTargetCusFollowBehavior (line 19) | Integer countTargetCusFollowBehavior(Integer cusIdFrom, Integer cusIdTo);
    method deleteTargetCusFollowBehavior (line 28) | Integer deleteTargetCusFollowBehavior(Integer cusIdFrom, Integer cusId...
    method addTargetCusFollowBehavior (line 37) | Integer addTargetCusFollowBehavior(Integer cusIdFrom, Integer cusIdTo);
    method countCusBehaviorFrom (line 46) | Integer countCusBehaviorFrom(Integer cusIdFrom, Integer behavior);
    method countCusBehaviorTo (line 55) | Integer countCusBehaviorTo(Integer cusIdTo, Integer behavior);
    method countTargetCusArtBehaviorFrom (line 66) | Integer countTargetCusArtBehaviorFrom(Integer cusIdFrom, Integer artId...
    method countTargetCusArtBehaviorTo (line 77) | Integer countTargetCusArtBehaviorTo(Integer cusIdTo, Integer artId, In...
    method addCusBehavior (line 91) | Integer addCusBehavior(
    method deleteCusBehavior (line 106) | Integer deleteCusBehavior(
    method getCusDynamicByCusId (line 118) | List<CusDynamicMod> getCusDynamicByCusId(Integer cusId, Integer start,...
    method getFollowCus (line 127) | List<Integer> getFollowCus(Integer cusId);

FILE: back/src/main/java/com/smacul/demo/dao/CusDao.java
  type CusDao (line 6) | @Repository
    method getCusByName (line 16) | Customer getCusByName(String cusName);
    method countCusByName (line 24) | Integer countCusByName(String cusName);
    method insertCusForRegister (line 34) | Integer insertCusForRegister(String cusName, String cusPass);
    method getCusById (line 42) | Customer getCusById(Integer cusId);
    method updateCusBasicInfo (line 50) | Integer updateCusBasicInfo(Customer customer);
    method updateCusBasicInfoWithPass (line 58) | Integer updateCusBasicInfoWithPass(Customer customer);

FILE: back/src/main/java/com/smacul/demo/dao/CusFeatureCountDao.java
  type CusFeatureCountDao (line 8) | @Repository
    method countBehaviorNum (line 17) | Integer countBehaviorNum(Integer cusId);
    method getCusFeatureCountByCusId (line 25) | CusFeatureCount getCusFeatureCountByCusId(Integer cusId);
    method getCusArtTypesBehaviorNums (line 33) | List<Integer> getCusArtTypesBehaviorNums(Integer cusId);
    method updateCusFeature (line 43) | Integer updateCusFeature(Integer cusId, String column, Integer num);
    method initialCusFeature (line 51) | Integer initialCusFeature(Integer cusId);
    method getRelativeCusList (line 60) | List<Integer> getRelativeCusList(Integer cusId, Integer num);

FILE: back/src/main/java/com/smacul/demo/dao/CusRecommendRecordDao.java
  type CusRecommendRecordDao (line 7) | @Repository
    method addRecommendList (line 17) | Integer addRecommendList(Integer cusId, List<Integer> list);
    method deleteOldCommentList (line 24) | void deleteOldCommentList(Integer cusId);

FILE: back/src/main/java/com/smacul/demo/dao/RepDao.java
  type RepDao (line 9) | @Repository
    method getRepFullList (line 19) | List<RepFullMod> getRepFullList(Integer comId);
    method addRep (line 28) | Integer addRep(Reply reply);
    method getSingleRep (line 37) | RepFullMod getSingleRep(Integer flag, Integer repId);

FILE: back/src/main/java/com/smacul/demo/model/ArtFullMod.java
  class ArtFullMod (line 8) | public class ArtFullMod {
    method getArtId (line 28) | public Integer getArtId() {
    method setArtId (line 32) | public void setArtId(Integer artId) {
    method getArtTitle (line 36) | public String getArtTitle() {
    method setArtTitle (line 40) | public void setArtTitle(String artTitle) {
    method getArtContent (line 44) | public String getArtContent() {
    method setArtContent (line 48) | public void setArtContent(String artContent) {
    method getArtSpider (line 52) | public String getArtSpider() {
    method setArtSpider (line 56) | public void setArtSpider(String artSpider) {
    method getArtType (line 60) | public String getArtType() {
    method setArtType (line 64) | public void setArtType(String artType) {
    method getArtTags (line 68) | public String getArtTags() {
    method setArtTags (line 72) | public void setArtTags(String artTags) {
    method getArtImageUrl (line 76) | public String getArtImageUrl() {
    method setArtImageUrl (line 80) | public void setArtImageUrl(String artImageUrl) {
    method getArtTime (line 84) | public Timestamp getArtTime() {
    method setArtTime (line 88) | public void setArtTime(Timestamp artTime) {
    method getArtLegal (line 92) | public Integer getArtLegal() {
    method setArtLegal (line 96) | public void setArtLegal(Integer artLegal) {
    method getArtCusId (line 100) | public Integer getArtCusId() {
    method setArtCusId (line 104) | public void setArtCusId(Integer artCusId) {
    method getCustomer (line 108) | public Customer getCustomer() {
    method setCustomer (line 112) | public void setCustomer(Customer customer) {
    method getArtFeature (line 116) | public ArtFeatureCount getArtFeature() {
    method setArtFeature (line 120) | public void setArtFeature(ArtFeatureCount artFeature) {
    method getCusArtBehavior (line 124) | public CusArtBehaviorMod getCusArtBehavior() {
    method setCusArtBehavior (line 128) | public void setCusArtBehavior(CusArtBehaviorMod cusArtBehavior) {

FILE: back/src/main/java/com/smacul/demo/model/ComFullMod.java
  class ComFullMod (line 9) | public class ComFullMod {
    method getComId (line 22) | public Integer getComId() {
    method setComId (line 26) | public void setComId(Integer comId) {
    method getComContent (line 30) | public String getComContent() {
    method setComContent (line 34) | public void setComContent(String comContent) {
    method getComTime (line 38) | public Timestamp getComTime() {
    method setComTime (line 42) | public void setComTime(Timestamp comTime) {
    method getComLegal (line 46) | public Integer getComLegal() {
    method setComLegal (line 50) | public void setComLegal(Integer comLegal) {
    method getComSpider (line 54) | public String getComSpider() {
    method setComSpider (line 58) | public void setComSpider(String comSpider) {
    method getComCusId (line 62) | public Integer getComCusId() {
    method setComCusId (line 66) | public void setComCusId(Integer comCusId) {
    method getComArtId (line 70) | public Integer getComArtId() {
    method setComArtId (line 74) | public void setComArtId(Integer comArtId) {
    method getCustomer (line 78) | public Customer getCustomer() {
    method setCustomer (line 82) | public void setCustomer(Customer customer) {
    method getReplys (line 86) | public List<RepFullMod> getReplys() {
    method setReplys (line 90) | public void setReplys(List<RepFullMod> replys) {

FILE: back/src/main/java/com/smacul/demo/model/CusArtBehaviorMod.java
  class CusArtBehaviorMod (line 3) | public class CusArtBehaviorMod {
    method getCusId (line 11) | public Integer getCusId() {
    method setCusId (line 15) | public void setCusId(Integer cusId) {
    method getArtId (line 19) | public Integer getArtId() {
    method setArtId (line 23) | public void setArtId(Integer artId) {
    method getPreference (line 27) | public Integer getPreference() {
    method setPreference (line 31) | public void setPreference(Integer preference) {
    method getFollow (line 35) | public Boolean getFollow() {
    method setFollow (line 39) | public void setFollow(Boolean follow) {
    method getRead (line 43) | public Boolean getRead() {
    method setRead (line 47) | public void setRead(Boolean read) {
    method getArtAuthor (line 51) | public Boolean getArtAuthor() {
    method setArtAuthor (line 55) | public void setArtAuthor(Boolean artAuthor) {

FILE: back/src/main/java/com/smacul/demo/model/CusDynamicMod.java
  class CusDynamicMod (line 7) | public class CusDynamicMod {
    method getCbrId (line 24) | public Integer getCbrId() {
    method setCbrId (line 28) | public void setCbrId(Integer cbrId) {
    method getCbrCusIdFrom (line 32) | public Integer getCbrCusIdFrom() {
    method setCbrCusIdFrom (line 36) | public void setCbrCusIdFrom(Integer cbrCusIdFrom) {
    method getCbrCusIdTo (line 40) | public Integer getCbrCusIdTo() {
    method setCbrCusIdTo (line 44) | public void setCbrCusIdTo(Integer cbrCusIdTo) {
    method getCbrBehavior (line 48) | public Integer getCbrBehavior() {
    method setCbrBehavior (line 52) | public void setCbrBehavior(Integer cbrBehavior) {
    method getCbrTime (line 56) | public Timestamp getCbrTime() {
    method setCbrTime (line 60) | public void setCbrTime(Timestamp cbrTime) {
    method getCbrType (line 64) | public Integer getCbrType() {
    method setCbrType (line 68) | public void setCbrType(Integer cbrType) {
    method getCusFrom (line 72) | public Customer getCusFrom() {
    method setCusFrom (line 76) | public void setCusFrom(Customer cusFrom) {
    method getCusTo (line 80) | public Customer getCusTo() {
    method setCusTo (line 84) | public void setCusTo(Customer cusTo) {
    method getArticle (line 88) | public ArtFullMod getArticle() {
    method setArticle (line 92) | public void setArticle(ArtFullMod article) {
    method getComment (line 96) | public ComFullMod getComment() {
    method setComment (line 100) | public void setComment(ComFullMod comment) {
    method getReply (line 104) | public RepFullMod getReply() {
    method setReply (line 108) | public void setReply(RepFullMod reply) {
    method getCbrArtId (line 112) | public Integer getCbrArtId() {
    method setCbrArtId (line 116) | public void setCbrArtId(Integer cbrArtId) {

FILE: back/src/main/java/com/smacul/demo/model/CusFeatureFullMod.java
  class CusFeatureFullMod (line 5) | public class CusFeatureFullMod {
    method getCusId (line 17) | public Integer getCusId() {
    method setCusId (line 21) | public void setCusId(Integer cusId) {
    method getReadNum (line 25) | public Integer getReadNum() {
    method setReadNum (line 29) | public void setReadNum(Integer readNum) {
    method getFanNum (line 33) | public Integer getFanNum() {
    method setFanNum (line 37) | public void setFanNum(Integer fanNum) {
    method getFollowNum (line 41) | public Integer getFollowNum() {
    method setFollowNum (line 45) | public void setFollowNum(Integer followNum) {
    method getArtEditNum (line 49) | public Integer getArtEditNum() {
    method setArtEditNum (line 53) | public void setArtEditNum(Integer artEditNum) {
    method getComEditNum (line 57) | public Integer getComEditNum() {
    method setComEditNum (line 61) | public void setComEditNum(Integer comEditNum) {
    method getRepEditNum (line 65) | public Integer getRepEditNum() {
    method setRepEditNum (line 69) | public void setRepEditNum(Integer repEditNum) {
    method getFeatureCount (line 73) | public CusFeatureCount getFeatureCount() {
    method setFeatureCount (line 77) | public void setFeatureCount(CusFeatureCount featureCount) {

FILE: back/src/main/java/com/smacul/demo/model/RepFullMod.java
  class RepFullMod (line 7) | public class RepFullMod {
    method getRepId (line 24) | public Integer getRepId() {
    method setRepId (line 28) | public void setRepId(Integer repId) {
    method getRepContent (line 32) | public String getRepContent() {
    method setRepContent (line 36) | public void setRepContent(String repContent) {
    method getRepType (line 40) | public Integer getRepType() {
    method setRepType (line 44) | public void setRepType(Integer repType) {
    method getRepTime (line 48) | public Timestamp getRepTime() {
    method setRepTime (line 52) | public void setRepTime(Timestamp repTime) {
    method getRepLegal (line 56) | public Integer getRepLegal() {
    method setRepLegal (line 60) | public void setRepLegal(Integer repLegal) {
    method getRepSpider (line 64) | public String getRepSpider() {
    method setRepSpider (line 68) | public void setRepSpider(String repSpider) {
    method getRepCusId (line 72) | public Integer getRepCusId() {
    method setRepCusId (line 76) | public void setRepCusId(Integer repCusId) {
    method getRepArtId (line 80) | public Integer getRepArtId() {
    method setRepArtId (line 84) | public void setRepArtId(Integer repArtId) {
    method getRepComId (line 88) | public Integer getRepComId() {
    method setRepComId (line 92) | public void setRepComId(Integer repComId) {
    method getRepRepId (line 96) | public Integer getRepRepId() {
    method setRepRepId (line 100) | public void setRepRepId(Integer repRepId) {
    method getCustomer (line 104) | public Customer getCustomer() {
    method setCustomer (line 108) | public void setCustomer(Customer customer) {

FILE: back/src/main/java/com/smacul/demo/service/DiscussService.java
  type DiscussService (line 10) | public interface DiscussService {
    method getComList (line 18) | List<ComFullMod> getComList(Integer artId);
    method addNewCom (line 26) | String addNewCom(Comment comment);
    method addNewRep (line 34) | String addNewRep(Reply reply);

FILE: back/src/main/java/com/smacul/demo/service/EditService.java
  type EditService (line 5) | public interface EditService {
    method addNewArt (line 14) | String addNewArt(Article article);

FILE: back/src/main/java/com/smacul/demo/service/LoadService.java
  type LoadService (line 7) | public interface LoadService {
    method getArtTypesForNew (line 14) | List<String> getArtTypesForNew();
    method getArtTypesForOld (line 22) | List<String> getArtTypesForOld(Integer cusId);
    method getTinyArtOnePageByTypeForNew (line 36) | List<ArtFullMod> getTinyArtOnePageByTypeForNew(Integer cusId, String a...
    method getTinyArtOnePageByTypeForOld (line 54) | List<ArtFullMod> getTinyArtOnePageByTypeForOld(
    method getHotArtOnePage (line 64) | List<ArtFullMod> getHotArtOnePage(Integer page, Integer pageSize);
    method getFullArt (line 74) | ArtFullMod getFullArt(Integer cusId, Integer artId);

FILE: back/src/main/java/com/smacul/demo/service/SearchService.java
  type SearchService (line 7) | public interface SearchService {
    method searchContentSimple (line 18) | List<ArtFullMod> searchContentSimple(String key, Integer page, Integer...

FILE: back/src/main/java/com/smacul/demo/service/SelfService.java
  type SelfService (line 10) | public interface SelfService {
    method checkIsNewUser (line 18) | Boolean checkIsNewUser(Integer cusId);
    method checkCusForLogin (line 28) | Customer checkCusForLogin(String cusName, String cusPass) throws NoSuc...
    method setNewCus (line 39) | String setNewCus(String cusName, String cusPass) throws NoSuchAlgorith...
    method getCusBasicInfo (line 47) | Customer getCusBasicInfo(Integer cusId);
    method setCusBasicInfo (line 56) | Boolean setCusBasicInfo(Customer customer) throws NoSuchAlgorithmExcep...
    method setCusFollow (line 66) | Boolean setCusFollow(Integer cusIdFrom, Integer cusIdTo);
    method getCusFeatureInfo (line 74) | CusFeatureFullMod getCusFeatureInfo(Integer cusId);
    method getCusDynamic (line 85) | List<CusDynamicMod> getCusDynamic(Integer cusId, Integer page, Integer...
    method checkCusFollow (line 94) | Boolean checkCusFollow(Integer cusIdFrom, Integer cusIdTo);
    method getRelativeCusList (line 107) | List<Integer> getRelativeCusList(Integer cusId, Integer num);

FILE: back/src/main/java/com/smacul/demo/service/SessionService.java
  type SessionService (line 10) | public interface SessionService {
    method setCusSession (line 12) | void setCusSession(Customer cus);
    method setRelSession (line 14) | void setRelSession(List<Integer> rel);
    method getCusSession (line 16) | Customer getCusSession();
    method getRelSession (line 18) | List<Integer> getRelSession();
    method getPagThenAddOne (line 20) | Integer getPagThenAddOne(String category);
    method getSetPagAfterCusChange (line 22) | Integer getSetPagAfterCusChange(String category);
    method initPagSession (line 24) | void initPagSession();

FILE: back/src/main/java/com/smacul/demo/service/ShapeService.java
  type ShapeService (line 8) | public interface ShapeService {
    method setCusBehaviorArtEdit (line 19) | Boolean setCusBehaviorArtEdit(Integer cusId, Integer artId);
    method setCusBehaviorArtRead (line 31) | Boolean setCusBehaviorArtRead(Integer cusId, Integer artId);
    method setCusBehaviorArtLike (line 43) | Boolean setCusBehaviorArtLike(Integer cusId, Integer artId, Boolean ty...
    method setCusBehaviorArtDislike (line 55) | Boolean setCusBehaviorArtDislike(Integer cusId, Integer artId, Boolean...
    method setCusBehaviorComEdit (line 66) | Boolean setCusBehaviorComEdit(Integer cusId, Integer artId, Integer co...
    method setCusBehaviorComLike (line 76) | Boolean setCusBehaviorComLike(Integer cusId, Integer comCusId, Integer...
    method setCusBehaviorComDislike (line 86) | Boolean setCusBehaviorComDislike(Integer cusId, Integer comCusId, Inte...
    method setCusBehaviorRepEdit (line 98) | Boolean setCusBehaviorRepEdit(Integer cusId, Integer artId, Integer re...
    method setCusBehaviorRepLike (line 108) | Boolean setCusBehaviorRepLike(Integer cusId, Integer repCusId, Integer...
    method setCusBehaviorRepDislike (line 118) | Boolean setCusBehaviorRepDislike(Integer cusId, Integer repCusId, Inte...
    method setCusBehaviorCusFollow (line 129) | Boolean setCusBehaviorCusFollow(Integer cusIdFrom, Integer cusIdTo);
    method recordRecommendList (line 137) | Boolean recordRecommendList(Integer cusId, List<ArtFullMod> list);

FILE: back/src/main/java/com/smacul/demo/service/impl/DiscussServiceImpl.java
  class DiscussServiceImpl (line 14) | @Service
    method getComList (line 22) | @Override
    method addNewCom (line 27) | @Override
    method addNewRep (line 36) | @Override

FILE: back/src/main/java/com/smacul/demo/service/impl/EditServiceImpl.java
  class EditServiceImpl (line 10) | @Service
    method addNewArt (line 16) | @Override

FILE: back/src/main/java/com/smacul/demo/service/impl/LoadServiceImpl.java
  class LoadServiceImpl (line 20) | @Service
    method getArtTypesForNew (line 32) | @Override
    method getArtTypesForOld (line 38) | @Override
    method getTinyArtOnePageByTypeForNew (line 44) | @Override
    method getTinyArtOnePageByTypeForOld (line 63) | @Override
    method getHotArtOnePage (line 95) | @Override
    method getFullArt (line 104) | @Override

FILE: back/src/main/java/com/smacul/demo/service/impl/SearchServiceImpl.java
  class SearchServiceImpl (line 13) | @Service
    method searchContentSimple (line 19) | @Override

FILE: back/src/main/java/com/smacul/demo/service/impl/SelfServiceImpl.java
  class SelfServiceImpl (line 21) | @Service
    method checkIsNewUser (line 31) | @Override
    method checkCusForLogin (line 41) | @Override
    method setNewCus (line 52) | @Override
    method getCusBasicInfo (line 71) | @Override
    method setCusBasicInfo (line 78) | @Override
    method setCusFollow (line 93) | @Override
    method getCusFeatureInfo (line 107) | @Override
    method getCusDynamic (line 121) | @Override
    method checkCusFollow (line 133) | @Override
    method getRelativeCusList (line 142) | @Override

FILE: back/src/main/java/com/smacul/demo/service/impl/SessionServiceImpl.java
  class SessionServiceImpl (line 14) | @Service
    method setCusSession (line 24) | @Override
    method setRelSession (line 29) | @Override
    method getCusSession (line 34) | @Override
    method getRelSession (line 39) | @Override
    method initPagSession (line 44) | @Override
    method getPagThenAddOne (line 49) | @Override
    method getSetPagAfterCusChange (line 68) | @Override

FILE: back/src/main/java/com/smacul/demo/service/impl/ShapeServiceImpl.java
  class ShapeServiceImpl (line 13) | @Service
    method setCusBehaviorArtEdit (line 27) | @Override
    method setCusBehaviorArtRead (line 39) | @Override
    method setCusBehaviorArtLike (line 59) | @Override
    method setCusBehaviorArtDislike (line 81) | @Override
    method setCusBehaviorComEdit (line 103) | @Override
    method setCusBehaviorComLike (line 116) | @Override
    method setCusBehaviorComDislike (line 121) | @Override
    method setCusBehaviorRepEdit (line 126) | @Override
    method setCusBehaviorRepLike (line 139) | @Override
    method setCusBehaviorRepDislike (line 144) | @Override
    method setCusBehaviorCusFollow (line 149) | @Override
    method recordRecommendList (line 158) | @Override

FILE: back/src/main/java/com/smacul/demo/util/MD5.java
  class MD5 (line 6) | public class MD5 {
    method MD5Creator (line 8) | public static String MD5Creator(String plainString) throws NoSuchAlgor...

FILE: back/src/main/java/com/smacul/demo/util/PageHandler.java
  class PageHandler (line 7) | public class PageHandler {
    method calcuStartNO (line 9) | public static Integer calcuStartNO(Integer page, Integer pageSize) {
    method initPageList (line 13) | public static Map<String, Integer> initPageList() {

FILE: back/src/main/java/com/smacul/demo/util/TypeHandler.java
  class TypeHandler (line 7) | public class TypeHandler {
    method typeTransAllEnToCh (line 28) | public static List<String> typeTransAllEnToCh(List<String> enTypes) {
    method typeTransAllChToEn (line 46) | public static List<String> typeTransAllChToEn(List<String> chTypes) {
    method typeTransSingleEnToCh (line 58) | public static String typeTransSingleEnToCh(String enType) {
    method typeTransSingleChToEn (line 67) | public static String typeTransSingleChToEn(String chType) {

FILE: back/src/test/java/com/smacul/demo/DemoApplicationTests.java
  class DemoApplicationTests (line 6) | @SpringBootTest
    method contextLoads (line 9) | @Test

FILE: front/src/control/Discuss.js
  function getComList (line 5) | function getComList(artId) {
  function addNewCom (line 14) | function addNewCom(comment) {
  function cusAddReply (line 18) | function cusAddReply(reply) {

FILE: front/src/control/Edit.js
  function addNewArt (line 5) | function addNewArt(article) {

FILE: front/src/control/Load.js
  function getArtTypes (line 5) | function getArtTypes() {
  function getTinyArtOnePageByType (line 9) | function getTinyArtOnePageByType(artType, page, pageSize) {
  function getHotArtOnePage (line 20) | function getHotArtOnePage(page, pageSize) {
  function getFullArt (line 31) | function getFullArt(artId) {
  function setArtPreference (line 40) | function setArtPreference(artId, type) {

FILE: front/src/control/Search.js
  function searchContentSimple (line 5) | function searchContentSimple(key, page, pageSize) {

FILE: front/src/control/Self.js
  function cusLogin (line 5) | function cusLogin(cusName, cusPass) {
  function quitLogin (line 12) | function quitLogin() {
  function cusRegister (line 16) | function cusRegister(cusName, cusPass) {
  function getCusBasicInfo (line 23) | function getCusBasicInfo(cusId) {
  function setCusBasicInfo (line 32) | function setCusBasicInfo(customer) {
  function setCusFollow (line 41) | function setCusFollow(cusId) {
  function getCusFeatureInfo (line 51) | function getCusFeatureInfo(cusId) {
  function getCusSelfDynamic (line 60) | function getCusSelfDynamic(cusId, page, pageSize) {
  function checkCusFollow (line 71) | function checkCusFollow(cusId) {

FILE: front/src/plugins/axios.js
  method get (line 47) | get() {
  method get (line 52) | get() {

FILE: front/src/util/PageJump.js
  function jumpInCurPage (line 3) | function jumpInCurPage(road) {
  function jumpInNewPage (line 8) | function jumpInNewPage(road) {

FILE: front/src/util/TimeHandler.js
  function transUTCtoLocal (line 1) | function transUTCtoLocal(time) {

FILE: spider/Main.py
  class Major (line 32) | class Major:
    method __init__ (line 34) | def __init__(self, path):
    method major (line 49) | def major(self):

FILE: spider/dao/ArticleDao.py
  class ArticleDao (line 8) | class ArticleDao:
    method __init__ (line 16) | def __init__(self, base: MySql.MySql):
    method is_art_exist (line 20) | def is_art_exist(self, art_spider):
    method insert_art (line 44) | def insert_art(self, art_mod: ArtMod.ArticleModel):
    method search_art_id_by_spider (line 71) | def search_art_id_by_spider(self, art_spider):
    method search_art_time_by_spider (line 90) | def search_art_time_by_spider(self, art_spider):
    method check_art_cus_relationship (line 109) | def check_art_cus_relationship(self, art_id, cus_id):
    method update_art_com_number (line 134) | def update_art_com_number(self, art_id):
    method update_art_feature (line 147) | def update_art_feature(self, behavior, art_id, art_time):
    method get_same_category_art (line 190) | def get_same_category_art(self, cur_art_id, category):

FILE: spider/dao/CommentDao.py
  class CommentDao (line 7) | class CommentDao:
    method __init__ (line 15) | def __init__(self, base: MySql.MySql):
    method is_com_exist (line 19) | def is_com_exist(self, com_spider):
    method insert_com (line 42) | def insert_com(self, com_mod: ComMod.CommentModel):
    method search_com_id_by_spider (line 66) | def search_com_id_by_spider(self, com_spider):
    method check_com_cus_relationship (line 85) | def check_com_cus_relationship(self, art_id, com_id, cus_id):

FILE: spider/dao/CustomerDao.py
  class CustomerDao (line 7) | class CustomerDao:
    method __init__ (line 15) | def __init__(self, base: MySql.MySql):
    method is_cus_name_exist (line 19) | def is_cus_name_exist(self, cus_name):
    method get_cus_by_name (line 42) | def get_cus_by_name(self, cus_mod: CusMod.CustomerModel):
    method insert_then_get_cus (line 69) | def insert_then_get_cus(self, cus_mod: CusMod.CustomerModel):
    method insert_cus (line 89) | def insert_cus(self, cus_mod: CusMod.CustomerModel):
    method insert_cus_behavior (line 113) | def insert_cus_behavior(self, cbr_cus_id_from, cbr_cus_id_to, cbr_beha...
    method update_cus_feature (line 152) | def update_cus_feature(self, category, cus_id, update_num=2, flag=False):
    method is_cus_exist (line 198) | def is_cus_exist(self, cus_spider):
    method search_cus_id_by_spider (line 220) | def search_cus_id_by_spider(self, cus_spider):

FILE: spider/dao/ReplyDao.py
  class ReplyDao (line 7) | class ReplyDao:
    method __init__ (line 15) | def __init__(self, base: MySql.MySql):
    method is_rep_exist (line 19) | def is_rep_exist(self, rep_spider):
    method insert_rep (line 43) | def insert_rep(self, rep_mod: RepMod.ReplyModel):
    method search_rep_id_by_spider (line 79) | def search_rep_id_by_spider(self, rep_spider):
    method check_rep_cus_relationship (line 98) | def check_rep_cus_relationship(self, art_id, rep_id, cus_id):
    method search_rep_rep_by_spyder (line 124) | def search_rep_rep_by_spyder(self, rep_json, rep_mod: RepMod.ReplyModel):

FILE: spider/model/ArticleModel.py
  class ArticleModel (line 1) | class ArticleModel:
    method __init__ (line 3) | def __init__(self):

FILE: spider/model/CommentModel.py
  class CommentModel (line 1) | class CommentModel:
    method __init__ (line 3) | def __init__(self):

FILE: spider/model/CustomerModel.py
  class CustomerModel (line 1) | class CustomerModel:
    method __init__ (line 2) | def __init__(self):

FILE: spider/model/ReplyModel.py
  class ReplyModel (line 1) | class ReplyModel:
    method __init__ (line 3) | def __init__(self):

FILE: spider/process/ArticleProcess.py
  class ArticleProcess (line 10) | class ArticleProcess:
    method get_arts_brief_json_by_category (line 18) | def get_arts_brief_json_by_category(self, category):
    method set_art (line 158) | def set_art(self, art_brief_json, category, art_cus_id, art_mod: ArtMo...
    method get_art_json (line 209) | def get_art_json(self, art_brief_json):

FILE: spider/process/CommentProcess.py
  class CommentProcess (line 8) | class CommentProcess:
    method get_coms_json (line 16) | def get_coms_json(self, art_brief_json):
    method set_com (line 117) | def set_com(self, com_json, art_id, cus_id, com_mod: ComMod.CommentMod...

FILE: spider/process/CustomerProcess.py
  class CustomerProcess (line 6) | class CustomerProcess:
    method set_art_cus (line 14) | def set_art_cus(self, art_brief_json, cus_mod: CusMod):
    method set_com_cus (line 38) | def set_com_cus(self, com_json, cus_mod: CusMod.CustomerModel):
    method set_rep_cus (line 62) | def set_rep_cus(self, rep_json, cus_mod: CusMod.CustomerModel):

FILE: spider/process/ReplyProcess.py
  class ReplyProcess (line 8) | class ReplyProcess:
    method get_reps_json (line 16) | def get_reps_json(self, com_json):
    method set_rep (line 331) | def set_rep(self, rep_json, rep_art_id, rep_com_id, rep_cus_id, rep_mo...

FILE: spider/util/Driver.py
  class Driver (line 5) | class Driver:
    method __init__ (line 7) | def __init__(self):
    method get_chrome_driver (line 11) | def get_chrome_driver():

FILE: spider/util/Json.py
  class Json (line 4) | class Json:
    method __init__ (line 6) | def __init__(self):
    method read_json_file (line 10) | def read_json_file(path, encoding='utf-8'):

FILE: spider/util/Md5.py
  class Md5 (line 4) | class Md5:
    method set_cus_pass (line 7) | def set_cus_pass(password):

FILE: spider/util/MySql.py
  class MySql (line 5) | class MySql:
    method __init__ (line 7) | def __init__(self, db_name, user, password, host="localhost", charset=...
    method execute_sql (line 15) | def execute_sql(self, sql):
    method commit_transactions (line 19) | def commit_transactions(self):
    method commit_rollback (line 23) | def commit_rollback(self):
    method get_result_all (line 27) | def get_result_all(self):
    method get_result_one (line 32) | def get_result_one(self):

FILE: spider/util/Request.py
  class Request (line 4) | class Request:
    method __init__ (line 8) | def __init__(self, url, headers=None, cookies=None):
    method set_url (line 13) | def set_url(self, url):
    method set_headers (line 16) | def set_headers(self, headers):
    method set_cookie (line 19) | def set_cookie(self, cookie):
    method more (line 22) | def more(self):

FILE: spider/util/Time.py
  class Time (line 4) | class Time:
    method time_trans (line 7) | def time_trans(time_data):
    method get_local_time (line 13) | def get_local_time():
Condensed preview — 156 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (400K chars).
[
  {
    "path": ".gitattributes",
    "chars": 66,
    "preview": "# Auto detect text files and perform LF normalization\n* text=auto\n"
  },
  {
    "path": ".gitignore",
    "chars": 260,
    "preview": "\n# crawler/.idea/*\n# crawler/__pycache__/*\n# crawler/database-properties.json\n.DS_Store\n\n/back/lib/*.jar\nback/src/main/r"
  },
  {
    "path": "LICENSE",
    "chars": 1063,
    "preview": "MIT License\n\nCopyright (c) 2019 SmacUL\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof "
  },
  {
    "path": "NewsRecommend.sql",
    "chars": 8625,
    "preview": "DROP DATABASE IF EXISTS NR;\nCREATE DATABASE IF NOT EXISTS NR CHARACTER SET utf8mb4;\n\n\n-- cus 用户\nDROP TABLE IF EXISTS NR."
  },
  {
    "path": "README.md",
    "chars": 1579,
    "preview": "# NewsRecommend\n\n基于协同过滤算法的新闻推荐系统, 项目分前后端与爬虫. \n\n实现热点新闻推荐以及个性化新闻推荐.\n\n[项目的具体说明](https://smacul.github.io/log/news_recommend"
  },
  {
    "path": "back/.gitignore",
    "chars": 377,
    "preview": "HELP.md\ntarget/\n!.mvn/wrapper/maven-wrapper.jar\n!**/src/main/**\n!**/src/test/**\n\n### STS ###\n.apt_generated\n.classpath\n."
  },
  {
    "path": "back/.mvn/wrapper/MavenWrapperDownloader.java",
    "chars": 4948,
    "preview": "/*\n * Copyright 2012-2019 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lic"
  },
  {
    "path": "back/.mvn/wrapper/maven-wrapper.properties",
    "chars": 218,
    "preview": "distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.2/apache-maven-3.6.2-bin.zip\nwrap"
  },
  {
    "path": "back/mvnw",
    "chars": 10079,
    "preview": "#!/bin/sh\n# ----------------------------------------------------------------------------\n# Licensed to the Apache Softwa"
  },
  {
    "path": "back/mvnw.cmd",
    "chars": 6610,
    "preview": "@REM ----------------------------------------------------------------------------\n@REM Licensed to the Apache Software F"
  },
  {
    "path": "back/pom.xml",
    "chars": 3187,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/DemoApplication.java",
    "chars": 561,
    "preview": "package com.smacul.demo;\n\nimport org.mybatis.spring.annotation.MapperScan;\nimport org.springframework.boot.SpringApplica"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/bean/ArtFeatureCount.java",
    "chars": 1624,
    "preview": "package com.smacul.demo.bean;\n\npublic class ArtFeatureCount {\n\n    private Integer afcId;\n    private Integer afcArtId;\n"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/bean/ArtScoreList.java",
    "chars": 456,
    "preview": "package com.smacul.demo.bean;\n\npublic class ArtScoreList {\n\n    private Integer aslArtId;\n    private Integer aslArtScor"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/bean/ArtTimeList.java",
    "chars": 433,
    "preview": "package com.smacul.demo.bean;\n\npublic class ArtTimeList {\n\n    private Integer atlId;\n    private Integer atlArtScore;\n\n"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/bean/Article.java",
    "chars": 1934,
    "preview": "package com.smacul.demo.bean;\n\nimport java.sql.Timestamp;\n\npublic class Article {\n    private Integer artId;\n    private"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/bean/Comment.java",
    "chars": 1382,
    "preview": "package com.smacul.demo.bean;\n\nimport java.sql.Timestamp;\n\npublic class Comment {\n\n    private Integer comId;\n    privat"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/bean/CusBehaviorRecord.java",
    "chars": 1683,
    "preview": "package com.smacul.demo.bean;\n\nimport java.sql.Timestamp;\n\npublic class CusBehaviorRecord {\n\n    private Integer cbrId;\n"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/bean/CusFeatureCount.java",
    "chars": 4420,
    "preview": "package com.smacul.demo.bean;\n\npublic class CusFeatureCount {\n    private Integer cfcId;\n    private Integer cfcCusId;\n\n"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/bean/Customer.java",
    "chars": 1789,
    "preview": "package com.smacul.demo.bean;\n\n\nimport java.sql.Timestamp;\n\npublic class Customer {\n    private Integer cusId;\n    priva"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/bean/Reply.java",
    "chars": 1931,
    "preview": "package com.smacul.demo.bean;\n\nimport java.sql.Timestamp;\n\npublic class Reply {\n\n    private Integer repId;\n    private "
  },
  {
    "path": "back/src/main/java/com/smacul/demo/controller/DiscussController.java",
    "chars": 2463,
    "preview": "package com.smacul.demo.controller;\n\nimport com.smacul.demo.bean.Comment;\nimport com.smacul.demo.bean.Customer;\nimport c"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/controller/EditController.java",
    "chars": 1249,
    "preview": "package com.smacul.demo.controller;\n\nimport com.smacul.demo.bean.Article;\nimport com.smacul.demo.bean.Customer;\nimport c"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/controller/LoadController.java",
    "chars": 6402,
    "preview": "package com.smacul.demo.controller;\n\nimport com.smacul.demo.bean.Customer;\nimport com.smacul.demo.model.ArtFullMod;\nimpo"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/controller/SearchController.java",
    "chars": 1131,
    "preview": "package com.smacul.demo.controller;\n\nimport com.smacul.demo.bean.Customer;\nimport com.smacul.demo.model.ArtFullMod;\nimpo"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/controller/SelfController.java",
    "chars": 5599,
    "preview": "package com.smacul.demo.controller;\n\nimport com.smacul.demo.bean.Customer;\nimport com.smacul.demo.dao.CusDao;\nimport com"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/dao/ArtDao.java",
    "chars": 5065,
    "preview": "package com.smacul.demo.dao;\n\nimport com.smacul.demo.bean.Article;\nimport com.smacul.demo.model.ArtFullMod;\nimport org.s"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/dao/ArtFeatureCountDao.java",
    "chars": 590,
    "preview": "package com.smacul.demo.dao;\n\nimport com.smacul.demo.bean.ArtFeatureCount;\nimport org.springframework.stereotype.Reposit"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/dao/ArtScoreListDao.java",
    "chars": 130,
    "preview": "package com.smacul.demo.dao;\n\nimport org.springframework.stereotype.Repository;\n\n@Repository\npublic interface ArtScoreLi"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/dao/ArtTimeList.java",
    "chars": 126,
    "preview": "package com.smacul.demo.dao;\n\nimport org.springframework.stereotype.Repository;\n\n@Repository\npublic interface ArtTimeLis"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/dao/ComDao.java",
    "chars": 713,
    "preview": "package com.smacul.demo.dao;\n\nimport com.smacul.demo.bean.Comment;\nimport com.smacul.demo.model.ComFullMod;\nimport org.s"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/dao/CusBehaviorRecordDao.java",
    "chars": 2989,
    "preview": "package com.smacul.demo.dao;\n\nimport com.smacul.demo.bean.CusBehaviorRecord;\nimport com.smacul.demo.model.CusDynamicMod;"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/dao/CusDao.java",
    "chars": 1125,
    "preview": "package com.smacul.demo.dao;\n\nimport com.smacul.demo.bean.Customer;\nimport org.springframework.stereotype.Repository;\n\n@"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/dao/CusFeatureCountDao.java",
    "chars": 1244,
    "preview": "package com.smacul.demo.dao;\n\nimport com.smacul.demo.bean.CusFeatureCount;\nimport org.springframework.stereotype.Reposit"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/dao/CusRecommendRecordDao.java",
    "chars": 457,
    "preview": "package com.smacul.demo.dao;\n\nimport org.springframework.stereotype.Repository;\n\nimport java.util.List;\n\n@Repository\npub"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/dao/RepDao.java",
    "chars": 744,
    "preview": "package com.smacul.demo.dao;\n\nimport com.smacul.demo.bean.Reply;\nimport com.smacul.demo.model.RepFullMod;\nimport org.spr"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/model/ArtFullMod.java",
    "chars": 2723,
    "preview": "package com.smacul.demo.model;\n\nimport com.smacul.demo.bean.ArtFeatureCount;\nimport com.smacul.demo.bean.Customer;\n\nimpo"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/model/ComFullMod.java",
    "chars": 1872,
    "preview": "package com.smacul.demo.model;\n\nimport com.smacul.demo.bean.Customer;\n//import com.smacul.demo.bean.Reply;\n\nimport java."
  },
  {
    "path": "back/src/main/java/com/smacul/demo/model/CusArtBehaviorMod.java",
    "chars": 1123,
    "preview": "package com.smacul.demo.model;\n\npublic class CusArtBehaviorMod {\n    private Integer cusId;\n    private Integer artId;\n "
  },
  {
    "path": "back/src/main/java/com/smacul/demo/model/CusDynamicMod.java",
    "chars": 2412,
    "preview": "package com.smacul.demo.model;\n\nimport com.smacul.demo.bean.Customer;\n\nimport java.sql.Timestamp;\n\npublic class CusDynam"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/model/CusFeatureFullMod.java",
    "chars": 1662,
    "preview": "package com.smacul.demo.model;\n\nimport com.smacul.demo.bean.CusFeatureCount;\n\npublic class CusFeatureFullMod {\n    priva"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/model/RepFullMod.java",
    "chars": 2166,
    "preview": "package com.smacul.demo.model;\n\nimport com.smacul.demo.bean.Customer;\n\nimport java.sql.Timestamp;\n\npublic class RepFullM"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/service/DiscussService.java",
    "chars": 662,
    "preview": "package com.smacul.demo.service;\n\nimport com.smacul.demo.bean.Comment;\nimport com.smacul.demo.bean.Reply;\nimport com.sma"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/service/EditService.java",
    "chars": 269,
    "preview": "package com.smacul.demo.service;\n\nimport com.smacul.demo.bean.Article;\n\npublic interface EditService {\n\n    /**\n     * 用"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/service/LoadService.java",
    "chars": 1881,
    "preview": "package com.smacul.demo.service;\n\nimport com.smacul.demo.model.ArtFullMod;\n\nimport java.util.List;\n\npublic interface Loa"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/service/SearchService.java",
    "chars": 368,
    "preview": "package com.smacul.demo.service;\n\nimport com.smacul.demo.model.ArtFullMod;\n\nimport java.util.List;\n\npublic interface Sea"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/service/SelfService.java",
    "chars": 2465,
    "preview": "package com.smacul.demo.service;\n\nimport com.smacul.demo.bean.Customer;\nimport com.smacul.demo.model.CusDynamicMod;\nimpo"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/service/SessionService.java",
    "chars": 564,
    "preview": "package com.smacul.demo.service;\n\nimport com.smacul.demo.bean.Customer;\nimport org.springframework.beans.factory.annotat"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/service/ShapeService.java",
    "chars": 4043,
    "preview": "package com.smacul.demo.service;\n\nimport com.smacul.demo.model.ArtFullMod;\nimport com.sun.org.apache.xpath.internal.oper"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/service/impl/DiscussServiceImpl.java",
    "chars": 1044,
    "preview": "package com.smacul.demo.service.impl;\n\nimport com.smacul.demo.bean.Comment;\nimport com.smacul.demo.bean.Reply;\nimport co"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/service/impl/EditServiceImpl.java",
    "chars": 748,
    "preview": "package com.smacul.demo.service.impl;\n\nimport com.smacul.demo.bean.Article;\nimport com.smacul.demo.dao.ArtDao;\nimport co"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/service/impl/LoadServiceImpl.java",
    "chars": 5539,
    "preview": "package com.smacul.demo.service.impl;\n\nimport com.smacul.demo.dao.ArtDao;\nimport com.smacul.demo.dao.ArtFeatureCountDao;"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/service/impl/SearchServiceImpl.java",
    "chars": 921,
    "preview": "package com.smacul.demo.service.impl;\n\nimport com.smacul.demo.dao.ArtDao;\nimport com.smacul.demo.model.ArtFullMod;\nimpor"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/service/impl/SelfServiceImpl.java",
    "chars": 5790,
    "preview": "package com.smacul.demo.service.impl;\n\nimport com.smacul.demo.bean.CusBehaviorRecord;\nimport com.smacul.demo.bean.Custom"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/service/impl/SessionServiceImpl.java",
    "chars": 2698,
    "preview": "package com.smacul.demo.service.impl;\n\nimport com.smacul.demo.bean.Customer;\nimport com.smacul.demo.service.SessionServi"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/service/impl/ShapeServiceImpl.java",
    "chars": 6342,
    "preview": "package com.smacul.demo.service.impl;\n\nimport com.smacul.demo.bean.Customer;\nimport com.smacul.demo.dao.*;\nimport com.sm"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/util/MD5.java",
    "chars": 725,
    "preview": "package com.smacul.demo.util;\n\nimport java.security.MessageDigest;\nimport java.security.NoSuchAlgorithmException;\n\npubli"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/util/PageHandler.java",
    "chars": 1447,
    "preview": "package com.smacul.demo.util;\n\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\npublic class Page"
  },
  {
    "path": "back/src/main/java/com/smacul/demo/util/TypeHandler.java",
    "chars": 2322,
    "preview": "package com.smacul.demo.util;\n\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\npublic class Type"
  },
  {
    "path": "back/src/main/resources/mapper/ArtFeatureCountMap.xml",
    "chars": 607,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<!DOCTYPE mapper\n        PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\"\n        \"ht"
  },
  {
    "path": "back/src/main/resources/mapper/ArtMap.xml",
    "chars": 9537,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<!DOCTYPE mapper\n        PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\"\n        \"ht"
  },
  {
    "path": "back/src/main/resources/mapper/ArtScoreListMap.xml",
    "chars": 232,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<!DOCTYPE mapper\n        PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\"\n        \"ht"
  },
  {
    "path": "back/src/main/resources/mapper/ArtTimeListMap.xml",
    "chars": 228,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<!DOCTYPE mapper\n        PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\"\n        \"ht"
  },
  {
    "path": "back/src/main/resources/mapper/ComMap.xml",
    "chars": 1763,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<!DOCTYPE mapper\n        PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\"\n        \"ht"
  },
  {
    "path": "back/src/main/resources/mapper/CusBehaviorRecordMap.xml",
    "chars": 4558,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<!DOCTYPE mapper\n        PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\"\n        \"ht"
  },
  {
    "path": "back/src/main/resources/mapper/CusFeatureCountMap.xml",
    "chars": 4768,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<!DOCTYPE mapper\n        PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\"\n        \"ht"
  },
  {
    "path": "back/src/main/resources/mapper/CusMap.xml",
    "chars": 1554,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<!DOCTYPE mapper\n        PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\"\n        \"ht"
  },
  {
    "path": "back/src/main/resources/mapper/CusRecommendRecordDao.xml",
    "chars": 646,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<!DOCTYPE mapper\n        PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\"\n        \"ht"
  },
  {
    "path": "back/src/main/resources/mapper/RepMap.xml",
    "chars": 1136,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<!DOCTYPE mapper\n        PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\"\n        \"ht"
  },
  {
    "path": "back/src/main/resources/templates/application.properties.template",
    "chars": 257,
    "preview": "spring.datasource.driverClassName = com.mysql.jdbc.Driver\nspring.datasource.url = jdbc:mysql://\nspring.datasource.userna"
  },
  {
    "path": "back/src/test/java/com/smacul/demo/DemoApplicationTests.java",
    "chars": 214,
    "preview": "package com.smacul.demo;\n\nimport org.junit.jupiter.api.Test;\nimport org.springframework.boot.test.context.SpringBootTest"
  },
  {
    "path": "front/.gitignore",
    "chars": 214,
    "preview": ".DS_Store\nnode_modules\n/dist\n\n# local env files\n.env.local\n.env.*.local\n\n# Log files\nnpm-debug.log*\nyarn-debug.log*\nyarn"
  },
  {
    "path": "front/README.md",
    "chars": 309,
    "preview": "# front\n\n## Project setup\n```\nyarn install\n```\n\n### Compiles and hot-reloads for development\n```\nyarn serve\n```\n\n### Com"
  },
  {
    "path": "front/babel.config.js",
    "chars": 73,
    "preview": "module.exports = {\n  presets: [\n    '@vue/cli-plugin-babel/preset'\n  ]\n}\n"
  },
  {
    "path": "front/package.json",
    "chars": 1146,
    "preview": "{\n  \"name\": \"front\",\n  \"version\": \"0.1.0\",\n  \"private\": true,\n  \"scripts\": {\n    \"serve\": \"vue-cli-service serve\",\n    \""
  },
  {
    "path": "front/public/index.html",
    "chars": 547,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE="
  },
  {
    "path": "front/src/App.vue",
    "chars": 856,
    "preview": "<template>\n    <div id=\"app\">\n        <!--<div id=\"nav\">-->\n        <!--  <router-link to=\"/\">Home</router-link> |-->\n  "
  },
  {
    "path": "front/src/assets/css/Narrow.css",
    "chars": 715,
    "preview": "body {\n    margin: 0 auto;\n}\n\nheader {\n    height: 60px;\n    margin-bottom: 10px;\n    box-shadow: 0 1px 4px 0 rgba(0,0,0"
  },
  {
    "path": "front/src/assets/css/Normal.css",
    "chars": 737,
    "preview": "body {\n    margin: 0 auto;\n}\n\nheader {\n    height: 60px;\n    margin-bottom: 10px;\n    box-shadow: 0 1px 4px 0 rgba(0,0,0"
  },
  {
    "path": "front/src/components/HelloWorld.vue",
    "chars": 2025,
    "preview": "<template>\n  <div class=\"hello\">\n    <h1>{{ msg }}</h1>\n    <p>\n      For a guide and recipes on how to configure / cust"
  },
  {
    "path": "front/src/components/app/HelloWorld.vue",
    "chars": 2053,
    "preview": "<template>\n  <div class=\"hello\">\n    <h1>{{ msg }}</h1>\n    <p>\n      For a guide and recipes on how to configure / cust"
  },
  {
    "path": "front/src/components/article/ArticleCenter.vue",
    "chars": 4134,
    "preview": "<template>\n    <div class=\"article-main\">\n        <div class=\"title\">{{articleMain.artTitle}}</div>\n        <div class=\""
  },
  {
    "path": "front/src/components/article/CommentReplyCenter.vue",
    "chars": 7917,
    "preview": "<template>\n    <div>\n        <comment-reply-input :customer=\"customer\" @messageHandler=\"addComment\"></comment-reply-inpu"
  },
  {
    "path": "front/src/components/article/RightMenu.vue",
    "chars": 1805,
    "preview": "<template>\n    <div>\n        <editor-brief class=\"editor-brief\" :articleAuthor=\"articleAuthor\"></editor-brief>\n        <"
  },
  {
    "path": "front/src/components/article/TopBar.vue",
    "chars": 2322,
    "preview": "<template>\n    <div class=\"clear-float\">\n        <div class=\"body-image\" v-on:click=\"jumpToIndex\">\n            <img src="
  },
  {
    "path": "front/src/components/article/comment-reply-main/CommentReplyInput.vue",
    "chars": 3615,
    "preview": "<template>\n    <div class=\"comment-reply-input\">\n        <div class=\"avatar\">\n            <img :src=\"customer.cusAvatarU"
  },
  {
    "path": "front/src/components/article/comment-reply-main/ReplyMain.vue",
    "chars": 5824,
    "preview": "<template>\n    <div class=\"reply-main\">\n        <div  v-for=\"(reply, i) in replys.slice((control.rep.page-1)*control.rep"
  },
  {
    "path": "front/src/components/common/DarkCard.vue",
    "chars": 297,
    "preview": "<template>\n    <div class=\"dark-card\">\n        <slot></slot>\n    </div>\n</template>\n\n<script>\n    export default {\n     "
  },
  {
    "path": "front/src/components/common/EditEntrance.vue",
    "chars": 942,
    "preview": "<template>\n    <card-panel>\n        <img class=\"body-image\" :src=\"logoSrc\"/>\n        <div class=\"body-title\">\n          "
  },
  {
    "path": "front/src/components/common/EditorBrief.vue",
    "chars": 2328,
    "preview": "<template>\n    <dark-card>\n        <div class=\"clear-float\">\n            <img class=\"image\" :src=\"articleAuthor.cusAvata"
  },
  {
    "path": "front/src/components/common/FloatCard.vue",
    "chars": 493,
    "preview": "<template>\n    <div class=\"float-card\">\n        <slot></slot>\n    </div>\n</template>\n\n<script>\n    export default {\n    "
  },
  {
    "path": "front/src/components/common/HotArticle.vue",
    "chars": 2230,
    "preview": "<template>\n    <dark-card>\n        <div class=\"hot-art-header clear-float\">\n            <span class=\"header-title\">{{ ti"
  },
  {
    "path": "front/src/components/common/SearchPanel.vue",
    "chars": 1005,
    "preview": "<template>\n    <div class=\"search\">\n        <el-input v-model=\"message\" placeholder=\"请输入内容\"></el-input>\n        <el-butt"
  },
  {
    "path": "front/src/components/common/TinyArticle.vue",
    "chars": 2934,
    "preview": "<template>\n    <float-card class=\"float-card clear-float\">\n        <div class=\"image\" v-if=\"tinyArticle.artImageUrl !== "
  },
  {
    "path": "front/src/components/edit/TopBar.vue",
    "chars": 2322,
    "preview": "<template>\n    <div class=\"clear-float\">\n        <div class=\"body-image\" v-on:click=\"jumpToIndex\">\n            <img src="
  },
  {
    "path": "front/src/components/index/LeftMenu.vue",
    "chars": 4079,
    "preview": "<template>\n    <el-menu :default-active=\"curIndex.toString()\" class=\"el-menu-vertical-demo\">\n        <el-menu-item v-for"
  },
  {
    "path": "front/src/components/index/TopBar.vue",
    "chars": 2313,
    "preview": "<template>\n    <div class=\"clear-float\">\n        <div class=\"body-image\" v-on:click=\"jumpToIndex\">\n            <img src="
  },
  {
    "path": "front/src/components/port/LoginPart.vue",
    "chars": 3110,
    "preview": "<template>\n    <div>\n        <h1>登 录</h1>\n        <el-form :model=\"ruleForm\" status-icon :rules=\"rules\" ref=\"ruleForm\" l"
  },
  {
    "path": "front/src/components/port/RegisterPart.vue",
    "chars": 4104,
    "preview": "<template>\n    <div>\n        <h1>注 册</h1>\n        <el-form :model=\"ruleForm\" status-icon :rules=\"rules\" ref=\"ruleForm\" l"
  },
  {
    "path": "front/src/components/search/RightMenu.vue",
    "chars": 1418,
    "preview": "<template>\n    <div>\n        <edit-entrance class=\"edit-entrance\"></edit-entrance>\n        <hot-article :title=\"hotArtic"
  },
  {
    "path": "front/src/components/search/TinyCenter.vue",
    "chars": 1288,
    "preview": "<template>\n    <div>\n        <tiny-article v-for=\"(tinyArticle, i) in tinyArticles\" :key=\"i\" :tinyArticle=\"tinyArticle\">"
  },
  {
    "path": "front/src/components/search/TopBar.vue",
    "chars": 2366,
    "preview": "<template>\n    <div class=\"clear-float\">\n        <div class=\"body-image\" v-on:click=\"jumpToIndex\">\n            <img src="
  },
  {
    "path": "front/src/components/self/EditorMain.vue",
    "chars": 2768,
    "preview": "<template>\n    <dark-card>\n        <div :style=\"note\">\n            <!-- 用户信息的显示板 -->\n            <div class=\"customer\">\n"
  },
  {
    "path": "front/src/components/self/RightMenu.vue",
    "chars": 2085,
    "preview": "<template>\n    <div>\n        <div class=\"achievement-panel\">\n            <div class=\"follower-followee\">\n               "
  },
  {
    "path": "front/src/components/self/TinyCenter.vue",
    "chars": 7691,
    "preview": "<template>\n    <div>\n        <float-card class=\"float-card clear-float\" v-for=\"(customerDynamic, i) in customerDynamics\""
  },
  {
    "path": "front/src/components/self/TopBar.vue",
    "chars": 2312,
    "preview": "<template>\n    <div class=\"clear-float\">\n        <div class=\"body-image\"  v-on:click=\"jumpToIndex\">\n            <img src"
  },
  {
    "path": "front/src/control/Discuss.js",
    "chars": 698,
    "preview": "import axios from 'axios'\n\nlet base = '/api/discuss/';\n\nexport function getComList(artId) {\n    let config = {\n        p"
  },
  {
    "path": "front/src/control/Edit.js",
    "chars": 138,
    "preview": "import axios from 'axios'\n\nlet base = '/api/edit/';\n\nexport function addNewArt(article) {\n    return axios.post(base + '"
  },
  {
    "path": "front/src/control/Load.js",
    "chars": 949,
    "preview": "import axios from 'axios'\n\nlet base = '/api/load/';\n\nexport function getArtTypes() {\n    return axios.get(base + 'type')"
  },
  {
    "path": "front/src/control/Search.js",
    "chars": 517,
    "preview": "import axios from 'axios'\n\nlet base = '/api/search/';\n\nexport function searchContentSimple(key, page, pageSize) {\n    le"
  },
  {
    "path": "front/src/control/Self.js",
    "chars": 1626,
    "preview": "import axios from 'axios'\n\nlet base = '/api/self/';\n\nexport function cusLogin(cusName, cusPass) {\n    let data = new For"
  },
  {
    "path": "front/src/main.js",
    "chars": 444,
    "preview": "import Vue from 'vue'\nimport './plugins/axios'\nimport App from './App.vue'\nimport ElementUI from 'element-ui'\n// import "
  },
  {
    "path": "front/src/plugins/axios.js",
    "chars": 1355,
    "preview": "\"use strict\";\n\nimport Vue from 'vue';\nimport axios from \"axios\";\n\n// Full config:  https://github.com/axios/axios#reques"
  },
  {
    "path": "front/src/router/index.js",
    "chars": 1383,
    "preview": "import Vue from 'vue'\nimport VueRouter from 'vue-router'\n// import Home from '../views/Home.vue'\n\n\nimport IndexView from"
  },
  {
    "path": "front/src/styles.scss",
    "chars": 180,
    "preview": "/* theme color */\n$--color-primary: teal;\n\n/* icon font path, required */\n$--font-path: '~element-ui/lib/theme-chalk/fon"
  },
  {
    "path": "front/src/util/PageJump.js",
    "chars": 273,
    "preview": "import router from '@/router/index.js'\n\nexport function jumpInCurPage(road) {\n    let route = router.resolve(road);\n    "
  },
  {
    "path": "front/src/util/TimeHandler.js",
    "chars": 97,
    "preview": "export function transUTCtoLocal(time) {\n    return new Date(Date.parse(time)).toLocaleString();\n}"
  },
  {
    "path": "front/src/views/About.vue",
    "chars": 89,
    "preview": "<template>\n  <div class=\"about\">\n    <h1>This is an about page</h1>\n  </div>\n</template>\n"
  },
  {
    "path": "front/src/views/ArticleView.vue",
    "chars": 5101,
    "preview": "<template>\n    <div>\n        <header><top-bar class=\"top-bar\" :customer=\"customer\"></top-bar></header>\n        <main>\n  "
  },
  {
    "path": "front/src/views/EditView.vue",
    "chars": 6837,
    "preview": "<template>\n    <div>\n        <header>\n            <top-bar class=\"top-bar\" :customer=\"customer\"></top-bar>\n        </hea"
  },
  {
    "path": "front/src/views/Home.vue",
    "chars": 328,
    "preview": "<template>\n  <div class=\"home\">\n    <img alt=\"Vue logo\" src=\"../assets/logo.png\">\n    <HelloWorld msg=\"Welcome to Your V"
  },
  {
    "path": "front/src/views/IndexView.vue",
    "chars": 8295,
    "preview": "<template>\n    <div>\n        <header>\n            <top-bar class=\"top-bar\" :customer=\"customer\"></top-bar>\n        </hea"
  },
  {
    "path": "front/src/views/PortView.vue",
    "chars": 1122,
    "preview": "<template>\n    <div>\n        <login-part v-if=\"page.loginShow\" class=\"login-part\" v-on:changePanel=\"changePanel\"></login"
  },
  {
    "path": "front/src/views/SearchView.vue",
    "chars": 5710,
    "preview": "<template>\n    <div>\n        <header><top-bar class=\"top-bar\" :customer=\"customer\"></top-bar></header>\n        <main>\n  "
  },
  {
    "path": "front/src/views/SelfView.vue",
    "chars": 4562,
    "preview": "<template>\n    <div>\n        <header><top-bar class=\"top-bar\" :customer=\"customer\"></top-bar></header>\n\n        <main>\n "
  },
  {
    "path": "front/vue.config.js",
    "chars": 1278,
    "preview": "module.exports = {\n    devServer: {\n        // Paths\n        // assetsSubDirectory: 'static',\n        // assetsPublicPat"
  },
  {
    "path": "spider/Main.py",
    "chars": 16661,
    "preview": "import model.ArticleModel as ArtMod\nimport model.ReplyModel as RepMod\nimport model.CommentModel as ComMod\nimport model.C"
  },
  {
    "path": "spider/dao/ArticleDao.py",
    "chars": 7075,
    "preview": "import util.MySql as MySql\nimport model.ArticleModel as ArtMod\nimport random\n\nimport logging\n\n\nclass ArticleDao:\n    \"\"\""
  },
  {
    "path": "spider/dao/CommentDao.py",
    "chars": 3506,
    "preview": "import util.MySql as MySql\nimport model.CommentModel as ComMod\n\nimport logging\n\n\nclass CommentDao:\n    \"\"\" 负责评论的数据库操作\n\n "
  },
  {
    "path": "spider/dao/CustomerDao.py",
    "chars": 8683,
    "preview": "import util.MySql as MySql\nimport model.CustomerModel as CusMod\n\nimport logging\n\n\nclass CustomerDao:\n    \"\"\" 负责用户的数据库操作\n"
  },
  {
    "path": "spider/dao/ReplyDao.py",
    "chars": 4913,
    "preview": "import util.MySql as MySql\nimport model.ReplyModel as RepMod\n\nimport logging\n\n\nclass ReplyDao:\n    \"\"\" 回复消息数据库处理\n\n    # "
  },
  {
    "path": "spider/dao/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "spider/model/ArticleModel.py",
    "chars": 350,
    "preview": "class ArticleModel:\n\n    def __init__(self):\n        self.art_id = None\n        self.art_title = None\n        self.art_c"
  },
  {
    "path": "spider/model/CommentModel.py",
    "chars": 255,
    "preview": "class CommentModel:\n\n    def __init__(self):\n        self.com_id = None\n        self.com_content = None\n        self.com"
  },
  {
    "path": "spider/model/CustomerModel.py",
    "chars": 348,
    "preview": "class CustomerModel:\n    def __init__(self):\n        \"\"\"\n        cus_gender 默认 0\n        cus_time 默认插入时间\n\n        20-04-"
  },
  {
    "path": "spider/model/ReplyModel.py",
    "chars": 345,
    "preview": "class ReplyModel:\n\n    def __init__(self):\n        self.rep_id = None\n        self.rep_content = None\n        self.rep_t"
  },
  {
    "path": "spider/model/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "spider/process/ArticleProcess.py",
    "chars": 10576,
    "preview": "import util.Request as Request\nimport util.Time as Time\nimport util.Driver as Driver\nimport model.ArticleModel as ArtMod"
  },
  {
    "path": "spider/process/CommentProcess.py",
    "chars": 4754,
    "preview": "import util.Request as Request\nimport util.Time as Time\nimport model.CommentModel as ComMod\n\nimport logging\n\n\nclass Comm"
  },
  {
    "path": "spider/process/CustomerProcess.py",
    "chars": 2833,
    "preview": "import model.CustomerModel as CusMod\nimport util.Md5 as Md5\nimport logging\n\n\nclass CustomerProcess:\n    \"\"\" 用户数据的获取与填充\n\n"
  },
  {
    "path": "spider/process/ReplyProcess.py",
    "chars": 13338,
    "preview": "import util.Request as Request\nimport util.Time as Time\nimport model.ReplyModel as RepMod\n\nimport logging\n\n\nclass ReplyP"
  },
  {
    "path": "spider/process/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "spider/util/Driver.py",
    "chars": 657,
    "preview": "import selenium.webdriver as webdriver\nimport selenium.webdriver.chrome.options as options\n\n\nclass Driver:\n\n    def __in"
  },
  {
    "path": "spider/util/Json.py",
    "chars": 202,
    "preview": "import json\n\n\nclass Json:\n\n    def __init__(self):\n        pass\n\n    @staticmethod\n    def read_json_file(path, encoding"
  },
  {
    "path": "spider/util/Md5.py",
    "chars": 268,
    "preview": "import hashlib\n\n\nclass Md5:\n\n    @staticmethod\n    def set_cus_pass(password):\n        \"\"\" 为用户密码进行 MD-5 加密\n\n        :par"
  },
  {
    "path": "spider/util/MySql.py",
    "chars": 1045,
    "preview": "import pymysql\nimport logging\n\n\nclass MySql:\n\n    def __init__(self, db_name, user, password, host=\"localhost\", charset="
  },
  {
    "path": "spider/util/Request.py",
    "chars": 602,
    "preview": "import requests\n\n\nclass Request:\n    \"\"\" 用于创建访问请求\n    \"\"\"\n\n    def __init__(self, url, headers=None, cookies=None):\n    "
  },
  {
    "path": "spider/util/Time.py",
    "chars": 306,
    "preview": "import time\n\n\nclass Time:\n\n    @staticmethod\n    def time_trans(time_data):\n        time_stamp = time_data\n        time_"
  },
  {
    "path": "spider/util/__init__.py",
    "chars": 0,
    "preview": ""
  }
]

// ... and 7 more files (download for full content)

About this extraction

This page contains the full source code of the SmacUL/NewsRecommend GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 156 files (348.3 KB), approximately 95.5k tokens, and a symbol index with 598 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!