V 0.1.0, 项目架构基本完成。
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
/.idea/
|
||||
/private/
|
||||
/storage/
|
||||
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 linlinjava(linlinjava@163.com)
|
||||
|
||||
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.
|
||||
119
README.md
Normal file
@@ -0,0 +1,119 @@
|
||||
litemall
|
||||
=====
|
||||
|
||||
又一个小商场系统。
|
||||
|
||||
项目代码
|
||||
====
|
||||
|
||||
* [码云](https://gitee.com/linlinjava/litemall)
|
||||
* [GitHub](https://github.com/linlinjava/litemall)
|
||||
|
||||
项目架构
|
||||
====
|
||||

|
||||
|
||||
技术栈
|
||||
===
|
||||
|
||||
> 1. Spring Boot
|
||||
> 2. Vue
|
||||
> 3. 微信小程序
|
||||
|
||||

|
||||
|
||||
效果
|
||||
==
|
||||
|
||||
### 小商城效果
|
||||
|
||||

|
||||
|
||||
* 首页
|
||||
* 专题列表、专题详情
|
||||
* 分类列表、分类详情
|
||||
* 品牌列表、品牌详情
|
||||
* 新品首发
|
||||
* 人气推荐
|
||||
* 商品搜索
|
||||
* 商品详情
|
||||
* 商品评价列表、商品评价
|
||||
* 购物车
|
||||
* 下单
|
||||
* 我的主页
|
||||
* 订单列表、订单详情
|
||||
* 地址列表、地址添加、地址删除
|
||||
* 我的收藏
|
||||
* 我的足迹
|
||||
|
||||
|
||||
### 管理平台效果
|
||||
|
||||

|
||||
|
||||
* 会员管理
|
||||
|
||||
* 商场管理
|
||||
|
||||
* 商品管理
|
||||
|
||||
* 推广管理
|
||||
|
||||
* 系统管理
|
||||
|
||||
|
||||
云演示
|
||||
==
|
||||
|
||||
### 小商城演示访问
|
||||
|
||||
由于没有上线,只能在微信开发工具中测试运行:
|
||||
|
||||
1. 微信开发工具导入litemall-wx项目;
|
||||
2. 项目配置,启用“不校验合法域名、web-view(业务域名)、TLS 版本以及 HTTPS 证书”
|
||||
3. 点击“编译”,即可在微信开发工具预览效果;
|
||||
4. 也可以点击“预览”,然后手机扫描登陆。
|
||||
|
||||

|
||||
|
||||
### 管理平台演示访问
|
||||
|
||||
1. 浏览器打开,输入以下网址`http://122.152.206.172:8080/#/login`
|
||||
2. 用户名`admin123`,密码`admin123`
|
||||
|
||||
文档
|
||||
==
|
||||
|
||||
1. [系统架构](doc/1.md)
|
||||
2. [基础子系统](doc/2.md)
|
||||
3. [小程序子系统](doc/3.md)
|
||||
4. [管理后台子系统](doc/4.md)
|
||||
5. [商场子系统](doc/5.md)
|
||||
6. [下一步计划](doc/6.md)
|
||||
|
||||
更新
|
||||
==
|
||||
|
||||
* V 0.1.0,项目架构基本完成。
|
||||
|
||||
警告
|
||||
==
|
||||
|
||||
> 1. 本项目仅用于学习练习
|
||||
> 2. 数据库数据来自nideshop
|
||||
> 3. 项目代码目前还不完善,仍处在开发中
|
||||
> 4. 项目开源(MIT),但不承担任何使用后果
|
||||
|
||||
|
||||
致谢
|
||||
==
|
||||
|
||||
本项目基于或参考以下项目:
|
||||
> 1. nideshop-mini-program
|
||||
> 如果后端希望采用nodejs,用户可以访问nideshop项目
|
||||
> 2. platform
|
||||
> 如果后端希望采用非spring boot版的普通spring版或者更多功能,
|
||||
> 用户可以访问platform项目
|
||||
> 3. vue-element-admin
|
||||
|
||||
本项目所依赖的其他开源项目见相关章节
|
||||
4
deploy/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
/litemall-admin-api/litemall-admin-api.jar
|
||||
/litemall-os-api/litemall-os-api.jar
|
||||
/litemall-wx-api/litemall-wx-api.jar
|
||||
/litemall-admin/dist.tar
|
||||
24
deploy/README.md
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
1. 项目进一步打包到deploy文件夹中:
|
||||
* litemall-os-api模块编译得到的litemall-os-api-0.1.0.jar 保存到deploy的litemall-os-api文件夹中,同时重命名成litemall-os-api.jar
|
||||
* litemall-wx-api模块编译得到的litemall-wx-api-0.1.0.jar 保存到deploy的litemall-wx-api文件夹中,同时重命名成litemall-wx-api.jar
|
||||
* litemall-admin-api模块编译得到的litemall-admin-api-0.1.0.jar 保存到deploy的litemall-admin-api文件夹中,同时重命名成litemall-admin-api.jar
|
||||
* litemall-admin模块编译以后,把dist文件夹压缩,然后放到deploy的litemall-admin文件夹中。
|
||||
|
||||
2. 使用FileZilla把deploy整个文件夹上传到云主机的/home/ubuntu文件夹中
|
||||
|
||||
3. 使用PuTTY登陆云主机
|
||||
|
||||
4. 运行脚本部署运行
|
||||
|
||||
```bash
|
||||
sudo ./deploy/bin/deploy.sh
|
||||
```
|
||||
|
||||
5. 测试部署是否成功
|
||||
请确保litemall的Spring Boot应用模块所对应的端口已经打开;
|
||||
然后测试是否能够访问(xxx.xxx.xxx.xxx是云主机IP):
|
||||
|
||||
> http://xxx.xxx.xxx.xxx:8081/storage/index/index
|
||||
> http://xxx.xxx.xxx.xxx:8082/wx/index/index
|
||||
> http://xxx.xxx.xxx.xxx:8083/admin/index/index
|
||||
24
deploy/bin/deploy.sh
Normal file
@@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
|
||||
#部署litemall-admin静态文件应用
|
||||
cd /home/ubuntu/deploy/litemall-admin
|
||||
rm -rf dist
|
||||
mkdir dist
|
||||
tar -zxvf dist.tar -C dist
|
||||
cd .
|
||||
|
||||
#部署三个Spring Boot应用
|
||||
#如果服务已经启动,则尝试停止
|
||||
sudo /etc/init.d/litemall-os-api stop
|
||||
sudo /etc/init.d/litemall-wx-api stop
|
||||
sudo /etc/init.d/litemall-admin-api stop
|
||||
|
||||
#部署Spring Boot应用成服务
|
||||
sudo ln -f -s /home/ubuntu/deploy/litemall-os-api/litemall-os-api.jar /etc/init.d/litemall-os-api
|
||||
sudo ln -f -s /home/ubuntu/deploy/litemall-wx-api/litemall-wx-api.jar /etc/init.d/litemall-wx-api
|
||||
sudo ln -f -s /home/ubuntu/deploy/litemall-admin-api/litemall-admin-api.jar /etc/init.d/litemall-admin-api
|
||||
|
||||
#启动服务
|
||||
sudo /etc/init.d/litemall-os-api restart
|
||||
sudo /etc/init.d/litemall-wx-api restart
|
||||
sudo /etc/init.d/litemall-admin-api restart
|
||||
2
deploy/litemall-admin-api/litemall-admin-api.conf
Normal file
@@ -0,0 +1,2 @@
|
||||
RUN_ARGS=--spring.profiles.active=prod
|
||||
JAVA_OPTS=
|
||||
2
deploy/litemall-os-api/litemall-os-api.conf
Normal file
@@ -0,0 +1,2 @@
|
||||
RUN_ARGS=--spring.profiles.active=prod
|
||||
JAVA_OPTS=
|
||||
2
deploy/litemall-wx-api/litemall-wx-api.conf
Normal file
@@ -0,0 +1,2 @@
|
||||
RUN_ARGS=--spring.profiles.active=prod
|
||||
JAVA_OPTS=
|
||||
446
doc/1.md
Normal file
@@ -0,0 +1,446 @@
|
||||
# 1 litemall系统
|
||||
|
||||
## 1.1 简介
|
||||
|
||||
litemall是一个简单的商场系统,基于现有的开源项目,重新实现一个完整的前后端项目,包含小程序客户端和网页管理端。
|
||||
|
||||

|
||||
|
||||
|
||||
项目的架构是三个系统和六个模块:
|
||||
|
||||
* 基础系统(core),由数据库、数据库业务模块litemall-db、对象存储模块litemall-os-api组成;
|
||||
* 小商场系统(wxmall),由litemall-wx-api模块和litemall-wx模块组成;
|
||||
* 后台管理系统(admin),由litemall-admin-api模块和litemall-admin模块组成。
|
||||
* 简单商城系统(mall),这里仅列出,目前没有开发计划。
|
||||
|
||||
而六个模块的开发设计到三种技术栈:
|
||||
|
||||
* Spring Boot技术栈,采用IDEA开发工具,开发litemall-db、litemall-os-api、litemall-admin-api和litemall-wx-api共四个模块;
|
||||
* miniprogram(微信小程序)技术栈,采用微信小程序开发工具,开发litemall-wx模块;
|
||||
* Vue技术栈,采用VSC开发工具,开发litemall-admin模块。
|
||||
|
||||
## 1.2 系统功能
|
||||
|
||||
从业务功能上,目前由五个业务模块(参考nideshop-mini-program和platform)组成:
|
||||
|
||||
* 会员业务模块
|
||||
* 商场业务模块
|
||||
* 商品业务模块
|
||||
* 推广业务模块
|
||||
* 系统业务模块(仅管理平台)
|
||||
|
||||
### 1.2.1 小程序端功能
|
||||
|
||||
* 首页
|
||||
|
||||
* 专题列表
|
||||
|
||||
* 专题详情
|
||||
|
||||
* 分类列表
|
||||
|
||||
* 分类详情
|
||||
|
||||
* 品牌列表
|
||||
|
||||
* 品牌详情
|
||||
|
||||
* 新品首发
|
||||
|
||||
* 人气推荐
|
||||
|
||||
* 商品搜索
|
||||
|
||||
* 商品详情
|
||||
|
||||
* 商品评价列表
|
||||
|
||||
* 商品评价
|
||||
|
||||
* 购物车
|
||||
|
||||
* 下单
|
||||
|
||||
* 我的主页
|
||||
|
||||
* 订单列表
|
||||
|
||||
* 订单详情
|
||||
|
||||
* 地址列表
|
||||
|
||||
* 地址添加
|
||||
|
||||
* 我的收藏
|
||||
|
||||
* 我的足迹
|
||||
|
||||
* 支付页面(待定)
|
||||
|
||||
* 优惠券选择(待定)
|
||||
|
||||
* 我的优惠券(待定)
|
||||
|
||||
### 1.2.2 管理平台功能
|
||||
|
||||
* 会员管理
|
||||
* 会员管理
|
||||
* 收货地址管理
|
||||
* 会员收藏
|
||||
* 会员足迹
|
||||
* 搜索历史
|
||||
* 购物车
|
||||
* 会员等级(待定)
|
||||
* 会员优惠劵(待定)
|
||||
* 商城管理
|
||||
* 区域配置
|
||||
* 品牌制造商
|
||||
* 订单管理
|
||||
* 商品类目
|
||||
* 通用问题
|
||||
* 关键词
|
||||
* 渠道管理(待定)
|
||||
* 商品管理
|
||||
* 商品管理
|
||||
* 商品参数
|
||||
* 商品规格
|
||||
* 货品管理
|
||||
* 用户评论
|
||||
* 团购设置(待定)
|
||||
* 商品满减搭配(待定)
|
||||
* 推广管理
|
||||
* 广告列表
|
||||
* 专题管理
|
||||
* 优惠劵管理(待定)
|
||||
* 系统管理
|
||||
* 管理员
|
||||
* 对象存储
|
||||
* 权限管理(待定)
|
||||
* 定时任务(待定)
|
||||
* 参数管理(待定)
|
||||
* 系统日志(待定)
|
||||
|
||||
## 1.3 项目特点
|
||||
|
||||
存在以下特点:
|
||||
|
||||
* 数据库方面,只是简单的表,表和表之间的依赖关系没有采用外键设计,而是依赖Java代码在service层面或者业务层面保证。这样做的好处是数据库频繁改动很方便,不会因为外键而导致数据库难以修改;
|
||||
* 涉及三种技术栈,但是每种技术栈仅涉及最基础的技术;
|
||||
* 后端技术栈,仅涉及 Spring,Spring Boot, Spring MVC和Mybatis技术,其他后端技术暂时不采用;
|
||||
* 小程序技术栈,仅涉及miniprogram官方文档和nideshop-mini-program项目;
|
||||
* 前端技术栈,仅涉及vue, vuex, vue-route,element-ui技术和vue-element-admin项目;
|
||||
* 安全方面,仅采用最基本的代码,提供简单基本的安全服务;
|
||||
* 性能方面,没有涉及内存数据库缓存功能,而是完全依赖MySQL;
|
||||
* 对象存储服务(图片上传和下载)方面,没有采用云存储方案,而是实现自有的简单文件上传下载功能。对象只是简单存储在后台主机的一个文件夹中,从而解耦当前项目对对象存储云平台的依赖,同时加强对对象存储概念的理解。
|
||||
|
||||
总之,目前的系统只是为了学习技术和业务而开发的一个简单商场原型系统。虽然缺失很多企业级功能,但是是完整和合理的原型系统。
|
||||
|
||||
注意:
|
||||
> 以上特点并不一定是优点。
|
||||
|
||||
## 1.4 开发方案
|
||||
|
||||

|
||||
|
||||
如图所示,当前开发阶段的方案:
|
||||
|
||||
* MySQL数据访问地址`jdbc:mysql://localhost:3306/litemall`
|
||||
* litemall-os-api对象存储服务地址`http://localhost:8081`
|
||||
* litemall-wx-api后台服务地址`http://localhost:8082`,数据则来自MySQL
|
||||
* litemall-admin-api后台服务地址`http://localhost:8083`,数据则来自MySQL
|
||||
* litemall-admin前端访问地址`http://localhost:9527`, 数据来自litemall-admin-api
|
||||
* litemall-wx没有前端访问地址,而是直接在微信小程序工具上编译测试开发,最终会部署到微信官方平台(即不需要自己部署web服务器),而数据则来自litemall-wx-api
|
||||
|
||||
|
||||
### 1.4.1 Spring Boot开发环境
|
||||
|
||||
1. 安装JDK8
|
||||
2. 安装IDEA Community
|
||||
3. 安装maven
|
||||
4. 安装Git(可选)
|
||||
5. IDEA导入本项目
|
||||
6. 采用maven插件安装依赖库
|
||||
7. 编译本项目
|
||||
8. 运行litemall-os-api, 打开浏览器,输入
|
||||
```
|
||||
http://localhost:8081/storage/index/index
|
||||
```
|
||||
如果出现JSON数据,则Spring Boot开发环境部署成功,litemall-os-api模块运行正常。
|
||||
9. 同上,运行litemall-wx-api, 打开浏览器,输入
|
||||
```
|
||||
http://localhost:8082/wx/index/index
|
||||
```
|
||||
如果出现JSON数据,则litemall-wx-api模块运行正常。
|
||||
10. 同上,运行litemall-admin-api, 打开浏览器,输入
|
||||
```
|
||||
http://localhost:8083/admin/index/index
|
||||
```
|
||||
如果出现JSON数据,则litemall-admin-api模块运行正常。
|
||||
|
||||
注意:
|
||||
> 由于设置了三个不同的端口,因此开发时,IDEA可以同时运行litemall-os-api、litemall-wx-api和litemall-admin-api三个Spring Boot程序。
|
||||
|
||||
### 1.4.2 微信小程序开发环境
|
||||
|
||||
1. 安装微信小程序开发工具
|
||||
2. 导入本项目的litemall-wx模块文件夹
|
||||
3. 编译前,请确定litemall-wx-api模块已经运行,而litemall-wx模块的config文件夹中的api.js已经设置正确对应的后台数据服务地址;
|
||||
4. 点击`编译`,如果出现数据和图片,则运行正常
|
||||
|
||||
### 1.4.3 Vue开发环境
|
||||
|
||||
1. 安装npm(或者cnpm)
|
||||
2. 安装VSC(Visual Studio Code)
|
||||
3. 导入本项目的litemall-admin模块文件夹
|
||||
4. 安装依赖库
|
||||
|
||||
```
|
||||
cnpm install
|
||||
```
|
||||
5. 编译并运行
|
||||
|
||||
```
|
||||
cnpm run dev
|
||||
```
|
||||
然后,打开浏览器,输入`http://localhost:9527`。
|
||||
如果出现管理后台登陆页面,则表明管理后台的前端运行正常;
|
||||
6. 请确定litemall-admin-api模块已经运行,然后点击`登陆`,如果能够成功登陆,则表明管理后台的前端和后端对接成功,运行正常。
|
||||
|
||||
## 1.5 部署方案
|
||||
|
||||
在1.4节中介绍的是开发阶段时一些关键性开发流程。本节将介绍代码开发成功以后开始部署项目时一些关键性流程。
|
||||
|
||||
首先,需要明确的是开发时项目使用的服务地址是本地地址,即localhost;而部署时则应该根据具体情况设置合理的服务器地址和端口。
|
||||
其次,需要明确的是各模块之间的关系:
|
||||
|
||||
* litemall-os-api模块会包含litemall-db模块,部署在服务器中
|
||||
* litemall-wx-api模块会包含litemall-db模块,部署在服务器中
|
||||
* litemall-admin-api模块会包含litemall-db模块,部署在服务器中
|
||||
* litemall-wx模块部署在腾讯官方平台中,此外数据API地址指向litemall-wx-api所在服务qi地址
|
||||
* litemall-admin编译出的静态文件放在web服务器或者tomcat服务器,此外服务器地址设置指向3中litemall-admin-api所在地址
|
||||
|
||||
注意
|
||||
> * 这里litemall-os-api、litemall-admin-api和litemall-wx-api也可以选择编译成jar模式的可执行文件(因为内嵌tomcat服务器),然后直接运行。
|
||||
> * litemall-wx正式部署时需要设置https开头的合法域名,因此litemall-wx-api所在的服务器需要配置合适的域名和SSL证书,具体参见官方文档。
|
||||
|
||||
实际上,最终的部署方案是灵活的:
|
||||
|
||||
* 可以单一云主机中仅安装一个tomcat服务器并配置一个端口,然后同时部署四个项目的模块,从而提供四种服务
|
||||
(即litemall-admin静态页面,litemall-os-api存储服务、litemall-amdin-api后台服务和litemall-wx-api后台服务)。
|
||||
* 也可以是同一云主机中安装四个服务器分别配置四个端口,分别提供四种服务
|
||||
* 也可以是四个云主机各自安装服务器配置端口,分别提供四种服务
|
||||
* 当然,甚至多个服务器,并发提供服务。
|
||||
|
||||
注意
|
||||
> 1. `本机`指的是是当前的开发机
|
||||
> 2. `云主机`指的是用户购买并部署的远程主机
|
||||
|
||||
以下简单列举几种方案。
|
||||
|
||||
### 1.5.1 windows下本机测试部署方案
|
||||
|
||||
这里,我们是把window作为开发环境进行本项目的开发工作。
|
||||
而项目开发完毕以后,在正式部署之前,可以先进行一个简单的本机测试部署方案。
|
||||
|
||||
首先,需要确保本地MySQL已经安装并且导入了litemall.sql数据;
|
||||
其次,项目打包
|
||||
```
|
||||
cd litemall
|
||||
mvn clean
|
||||
mvn package
|
||||
```
|
||||
最后,本机测试性部署三个应用
|
||||
```
|
||||
cd litemall
|
||||
java -jar ./litemall-os-api/target/litemall-os-api-0.1.0.jar &
|
||||
java -jar ./litemall-wx-api/target/litemall-wx-api-0.1.0.jar &
|
||||
java -jar ./litemall-admin-api/target/litemall-admin-api-0.1.0.jar &
|
||||
```
|
||||
如果,能够访问以下链接的数据,则表明本地测试部署成功:
|
||||
```
|
||||
http://localhost:8081/storage/index/index
|
||||
http://localhost:8082/wx/index/index
|
||||
http://localhost:8083/admin/index/index
|
||||
```
|
||||
|
||||
注意
|
||||
> 由于这里使用`&`设置成后台运行,因此测试结束以后,用户需要自行通过任务管理器或其他软件关闭这三个后台Spring Boot应用。
|
||||
|
||||
### 1.5.2 简单局域网方案
|
||||
|
||||
局域网方案,面向的是最终服务器数据和部分应用程序部署在局域网内的场景。
|
||||
|
||||
### 1.5.3 基于ubuntu腾讯云的单机云部署方案
|
||||
单机云部署方案,面向的是云主机单机同时部署演示型场景
|
||||
创建云主机,安装ubuntu操作系统,按照JDK和MySQL应用运行环境,部署三个Spring Boot微服务后台应用。
|
||||
|
||||

|
||||
|
||||
#### 1.5.3.1 主机
|
||||
|
||||
腾讯云 ubuntu 16.04.1
|
||||
|
||||
1. 创建云主机虚拟机
|
||||
2. 安装操作系统
|
||||
3. 创建安全组
|
||||

|
||||
4. 安装SSH密钥(可选)
|
||||
5. 使用PuTTY远程登陆云主机
|
||||
|
||||
#### 1.5.3.2 JDK8
|
||||
|
||||
https://www.digitalocean.com/community/tutorials/how-to-install-java-with-apt-get-on-ubuntu-16-04
|
||||
http://www.webupd8.org/2012/09/install-oracle-java-8-in-ubuntu-via-ppa.html
|
||||
|
||||
```bash
|
||||
sudo add-apt-repository ppa:webupd8team/java
|
||||
sudo apt-get update
|
||||
sudo apt-get install oracle-java8-installer
|
||||
sudo apt-get install oracle-java8-set-default
|
||||
```
|
||||
|
||||
警告
|
||||
> "ppa:webupd8team/java" 不是Oracle官方PPA,可能存在安全隐患。
|
||||
|
||||
#### 1.5.3.3 MySQL
|
||||
|
||||
https://www.digitalocean.com/community/tutorials/how-to-install-mysql-on-ubuntu-16-04
|
||||
https://www.linuxidc.com/Linux/2017-01/139502.htm
|
||||
|
||||
```
|
||||
sudo apt-get update
|
||||
sudo apt-get install mysql-server
|
||||
sudo apt-get install mysql-client
|
||||
```
|
||||
|
||||
下面是可选地设置root账号远程访问MySQL
|
||||
|
||||
首先,MySQL默认不支持远程访问,因此需要修改配置文件
|
||||
```
|
||||
sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf
|
||||
```
|
||||
添加'#'注释掉其中的`bind-address`,
|
||||
```
|
||||
#bind-address= 127.0.0.1`;
|
||||
```
|
||||
|
||||
其次,设置root账号远程访问权限
|
||||
```
|
||||
mysql -u root -p
|
||||
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123456' WITH GRANT OPTION;
|
||||
FLUSH PRIVILEGES;
|
||||
quit;
|
||||
```
|
||||
|
||||
最后,登陆腾讯云,设置云主机的`安全组`,允许`3306`端口访问,然后重启云主机,使得这些配置生效。
|
||||
|
||||
警告
|
||||
> 1. 因为安全的原因,MySQL不应该设置远程访问,
|
||||
> 这里仅仅用于方便数据导入操作。
|
||||
> 2. MySQL应该部署在专门的服务器中,
|
||||
> 这里仅仅用于演示远程部署MySQL。
|
||||
|
||||
#### 1.5.3.4 litemall数据
|
||||
|
||||
这里可以采用命令行式,也可以采用MySQL自带的Workbench导入。
|
||||
|
||||
* 命令行导入
|
||||
|
||||
1. 采用FileZilla把本项目的litemall.sql上传到云主机
|
||||
2. 使用PuTTY登陆云主机
|
||||
3. 进入MySQL,输入上节所设置的MySQL的root密码
|
||||
4. 创建数据库、 创建用户并分配访问权限
|
||||
5. 导入数据
|
||||
6. 退出
|
||||
|
||||
* MySQL Workbench导入
|
||||
|
||||
1. 先确认已经在1.4.3节中设置了root可以远程访问;
|
||||
2. 创建一个新的连接,设置`Hostname` 、`Username` 和`Password`,
|
||||
然后点击``Test Connection`测试是否能够连接到云主机;
|
||||
如果测试成功,则进入;
|
||||

|
||||
3. 用户自行学习文档,完成`创建数据库`、`创建用户`和`分配权限`三个操作;
|
||||
4. 利用Workbench的`Server`菜单下的`Data Import`完成数据导入。
|
||||
|
||||
#### 1.5.3.5 Tomcat
|
||||
|
||||
1. 本项目中采用二进制jar包方式来部署Spring Boot后端应用,因此可以不需要部署在tomcat中。
|
||||
但是,litemall-admin前端项目最终会编译出静态文件,需要部署在服务器中,因此这里仍需安装tomcat。
|
||||
|
||||
```bash
|
||||
sudo apt-get install tomcat8
|
||||
```
|
||||
|
||||
2. 为了配置tomcat支持外部文件夹中,修改tomcat的server文件
|
||||
|
||||
```bash
|
||||
sudo vi /var/lib/tomcat8/conf/server.xml
|
||||
```
|
||||
在其中添加一行新的内容`<Context path="/" docBase="/home/ubuntu/deploy/litemall-admin/dist" reloadable="true" />`
|
||||
|
||||
3. 然后,重启tomcat
|
||||
|
||||
```
|
||||
sudo service tomcat8 restart
|
||||
```
|
||||
|
||||
|
||||
#### 1.5.3.5 项目打包
|
||||
|
||||
1. Spring Boot打包
|
||||
|
||||
通常项目打包方案存在两种:
|
||||
|
||||
* 一是打包war格式,因此云主机需要专门安装tomcat
|
||||
* 二是打包可执行jar格式,此时内部包含嵌入式tomcat
|
||||
|
||||
这里仅采用第二种方案,简化tomcat的安装配置过程。
|
||||
|
||||
采用如下命令进行项目打包
|
||||
|
||||
```
|
||||
cd litemall
|
||||
mvn clean
|
||||
mvn package
|
||||
```
|
||||
|
||||
2. Vue项目打包
|
||||
|
||||
采用如下命令进行项目打包
|
||||
|
||||
````bash
|
||||
cnpm run build:prod
|
||||
````
|
||||
|
||||
此时,litemall-admin模块的dist文件夹中就是最终部署时的代码。
|
||||
|
||||
#### 1.5.3.6 项目部署运行
|
||||
|
||||
https://docs.spring.io/spring-boot/docs/1.5.10.RELEASE/reference/htmlsingle/#deployment-service
|
||||
|
||||
1. 项目进一步打包到deploy文件夹中:
|
||||
* litemall-os-api模块编译得到的litemall-os-api-0.1.0.jar 保存到deploy的litemall-os-api文件夹中,同时重命名成litemall-os-api.jar
|
||||
* litemall-wx-api模块编译得到的litemall-wx-api-0.1.0.jar 保存到deploy的litemall-wx-api文件夹中,同时重命名成litemall-wx-api.jar
|
||||
* litemall-admin-api模块编译得到的litemall-admin-api-0.1.0.jar 保存到deploy的litemall-admin-api文件夹中,同时重命名成litemall-admin-api.jar
|
||||
* litemall-admin模块编译以后,把dist文件夹压缩,然后放到deploy的litemall-admin文件夹中。
|
||||
|
||||
2. 使用FileZilla把deploy整个文件夹上传到云主机的/home/ubuntu文件夹中
|
||||
|
||||
3. 使用PuTTY登陆云主机
|
||||
|
||||
4. 运行脚本部署运行
|
||||
|
||||
```bash
|
||||
sudo ./deploy/bin/deploy.sh
|
||||
```
|
||||

|
||||
5. 测试部署是否成功
|
||||
请确保litemall的Spring Boot应用模块所对应的端口已经打开;
|
||||
然后测试是否能够访问(xxx.xxx.xxx.xxx是云主机IP):
|
||||
|
||||
> http://xxx.xxx.xxx.xxx:8081/storage/index/index
|
||||
> http://xxx.xxx.xxx.xxx:8082/wx/index/index
|
||||
> http://xxx.xxx.xxx.xxx:8083/admin/index/index
|
||||
|
||||
246
doc/2.md
Normal file
@@ -0,0 +1,246 @@
|
||||
|
||||
# 2 litemall基础系统
|
||||
|
||||
目前litemall基础系统主要由litemall数据库、litemall-db模块和litemall-os-api模块组成。
|
||||
|
||||
## 2.1 litemall数据库
|
||||
|
||||
litemall数据库基于nideshop中的[nideshop.sql](https://github.com/tumobi/nideshop/blob/master/nideshop.sql)数据库,然后在实际开发过程中进行了调整和修改:
|
||||
|
||||
* 删除了一些目前不必要的表;
|
||||
* 删除了表中一些目前不必要的字段;
|
||||
* 行政区域数据litemall_region没有采用原nideshop中的数据,而是采用了[Administrative-divisions-of-China](https://github.com/modood/Administrative-divisions-of-China);
|
||||
* 表中的某些字段采用JSON;
|
||||
* 表中的日期或时间字段采用DATE、DATETIME;
|
||||
* 字段的数据类型粗粒度化,例如避免MEDIUMINT,而是INT;
|
||||
* 表的数据做了清理、调整和补充(假数据)。
|
||||
|
||||
具体不同可以比较litemall-db模块下sql文件夹中nideshop.sql和litemall.sql。
|
||||
|
||||
以下讨论一些关键性设计
|
||||
|
||||
注意:
|
||||
> 以下设计基于个人理解,很可能存在不合理或者与实际系统不符合的地方。
|
||||
|
||||
### 2.1.1 商品和货品设计
|
||||
|
||||
这里商品存在商品,商品属性,商品规格,货品四种表
|
||||
|
||||
商品表是一种商品的基本信息,主要包括商品介绍,商品图片,商品所属类目,商品品牌商等;
|
||||
|
||||
商品参数表其实也是商品的基本信息,但是由于是一对多关系,因此不能直接保存在商品表中(虽然采用JSON也可以但是不合理),
|
||||
因此采用独立的商品参数表,通常是商品的一些公共基本商品参数;
|
||||
|
||||
商品规格表是商品进一步区分货品的标识,例如同样一款衣服,基本信息一致,基本属性一致,但是在尺寸这个属性上可以
|
||||
把衣服区分成多个货品,而且造成对应的数量和价格不一致。
|
||||
|
||||
商品规格和规格值存在以下几种关系:
|
||||
|
||||
* 单一规格和单一规格值,最常见的,即当前商品存在一种货品;
|
||||
* 单一规格和多个规格值,较常见,即当前商品基于某个规格存在多种货品,通常价格都是相同的,当然也可能不相同;
|
||||
* 多个规格和单一规格值,可以简化成第一种情况,或者采用第四种情况,通常实际情况下不常见;
|
||||
* 多个规格和多个规格值,通常是两种规格或者三种规格较为常见,而且对应的价格不完全相同。
|
||||
|
||||
货品则是最终面向用户购买的商品标识,存在数量和价格两种属性。
|
||||
|
||||
因此这里一个商品表项,存在(至少0个)多个商品属性表项目,存在(至少一个)多个商品规格表项,
|
||||
存在(至少一个)多个货品表项。
|
||||
|
||||
举例如下:
|
||||
|
||||
* 一个商品“2018春季衣服商品编号1111111”,
|
||||
* 存在两个商品参数,
|
||||
* 属性名称“面向人群”,属性值“男士”
|
||||
* 属性名称“面料”,属性值“100%棉”
|
||||
* 存在两种规格共八个商品规格项,
|
||||
* 规格名称“尺寸”,规则值“S”
|
||||
* 规格名称“尺寸”,规则值“M”
|
||||
* 规格名称“尺寸”,规则值“L”
|
||||
* 规格名称“尺寸”,规则值“XL”
|
||||
* 规格名称“尺寸”,规则值“XXL”
|
||||
* 规格名称“颜色”,规格值“蓝色”
|
||||
* 规格名称“颜色”,规格值“灰色”
|
||||
* 规格名称“颜色”,规格值“黑色”
|
||||
* 存在15个货品(尺寸*颜色=15个货品)
|
||||
* 货品“S蓝”,数量 100, 价格 100
|
||||
* 货品“M蓝”,数量 100, 价格 100
|
||||
* 货品“L蓝”,数量 100, 价格 100
|
||||
* 货品“XL蓝”,数量 100, 价格 100
|
||||
* 货品“XXL蓝”,数量 100, 价格 100
|
||||
* 货品“S灰”,数量 100, 价格 100
|
||||
* 货品“M灰”,数量 100, 价格 100
|
||||
* 货品“L灰”,数量 100, 价格 100
|
||||
* 货品“XL灰”,数量 100, 价格 100
|
||||
* 货品“XXL灰”,数量 100, 价格 100
|
||||
* 货品“S黑”,数量 100, 价格 100
|
||||
* 货品“M黑”,数量 100, 价格 100
|
||||
* 货品“L黑”,数量 100, 价格 100
|
||||
* 货品“XL黑”,数量 0, 价格 100
|
||||
* 货品“XXL黑”,数量 0, 价格 100
|
||||
|
||||
以下是一些细节的讨论:
|
||||
|
||||
* 商品表中可能存在数量和价格属性,而货品中也存在数量和价格属性,
|
||||
但是商品表中的数量和价格应该仅用于展示,而不能用于最终的订单价格计算。
|
||||
商品表的数量应该是所有货品数量的总和。
|
||||
商品表的价格应该和某个货品的价格一样,通常应该是所有货品价格的最小值。
|
||||
因此这里商品表的数量和价格属性可能可以采用自动计算。
|
||||
* 商品规格可以存在规格图片,效果是规格名称前放置规格图片
|
||||
* 货品也可以存在货品图片,效果是所有规格选定以后对应的货品有货,则在货品价格前放置货品图片
|
||||
|
||||
注意:
|
||||
|
||||
> 这里的设计可能与实际项目设计不一致,但是目前是可行的。
|
||||
> 商品的中文用语“商品”和英语用语“goods”,货品的中文用语“货品”和英语用语“product”可能是不正确的。
|
||||
|
||||
### 2.1.2 用户和微信用户设计
|
||||
|
||||
目前准备支持用户普通账号登陆和微信登陆两种方式,两种登陆方式仅仅采用一个litemall-user表可能不是很合适。此外,如果进一步支持其他多种第三方登陆,那么这里需要重新设计。
|
||||
|
||||
### 2.1.3 行政区域设计
|
||||
|
||||
原nideship.sql中存在region数据,但是litemall.sql的region数据则来自
|
||||
[Administrative-divisions-of-China](https://github.com/modood/Administrative-divisions-of-China)项目。从该项目中导入数据到litemall.sql的litemall-province、litemall-city、litemall-area和litemall-street四个表,然后重新生成一个新的litemall-region表。
|
||||
|
||||
### 2.1.4 订单设计
|
||||
|
||||
订单信息主要由基本信息、商品信息、地址信息、费用信息、快递信息、支付信息和其他信息组成。
|
||||
|
||||
* 基本信息
|
||||
订单创建时的一些基本信息。
|
||||
|
||||
* 商品信息
|
||||
由于订单可以存在多个商品,因此订单的商品信息是由独立的订单商品表记录(可能更应该称为货品)。
|
||||
|
||||
* 费用信息
|
||||
|
||||
* 快递信息
|
||||
目前快递信息仅仅记录快递公司、快递单号、快递发出时间、快递接收时间。而如果快递过程中如果存在一些异常,例如物品丢失,则目前系统难以处理。关于快递费的计算,目前采取简单方式,即满88元则免费,否则10元。
|
||||
|
||||
* 支付信息
|
||||
|
||||
|
||||
* 其他信息
|
||||
|
||||
#### 2.1.4.1 订单状态
|
||||
|
||||

|
||||
|
||||
订单分成几种基本的状态:
|
||||
|
||||
* 下单
|
||||
状态码101,此时订单生成,记录订单编号、收货地址信息、订单商品信息和订单相关费用信息;
|
||||
* 付款
|
||||
状态码201,此时用户微信支付付款,系统记录微信支付订单号、支付时间、支付状态;
|
||||
* 发货
|
||||
状态码301,此时商场已经发货,系统记录快递公司、快递单号、快递发送时间。
|
||||
当快递公司反馈用户签收后,系统记录快递到达时间。
|
||||
* 收货
|
||||
状态码401,当用户收到货以后点击确认收货,系统记录确认时间。
|
||||
此时,用户可以评价订单商品。
|
||||
|
||||
除了这几种正常状态以外,还存在一些非普通的状态:
|
||||
|
||||
* 订单取消
|
||||
状态码102,用户在生产订单以后未付款之前,点击取消按钮,系统记录结束时间
|
||||
* 订单取消并退款
|
||||
状态码202,用户付款以后未发货前,点击取消按钮,系统记录结束时间和退款信息
|
||||
* 系统自动确认收货
|
||||
状态码402,快递反馈商场用户已签收,但是用户却不点击确认收货按钮,
|
||||
此时系统在快递到达时间的一段时间后,自动确认收货。
|
||||
用户不能再点击确认收货按钮,但是可以评价订单商品
|
||||
|
||||
当然,以上的基本状态和非普通状态,和实际项目相比仍然相对简单。
|
||||
|
||||
此外,当订单状态码是102、202、401、402时,订单可以设置删除状态,此时
|
||||
用户查看自己订单信息时将看不到这些“已删除”的订单。
|
||||
|
||||
|
||||
#### 2.1.4.2 状态码所支持的操作
|
||||
|
||||
不同的状态码下面,用户能够进行的操作是:
|
||||
|
||||
* 101
|
||||
此时,用户可以“订单支付”、“订单取消”
|
||||
* 102
|
||||
此时,用户可以“订单删除”
|
||||
* 201
|
||||
此时,用户可以“订单取消”(并退款)
|
||||
* 202
|
||||
此时,用户可以“订单删除”
|
||||
* 301
|
||||
此时,用户可以“确认收货”
|
||||
* 401
|
||||
此时,用户可以“订单删除”、“评价”、“再次购买”
|
||||
* 402
|
||||
此时,用户可以“订单删除”、“评价”、“再次购买”
|
||||
|
||||
#### 2.1.4.3 售后处理
|
||||
|
||||
目前不支持售后或退货相关业务。
|
||||
|
||||
#### 2.1.4.4 黑名单
|
||||
|
||||
从一些资料看,如果用户订单多次取消,应该加入黑名单。
|
||||
目前不支持。
|
||||
|
||||
## 2.2 litemall-db
|
||||
|
||||

|
||||
|
||||
这里litemall-db模块可以分成以下几种代码:
|
||||
|
||||
* mybatis generator自动化代码
|
||||
* 业务代码
|
||||
* 安全代码
|
||||
* JSON支持代码
|
||||
* 配置代码
|
||||
|
||||
### 2.2.1 自动化代码
|
||||
|
||||
通过mybatis generator插件可以自动生成三种代码:
|
||||
|
||||
* src文件夹`domain` Java代码
|
||||
* src文件夹`dao` Java代码
|
||||
* resources文件夹`dao` Mapper代码
|
||||
|
||||
这里的代码封装了对数据库的操作,因此用户不需要直接操作sql代码,而是直接操作Java代码即可完成对数据库的访问处理。
|
||||
|
||||
当然,为了达到数据库访问效率,用户也可以自定义mapper文件和对应的Java代码,但是至少目前这里不采用。例如,当需要访问两个表的数据时,这里是在业务层通过Java代码遍历的形式来访问两个表。
|
||||
|
||||
### 2.2.2 业务代码
|
||||
|
||||
基于2.2.1的代码,业务代码处理一些具体业务相关的操作,对其他模块提供具体的服务。
|
||||
|
||||
### 2.2.3 安全代码
|
||||
|
||||
### 2.2.4 JSON支持代码
|
||||
|
||||
### 2.2.5 配置代码
|
||||
|
||||
采用Java注解的方式来完成一些特定的配置操作。
|
||||
|
||||
## 2.3 litemall-os-api
|
||||
|
||||
对象存储服务目前的目标是支持图片的上传下载。
|
||||
|
||||
### 2.3.1 业务
|
||||
|
||||
支持服务:
|
||||
|
||||
* 列表
|
||||
* 创建
|
||||
* 修改
|
||||
* 读取
|
||||
* 删除
|
||||
* 下载,即下载对象数据文件
|
||||
* 访问,即直接访问对象数据
|
||||
|
||||
### 2.3.2 安全
|
||||
|
||||
警告
|
||||
> 目前这里没有任何安全机制,这意味着任何人如果知道对象存储服务的地址,都可以直接存储访问对象数据。
|
||||
|
||||
这样简化的目的是对象存储服务建议最终采用云服务,因此这里仅仅实现一个简单的服务面向测试开发。
|
||||
|
||||
如果用户需要局域网部署,那么这里需要加入一定的安全机制。
|
||||
47
doc/3.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# 3 litemall小商城
|
||||
|
||||
技术:
|
||||
|
||||
* 小商城前端,即litemall-wx模块
|
||||
* 微信小程序
|
||||
* 小商城后端,即litemall-wx-api模块
|
||||
* Spring Boot 1.5.10
|
||||
* Spring MVC
|
||||
* [weixin-java-tools](https://gitee.com/binary/weixin-java-tools)
|
||||
|
||||
|
||||
目前发现需要完善的:
|
||||
|
||||
* 支付功能
|
||||
* 运费计算
|
||||
* 优惠券功能
|
||||
* 商品搜索
|
||||
* 进一步区分商品和货品的关系
|
||||
* 地址优化,目前每一次点击都会请求后台,应该缓存已有的数据
|
||||
* 商品数量和规格中,如果货品数量不足,则显示不能点击的效果
|
||||
* 登陆逻辑重新设计,如果用户没有登陆,则相关页面显示登陆的效果
|
||||
|
||||
## 3.1 litemall-wx-api
|
||||
|
||||
### 3.1.1 业务
|
||||
|
||||
### 3.1.2 安全
|
||||
|
||||
### 3.1.3 支付
|
||||
|
||||
准备采用weixin-java-tools工具简化微信支付代码的开发。
|
||||
由于需要商户相关信息,目前没有开发。
|
||||
|
||||
## 3.2 litemall-wx
|
||||
|
||||
这里的代码基于[nideshop-mini-program](https://gitee.com/tumobi/nideshop-mini-program),但是做了一定的修改:
|
||||
|
||||
* 数据属性名称调整,原项目中数据属性名称是下划线法命名(例如goods_id),而这里采用骆驼式命名法(例如goodsId),因此代码中需要进行相应调整;
|
||||
* 代码清理重构,删除了一些目前不必要的文件,梳理一些逻辑功能;
|
||||
* BUG修补,修改了一些错误;
|
||||
* 功能完善拓展,例如商品立即购买功能、商品评价功能;
|
||||
|
||||
具体变化可以采用工具进行对比。
|
||||
|
||||
注意
|
||||
> 目前litemall-wx项目代码基于nideshop-mini-program的commit版本[acbf6276eb27abc6a48887cddd223d7261f0088e](https://github.com/tumobi/nideshop-mini-program/commit/acbf6276eb27abc6a48887cddd223d7261f0088e)。由于改动变化较大,因此之后litemall-wx将独立开发,nideshop-mini-program的跟新不一定会合并到litemall-wx中。
|
||||
47
doc/4.md
Normal file
@@ -0,0 +1,47 @@
|
||||
|
||||
# 4 litemall后台管理
|
||||
|
||||
这里的后台管理业务参考了[platform](https://gitee.com/fuyang_lipengjun/platform).
|
||||
|
||||
技术架构:
|
||||
|
||||
* 后台管理前端,即litemall-admin模块
|
||||
* vue
|
||||
* vuex
|
||||
* vue-router
|
||||
* axios
|
||||
* element-ui
|
||||
* vue-element-admin
|
||||
* 其他,见package.json
|
||||
* 后台管理后端, 即litemall-admin-api模块
|
||||
* Spring Boot 1.5.10
|
||||
* Spring MVC
|
||||
|
||||
目前存在的问题
|
||||
|
||||
* 大部分页面仅仅是一个表CRUD的效果,交互性一般。
|
||||
例如,显示商品的时候,只是简单显示表中保存的类目ID和品牌商ID,更好的效果可能是显示对应的类目名称和品牌商名称,同时能够显示更详细的类目信息和品牌商信息。
|
||||
* 地址优化,目前每一次点击都会请求后台,应该缓存已有的数据
|
||||
* 管理员角色和权限设计
|
||||
* 首页中实现一些小组件,同时点击能够跳转相应页面
|
||||
* 查询时排序功能
|
||||
* 业务功能重新设计,例如即使是管理员也不能删除修改用户的相关数据
|
||||
* 用户密码加密存储
|
||||
|
||||
## 4.1 litemall-admin-api
|
||||
|
||||
|
||||
### 4.1.1 业务
|
||||
|
||||
### 4.1.2 安全配置
|
||||
|
||||
### 4.1.3 CROS配置
|
||||
|
||||
## 4.2 litemall-admin
|
||||
|
||||
litemall-admin模块的代码基于[vue-element-admin](https://github.com/PanJiaChen/vue-element-admin)
|
||||
|
||||
|
||||
## 4.3 开发新组件
|
||||
|
||||
这里介绍开发一个新的组件的流程。
|
||||
8
doc/5.md
Normal file
@@ -0,0 +1,8 @@
|
||||
|
||||
# 5 litemall商场网站
|
||||
|
||||
目前不开发
|
||||
|
||||
## 5.1 litemall-web-api
|
||||
|
||||
## 5.2 litemall-web
|
||||
109
doc/6.md
Normal file
@@ -0,0 +1,109 @@
|
||||
# 6 下一步计划
|
||||
|
||||
6.1节涉及到技术层面需要改进的部分,而6.2节则是业务方面未实现的部分,这两个部分的代码都会在本项目中实现。而6.3节会进一步完善本项目的安全和性能,但是不一定会在本项目中实现,因为会增加相当大的复杂性。
|
||||
|
||||
## 6.1 技术
|
||||
|
||||
### 6.1.1 ENUM
|
||||
数据库中涉及到枚举类型的字段,目前设置成VARCHAR。
|
||||
下一步应该设计不同的业务enum类型,然后mybatis自定义BaseTypeHandler来处理不同的枚举类型。
|
||||
|
||||
### 6.1.2 litemall-db AutoConig
|
||||
目前,litemall-os-api、litemall-admin-api和litemall-wx-api引入litemall-db的时候,需要在Application类中显式注解查找包和MapperScan来对litemall-db中的mapper查找,此外需要在application.properties配置文件中完成对数据库、数据池等配置。
|
||||
例如
|
||||
```
|
||||
@SpringBootApplication(scanBasePackages={"org.linlinjava.litemall.admin","org.linlinjava.litemall.db"})
|
||||
@MapperScan("org.linlinjava.litemall.db.dao")
|
||||
public class Application {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
下一步,应该自动部署,即引入litemall-db则会自动引入对mapper的查找,
|
||||
同时自动部署对数据库、PageHelper和Druid的配置。
|
||||
|
||||
### 6.1.3 统一对日期时间域的处理
|
||||
目前,数据库的日期时间域有的采用DATE,有的是DATETIME,而对应Java用LocalDate和LocalDateTime。
|
||||
下一步应该根据具体业务功能采用合适的。
|
||||
|
||||
### 6.1.4 vue-element-admin跟新
|
||||
目前的vue-element-admin基于element 2.0.8, 因此element的很多修复没有跟新。
|
||||
|
||||
### 6.1.5 事务管理
|
||||
|
||||
目前没有事务管理,因此如果直接把项目用于正式运行中,可能会存在数据不一致等问题。
|
||||
|
||||
### 6.1.6 小程序登陆设计
|
||||
|
||||
个人觉得目前nideshop-mini-program里的登陆设计内部实现不是很合理。
|
||||
|
||||
### 6.1.n 代码重构
|
||||
|
||||
技术不断迭代开发中,应该在业务基本完成和功能基本完善以后,
|
||||
重新审视代码架构和技术,或者重构代码,或者采用更为合理的技术。
|
||||
|
||||
## 6.2 业务
|
||||
|
||||
### 6.2.1 支付模块
|
||||
|
||||
目前微信支付模块因缺乏支付权限而不能开发。
|
||||
|
||||
### 6.2.2 任务日程模块
|
||||
|
||||
部分业务需要引入任务管理服务,例如订单下单以后一个小时未支付则自动失效关闭。
|
||||
|
||||
### 6.2.3 监控管理
|
||||
|
||||
项目运行的整个运行过程应该需要监控管理
|
||||
|
||||
### 6.2.4 权限管理
|
||||
|
||||
目前安全实现非常粗糙,仅仅依赖管理员的用户名和密码。
|
||||
更好的做法是引入角色权限机制。
|
||||
|
||||
## 6.3 企业级
|
||||
|
||||
### 6.3.1 安全(必须)
|
||||
|
||||
尽在系统所有业务功能完整实现以后。
|
||||
|
||||
### 6.3.2 性能(建议)
|
||||
|
||||
仅在系统所有业务功能完整实现以后。
|
||||
|
||||
性能的提升存在多种方案。
|
||||
|
||||
目前考虑到的技术方案:
|
||||
|
||||
* 采用内存数据库,如redis,缓存一些改动较少的数据,例如行政区域数据。
|
||||
* 数据库方面可以引入冗余,例如首页的数据可以先从其他表更新到一个独立的表。
|
||||
|
||||
### 6.3.3 对象存储云服务(建议)
|
||||
|
||||
仅在系统所有业务功能完整实现以后。
|
||||
|
||||
对象存储云服务不一定是必须的:
|
||||
|
||||
* 局域网中只能采用内部对象存储服务
|
||||
* 对象存储云服务也是一笔开销
|
||||
* 引入对象存储云服务也增加了一定的复杂性
|
||||
* 导致对具体云平台的耦合
|
||||
|
||||
当然,对象存储云服务的益处也是毋庸置疑的,因此建议部署使用。
|
||||
|
||||
### 6.3.4 云数据库(必须)
|
||||
|
||||
同上,如果仅在局域网中部署项目,那么数据库的部署也只能是在局域网中,但是在互联网中部署应用,数据的重要性和优先级是最高的,采用云数据库可以方便带来其提供的安全和性能服务。
|
||||
|
||||
### 6.3.5 短信服务(必须)
|
||||
|
||||
真正的项目里面肯定需要短信功能。
|
||||
|
||||
### 6.3.6 推荐系统(可选)
|
||||
|
||||
目前的关键字是管理员设置,然后用户的搜索时匹配关键字,因此需要专业的推荐系统。
|
||||
|
||||
### 6.3.6 Spring Boot 2.0迁移(可选)
|
||||
BIN
doc/pic/1.png
Normal file
|
After Width: | Height: | Size: 124 KiB |
BIN
doc/pic/2.png
Normal file
|
After Width: | Height: | Size: 64 KiB |
BIN
doc/pic/3.png
Normal file
|
After Width: | Height: | Size: 288 KiB |
BIN
doc/pic/4.png
Normal file
|
After Width: | Height: | Size: 167 KiB |
BIN
doc/pic/5.gif
Normal file
|
After Width: | Height: | Size: 9.0 MiB |
BIN
doc/pic/litemall.ico
Normal file
|
After Width: | Height: | Size: 66 KiB |
BIN
doc/pic/litemall.png
Normal file
|
After Width: | Height: | Size: 8.3 KiB |
BIN
doc/pic1/1-1.png
Normal file
|
After Width: | Height: | Size: 71 KiB |
BIN
doc/pic1/1-2.png
Normal file
|
After Width: | Height: | Size: 116 KiB |
BIN
doc/pic1/1-3.png
Normal file
|
After Width: | Height: | Size: 124 KiB |
BIN
doc/pic1/1-4.png
Normal file
|
After Width: | Height: | Size: 57 KiB |
BIN
doc/pic1/1-5.png
Normal file
|
After Width: | Height: | Size: 261 KiB |
BIN
doc/pic1/1-6.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
doc/pic2/2-1.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
doc/pic2/2-2.png
Normal file
|
After Width: | Height: | Size: 118 KiB |
2
litemall-admin-api/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
|
||||
/target/
|
||||
65
litemall-admin-api/litemall-admin-api.iml
Normal file
@@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
|
||||
<output url="file://$MODULE_DIR$/target/classes" />
|
||||
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="litemall-db" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:1.5.10.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:1.5.10.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.1.11" level="project" />
|
||||
<orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.1.11" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.25" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.slf4j:jcl-over-slf4j:1.7.25" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.25" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.slf4j:log4j-over-slf4j:1.7.25" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-core:4.3.14.RELEASE" level="project" />
|
||||
<orderEntry type="library" scope="RUNTIME" name="Maven: org.yaml:snakeyaml:1.17" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-starter:1.3.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:1.5.10.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.tomcat:tomcat-jdbc:8.5.27" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.tomcat:tomcat-juli:8.5.27" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-jdbc:4.3.14.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-tx:4.3.14.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-autoconfigure:1.3.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.mybatis:mybatis:3.4.6" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:1.3.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-starter:1.2.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-autoconfigure:1.2.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper:5.1.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:1.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: mysql:mysql-connector-java:5.1.45" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.alibaba:druid-spring-boot-starter:1.1.6" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.alibaba:druid:1.1.6" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.8.10" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:1.5.10.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:1.5.10.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-core:8.5.27" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.tomcat:tomcat-annotations-api:8.5.27" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:8.5.27" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:8.5.27" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.hibernate:hibernate-validator:5.3.6.Final" level="project" />
|
||||
<orderEntry type="library" name="Maven: javax.validation:validation-api:1.1.0.Final" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.3.1.Final" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.3.4" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-web:4.3.14.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-aop:4.3.14.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-beans:4.3.14.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-context:4.3.14.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-webmvc:4.3.14.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-expression:4.3.14.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.8.10" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.8.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.8.10" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-devtools:1.5.10.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:1.5.10.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:1.5.10.RELEASE" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
71
litemall-admin-api/pom.xml
Normal file
@@ -0,0 +1,71 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.linlinjava</groupId>
|
||||
<artifactId>litemall-admin-api</artifactId>
|
||||
<version>0.1.0</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>1.5.10.RELEASE</version>
|
||||
<relativePath></relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
<maven.test.skip>true</maven.test.skip>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.linlinjava</groupId>
|
||||
<artifactId>litemall-db</artifactId>
|
||||
<version>0.1.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Spring Boot Web 依赖 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||
<version>2.8.10</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Spring Boot Shiro 依赖 -->
|
||||
<!--<dependency>-->
|
||||
<!--<groupId>org.apache.shiro</groupId>-->
|
||||
<!--<artifactId>shiro-spring-boot-web-starter</artifactId>-->
|
||||
<!--<version>1.4.0</version>-->
|
||||
<!--</dependency>-->
|
||||
|
||||
<!-- 热部署模块 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<executable>true</executable>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,15 @@
|
||||
package org.linlinjava.litemall.admin;
|
||||
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication(scanBasePackages={"org.linlinjava.litemall.admin","org.linlinjava.litemall.db"})
|
||||
@MapperScan("org.linlinjava.litemall.db.dao")
|
||||
public class Application {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package org.linlinjava.litemall.admin.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
|
||||
@Target(ElementType.PARAMETER)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface LoginAdmin {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package org.linlinjava.litemall.admin.annotation.support;
|
||||
|
||||
import org.linlinjava.litemall.admin.annotation.LoginAdmin;
|
||||
import org.linlinjava.litemall.admin.service.AdminTokenManager;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.web.bind.support.WebDataBinderFactory;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
|
||||
|
||||
public class LoginAdminHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
|
||||
public static final String LOGIN_TOKEN_KEY = "X-Token";
|
||||
@Override
|
||||
public boolean supportsParameter(MethodParameter parameter) {
|
||||
return parameter.getParameterType().isAssignableFrom(Integer.class)&¶meter.hasParameterAnnotation(LoginAdmin.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer container,
|
||||
NativeWebRequest request, WebDataBinderFactory factory) throws Exception {
|
||||
|
||||
// return new Integer(1);
|
||||
String token = request.getHeader(LOGIN_TOKEN_KEY);
|
||||
if(token == null || token.isEmpty()){
|
||||
return null;
|
||||
}
|
||||
|
||||
return AdminTokenManager.getUserId(token);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.linlinjava.litemall.admin.config;
|
||||
|
||||
import org.linlinjava.litemall.admin.annotation.support.LoginAdminHandlerMethodArgumentResolver;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Configuration
|
||||
public class AdminConfig extends WebMvcConfigurerAdapter {
|
||||
@Override
|
||||
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
|
||||
argumentResolvers.add(new LoginAdminHandlerMethodArgumentResolver());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.linlinjava.litemall.admin.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.cors.CorsConfiguration;
|
||||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||
import org.springframework.web.filter.CorsFilter;
|
||||
|
||||
@Configuration
|
||||
public class CorsConfig {
|
||||
private CorsConfiguration buildConfig() {
|
||||
CorsConfiguration corsConfiguration = new CorsConfiguration();
|
||||
corsConfiguration.addAllowedOrigin("*"); // 1 设置访问源地址
|
||||
corsConfiguration.addAllowedHeader("*"); // 2 设置访问源请求头
|
||||
corsConfiguration.addAllowedMethod("*"); // 3 设置访问源请求方法
|
||||
return corsConfiguration;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CorsFilter corsFilter() {
|
||||
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||
source.registerCorsConfiguration("/**", buildConfig()); // 4 对接口配置跨域设置
|
||||
return new CorsFilter(source);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package org.linlinjava.litemall.admin.config;
|
||||
|
||||
import org.linlinjava.litemall.db.util.ResponseUtil;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
|
||||
|
||||
@ControllerAdvice
|
||||
public class GlobalExceptionHandler {
|
||||
|
||||
|
||||
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
|
||||
@ResponseBody
|
||||
public Object argumentHandler(MethodArgumentTypeMismatchException e){
|
||||
e.printStackTrace();
|
||||
return ResponseUtil.badArgumentValue();
|
||||
}
|
||||
|
||||
@ExceptionHandler(Exception.class)
|
||||
@ResponseBody
|
||||
public Object exceptionHandler(Exception e){
|
||||
e.printStackTrace();
|
||||
return ResponseUtil.serious();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package org.linlinjava.litemall.admin.config;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
|
||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
|
||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
@Configuration
|
||||
public class JacksonConfig {
|
||||
@Bean
|
||||
@Primary
|
||||
public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
|
||||
JavaTimeModule javaTimeModule = new JavaTimeModule();
|
||||
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
|
||||
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
|
||||
javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
|
||||
|
||||
ObjectMapper objectMapper = builder.createXmlMapper(false).build();
|
||||
objectMapper.registerModule(javaTimeModule);
|
||||
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
|
||||
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
||||
return objectMapper;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package org.linlinjava.litemall.admin.dao;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
public class AdminToken {
|
||||
private Integer userId;
|
||||
private String token;
|
||||
private LocalDateTime expireTime;
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
public void setUserId(Integer userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public void setToken(String token) {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
public void setExpireTime(LocalDateTime expireTime) {
|
||||
this.expireTime = expireTime;
|
||||
}
|
||||
|
||||
public void setUpdateTime(LocalDateTime updateTime) {
|
||||
this.updateTime = updateTime;
|
||||
}
|
||||
|
||||
public Integer getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
public LocalDateTime getExpireTime() {
|
||||
return expireTime;
|
||||
}
|
||||
|
||||
public LocalDateTime getUpdateTime() {
|
||||
return updateTime;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package org.linlinjava.litemall.admin.service;
|
||||
|
||||
import org.linlinjava.litemall.admin.dao.AdminToken;
|
||||
import org.linlinjava.litemall.db.util.CharUtil;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class AdminTokenManager {
|
||||
private static Map<String, AdminToken> tokenMap = new HashMap<>();
|
||||
private static Map<Integer, AdminToken> idMap = new HashMap<>();
|
||||
|
||||
public static Integer getUserId(String token) {
|
||||
|
||||
AdminToken userToken = tokenMap.get(token);
|
||||
if(userToken == null){
|
||||
return null;
|
||||
}
|
||||
|
||||
if(userToken.getExpireTime().isBefore(LocalDateTime.now())){
|
||||
tokenMap.remove(token);
|
||||
idMap.remove(userToken.getUserId());
|
||||
return null;
|
||||
}
|
||||
|
||||
return userToken.getUserId();
|
||||
}
|
||||
|
||||
|
||||
public static AdminToken generateToken(Integer id){
|
||||
AdminToken userToken = idMap.get(id);
|
||||
if(userToken != null) {
|
||||
tokenMap.remove(userToken.getToken());
|
||||
idMap.remove(id);
|
||||
}
|
||||
|
||||
String token = CharUtil.getRandomString(32);
|
||||
while (tokenMap.containsKey(token)) {
|
||||
token = CharUtil.getRandomString(32);
|
||||
}
|
||||
|
||||
LocalDateTime update = LocalDateTime.now();
|
||||
LocalDateTime expire = update.plusDays(1);
|
||||
|
||||
userToken = new AdminToken();
|
||||
userToken.setToken(token);
|
||||
userToken.setUpdateTime(update);
|
||||
userToken.setExpireTime(expire);
|
||||
userToken.setUserId(id);
|
||||
tokenMap.put(token, userToken);
|
||||
idMap.put(id, userToken);
|
||||
|
||||
return userToken;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package org.linlinjava.litemall.admin.web;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.linlinjava.litemall.admin.annotation.LoginAdmin;
|
||||
import org.linlinjava.litemall.db.domain.LitemallAd;
|
||||
import org.linlinjava.litemall.db.service.LitemallAdService;
|
||||
import org.linlinjava.litemall.db.util.ResponseUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/ad")
|
||||
public class AdController {
|
||||
private final Log logger = LogFactory.getLog(AdController.class);
|
||||
|
||||
@Autowired
|
||||
private LitemallAdService adService;
|
||||
|
||||
@GetMapping("/list")
|
||||
public Object list(@LoginAdmin Integer adminId,
|
||||
String name, String content,
|
||||
@RequestParam(value = "page", defaultValue = "1") Integer page,
|
||||
@RequestParam(value = "limit", defaultValue = "10") Integer limit,
|
||||
String sort, String order){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
|
||||
List<LitemallAd> adList = adService.querySelective(name, content, page, limit, sort, order);
|
||||
int total = adService.countSelective(name, content, page, limit, sort, order);
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("total", total);
|
||||
data.put("items", adList);
|
||||
|
||||
return ResponseUtil.ok(data);
|
||||
}
|
||||
|
||||
@PostMapping("/create")
|
||||
public Object create(@LoginAdmin Integer adminId, @RequestBody LitemallAd ad){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
adService.add(ad);
|
||||
return ResponseUtil.ok(ad);
|
||||
}
|
||||
|
||||
@GetMapping("/read")
|
||||
public Object read(@LoginAdmin Integer adminId, Integer id){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
|
||||
if(id == null){
|
||||
return ResponseUtil.badArgument();
|
||||
}
|
||||
|
||||
LitemallAd brand = adService.findById(id);
|
||||
return ResponseUtil.ok(brand);
|
||||
}
|
||||
|
||||
@PostMapping("/update")
|
||||
public Object update(@LoginAdmin Integer adminId, @RequestBody LitemallAd ad){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
adService.updateById(ad);
|
||||
return ResponseUtil.ok(ad);
|
||||
}
|
||||
|
||||
@PostMapping("/delete")
|
||||
public Object delete(@LoginAdmin Integer adminId, @RequestBody LitemallAd ad){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
adService.deleteById(ad.getId());
|
||||
return ResponseUtil.ok();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
package org.linlinjava.litemall.admin.web;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.linlinjava.litemall.admin.annotation.LoginAdmin;
|
||||
import org.linlinjava.litemall.db.domain.LitemallAddress;
|
||||
import org.linlinjava.litemall.db.service.LitemallAddressService;
|
||||
import org.linlinjava.litemall.db.service.LitemallRegionService;
|
||||
import org.linlinjava.litemall.db.util.ResponseUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/address")
|
||||
public class AddressController {
|
||||
private final Log logger = LogFactory.getLog(AddressController.class);
|
||||
|
||||
@Autowired
|
||||
private LitemallAddressService addressService;
|
||||
@Autowired
|
||||
private LitemallRegionService regionService;
|
||||
|
||||
private Map<String, Object> toVo (LitemallAddress address){
|
||||
Map<String, Object> addressVo = new HashMap<>();
|
||||
addressVo.put("id", address.getId());
|
||||
addressVo.put("userId", address.getUserId());
|
||||
addressVo.put("name", address.getName());
|
||||
addressVo.put("mobile", address.getMobile());
|
||||
addressVo.put("isDefault", address.getIsDefault());
|
||||
addressVo.put("provinceId", address.getProvinceId());
|
||||
addressVo.put("cityId", address.getCityId());
|
||||
addressVo.put("areaId", address.getAreaId());
|
||||
addressVo.put("address", address.getAddress());
|
||||
String province = regionService.findById(address.getProvinceId()).getName();
|
||||
String city = regionService.findById(address.getCityId()).getName();
|
||||
String area = regionService.findById(address.getAreaId()).getName();
|
||||
addressVo.put("province", province);
|
||||
addressVo.put("city", city);
|
||||
addressVo.put("area", area);
|
||||
return addressVo;
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
public Object list(@LoginAdmin Integer adminId,
|
||||
Integer userId, String name,
|
||||
@RequestParam(value = "page", defaultValue = "1") Integer page,
|
||||
@RequestParam(value = "limit", defaultValue = "10") Integer limit,
|
||||
String sort, String order){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.fail401();
|
||||
}
|
||||
|
||||
List<LitemallAddress> addressList = addressService.querySelective(userId, name, page, limit, sort, order);
|
||||
int total = addressService.countSelective(userId, name, page, limit, sort, order);
|
||||
|
||||
List<Map<String, Object>> addressVoList = new ArrayList<>(addressList.size());
|
||||
for(LitemallAddress address : addressList){
|
||||
Map<String, Object> addressVo = toVo(address);
|
||||
addressVoList.add(addressVo);
|
||||
}
|
||||
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("total", total);
|
||||
data.put("items", addressVoList);
|
||||
|
||||
return ResponseUtil.ok(data);
|
||||
}
|
||||
|
||||
@PostMapping("/create")
|
||||
public Object create(@LoginAdmin Integer adminId, @RequestBody LitemallAddress address){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.fail401();
|
||||
}
|
||||
|
||||
addressService.add(address);
|
||||
|
||||
Map<String, Object> addressVo = toVo(address);
|
||||
return ResponseUtil.ok(addressVo);
|
||||
}
|
||||
|
||||
@GetMapping("/read")
|
||||
public Object read(@LoginAdmin Integer adminId, Integer addressId){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.fail401();
|
||||
}
|
||||
|
||||
LitemallAddress address = addressService.findById(addressId);
|
||||
Map<String, Object> addressVo = toVo(address);
|
||||
return ResponseUtil.ok(addressVo);
|
||||
}
|
||||
|
||||
@PostMapping("/update")
|
||||
public Object update(@LoginAdmin Integer adminId, @RequestBody LitemallAddress address){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.fail401();
|
||||
}
|
||||
addressService.updateById(address);
|
||||
Map<String, Object> addressVo = toVo(address);
|
||||
return ResponseUtil.ok(addressVo);
|
||||
}
|
||||
|
||||
@PostMapping("/delete")
|
||||
public Object delete(@LoginAdmin Integer adminId, @RequestBody LitemallAddress address){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.fail401();
|
||||
}
|
||||
addressService.delete(address.getId());
|
||||
return ResponseUtil.ok();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
package org.linlinjava.litemall.admin.web;
|
||||
|
||||
import org.linlinjava.litemall.admin.annotation.LoginAdmin;
|
||||
import org.linlinjava.litemall.admin.service.AdminTokenManager;
|
||||
import org.linlinjava.litemall.db.domain.LitemallAdmin;
|
||||
import org.linlinjava.litemall.db.service.LitemallAdminService;
|
||||
import org.linlinjava.litemall.db.util.ResponseUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/admin")
|
||||
public class AdminController {
|
||||
@Autowired
|
||||
private LitemallAdminService adminService;
|
||||
|
||||
@GetMapping("/info")
|
||||
public Object info(String token){
|
||||
Integer adminId = AdminTokenManager.getUserId(token);
|
||||
if(adminId == null){
|
||||
return ResponseUtil.badArgumentValue();
|
||||
}
|
||||
LitemallAdmin admin = adminService.findById(adminId);
|
||||
if(admin == null){
|
||||
return ResponseUtil.badArgumentValue();
|
||||
}
|
||||
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("name", admin.getUsername());
|
||||
data.put("avatar", admin.getAvatar());
|
||||
|
||||
// 目前roles不支持,这里简单设置admin
|
||||
List<String> roles = new ArrayList<>();
|
||||
roles.add("admin");
|
||||
data.put("roles", roles);
|
||||
data.put("introduction", "admin introduction");
|
||||
return ResponseUtil.ok(data);
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
public Object list(@LoginAdmin Integer adminId,
|
||||
String username,
|
||||
@RequestParam(value = "page", defaultValue = "1") Integer page,
|
||||
@RequestParam(value = "limit", defaultValue = "10") Integer limit,
|
||||
String sort, String order){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
|
||||
List<LitemallAdmin> adminList = adminService.querySelective(username, page, limit, sort, order);
|
||||
int total = adminService.countSelective(username, page, limit, sort, order);
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("total", total);
|
||||
data.put("items", adminList);
|
||||
|
||||
return ResponseUtil.ok(data);
|
||||
}
|
||||
|
||||
@PostMapping("/create")
|
||||
public Object create(@LoginAdmin Integer adminId, @RequestBody LitemallAdmin admin){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
adminService.add(admin);
|
||||
return ResponseUtil.ok(admin);
|
||||
}
|
||||
|
||||
@GetMapping("/read")
|
||||
public Object read(@LoginAdmin Integer adminId, Integer id){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
|
||||
if(id == null){
|
||||
return ResponseUtil.badArgument();
|
||||
}
|
||||
|
||||
LitemallAdmin admin = adminService.findById(id);
|
||||
return ResponseUtil.ok(admin);
|
||||
}
|
||||
|
||||
@PostMapping("/update")
|
||||
public Object update(@LoginAdmin Integer adminId, @RequestBody LitemallAdmin admin){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
adminService.updateById(admin);
|
||||
return ResponseUtil.ok(admin);
|
||||
}
|
||||
|
||||
@PostMapping("/delete")
|
||||
public Object delete(@LoginAdmin Integer adminId, @RequestBody LitemallAdmin admin){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
|
||||
Integer anotherAdminId = admin.getId();
|
||||
if(anotherAdminId.intValue() == 1){
|
||||
return ResponseUtil.fail(403, "超级用户不能删除");
|
||||
}
|
||||
adminService.deleteById(anotherAdminId);
|
||||
return ResponseUtil.ok();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package org.linlinjava.litemall.admin.web;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.linlinjava.litemall.admin.dao.AdminToken;
|
||||
import org.linlinjava.litemall.admin.annotation.LoginAdmin;
|
||||
import org.linlinjava.litemall.admin.service.AdminTokenManager;
|
||||
import org.linlinjava.litemall.db.domain.LitemallAdmin;
|
||||
import org.linlinjava.litemall.db.service.LitemallAdminService;
|
||||
import org.linlinjava.litemall.db.util.JacksonUtil;
|
||||
import org.linlinjava.litemall.db.util.ResponseUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/login")
|
||||
public class AuthController {
|
||||
private final Log logger = LogFactory.getLog(AuthController.class);
|
||||
|
||||
@Autowired
|
||||
private LitemallAdminService adminService;
|
||||
|
||||
/*
|
||||
* { username : value, password : value }
|
||||
*/
|
||||
@PostMapping("/login")
|
||||
public Object login(@RequestBody String body){
|
||||
String username = JacksonUtil.parseString(body, "username");
|
||||
String password = JacksonUtil.parseString(body, "password");
|
||||
|
||||
if(StringUtils.isEmpty(username) || StringUtils.isEmpty(password)){
|
||||
return ResponseUtil.badArgument();
|
||||
}
|
||||
|
||||
List<LitemallAdmin> adminList = adminService.findAdmin(username, password);
|
||||
Assert.state(adminList.size() < 2, "同一个用户名存在两个账户");
|
||||
if(adminList.size() == 0){
|
||||
return ResponseUtil.badArgumentValue();
|
||||
}
|
||||
|
||||
LitemallAdmin admin = adminList.get(0);
|
||||
Integer adminId = admin.getId();
|
||||
// token
|
||||
AdminToken adminToken = AdminTokenManager.generateToken(adminId);
|
||||
|
||||
return ResponseUtil.ok(adminToken.getToken());
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
@PostMapping("/logout")
|
||||
public Object login(@LoginAdmin Integer adminId){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
|
||||
return ResponseUtil.ok();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package org.linlinjava.litemall.admin.web;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.linlinjava.litemall.admin.annotation.LoginAdmin;
|
||||
import org.linlinjava.litemall.db.domain.LitemallBrand;
|
||||
import org.linlinjava.litemall.db.service.LitemallBrandService;
|
||||
import org.linlinjava.litemall.db.util.ResponseUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/brand")
|
||||
public class BrandController {
|
||||
private final Log logger = LogFactory.getLog(BrandController.class);
|
||||
|
||||
@Autowired
|
||||
private LitemallBrandService brandService;
|
||||
|
||||
@GetMapping("/list")
|
||||
public Object list(@LoginAdmin Integer adminId,
|
||||
String id, String name,
|
||||
@RequestParam(value = "page", defaultValue = "1") Integer page,
|
||||
@RequestParam(value = "limit", defaultValue = "10") Integer limit,
|
||||
String sort, String order){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
|
||||
List<LitemallBrand> brandList = brandService.querySelective(id, name, page, limit, sort, order);
|
||||
int total = brandService.countSelective(id, name, page, limit, sort, order);
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("total", total);
|
||||
data.put("items", brandList);
|
||||
|
||||
return ResponseUtil.ok(data);
|
||||
}
|
||||
|
||||
@PostMapping("/create")
|
||||
public Object create(@LoginAdmin Integer adminId, @RequestBody LitemallBrand brand){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
brandService.add(brand);
|
||||
return ResponseUtil.ok(brand);
|
||||
}
|
||||
|
||||
@GetMapping("/read")
|
||||
public Object read(@LoginAdmin Integer adminId, Integer id){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
|
||||
if(id == null){
|
||||
return ResponseUtil.badArgument();
|
||||
}
|
||||
|
||||
LitemallBrand brand = brandService.findById(id);
|
||||
return ResponseUtil.ok(brand);
|
||||
}
|
||||
|
||||
@PostMapping("/update")
|
||||
public Object update(@LoginAdmin Integer adminId, @RequestBody LitemallBrand brand){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
brandService.updateById(brand);
|
||||
return ResponseUtil.ok(brand);
|
||||
}
|
||||
|
||||
@PostMapping("/delete")
|
||||
public Object delete(@LoginAdmin Integer adminId, @RequestBody LitemallBrand brand){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
brandService.deleteById(brand.getId());
|
||||
return ResponseUtil.ok();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package org.linlinjava.litemall.admin.web;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.linlinjava.litemall.admin.annotation.LoginAdmin;
|
||||
import org.linlinjava.litemall.db.domain.LitemallCart;
|
||||
import org.linlinjava.litemall.db.service.LitemallCartService;
|
||||
import org.linlinjava.litemall.db.service.LitemallGoodsService;
|
||||
import org.linlinjava.litemall.db.service.LitemallProductService;
|
||||
import org.linlinjava.litemall.db.service.LitemallUserService;
|
||||
import org.linlinjava.litemall.db.util.ResponseUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/cart")
|
||||
public class CartController {
|
||||
private final Log logger = LogFactory.getLog(CartController.class);
|
||||
|
||||
@Autowired
|
||||
private LitemallCartService cartService;
|
||||
@Autowired
|
||||
private LitemallUserService userService;
|
||||
@Autowired
|
||||
private LitemallGoodsService goodsService;
|
||||
@Autowired
|
||||
private LitemallProductService productService;
|
||||
|
||||
@GetMapping("/list")
|
||||
public Object list(@LoginAdmin Integer adminId,
|
||||
Integer userId, Integer goodsId,
|
||||
@RequestParam(value = "page", defaultValue = "1") Integer page,
|
||||
@RequestParam(value = "limit", defaultValue = "10") Integer limit,
|
||||
String sort, String order){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.fail401();
|
||||
}
|
||||
List<LitemallCart> cartList = cartService.querySelective(userId, goodsId, page, limit, sort, order);
|
||||
int total = cartService.countSelective(userId, goodsId, page, limit, sort, order);
|
||||
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("total", total);
|
||||
data.put("items", cartList);
|
||||
|
||||
return ResponseUtil.ok(data);
|
||||
}
|
||||
|
||||
/*
|
||||
* 目前的逻辑不支持管理员创建
|
||||
*/
|
||||
@PostMapping("/create")
|
||||
public Object create(@LoginAdmin Integer adminId, @RequestBody LitemallCart cart){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.fail401();
|
||||
}
|
||||
|
||||
return ResponseUtil.fail501();
|
||||
}
|
||||
|
||||
@GetMapping("/read")
|
||||
public Object read(@LoginAdmin Integer adminId, Integer id){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.fail401();
|
||||
}
|
||||
|
||||
LitemallCart cart = cartService.findById(id);
|
||||
return ResponseUtil.ok(cart);
|
||||
}
|
||||
|
||||
/*
|
||||
* 目前的逻辑不支持管理员创建
|
||||
*/
|
||||
@PostMapping("/update")
|
||||
public Object update(@LoginAdmin Integer adminId, @RequestBody LitemallCart cart){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.fail401();
|
||||
}
|
||||
return ResponseUtil.fail501();
|
||||
}
|
||||
|
||||
@PostMapping("/delete")
|
||||
public Object delete(@LoginAdmin Integer adminId, @RequestBody LitemallCart cart){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.fail401();
|
||||
}
|
||||
cartService.deleteById(cart.getId());
|
||||
return ResponseUtil.ok();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
package org.linlinjava.litemall.admin.web;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.linlinjava.litemall.admin.annotation.LoginAdmin;
|
||||
import org.linlinjava.litemall.db.domain.LitemallCategory;
|
||||
import org.linlinjava.litemall.db.service.LitemallCategoryService;
|
||||
import org.linlinjava.litemall.db.util.ResponseUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/category")
|
||||
public class CategoryController {
|
||||
private final Log logger = LogFactory.getLog(CategoryController.class);
|
||||
|
||||
@Autowired
|
||||
private LitemallCategoryService categoryService;
|
||||
|
||||
@GetMapping("/list")
|
||||
public Object list(@LoginAdmin Integer adminId,
|
||||
String id, String name,
|
||||
@RequestParam(value = "page", defaultValue = "1") Integer page,
|
||||
@RequestParam(value = "limit", defaultValue = "10") Integer limit,
|
||||
String sort, String order){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
|
||||
List<LitemallCategory> collectList = categoryService.querySelective(id, name, page, limit, sort, order);
|
||||
int total = categoryService.countSelective(id, name, page, limit, sort, order);
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("total", total);
|
||||
data.put("items", collectList);
|
||||
|
||||
return ResponseUtil.ok(data);
|
||||
}
|
||||
|
||||
@PostMapping("/create")
|
||||
public Object create(@LoginAdmin Integer adminId, @RequestBody LitemallCategory category){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
categoryService.add(category);
|
||||
return ResponseUtil.ok();
|
||||
}
|
||||
|
||||
@GetMapping("/read")
|
||||
public Object read(@LoginAdmin Integer adminId, Integer id){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
|
||||
if(id == null){
|
||||
return ResponseUtil.badArgument();
|
||||
}
|
||||
|
||||
LitemallCategory category = categoryService.findById(id);
|
||||
return ResponseUtil.ok(category);
|
||||
}
|
||||
|
||||
@PostMapping("/update")
|
||||
public Object update(@LoginAdmin Integer adminId, @RequestBody LitemallCategory category){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
categoryService.updateById(category);
|
||||
return ResponseUtil.ok();
|
||||
}
|
||||
|
||||
@PostMapping("/delete")
|
||||
public Object delete(@LoginAdmin Integer adminId, @RequestBody LitemallCategory category){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
categoryService.deleteById(category.getId());
|
||||
return ResponseUtil.ok();
|
||||
}
|
||||
|
||||
@GetMapping("/l1")
|
||||
public Object catL1(@LoginAdmin Integer adminId) {
|
||||
if (adminId == null) {
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
|
||||
// 所有一级分类目录
|
||||
List<LitemallCategory> l1CatList = categoryService.queryL1();
|
||||
HashMap<Integer, String> data = new HashMap<>(l1CatList.size());
|
||||
for(LitemallCategory category : l1CatList){
|
||||
data.put(category.getId(), category.getName());
|
||||
}
|
||||
return ResponseUtil.ok(data);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package org.linlinjava.litemall.admin.web;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.linlinjava.litemall.admin.annotation.LoginAdmin;
|
||||
import org.linlinjava.litemall.db.domain.LitemallCollect;
|
||||
import org.linlinjava.litemall.db.service.LitemallCollectService;
|
||||
import org.linlinjava.litemall.db.util.ResponseUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/collect")
|
||||
public class CollectController {
|
||||
private final Log logger = LogFactory.getLog(CollectController.class);
|
||||
|
||||
@Autowired
|
||||
private LitemallCollectService collectService;
|
||||
|
||||
@GetMapping("/list")
|
||||
public Object list(@LoginAdmin Integer adminId,
|
||||
String userId, String valueId,
|
||||
@RequestParam(value = "page", defaultValue = "1") Integer page,
|
||||
@RequestParam(value = "limit", defaultValue = "10") Integer limit,
|
||||
String sort, String order){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
|
||||
List<LitemallCollect> collectList = collectService.querySelective(userId, valueId, page, limit, sort, order);
|
||||
int total = collectService.countSelective(userId, valueId, page, limit, sort, order);
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("total", total);
|
||||
data.put("items", collectList);
|
||||
|
||||
return ResponseUtil.ok(data);
|
||||
}
|
||||
|
||||
@PostMapping("/create")
|
||||
public Object create(@LoginAdmin Integer adminId, @RequestBody LitemallCollect collect){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
return ResponseUtil.unsupport();
|
||||
}
|
||||
|
||||
@GetMapping("/read")
|
||||
public Object read(@LoginAdmin Integer adminId, Integer id){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
|
||||
if(id == null){
|
||||
return ResponseUtil.badArgument();
|
||||
}
|
||||
|
||||
LitemallCollect collect = collectService.findById(id);
|
||||
return ResponseUtil.ok(collect);
|
||||
}
|
||||
|
||||
@PostMapping("/update")
|
||||
public Object update(@LoginAdmin Integer adminId, @RequestBody LitemallCollect collect){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
collectService.updateById(collect);
|
||||
return ResponseUtil.ok();
|
||||
}
|
||||
|
||||
@PostMapping("/delete")
|
||||
public Object delete(@LoginAdmin Integer adminId, @RequestBody LitemallCollect collect){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
collectService.deleteById(collect.getId());
|
||||
return ResponseUtil.ok();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package org.linlinjava.litemall.admin.web;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.linlinjava.litemall.admin.annotation.LoginAdmin;
|
||||
import org.linlinjava.litemall.db.domain.LitemallComment;
|
||||
import org.linlinjava.litemall.db.service.LitemallCommentService;
|
||||
import org.linlinjava.litemall.db.util.ResponseUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/comment")
|
||||
public class CommentController {
|
||||
private final Log logger = LogFactory.getLog(CommentController.class);
|
||||
|
||||
@Autowired
|
||||
private LitemallCommentService commentService;
|
||||
|
||||
@GetMapping("/list")
|
||||
public Object list(@LoginAdmin Integer adminId,
|
||||
String userId, String valueId,
|
||||
@RequestParam(value = "page", defaultValue = "1") Integer page,
|
||||
@RequestParam(value = "limit", defaultValue = "10") Integer limit,
|
||||
String sort, String order){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
|
||||
List<LitemallComment> brandList = commentService.querySelective(userId, valueId, page, limit, sort, order);
|
||||
int total = commentService.countSelective(userId, valueId, page, limit, sort, order);
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("total", total);
|
||||
data.put("items", brandList);
|
||||
|
||||
return ResponseUtil.ok(data);
|
||||
}
|
||||
|
||||
@PostMapping("/create")
|
||||
public Object create(@LoginAdmin Integer adminId, @RequestBody LitemallComment comment){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
commentService.add(comment);
|
||||
return ResponseUtil.ok(comment);
|
||||
}
|
||||
|
||||
@GetMapping("/read")
|
||||
public Object read(@LoginAdmin Integer adminId, Integer id){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
|
||||
if(id == null){
|
||||
return ResponseUtil.badArgument();
|
||||
}
|
||||
|
||||
LitemallComment comment = commentService.findById(id);
|
||||
return ResponseUtil.ok(comment);
|
||||
}
|
||||
|
||||
@PostMapping("/update")
|
||||
public Object update(@LoginAdmin Integer adminId, @RequestBody LitemallComment comment){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
commentService.updateById(comment);
|
||||
return ResponseUtil.ok(comment);
|
||||
}
|
||||
|
||||
@PostMapping("/delete")
|
||||
public Object delete(@LoginAdmin Integer adminId, @RequestBody LitemallComment comment){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
commentService.deleteById(comment.getId());
|
||||
return ResponseUtil.ok();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package org.linlinjava.litemall.admin.web;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.linlinjava.litemall.admin.annotation.LoginAdmin;
|
||||
import org.linlinjava.litemall.db.service.LitemallGoodsService;
|
||||
import org.linlinjava.litemall.db.service.LitemallOrderService;
|
||||
import org.linlinjava.litemall.db.service.LitemallProductService;
|
||||
import org.linlinjava.litemall.db.service.LitemallUserService;
|
||||
import org.linlinjava.litemall.db.util.ResponseUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/dashboard")
|
||||
public class DashbordController {
|
||||
private final Log logger = LogFactory.getLog(DashbordController.class);
|
||||
|
||||
@Autowired
|
||||
private LitemallUserService userService;
|
||||
@Autowired
|
||||
private LitemallGoodsService goodsService;
|
||||
@Autowired
|
||||
private LitemallProductService productService;
|
||||
@Autowired
|
||||
private LitemallOrderService orderService;
|
||||
|
||||
@GetMapping("")
|
||||
public Object info(@LoginAdmin Integer adminId){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
|
||||
int userTotal = userService.count();
|
||||
int goodsTotal = goodsService.count();
|
||||
int productTotal = productService.count();
|
||||
int orderTotal = orderService.count();
|
||||
Map<String, Integer> data = new HashMap<>();
|
||||
data.put("userTotal", userTotal);
|
||||
data.put("goodsTotal", goodsTotal);
|
||||
data.put("productTotal", productTotal);
|
||||
data.put("orderTotal", orderTotal);
|
||||
|
||||
return ResponseUtil.ok(data);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package org.linlinjava.litemall.admin.web;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.linlinjava.litemall.admin.annotation.LoginAdmin;
|
||||
import org.linlinjava.litemall.db.domain.LitemallFootprint;
|
||||
import org.linlinjava.litemall.db.service.LitemallFootprintService;
|
||||
import org.linlinjava.litemall.db.util.ResponseUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/footprint")
|
||||
public class FootprintController {
|
||||
private final Log logger = LogFactory.getLog(FootprintController.class);
|
||||
|
||||
@Autowired
|
||||
private LitemallFootprintService footprintService;
|
||||
|
||||
@GetMapping("/list")
|
||||
public Object list(@LoginAdmin Integer adminId,
|
||||
String userId, String goodsId,
|
||||
@RequestParam(value = "page", defaultValue = "1") Integer page,
|
||||
@RequestParam(value = "limit", defaultValue = "10") Integer limit,
|
||||
String sort, String order){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
|
||||
List<LitemallFootprint> footprintList = footprintService.querySelective(userId, goodsId, page, limit, sort, order);
|
||||
int total = footprintService.countSelective(userId, goodsId, page, limit, sort, order);
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("total", total);
|
||||
data.put("items", footprintList);
|
||||
|
||||
return ResponseUtil.ok(data);
|
||||
}
|
||||
|
||||
@PostMapping("/create")
|
||||
public Object create(@LoginAdmin Integer adminId, @RequestBody LitemallFootprint footprint){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
return ResponseUtil.unsupport();
|
||||
}
|
||||
|
||||
@GetMapping("/read")
|
||||
public Object read(@LoginAdmin Integer adminId, Integer id){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
|
||||
if(id == null){
|
||||
return ResponseUtil.badArgument();
|
||||
}
|
||||
|
||||
LitemallFootprint footprint = footprintService.findById(id);
|
||||
return ResponseUtil.ok(footprint);
|
||||
}
|
||||
|
||||
@PostMapping("/update")
|
||||
public Object update(@LoginAdmin Integer adminId, @RequestBody LitemallFootprint footprint){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
footprintService.updateById(footprint);
|
||||
return ResponseUtil.ok();
|
||||
}
|
||||
|
||||
@PostMapping("/delete")
|
||||
public Object delete(@LoginAdmin Integer adminId, @RequestBody LitemallFootprint footprint){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
footprintService.deleteById(footprint.getId());
|
||||
return ResponseUtil.ok();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package org.linlinjava.litemall.admin.web;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.linlinjava.litemall.admin.annotation.LoginAdmin;
|
||||
import org.linlinjava.litemall.db.domain.LitemallGoodsAttribute;
|
||||
import org.linlinjava.litemall.db.service.LitemallGoodsAttributeService;
|
||||
import org.linlinjava.litemall.db.util.ResponseUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/goods-attribute")
|
||||
public class GoodsAttributeController {
|
||||
private final Log logger = LogFactory.getLog(GoodsAttributeController.class);
|
||||
|
||||
@Autowired
|
||||
private LitemallGoodsAttributeService goodsAttributeService;
|
||||
|
||||
@GetMapping("/list")
|
||||
public Object list(@LoginAdmin Integer adminId,
|
||||
Integer goodsId,
|
||||
@RequestParam(value = "page", defaultValue = "1") Integer page,
|
||||
@RequestParam(value = "limit", defaultValue = "10") Integer limit,
|
||||
String sort, String order){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
|
||||
List<LitemallGoodsAttribute> goodsAttributeList = goodsAttributeService.querySelective(goodsId, page, limit, sort, order);
|
||||
int total = goodsAttributeService.countSelective(goodsId, page, limit, sort, order);
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("total", total);
|
||||
data.put("items", goodsAttributeList);
|
||||
|
||||
return ResponseUtil.ok(data);
|
||||
}
|
||||
|
||||
@PostMapping("/create")
|
||||
public Object create(@LoginAdmin Integer adminId, @RequestBody LitemallGoodsAttribute goodsAttribute){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
goodsAttributeService.add(goodsAttribute);
|
||||
return ResponseUtil.ok(goodsAttribute);
|
||||
}
|
||||
|
||||
@GetMapping("/read")
|
||||
public Object read(@LoginAdmin Integer adminId, Integer id){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
|
||||
if(id == null){
|
||||
return ResponseUtil.badArgument();
|
||||
}
|
||||
|
||||
LitemallGoodsAttribute goodsAttribute = goodsAttributeService.findById(id);
|
||||
return ResponseUtil.ok(goodsAttribute);
|
||||
}
|
||||
|
||||
@PostMapping("/update")
|
||||
public Object update(@LoginAdmin Integer adminId, @RequestBody LitemallGoodsAttribute goodsAttribute){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
goodsAttributeService.updateById(goodsAttribute);
|
||||
return ResponseUtil.ok(goodsAttribute);
|
||||
}
|
||||
|
||||
@PostMapping("/delete")
|
||||
public Object delete(@LoginAdmin Integer adminId, @RequestBody LitemallGoodsAttribute goodsAttribute){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
goodsAttributeService.deleteById(goodsAttribute.getId());
|
||||
return ResponseUtil.ok();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package org.linlinjava.litemall.admin.web;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.linlinjava.litemall.admin.annotation.LoginAdmin;
|
||||
import org.linlinjava.litemall.db.domain.LitemallGoods;
|
||||
import org.linlinjava.litemall.db.service.LitemallGoodsService;
|
||||
import org.linlinjava.litemall.db.util.ResponseUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/goods")
|
||||
public class GoodsController {
|
||||
private final Log logger = LogFactory.getLog(GoodsController.class);
|
||||
|
||||
@Autowired
|
||||
private LitemallGoodsService goodsService;
|
||||
|
||||
@GetMapping("/list")
|
||||
public Object list(@LoginAdmin Integer adminId,
|
||||
String goodsSn, String name,
|
||||
@RequestParam(value = "page", defaultValue = "1") Integer page,
|
||||
@RequestParam(value = "limit", defaultValue = "10") Integer limit,
|
||||
String sort, String order){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
|
||||
List<LitemallGoods> goodsList = goodsService.querySelective(goodsSn, name, page, limit, sort, order);
|
||||
int total = goodsService.countSelective(goodsSn, name, page, limit, sort, order);
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("total", total);
|
||||
data.put("items", goodsList);
|
||||
|
||||
return ResponseUtil.ok(data);
|
||||
}
|
||||
|
||||
@PostMapping("/create")
|
||||
public Object create(@LoginAdmin Integer adminId, @RequestBody LitemallGoods goods){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
goodsService.add(goods);
|
||||
return ResponseUtil.ok(goods);
|
||||
}
|
||||
|
||||
@GetMapping("/read")
|
||||
public Object read(@LoginAdmin Integer adminId, Integer id){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
|
||||
if(id == null){
|
||||
return ResponseUtil.badArgument();
|
||||
}
|
||||
|
||||
LitemallGoods goods = goodsService.findById(id);
|
||||
return ResponseUtil.ok(goods);
|
||||
}
|
||||
|
||||
@PostMapping("/update")
|
||||
public Object update(@LoginAdmin Integer adminId, @RequestBody LitemallGoods goods){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
goodsService.updateById(goods);
|
||||
return ResponseUtil.ok(goods);
|
||||
}
|
||||
|
||||
@PostMapping("/delete")
|
||||
public Object delete(@LoginAdmin Integer adminId, @RequestBody LitemallGoods goods){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
goodsService.deleteById(goods.getId());
|
||||
return ResponseUtil.ok();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package org.linlinjava.litemall.admin.web;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.linlinjava.litemall.admin.annotation.LoginAdmin;
|
||||
import org.linlinjava.litemall.db.domain.LitemallGoodsSpecification;
|
||||
import org.linlinjava.litemall.db.service.LitemallGoodsSpecificationService;
|
||||
import org.linlinjava.litemall.db.util.ResponseUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/goods-specification")
|
||||
public class GoodsSpecificationController {
|
||||
private final Log logger = LogFactory.getLog(GoodsSpecificationController.class);
|
||||
|
||||
@Autowired
|
||||
private LitemallGoodsSpecificationService goodsSpecificationService;
|
||||
|
||||
@GetMapping("/list")
|
||||
public Object list(@LoginAdmin Integer adminId,
|
||||
Integer goodsId,
|
||||
@RequestParam(value = "page", defaultValue = "1") Integer page,
|
||||
@RequestParam(value = "limit", defaultValue = "10") Integer limit,
|
||||
String sort, String order){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
|
||||
List<LitemallGoodsSpecification> goodsSpecificationList = goodsSpecificationService.querySelective(goodsId, page, limit, sort, order);
|
||||
int total = goodsSpecificationService.countSelective(goodsId, page, limit, sort, order);
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("total", total);
|
||||
data.put("items", goodsSpecificationList);
|
||||
|
||||
return ResponseUtil.ok(data);
|
||||
}
|
||||
|
||||
@PostMapping("/create")
|
||||
public Object create(@LoginAdmin Integer adminId, @RequestBody LitemallGoodsSpecification goodsSpecification){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
goodsSpecificationService.add(goodsSpecification);
|
||||
return ResponseUtil.ok(goodsSpecification);
|
||||
}
|
||||
|
||||
@GetMapping("/read")
|
||||
public Object read(@LoginAdmin Integer adminId, Integer id){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
|
||||
if(id == null){
|
||||
return ResponseUtil.badArgument();
|
||||
}
|
||||
|
||||
LitemallGoodsSpecification goodsSpecification = goodsSpecificationService.findById(id);
|
||||
return ResponseUtil.ok(goodsSpecification);
|
||||
}
|
||||
|
||||
@PostMapping("/update")
|
||||
public Object update(@LoginAdmin Integer adminId, @RequestBody LitemallGoodsSpecification goodsSpecification){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
goodsSpecificationService.updateById(goodsSpecification);
|
||||
return ResponseUtil.ok(goodsSpecification);
|
||||
}
|
||||
|
||||
@PostMapping("/delete")
|
||||
public Object delete(@LoginAdmin Integer adminId, @RequestBody LitemallGoodsSpecification goodsSpecification){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
goodsSpecificationService.deleteById(goodsSpecification.getId());
|
||||
return ResponseUtil.ok();
|
||||
}
|
||||
|
||||
@GetMapping("/volist")
|
||||
public Object volist(@LoginAdmin Integer adminId, Integer id){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
|
||||
if(id == null){
|
||||
return ResponseUtil.badArgument();
|
||||
}
|
||||
|
||||
Object goodsSpecificationVoList = goodsSpecificationService.getSpecificationVoList(id);
|
||||
return ResponseUtil.ok(goodsSpecificationVoList);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package org.linlinjava.litemall.admin.web;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.linlinjava.litemall.admin.annotation.LoginAdmin;
|
||||
import org.linlinjava.litemall.db.domain.LitemallSearchHistory;
|
||||
import org.linlinjava.litemall.db.service.LitemallSearchHistoryService;
|
||||
import org.linlinjava.litemall.db.util.ResponseUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/history")
|
||||
public class HistoryController {
|
||||
private final Log logger = LogFactory.getLog(HistoryController.class);
|
||||
|
||||
@Autowired
|
||||
private LitemallSearchHistoryService searchHistoryService;
|
||||
|
||||
@GetMapping("/list")
|
||||
public Object list(@LoginAdmin Integer adminId,
|
||||
String userId, String keyword,
|
||||
@RequestParam(value = "page", defaultValue = "1") Integer page,
|
||||
@RequestParam(value = "limit", defaultValue = "10") Integer limit,
|
||||
String sort, String order){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
|
||||
List<LitemallSearchHistory> footprintList = searchHistoryService.querySelective(userId, keyword, page, limit, sort, order);
|
||||
int total = searchHistoryService.countSelective(userId, keyword, page, limit, sort, order);
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("total", total);
|
||||
data.put("items", footprintList);
|
||||
|
||||
return ResponseUtil.ok(data);
|
||||
}
|
||||
|
||||
@PostMapping("/create")
|
||||
public Object create(@LoginAdmin Integer adminId, @RequestBody LitemallSearchHistory history){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.fail401();
|
||||
}
|
||||
return ResponseUtil.fail501();
|
||||
}
|
||||
|
||||
@GetMapping("/read")
|
||||
public Object read(@LoginAdmin Integer adminId, Integer id){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
|
||||
if(id == null){
|
||||
return ResponseUtil.badArgument();
|
||||
}
|
||||
|
||||
LitemallSearchHistory history = searchHistoryService.findById(id);
|
||||
return ResponseUtil.ok(history);
|
||||
}
|
||||
|
||||
@PostMapping("/update")
|
||||
public Object update(@LoginAdmin Integer adminId, @RequestBody LitemallSearchHistory history){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
searchHistoryService.updateById(history);
|
||||
return ResponseUtil.ok();
|
||||
}
|
||||
|
||||
@PostMapping("/delete")
|
||||
public Object delete(@LoginAdmin Integer adminId, @RequestBody LitemallSearchHistory history){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
searchHistoryService.deleteById(history.getId());
|
||||
return ResponseUtil.ok();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package org.linlinjava.litemall.admin.web;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.linlinjava.litemall.db.util.ResponseUtil;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/index")
|
||||
public class IndexController {
|
||||
private final Log logger = LogFactory.getLog(IndexController.class);
|
||||
|
||||
@RequestMapping("/index")
|
||||
public Object index(){
|
||||
return ResponseUtil.ok("hello world");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package org.linlinjava.litemall.admin.web;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.linlinjava.litemall.admin.annotation.LoginAdmin;
|
||||
import org.linlinjava.litemall.db.domain.LitemallIssue;
|
||||
import org.linlinjava.litemall.db.service.LitemallIssueService;
|
||||
import org.linlinjava.litemall.db.util.ResponseUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/issue")
|
||||
public class IssueController {
|
||||
private final Log logger = LogFactory.getLog(IssueController.class);
|
||||
|
||||
@Autowired
|
||||
private LitemallIssueService issueService;
|
||||
|
||||
@GetMapping("/list")
|
||||
public Object list(@LoginAdmin Integer adminId,
|
||||
String question,
|
||||
@RequestParam(value = "page", defaultValue = "1") Integer page,
|
||||
@RequestParam(value = "limit", defaultValue = "10") Integer limit,
|
||||
String sort, String order){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
|
||||
List<LitemallIssue> issueList = issueService.querySelective(question, page, limit, sort, order);
|
||||
int total = issueService.countSelective(question, page, limit, sort, order);
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("total", total);
|
||||
data.put("items", issueList);
|
||||
|
||||
return ResponseUtil.ok(data);
|
||||
}
|
||||
|
||||
@PostMapping("/create")
|
||||
public Object create(@LoginAdmin Integer adminId, @RequestBody LitemallIssue brand){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
issueService.add(brand);
|
||||
return ResponseUtil.ok(brand);
|
||||
}
|
||||
|
||||
@GetMapping("/read")
|
||||
public Object read(@LoginAdmin Integer adminId, Integer id){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
|
||||
if(id == null){
|
||||
return ResponseUtil.badArgument();
|
||||
}
|
||||
|
||||
LitemallIssue brand = issueService.findById(id);
|
||||
return ResponseUtil.ok(brand);
|
||||
}
|
||||
|
||||
@PostMapping("/update")
|
||||
public Object update(@LoginAdmin Integer adminId, @RequestBody LitemallIssue brand){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
issueService.updateById(brand);
|
||||
return ResponseUtil.ok(brand);
|
||||
}
|
||||
|
||||
@PostMapping("/delete")
|
||||
public Object delete(@LoginAdmin Integer adminId, @RequestBody LitemallIssue brand){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
issueService.deleteById(brand.getId());
|
||||
return ResponseUtil.ok();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package org.linlinjava.litemall.admin.web;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.linlinjava.litemall.admin.annotation.LoginAdmin;
|
||||
import org.linlinjava.litemall.db.domain.LitemallKeyword;
|
||||
import org.linlinjava.litemall.db.service.LitemallKeywordService;
|
||||
import org.linlinjava.litemall.db.util.ResponseUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/keyword")
|
||||
public class KeywordController {
|
||||
private final Log logger = LogFactory.getLog(KeywordController.class);
|
||||
|
||||
@Autowired
|
||||
private LitemallKeywordService keywordService;
|
||||
|
||||
@GetMapping("/list")
|
||||
public Object list(@LoginAdmin Integer adminId,
|
||||
String keyword, String url,
|
||||
@RequestParam(value = "page", defaultValue = "1") Integer page,
|
||||
@RequestParam(value = "limit", defaultValue = "10") Integer limit,
|
||||
String sort, String order){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
|
||||
List<LitemallKeyword> brandList = keywordService.querySelective(keyword, url, page, limit, sort, order);
|
||||
int total = keywordService.countSelective(keyword, url, page, limit, sort, order);
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("total", total);
|
||||
data.put("items", brandList);
|
||||
|
||||
return ResponseUtil.ok(data);
|
||||
}
|
||||
|
||||
@PostMapping("/create")
|
||||
public Object create(@LoginAdmin Integer adminId, @RequestBody LitemallKeyword keywords){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
keywordService.add(keywords);
|
||||
return ResponseUtil.ok(keywords);
|
||||
}
|
||||
|
||||
@GetMapping("/read")
|
||||
public Object read(@LoginAdmin Integer adminId, Integer id){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
|
||||
if(id == null){
|
||||
return ResponseUtil.badArgument();
|
||||
}
|
||||
|
||||
LitemallKeyword brand = keywordService.findById(id);
|
||||
return ResponseUtil.ok(brand);
|
||||
}
|
||||
|
||||
@PostMapping("/update")
|
||||
public Object update(@LoginAdmin Integer adminId, @RequestBody LitemallKeyword keywords){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
keywordService.updateById(keywords);
|
||||
return ResponseUtil.ok(keywords);
|
||||
}
|
||||
|
||||
@PostMapping("/delete")
|
||||
public Object delete(@LoginAdmin Integer adminId, @RequestBody LitemallKeyword brand){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
keywordService.deleteById(brand.getId());
|
||||
return ResponseUtil.ok();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
package org.linlinjava.litemall.admin.web;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.linlinjava.litemall.admin.annotation.LoginAdmin;
|
||||
import org.linlinjava.litemall.db.domain.LitemallOrder;
|
||||
import org.linlinjava.litemall.db.service.LitemallOrderService;
|
||||
import org.linlinjava.litemall.db.util.OrderUtil;
|
||||
import org.linlinjava.litemall.db.util.ResponseUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/order")
|
||||
public class OrderController {
|
||||
private final Log logger = LogFactory.getLog(OrderController.class);
|
||||
|
||||
@Autowired
|
||||
private LitemallOrderService orderService;
|
||||
|
||||
@GetMapping("/list")
|
||||
public Object list(@LoginAdmin Integer adminId,
|
||||
Integer userId, String orderSn,
|
||||
@RequestParam(value = "page", defaultValue = "1") Integer page,
|
||||
@RequestParam(value = "limit", defaultValue = "10") Integer limit,
|
||||
String sort, String order){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.fail401();
|
||||
}
|
||||
List<LitemallOrder> orderList = orderService.querySelective(userId, orderSn, page, limit, sort, order);
|
||||
int total = orderService.countSelective(userId, orderSn, page, limit, sort, order);
|
||||
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("total", total);
|
||||
data.put("items", orderList);
|
||||
|
||||
return ResponseUtil.ok(data);
|
||||
}
|
||||
|
||||
/*
|
||||
* 目前的逻辑不支持管理员创建
|
||||
*/
|
||||
@PostMapping("/create")
|
||||
public Object create(@LoginAdmin Integer adminId, @RequestBody LitemallOrder order){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
return ResponseUtil.unsupport();
|
||||
}
|
||||
|
||||
@GetMapping("/read")
|
||||
public Object read(@LoginAdmin Integer adminId, Integer id){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.fail401();
|
||||
}
|
||||
|
||||
LitemallOrder order = orderService.findById(id);
|
||||
return ResponseUtil.ok(order);
|
||||
}
|
||||
|
||||
/*
|
||||
* 目前仅仅支持管理员设置发货相关的信息
|
||||
*/
|
||||
@PostMapping("/update")
|
||||
public Object update(@LoginAdmin Integer adminId, @RequestBody LitemallOrder order){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
|
||||
Integer orderId = order.getId();
|
||||
if(orderId == null){
|
||||
return ResponseUtil.badArgument();
|
||||
}
|
||||
|
||||
LitemallOrder zmallOrder = orderService.findById(orderId);
|
||||
if(zmallOrder == null){
|
||||
return ResponseUtil.badArgumentValue();
|
||||
}
|
||||
|
||||
if(OrderUtil.isPayStatus(zmallOrder) || OrderUtil.isShipStatus(zmallOrder)){
|
||||
LitemallOrder newOrder = new LitemallOrder();
|
||||
newOrder.setId(orderId);
|
||||
newOrder.setShipChannel(order.getShipChannel());
|
||||
newOrder.setShipSn(order.getOrderSn());
|
||||
newOrder.setShipStartTime(order.getShipStartTime());
|
||||
newOrder.setShipEndTime(order.getShipEndTime());
|
||||
newOrder.setOrderStatus(OrderUtil.STATUS_SHIP);
|
||||
orderService.update(newOrder);
|
||||
}
|
||||
else {
|
||||
return ResponseUtil.badArgumentValue();
|
||||
}
|
||||
|
||||
zmallOrder = orderService.findById(orderId);
|
||||
return ResponseUtil.ok(zmallOrder);
|
||||
}
|
||||
|
||||
@PostMapping("/delete")
|
||||
public Object delete(@LoginAdmin Integer adminId, @RequestBody LitemallOrder order){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
return ResponseUtil.unsupport();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
package org.linlinjava.litemall.admin.web;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.linlinjava.litemall.admin.annotation.LoginAdmin;
|
||||
import org.linlinjava.litemall.db.domain.LitemallGoods;
|
||||
import org.linlinjava.litemall.db.domain.LitemallProduct;
|
||||
import org.linlinjava.litemall.db.service.LitemallGoodsService;
|
||||
import org.linlinjava.litemall.db.service.LitemallGoodsSpecificationService;
|
||||
import org.linlinjava.litemall.db.service.LitemallProductService;
|
||||
import org.linlinjava.litemall.db.util.ResponseUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/product")
|
||||
public class ProductController {
|
||||
private final Log logger = LogFactory.getLog(ProductController.class);
|
||||
|
||||
@Autowired
|
||||
private LitemallProductService productService;
|
||||
@Autowired
|
||||
private LitemallGoodsService goodsService;
|
||||
@Autowired
|
||||
private LitemallGoodsSpecificationService goodsSpecificationService;
|
||||
|
||||
@GetMapping("/list")
|
||||
public Object list(@LoginAdmin Integer adminId,
|
||||
Integer goodsId,
|
||||
@RequestParam(value = "page", defaultValue = "1") Integer page,
|
||||
@RequestParam(value = "limit", defaultValue = "10") Integer limit,
|
||||
String sort, String order){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
|
||||
List<LitemallProduct> productList = productService.querySelective(goodsId, page, limit, sort, order);
|
||||
int total = productService.countSelective(goodsId, page, limit, sort, order);
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("total", total);
|
||||
data.put("items", productList);
|
||||
|
||||
return ResponseUtil.ok(data);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param adminId
|
||||
* @param litemallProduct
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/create")
|
||||
public Object create(@LoginAdmin Integer adminId, @RequestBody LitemallProduct litemallProduct){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
|
||||
Integer goodsId = litemallProduct.getGoodsId();
|
||||
if(goodsId == null){
|
||||
return ResponseUtil.badArgument();
|
||||
}
|
||||
|
||||
LitemallGoods goods = goodsService.findById(goodsId);
|
||||
if(goods == null){
|
||||
return ResponseUtil.badArgumentValue();
|
||||
}
|
||||
|
||||
List<LitemallProduct> productList = productService.queryByGid(goodsId);
|
||||
if(productList.size() != 0){
|
||||
return ResponseUtil.badArgumentValue();
|
||||
}
|
||||
|
||||
Integer[] goodsSpecificationIds = goodsSpecificationService.queryIdsByGid(goodsId);
|
||||
if(goodsSpecificationIds.length == 0) {
|
||||
return ResponseUtil.serious();
|
||||
}
|
||||
|
||||
LitemallProduct product = new LitemallProduct();
|
||||
product.setGoodsId(goodsId);
|
||||
product.setGoodsNumber(0);
|
||||
product.setRetailPrice(new BigDecimal(0.00));
|
||||
product.setGoodsSpecificationIds(goodsSpecificationIds);
|
||||
productService.add(product);
|
||||
|
||||
return ResponseUtil.ok();
|
||||
}
|
||||
|
||||
@GetMapping("/read")
|
||||
public Object read(@LoginAdmin Integer adminId, Integer id){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
|
||||
if(id == null){
|
||||
return ResponseUtil.badArgument();
|
||||
}
|
||||
|
||||
LitemallProduct product = productService.findById(id);
|
||||
return ResponseUtil.ok(product);
|
||||
}
|
||||
|
||||
@PostMapping("/update")
|
||||
public Object update(@LoginAdmin Integer adminId, @RequestBody LitemallProduct product){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
productService.updateById(product);
|
||||
return ResponseUtil.ok(product);
|
||||
}
|
||||
|
||||
@PostMapping("/delete")
|
||||
public Object delete(@LoginAdmin Integer adminId, @RequestBody LitemallProduct product){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
productService.deleteById(product.getId());
|
||||
return ResponseUtil.ok();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package org.linlinjava.litemall.admin.web;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.linlinjava.litemall.admin.annotation.LoginAdmin;
|
||||
import org.linlinjava.litemall.db.domain.LitemallRegion;
|
||||
import org.linlinjava.litemall.db.service.LitemallRegionService;
|
||||
import org.linlinjava.litemall.db.util.ResponseUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/region")
|
||||
public class RegionController {
|
||||
private final Log logger = LogFactory.getLog(RegionController.class);
|
||||
|
||||
@Autowired
|
||||
private LitemallRegionService regionService;
|
||||
|
||||
@GetMapping("/clist")
|
||||
public Object clist(@LoginAdmin Integer adminId, Integer id) {
|
||||
if (id == null) {
|
||||
return ResponseUtil.badArgument();
|
||||
}
|
||||
|
||||
List<LitemallRegion> regionList = regionService.queryByPid(id);
|
||||
|
||||
return ResponseUtil.ok(regionList);
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
public Object list(@LoginAdmin Integer adminId,
|
||||
String name, Integer code,
|
||||
@RequestParam(value = "page", defaultValue = "1") Integer page,
|
||||
@RequestParam(value = "limit", defaultValue = "10") Integer limit,
|
||||
String sort, String order){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
|
||||
List<LitemallRegion> regionList = regionService.querySelective(name, code, page, limit, sort, order);
|
||||
int total = regionService.countSelective(name, code, page, limit, sort, order);
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("total", total);
|
||||
data.put("items", regionList);
|
||||
|
||||
return ResponseUtil.ok(data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package org.linlinjava.litemall.admin.web;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.linlinjava.litemall.admin.annotation.LoginAdmin;
|
||||
import org.linlinjava.litemall.db.domain.LitemallTopic;
|
||||
import org.linlinjava.litemall.db.service.LitemallTopicService;
|
||||
import org.linlinjava.litemall.db.util.ResponseUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/topic")
|
||||
public class TopicController {
|
||||
private final Log logger = LogFactory.getLog(TopicController.class);
|
||||
|
||||
@Autowired
|
||||
private LitemallTopicService topicService;
|
||||
|
||||
@GetMapping("/list")
|
||||
public Object list(@LoginAdmin Integer adminId,
|
||||
String title, String subtitle,
|
||||
@RequestParam(value = "page", defaultValue = "1") Integer page,
|
||||
@RequestParam(value = "limit", defaultValue = "10") Integer limit,
|
||||
String sort, String order){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
|
||||
List<LitemallTopic> topicList = topicService.querySelective(title, subtitle, page, limit, sort, order);
|
||||
int total = topicService.countSelective(title, subtitle, page, limit, sort, order);
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("total", total);
|
||||
data.put("items", topicList);
|
||||
|
||||
return ResponseUtil.ok(data);
|
||||
}
|
||||
|
||||
@PostMapping("/create")
|
||||
public Object create(@LoginAdmin Integer adminId, @RequestBody LitemallTopic topic){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
topicService.add(topic);
|
||||
return ResponseUtil.ok(topic);
|
||||
}
|
||||
|
||||
@GetMapping("/read")
|
||||
public Object read(@LoginAdmin Integer adminId, Integer id){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
|
||||
if(id == null){
|
||||
return ResponseUtil.badArgument();
|
||||
}
|
||||
|
||||
LitemallTopic brand = topicService.findById(id);
|
||||
return ResponseUtil.ok(brand);
|
||||
}
|
||||
|
||||
@PostMapping("/update")
|
||||
public Object update(@LoginAdmin Integer adminId, @RequestBody LitemallTopic topic){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
topicService.updateById(topic);
|
||||
return ResponseUtil.ok(topic);
|
||||
}
|
||||
|
||||
@PostMapping("/delete")
|
||||
public Object delete(@LoginAdmin Integer adminId, @RequestBody LitemallTopic topic){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
topicService.deleteById(topic.getId());
|
||||
return ResponseUtil.ok();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package org.linlinjava.litemall.admin.web;
|
||||
|
||||
import com.github.pagehelper.util.StringUtil;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.linlinjava.litemall.admin.annotation.LoginAdmin;
|
||||
import org.linlinjava.litemall.db.domain.LitemallUser;
|
||||
import org.linlinjava.litemall.db.service.LitemallUserService;
|
||||
import org.linlinjava.litemall.db.util.ResponseUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/user")
|
||||
public class UserController {
|
||||
private final Log logger = LogFactory.getLog(UserController.class);
|
||||
|
||||
@Autowired
|
||||
private LitemallUserService userService;
|
||||
|
||||
@GetMapping("/list")
|
||||
public Object list(@LoginAdmin Integer adminId,
|
||||
String username, String mobile,
|
||||
@RequestParam(value = "page", defaultValue = "1") Integer page,
|
||||
@RequestParam(value = "limit", defaultValue = "10") Integer limit,
|
||||
String sort, String order){
|
||||
if(adminId == null){
|
||||
return ResponseUtil.fail401();
|
||||
}
|
||||
List<LitemallUser> userList = userService.querySelective(username, mobile, page, limit, sort, order);
|
||||
int total = userService.countSeletive(username, mobile, page, limit, sort, order);
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("total", total);
|
||||
data.put("items", userList);
|
||||
|
||||
return ResponseUtil.ok(data);
|
||||
}
|
||||
|
||||
@GetMapping("/username")
|
||||
public Object username(String username){
|
||||
if(StringUtil.isEmpty(username)){
|
||||
return ResponseUtil.fail402();
|
||||
}
|
||||
|
||||
int total = userService.countSeletive(username, null, null, null, null, null);
|
||||
if(total == 0){
|
||||
return ResponseUtil.ok("不存在");
|
||||
}
|
||||
return ResponseUtil.ok("已存在");
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/create")
|
||||
public Object create(@LoginAdmin Integer adminId, @RequestBody LitemallUser user){
|
||||
logger.debug(user);
|
||||
|
||||
userService.add(user);
|
||||
return ResponseUtil.ok(user);
|
||||
}
|
||||
|
||||
@PostMapping("/update")
|
||||
public Object update(@LoginAdmin Integer adminId, @RequestBody LitemallUser user){
|
||||
logger.debug(user);
|
||||
|
||||
userService.update(user);
|
||||
return ResponseUtil.ok(user);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
pagehelper.helperDialect=mysql
|
||||
pagehelper.reasonable=true
|
||||
pagehelper.supportMethodsArguments=true
|
||||
pagehelper.params=count=countSql
|
||||
|
||||
spring.datasource.druid.url=jdbc:mysql://localhost:3306/litemall?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&verifyServerCertificate=false&useSSL=false
|
||||
spring.datasource.druid.driver-class-name=com.mysql.jdbc.Driver
|
||||
spring.datasource.druid.username=litemall
|
||||
spring.datasource.druid.password=litemall123456
|
||||
spring.datasource.druid.initial-size=50
|
||||
spring.datasource.druid.max-active=100
|
||||
spring.datasource.druid.min-idle=20
|
||||
spring.datasource.druid.max-wait=60000
|
||||
spring.datasource.druid.pool-prepared-statements=true
|
||||
spring.datasource.druid.max-pool-prepared-statement-per-connection-size=20
|
||||
spring.datasource.druid.validation-query=SELECT 1 FROM DUAL
|
||||
spring.datasource.druid.test-on-borrow=false
|
||||
spring.datasource.druid.test-on-return=false
|
||||
spring.datasource.druid.test-while-idle=true
|
||||
spring.datasource.druid.time-between-eviction-runs-millis=60000
|
||||
spring.datasource.druid.filters=stat,wall,log4j
|
||||
|
||||
|
||||
logging.level.root=ERROR
|
||||
logging.level.org.springframework=ERROR
|
||||
logging.level.org.mybatis=ERROR
|
||||
logging.level.org.linlinjava.litemall.db=ERROR
|
||||
logging.level.org.linlinjava.litemall=DEBUG
|
||||
@@ -0,0 +1,27 @@
|
||||
pagehelper.helperDialect=mysql
|
||||
pagehelper.reasonable=true
|
||||
pagehelper.supportMethodsArguments=true
|
||||
pagehelper.params=count=countSql
|
||||
|
||||
spring.datasource.druid.url=jdbc:mysql://localhost:3306/litemall?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&verifyServerCertificate=false&useSSL=false
|
||||
spring.datasource.druid.driver-class-name=com.mysql.jdbc.Driver
|
||||
spring.datasource.druid.username=litemall
|
||||
spring.datasource.druid.password=litemall123456
|
||||
spring.datasource.druid.initial-size=50
|
||||
spring.datasource.druid.max-active=100
|
||||
spring.datasource.druid.min-idle=20
|
||||
spring.datasource.druid.max-wait=60000
|
||||
spring.datasource.druid.pool-prepared-statements=true
|
||||
spring.datasource.druid.max-pool-prepared-statement-per-connection-size=20
|
||||
spring.datasource.druid.validation-query=SELECT 1 FROM DUAL
|
||||
spring.datasource.druid.test-on-borrow=false
|
||||
spring.datasource.druid.test-on-return=false
|
||||
spring.datasource.druid.test-while-idle=true
|
||||
spring.datasource.druid.time-between-eviction-runs-millis=60000
|
||||
spring.datasource.druid.filters=stat,wall,log4j
|
||||
|
||||
logging.level.root=ERROR
|
||||
logging.level.org.springframework=ERROR
|
||||
logging.level.org.mybatis=ERROR
|
||||
logging.level.org.linlinjava.litemall.db=ERROR
|
||||
logging.level.org.linlinjava.litemall=DEBUG
|
||||
@@ -0,0 +1,3 @@
|
||||
spring.profiles.active=dev
|
||||
server.port=8083
|
||||
logging.level.org.linlinjava.litemall.admin.Application=DEBUG
|
||||
12
litemall-admin/.babelrc
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"presets": [
|
||||
["env", {
|
||||
"modules": false,
|
||||
"targets": {
|
||||
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
|
||||
}
|
||||
}],
|
||||
"stage-2"
|
||||
],
|
||||
"plugins": ["transform-vue-jsx", "transform-runtime"]
|
||||
}
|
||||
14
litemall-admin/.editorconfig
Normal file
@@ -0,0 +1,14 @@
|
||||
# http://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
insert_final_newline = false
|
||||
trim_trailing_whitespace = false
|
||||
3
litemall-admin/.eslintignore
Normal file
@@ -0,0 +1,3 @@
|
||||
build/*.js
|
||||
config/*.js
|
||||
src/assets
|
||||
199
litemall-admin/.eslintrc.js
Normal file
@@ -0,0 +1,199 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
parser: 'babel-eslint',
|
||||
parserOptions: {
|
||||
sourceType: 'module'
|
||||
},
|
||||
env: {
|
||||
browser: true,
|
||||
node: true,
|
||||
es6: true,
|
||||
},
|
||||
extends: 'eslint:recommended',
|
||||
// required to lint *.vue files
|
||||
plugins: [
|
||||
'html'
|
||||
],
|
||||
// check if imports actually resolve
|
||||
'settings': {
|
||||
'import/resolver': {
|
||||
'webpack': {
|
||||
'config': 'build/webpack.base.conf.js'
|
||||
}
|
||||
}
|
||||
},
|
||||
// add your custom rules here
|
||||
//it is base on https://github.com/vuejs/eslint-config-vue
|
||||
'rules': {
|
||||
'accessor-pairs': 2,
|
||||
'arrow-spacing': [2, {
|
||||
'before': true,
|
||||
'after': true
|
||||
}],
|
||||
'block-spacing': [2, 'always'],
|
||||
'brace-style': [2, '1tbs', {
|
||||
'allowSingleLine': true
|
||||
}],
|
||||
'camelcase': [0, {
|
||||
'properties': 'always'
|
||||
}],
|
||||
'comma-dangle': [2, 'never'],
|
||||
'comma-spacing': [2, {
|
||||
'before': false,
|
||||
'after': true
|
||||
}],
|
||||
'comma-style': [2, 'last'],
|
||||
'constructor-super': 2,
|
||||
'curly': [2, 'multi-line'],
|
||||
'dot-location': [2, 'property'],
|
||||
'eol-last': 2,
|
||||
'eqeqeq': [2, 'allow-null'],
|
||||
'generator-star-spacing': [2, {
|
||||
'before': true,
|
||||
'after': true
|
||||
}],
|
||||
'handle-callback-err': [2, '^(err|error)$'],
|
||||
'indent': [2, 2, {
|
||||
'SwitchCase': 1
|
||||
}],
|
||||
'jsx-quotes': [2, 'prefer-single'],
|
||||
'key-spacing': [2, {
|
||||
'beforeColon': false,
|
||||
'afterColon': true
|
||||
}],
|
||||
'keyword-spacing': [2, {
|
||||
'before': true,
|
||||
'after': true
|
||||
}],
|
||||
'new-cap': [2, {
|
||||
'newIsCap': true,
|
||||
'capIsNew': false
|
||||
}],
|
||||
'new-parens': 2,
|
||||
'no-array-constructor': 2,
|
||||
'no-caller': 2,
|
||||
'no-console': 'off',
|
||||
'no-class-assign': 2,
|
||||
'no-cond-assign': 2,
|
||||
'no-const-assign': 2,
|
||||
'no-control-regex': 0,
|
||||
'no-delete-var': 2,
|
||||
'no-dupe-args': 2,
|
||||
'no-dupe-class-members': 2,
|
||||
'no-dupe-keys': 2,
|
||||
'no-duplicate-case': 2,
|
||||
'no-empty-character-class': 2,
|
||||
'no-empty-pattern': 2,
|
||||
'no-eval': 2,
|
||||
'no-ex-assign': 2,
|
||||
'no-extend-native': 2,
|
||||
'no-extra-bind': 2,
|
||||
'no-extra-boolean-cast': 2,
|
||||
'no-extra-parens': [2, 'functions'],
|
||||
'no-fallthrough': 2,
|
||||
'no-floating-decimal': 2,
|
||||
'no-func-assign': 2,
|
||||
'no-implied-eval': 2,
|
||||
'no-inner-declarations': [2, 'functions'],
|
||||
'no-invalid-regexp': 2,
|
||||
'no-irregular-whitespace': 2,
|
||||
'no-iterator': 2,
|
||||
'no-label-var': 2,
|
||||
'no-labels': [2, {
|
||||
'allowLoop': false,
|
||||
'allowSwitch': false
|
||||
}],
|
||||
'no-lone-blocks': 2,
|
||||
'no-mixed-spaces-and-tabs': 2,
|
||||
'no-multi-spaces': 2,
|
||||
'no-multi-str': 2,
|
||||
'no-multiple-empty-lines': [2, {
|
||||
'max': 1
|
||||
}],
|
||||
'no-native-reassign': 2,
|
||||
'no-negated-in-lhs': 2,
|
||||
'no-new-object': 2,
|
||||
'no-new-require': 2,
|
||||
'no-new-symbol': 2,
|
||||
'no-new-wrappers': 2,
|
||||
'no-obj-calls': 2,
|
||||
'no-octal': 2,
|
||||
'no-octal-escape': 2,
|
||||
'no-path-concat': 2,
|
||||
'no-proto': 2,
|
||||
'no-redeclare': 2,
|
||||
'no-regex-spaces': 2,
|
||||
'no-return-assign': [2, 'except-parens'],
|
||||
'no-self-assign': 2,
|
||||
'no-self-compare': 2,
|
||||
'no-sequences': 2,
|
||||
'no-shadow-restricted-names': 2,
|
||||
'no-spaced-func': 2,
|
||||
'no-sparse-arrays': 2,
|
||||
'no-this-before-super': 2,
|
||||
'no-throw-literal': 2,
|
||||
'no-trailing-spaces': 2,
|
||||
'no-undef': 2,
|
||||
'no-undef-init': 2,
|
||||
'no-unexpected-multiline': 2,
|
||||
'no-unmodified-loop-condition': 2,
|
||||
'no-unneeded-ternary': [2, {
|
||||
'defaultAssignment': false
|
||||
}],
|
||||
'no-unreachable': 2,
|
||||
'no-unsafe-finally': 2,
|
||||
'no-unused-vars': [2, {
|
||||
'vars': 'all',
|
||||
'args': 'none'
|
||||
}],
|
||||
'no-useless-call': 2,
|
||||
'no-useless-computed-key': 2,
|
||||
'no-useless-constructor': 2,
|
||||
'no-useless-escape': 0,
|
||||
'no-whitespace-before-property': 2,
|
||||
'no-with': 2,
|
||||
'one-var': [2, {
|
||||
'initialized': 'never'
|
||||
}],
|
||||
'operator-linebreak': [2, 'after', {
|
||||
'overrides': {
|
||||
'?': 'before',
|
||||
':': 'before'
|
||||
}
|
||||
}],
|
||||
'padded-blocks': [2, 'never'],
|
||||
'quotes': [2, 'single', {
|
||||
'avoidEscape': true,
|
||||
'allowTemplateLiterals': true
|
||||
}],
|
||||
'semi': [2, 'never'],
|
||||
'semi-spacing': [2, {
|
||||
'before': false,
|
||||
'after': true
|
||||
}],
|
||||
'space-before-blocks': [2, 'always'],
|
||||
'space-before-function-paren': [2, 'never'],
|
||||
'space-in-parens': [2, 'never'],
|
||||
'space-infix-ops': 2,
|
||||
'space-unary-ops': [2, {
|
||||
'words': true,
|
||||
'nonwords': false
|
||||
}],
|
||||
'spaced-comment': [2, 'always', {
|
||||
'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ',']
|
||||
}],
|
||||
'template-curly-spacing': [2, 'never'],
|
||||
'use-isnan': 2,
|
||||
'valid-typeof': 2,
|
||||
'wrap-iife': [2, 'any'],
|
||||
'yield-star-spacing': [2, 'both'],
|
||||
'yoda': [2, 'never'],
|
||||
'prefer-const': 2,
|
||||
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
|
||||
'object-curly-spacing': [2, 'always', {
|
||||
objectsInObjects: false
|
||||
}],
|
||||
'array-bracket-spacing': [2, 'never']
|
||||
}
|
||||
}
|
||||
|
||||
19
litemall-admin/.gitignore
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
.DS_Store
|
||||
node_modules/
|
||||
dist/
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
test/unit/coverage
|
||||
test/e2e/reports
|
||||
selenium-debug.log
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
|
||||
10
litemall-admin/.postcssrc.js
Normal file
@@ -0,0 +1,10 @@
|
||||
// https://github.com/michael-ciniawsky/postcss-load-config
|
||||
|
||||
module.exports = {
|
||||
"plugins": {
|
||||
"postcss-import": {},
|
||||
"postcss-url": {},
|
||||
// to edit target browsers: use "browserslist" field in package.json
|
||||
"autoprefixer": {}
|
||||
}
|
||||
}
|
||||
5
litemall-admin/.travis.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
language: node_js
|
||||
node_js: stable
|
||||
script: npm run test
|
||||
notifications:
|
||||
email: false
|
||||
48
litemall-admin/build/build.js
Normal file
@@ -0,0 +1,48 @@
|
||||
'use strict'
|
||||
require('./check-versions')()
|
||||
|
||||
const ora = require('ora')
|
||||
const rm = require('rimraf')
|
||||
const path = require('path')
|
||||
const chalk = require('chalk')
|
||||
const webpack = require('webpack')
|
||||
const config = require('../config')
|
||||
const webpackConfig = require('./webpack.prod.conf')
|
||||
const server = require('pushstate-server')
|
||||
|
||||
var spinner = ora('building for '+ process.env.env_config+ ' environment...' )
|
||||
spinner.start()
|
||||
|
||||
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
|
||||
if (err) throw err
|
||||
webpack(webpackConfig, (err, stats) => {
|
||||
spinner.stop()
|
||||
if (err) throw err
|
||||
process.stdout.write(stats.toString({
|
||||
colors: true,
|
||||
modules: false,
|
||||
children: false,
|
||||
chunks: false,
|
||||
chunkModules: false
|
||||
}) + '\n\n')
|
||||
|
||||
if (stats.hasErrors()) {
|
||||
console.log(chalk.red(' Build failed with errors.\n'))
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
console.log(chalk.cyan(' Build complete.\n'))
|
||||
console.log(chalk.yellow(
|
||||
' Tip: built files are meant to be served over an HTTP server.\n' +
|
||||
' Opening index.html over file:// won\'t work.\n'
|
||||
))
|
||||
if(process.env.npm_config_preview){
|
||||
server.start({
|
||||
port: 9526,
|
||||
directory: './dist',
|
||||
file: '/index.html'
|
||||
});
|
||||
console.log('> Listening at ' + 'http://localhost:9526' + '\n')
|
||||
}
|
||||
})
|
||||
})
|
||||
54
litemall-admin/build/check-versions.js
Normal file
@@ -0,0 +1,54 @@
|
||||
'use strict'
|
||||
const chalk = require('chalk')
|
||||
const semver = require('semver')
|
||||
const packageConfig = require('../package.json')
|
||||
const shell = require('shelljs')
|
||||
|
||||
function exec (cmd) {
|
||||
return require('child_process').execSync(cmd).toString().trim()
|
||||
}
|
||||
|
||||
const versionRequirements = [
|
||||
{
|
||||
name: 'node',
|
||||
currentVersion: semver.clean(process.version),
|
||||
versionRequirement: packageConfig.engines.node
|
||||
}
|
||||
]
|
||||
|
||||
if (shell.which('npm')) {
|
||||
versionRequirements.push({
|
||||
name: 'npm',
|
||||
currentVersion: exec('npm --version'),
|
||||
versionRequirement: packageConfig.engines.npm
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = function () {
|
||||
const warnings = []
|
||||
|
||||
for (let i = 0; i < versionRequirements.length; i++) {
|
||||
const mod = versionRequirements[i]
|
||||
|
||||
if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
|
||||
warnings.push(mod.name + ': ' +
|
||||
chalk.red(mod.currentVersion) + ' should be ' +
|
||||
chalk.green(mod.versionRequirement)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (warnings.length) {
|
||||
console.log('')
|
||||
console.log(chalk.yellow('To use this template, you must update following to modules:'))
|
||||
console.log()
|
||||
|
||||
for (let i = 0; i < warnings.length; i++) {
|
||||
const warning = warnings[i]
|
||||
console.log(' ' + warning)
|
||||
}
|
||||
|
||||
console.log()
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
BIN
litemall-admin/build/logo.png
Normal file
|
After Width: | Height: | Size: 6.7 KiB |
101
litemall-admin/build/utils.js
Normal file
@@ -0,0 +1,101 @@
|
||||
'use strict'
|
||||
const path = require('path')
|
||||
const config = require('../config')
|
||||
const ExtractTextPlugin = require('extract-text-webpack-plugin')
|
||||
const packageConfig = require('../package.json')
|
||||
|
||||
exports.assetsPath = function (_path) {
|
||||
const assetsSubDirectory = process.env.NODE_ENV === 'production'
|
||||
? config.build.assetsSubDirectory
|
||||
: config.dev.assetsSubDirectory
|
||||
|
||||
return path.posix.join(assetsSubDirectory, _path)
|
||||
}
|
||||
|
||||
exports.cssLoaders = function (options) {
|
||||
options = options || {}
|
||||
|
||||
const cssLoader = {
|
||||
loader: 'css-loader',
|
||||
options: {
|
||||
sourceMap: options.sourceMap
|
||||
}
|
||||
}
|
||||
|
||||
const postcssLoader = {
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
sourceMap: options.sourceMap
|
||||
}
|
||||
}
|
||||
|
||||
// generate loader string to be used with extract text plugin
|
||||
function generateLoaders (loader, loaderOptions) {
|
||||
const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
|
||||
|
||||
if (loader) {
|
||||
loaders.push({
|
||||
loader: loader + '-loader',
|
||||
options: Object.assign({}, loaderOptions, {
|
||||
sourceMap: options.sourceMap
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Extract CSS when that option is specified
|
||||
// (which is the case during production build)
|
||||
if (options.extract) {
|
||||
return ExtractTextPlugin.extract({
|
||||
use: loaders,
|
||||
fallback: 'vue-style-loader'
|
||||
})
|
||||
} else {
|
||||
return ['vue-style-loader'].concat(loaders)
|
||||
}
|
||||
}
|
||||
|
||||
// https://vue-loader.vuejs.org/en/configurations/extract-css.html
|
||||
return {
|
||||
css: generateLoaders(),
|
||||
postcss: generateLoaders(),
|
||||
less: generateLoaders('less'),
|
||||
sass: generateLoaders('sass', { indentedSyntax: true }),
|
||||
scss: generateLoaders('sass'),
|
||||
stylus: generateLoaders('stylus'),
|
||||
styl: generateLoaders('stylus')
|
||||
}
|
||||
}
|
||||
|
||||
// Generate loaders for standalone style files (outside of .vue)
|
||||
exports.styleLoaders = function (options) {
|
||||
const output = []
|
||||
const loaders = exports.cssLoaders(options)
|
||||
|
||||
for (const extension in loaders) {
|
||||
const loader = loaders[extension]
|
||||
output.push({
|
||||
test: new RegExp('\\.' + extension + '$'),
|
||||
use: loader
|
||||
})
|
||||
}
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
exports.createNotifierCallback = () => {
|
||||
const notifier = require('node-notifier')
|
||||
|
||||
return (severity, errors) => {
|
||||
if (severity !== 'error') return
|
||||
|
||||
const error = errors[0]
|
||||
const filename = error.file && error.file.split('!').pop()
|
||||
|
||||
notifier.notify({
|
||||
title: packageConfig.name,
|
||||
message: severity + ': ' + error.name,
|
||||
subtitle: filename || '',
|
||||
icon: path.join(__dirname, 'logo.png')
|
||||
})
|
||||
}
|
||||
}
|
||||
22
litemall-admin/build/vue-loader.conf.js
Normal file
@@ -0,0 +1,22 @@
|
||||
'use strict'
|
||||
const utils = require('./utils')
|
||||
const config = require('../config')
|
||||
const isProduction = process.env.NODE_ENV === 'production'
|
||||
const sourceMapEnabled = isProduction
|
||||
? config.build.productionSourceMap
|
||||
: config.dev.cssSourceMap
|
||||
|
||||
module.exports = {
|
||||
loaders: utils.cssLoaders({
|
||||
sourceMap: sourceMapEnabled,
|
||||
extract: isProduction
|
||||
}),
|
||||
cssSourceMap: sourceMapEnabled,
|
||||
cacheBusting: config.dev.cacheBusting,
|
||||
transformToRequire: {
|
||||
video: ['src', 'poster'],
|
||||
source: 'src',
|
||||
img: 'src',
|
||||
image: 'xlink:href'
|
||||
}
|
||||
}
|
||||
101
litemall-admin/build/webpack.base.conf.js
Normal file
@@ -0,0 +1,101 @@
|
||||
'use strict'
|
||||
const path = require('path')
|
||||
const utils = require('./utils')
|
||||
const config = require('../config')
|
||||
const vueLoaderConfig = require('./vue-loader.conf')
|
||||
|
||||
function resolve (dir) {
|
||||
return path.join(__dirname, '..', dir)
|
||||
}
|
||||
|
||||
const createLintingRule = () => ({
|
||||
test: /\.(js|vue)$/,
|
||||
loader: 'eslint-loader',
|
||||
enforce: 'pre',
|
||||
include: [resolve('src'), resolve('test')],
|
||||
options: {
|
||||
formatter: require('eslint-friendly-formatter'),
|
||||
emitWarning: !config.dev.showEslintErrorsInOverlay
|
||||
}
|
||||
})
|
||||
|
||||
module.exports = {
|
||||
context: path.resolve(__dirname, '../'),
|
||||
entry: {
|
||||
app: './src/main.js'
|
||||
},
|
||||
output: {
|
||||
path: config.build.assetsRoot,
|
||||
filename: '[name].js',
|
||||
publicPath: process.env.NODE_ENV === 'production'
|
||||
? config.build.assetsPublicPath
|
||||
: config.dev.assetsPublicPath
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.js', '.vue', '.json'],
|
||||
alias: {
|
||||
'vue$': 'vue/dist/vue.esm.js',
|
||||
'@': resolve('src'),
|
||||
}
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
...(config.dev.useEslint ? [createLintingRule()] : []),
|
||||
{
|
||||
test: /\.vue$/,
|
||||
loader: 'vue-loader',
|
||||
options: vueLoaderConfig
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
loader: 'babel-loader?cacheDirectory',
|
||||
include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
|
||||
},
|
||||
{
|
||||
test: /\.svg$/,
|
||||
loader: 'svg-sprite-loader',
|
||||
include: [resolve('src/icons')],
|
||||
options: {
|
||||
symbolId: 'icon-[name]'
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
|
||||
loader: 'url-loader',
|
||||
exclude: [resolve('src/icons')],
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: utils.assetsPath('img/[name].[hash:7].[ext]')
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: utils.assetsPath('media/[name].[hash:7].[ext]')
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
node: {
|
||||
// prevent webpack from injecting useless setImmediate polyfill because Vue
|
||||
// source contains it (although only uses it if it's native).
|
||||
setImmediate: false,
|
||||
// prevent webpack from injecting mocks to Node native modules
|
||||
// that does not make sense for the client
|
||||
dgram: 'empty',
|
||||
fs: 'empty',
|
||||
net: 'empty',
|
||||
tls: 'empty',
|
||||
child_process: 'empty'
|
||||
}
|
||||
}
|
||||
88
litemall-admin/build/webpack.dev.conf.js
Normal file
@@ -0,0 +1,88 @@
|
||||
'use strict'
|
||||
const path = require('path')
|
||||
const utils = require('./utils')
|
||||
const webpack = require('webpack')
|
||||
const config = require('../config')
|
||||
const merge = require('webpack-merge')
|
||||
const baseWebpackConfig = require('./webpack.base.conf')
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin')
|
||||
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
|
||||
const portfinder = require('portfinder')
|
||||
|
||||
function resolve (dir) {
|
||||
return path.join(__dirname, '..', dir)
|
||||
}
|
||||
|
||||
const HOST = process.env.HOST
|
||||
const PORT = process.env.PORT && Number(process.env.PORT)
|
||||
|
||||
const devWebpackConfig = merge(baseWebpackConfig, {
|
||||
module: {
|
||||
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
|
||||
},
|
||||
// cheap-module-eval-source-map is faster for development
|
||||
devtool: config.dev.devtool,
|
||||
|
||||
// these devServer options should be customized in /config/index.js
|
||||
devServer: {
|
||||
clientLogLevel: 'warning',
|
||||
historyApiFallback: true,
|
||||
hot: true,
|
||||
compress: true,
|
||||
host: HOST || config.dev.host,
|
||||
port: PORT || config.dev.port,
|
||||
open: config.dev.autoOpenBrowser,
|
||||
overlay: config.dev.errorOverlay
|
||||
? { warnings: false, errors: true }
|
||||
: false,
|
||||
publicPath: config.dev.assetsPublicPath,
|
||||
proxy: config.dev.proxyTable,
|
||||
quiet: true, // necessary for FriendlyErrorsPlugin
|
||||
watchOptions: {
|
||||
poll: config.dev.poll,
|
||||
}
|
||||
},
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': require('../config/dev.env')
|
||||
}),
|
||||
new webpack.HotModuleReplacementPlugin(),
|
||||
new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
|
||||
new webpack.NoEmitOnErrorsPlugin(),
|
||||
// https://github.com/ampedandwired/html-webpack-plugin
|
||||
new HtmlWebpackPlugin({
|
||||
filename: 'index.html',
|
||||
template: 'index.html',
|
||||
inject: true,
|
||||
favicon: resolve('favicon.ico'),
|
||||
title: 'zmall-admin',
|
||||
path: config.dev.assetsPublicPath + config.dev.assetsSubDirectory
|
||||
}),
|
||||
]
|
||||
})
|
||||
|
||||
module.exports = new Promise((resolve, reject) => {
|
||||
portfinder.basePort = process.env.PORT || config.dev.port
|
||||
portfinder.getPort((err, port) => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
} else {
|
||||
// publish the new Port, necessary for e2e tests
|
||||
process.env.PORT = port
|
||||
// add port to devServer config
|
||||
devWebpackConfig.devServer.port = port
|
||||
|
||||
// Add FriendlyErrorsPlugin
|
||||
devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
|
||||
compilationSuccessInfo: {
|
||||
messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
|
||||
},
|
||||
onErrors: config.dev.notifyOnErrors
|
||||
? utils.createNotifierCallback()
|
||||
: undefined
|
||||
}))
|
||||
|
||||
resolve(devWebpackConfig)
|
||||
}
|
||||
})
|
||||
})
|
||||
175
litemall-admin/build/webpack.prod.conf.js
Normal file
@@ -0,0 +1,175 @@
|
||||
'use strict'
|
||||
const path = require('path')
|
||||
const utils = require('./utils')
|
||||
const webpack = require('webpack')
|
||||
const config = require('../config')
|
||||
const merge = require('webpack-merge')
|
||||
const baseWebpackConfig = require('./webpack.base.conf')
|
||||
const CopyWebpackPlugin = require('copy-webpack-plugin')
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin')
|
||||
const ExtractTextPlugin = require('extract-text-webpack-plugin')
|
||||
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
|
||||
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
|
||||
|
||||
function resolve (dir) {
|
||||
return path.join(__dirname, '..', dir)
|
||||
}
|
||||
|
||||
const env = require('../config/'+process.env.env_config+'.env')
|
||||
|
||||
const webpackConfig = merge(baseWebpackConfig, {
|
||||
module: {
|
||||
rules: utils.styleLoaders({
|
||||
sourceMap: config.build.productionSourceMap,
|
||||
extract: true,
|
||||
usePostCSS: true
|
||||
})
|
||||
},
|
||||
devtool: config.build.productionSourceMap ? config.build.devtool : false,
|
||||
output: {
|
||||
path: config.build.assetsRoot,
|
||||
filename: utils.assetsPath('js/[name].[chunkhash].js'),
|
||||
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
|
||||
},
|
||||
plugins: [
|
||||
// http://vuejs.github.io/vue-loader/en/workflow/production.html
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': env
|
||||
}),
|
||||
new UglifyJsPlugin({
|
||||
uglifyOptions: {
|
||||
compress: {
|
||||
warnings: false
|
||||
}
|
||||
},
|
||||
sourceMap: config.build.productionSourceMap,
|
||||
parallel: true
|
||||
}),
|
||||
// extract css into its own file
|
||||
new ExtractTextPlugin({
|
||||
filename: utils.assetsPath('css/[name].[contenthash].css'),
|
||||
// Setting the following option to `false` will not extract CSS from codesplit chunks.
|
||||
// Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
|
||||
// increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
|
||||
allChunks: false,
|
||||
}),
|
||||
// Compress extracted CSS. We are using this plugin so that possible
|
||||
// duplicated CSS from different components can be deduped.
|
||||
new OptimizeCSSPlugin({
|
||||
cssProcessorOptions: config.build.productionSourceMap
|
||||
? { safe: true, map: { inline: false } }
|
||||
: { safe: true }
|
||||
}),
|
||||
// generate dist index.html with correct asset hash for caching.
|
||||
// you can customize output by editing /index.html
|
||||
// see https://github.com/ampedandwired/html-webpack-plugin
|
||||
new HtmlWebpackPlugin({
|
||||
filename: config.build.index,
|
||||
template: 'index.html',
|
||||
inject: true,
|
||||
favicon: resolve('favicon.ico'),
|
||||
title: 'vue-element-admin',
|
||||
path: config.build.assetsPublicPath + config.build.assetsSubDirectory,
|
||||
minify: {
|
||||
removeComments: true,
|
||||
collapseWhitespace: true,
|
||||
removeAttributeQuotes: true
|
||||
// more options:
|
||||
// https://github.com/kangax/html-minifier#options-quick-reference
|
||||
},
|
||||
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
|
||||
chunksSortMode: 'dependency'
|
||||
}),
|
||||
// keep module.id stable when vender modules does not change
|
||||
new webpack.HashedModuleIdsPlugin(),
|
||||
// enable scope hoisting
|
||||
new webpack.optimize.ModuleConcatenationPlugin(),
|
||||
// split vendor js into its own file
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
name: 'vendor',
|
||||
minChunks (module) {
|
||||
// any required modules inside node_modules are extracted to vendor
|
||||
return (
|
||||
module.resource &&
|
||||
/\.js$/.test(module.resource) &&
|
||||
module.resource.indexOf(
|
||||
path.join(__dirname, '../node_modules')
|
||||
) === 0
|
||||
)
|
||||
}
|
||||
}),
|
||||
// extract webpack runtime and module manifest to its own file in order to
|
||||
// prevent vendor hash from being updated whenever app bundle is updated
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
name: 'manifest',
|
||||
minChunks: Infinity
|
||||
}),
|
||||
// This instance extracts shared chunks from code splitted chunks and bundles them
|
||||
// in a separate chunk, similar to the vendor chunk
|
||||
// see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
name: 'app',
|
||||
async: 'vendor-async',
|
||||
children: true,
|
||||
minChunks: 3
|
||||
}),
|
||||
// split echarts into its own file
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
async: 'echarts',
|
||||
minChunks(module) {
|
||||
var context = module.context;
|
||||
return context && (context.indexOf('echarts') >= 0 || context.indexOf('zrender') >= 0);
|
||||
}
|
||||
}),
|
||||
// split xlsx into its own file
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
async: 'xlsx',
|
||||
minChunks(module) {
|
||||
var context = module.context;
|
||||
return context && (context.indexOf('xlsx') >= 0);
|
||||
}
|
||||
}),
|
||||
// split codemirror into its own file
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
async: 'codemirror',
|
||||
minChunks(module) {
|
||||
var context = module.context;
|
||||
return context && (context.indexOf('codemirror') >= 0);
|
||||
}
|
||||
}),
|
||||
|
||||
// copy custom static assets
|
||||
new CopyWebpackPlugin([
|
||||
{
|
||||
from: path.resolve(__dirname, '../static'),
|
||||
to: config.build.assetsSubDirectory,
|
||||
ignore: ['.*']
|
||||
}
|
||||
])
|
||||
]
|
||||
})
|
||||
|
||||
if (config.build.productionGzip) {
|
||||
const CompressionWebpackPlugin = require('compression-webpack-plugin')
|
||||
|
||||
webpackConfig.plugins.push(
|
||||
new CompressionWebpackPlugin({
|
||||
asset: '[path].gz[query]',
|
||||
algorithm: 'gzip',
|
||||
test: new RegExp(
|
||||
'\\.(' +
|
||||
config.build.productionGzipExtensions.join('|') +
|
||||
')$'
|
||||
),
|
||||
threshold: 10240,
|
||||
minRatio: 0.8
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
if (config.build.bundleAnalyzerReport) {
|
||||
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
|
||||
webpackConfig.plugins.push(new BundleAnalyzerPlugin())
|
||||
}
|
||||
|
||||
module.exports = webpackConfig
|
||||
6
litemall-admin/config/dev.env.js
Normal file
@@ -0,0 +1,6 @@
|
||||
module.exports = {
|
||||
NODE_ENV: '"development"',
|
||||
ENV_CONFIG: '"dev"',
|
||||
BASE_API: '"http://localhost:8083/admin"',
|
||||
OS_API: '"http://localhost:8081/storage"'
|
||||
}
|
||||
83
litemall-admin/config/index.js
Normal file
@@ -0,0 +1,83 @@
|
||||
'use strict'
|
||||
// Template version: 1.2.6
|
||||
// see http://vuejs-templates.github.io/webpack for documentation.
|
||||
|
||||
const path = require('path')
|
||||
|
||||
module.exports = {
|
||||
dev: {
|
||||
|
||||
// Paths
|
||||
assetsSubDirectory: 'static',
|
||||
assetsPublicPath: '/',
|
||||
proxyTable: {},
|
||||
|
||||
// Various Dev Server settings
|
||||
host: 'localhost', // can be overwritten by process.env.HOST
|
||||
port: 9527, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
|
||||
autoOpenBrowser: true,
|
||||
errorOverlay: true,
|
||||
notifyOnErrors: false,
|
||||
poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
|
||||
|
||||
// Use Eslint Loader?
|
||||
// If true, your code will be linted during bundling and
|
||||
// linting errors and warnings will be shown in the console.
|
||||
useEslint: true,
|
||||
// If true, eslint errors and warnings will also be shown in the error overlay
|
||||
// in the browser.
|
||||
showEslintErrorsInOverlay: false,
|
||||
|
||||
/**
|
||||
* Source Maps
|
||||
*/
|
||||
|
||||
// https://webpack.js.org/configuration/devtool/#development
|
||||
devtool: '#cheap-source-map',
|
||||
|
||||
// If you have problems debugging vue-files in devtools,
|
||||
// set this to false - it *may* help
|
||||
// https://vue-loader.vuejs.org/en/options.html#cachebusting
|
||||
cacheBusting: true,
|
||||
|
||||
// CSS Sourcemaps off by default because relative paths are "buggy"
|
||||
// with this option, according to the CSS-Loader README
|
||||
// (https://github.com/webpack/css-loader#sourcemaps)
|
||||
// In our experience, they generally work as expected,
|
||||
// just be aware of this issue when enabling this option.
|
||||
cssSourceMap: false,
|
||||
},
|
||||
|
||||
build: {
|
||||
// Template for index.html
|
||||
index: path.resolve(__dirname, '../dist/index.html'),
|
||||
|
||||
// Paths
|
||||
assetsRoot: path.resolve(__dirname, '../dist'),
|
||||
assetsSubDirectory: 'static',
|
||||
|
||||
// you can set by youself according to actual condition
|
||||
assetsPublicPath: './',
|
||||
|
||||
/**
|
||||
* Source Maps
|
||||
*/
|
||||
|
||||
productionSourceMap: false,
|
||||
// https://webpack.js.org/configuration/devtool/#production
|
||||
devtool: '#source-map',
|
||||
|
||||
// Gzip off by default as many popular static hosts such as
|
||||
// Surge or Netlify already gzip all static assets for you.
|
||||
// Before setting to `true`, make sure to:
|
||||
// npm install --save-dev compression-webpack-plugin
|
||||
productionGzip: false,
|
||||
productionGzipExtensions: ['js', 'css'],
|
||||
|
||||
// Run the build command with an extra argument to
|
||||
// View the bundle analyzer report after build finishes:
|
||||
// `npm run build --report`
|
||||
// Set to `true` or `false` to always turn it on or off
|
||||
bundleAnalyzerReport: process.env.npm_config_report
|
||||
}
|
||||
}
|
||||
6
litemall-admin/config/prod.env.js
Normal file
@@ -0,0 +1,6 @@
|
||||
module.exports = {
|
||||
NODE_ENV: '"production"',
|
||||
ENV_CONFIG: '"prod"',
|
||||
BASE_API: '"http://122.152.206.172:8083/admin"',
|
||||
OS_API: '"http://122.152.206.172:8081/storage"'
|
||||
}
|
||||
BIN
litemall-admin/favicon.ico
Normal file
|
After Width: | Height: | Size: 66 KiB |
15
litemall-admin/index.html
Normal file
@@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||
<title>zmall-admin</title>
|
||||
</head>
|
||||
<script src=<%= htmlWebpackPlugin.options.path %>/tinymce4.7.5/tinymce.min.js></script>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
||||
90
litemall-admin/package.json
Normal file
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"name": "litemall-admin",
|
||||
"version": "0.1.0",
|
||||
"description": "litemall-admin basing on vue-element-admin 3.6.2",
|
||||
"author": "linlinjava <linlinjava@163.com>",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
|
||||
"build:prod": "cross-env NODE_ENV=production env_config=prod node build/build.js",
|
||||
"lint": "eslint --ext .js,.vue src",
|
||||
"test": "npm run lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "0.17.1",
|
||||
"clipboard": "1.7.1",
|
||||
"echarts": "3.8.5",
|
||||
"element-ui": "2.0.8",
|
||||
"file-saver": "1.3.3",
|
||||
"font-awesome": "4.7.0",
|
||||
"js-cookie": "2.2.0",
|
||||
"mockjs": "1.0.1-beta3",
|
||||
"normalize.css": "7.0.0",
|
||||
"nprogress": "0.2.0",
|
||||
"screenfull": "3.3.2",
|
||||
"vue": "2.5.10",
|
||||
"vue-count-to": "1.0.13",
|
||||
"vue-router": "3.0.1",
|
||||
"vue-splitpane": "1.0.2",
|
||||
"vuex": "3.0.1",
|
||||
"xlsx": "^0.11.16"
|
||||
},
|
||||
"devDependencies": {
|
||||
"autoprefixer": "7.2.3",
|
||||
"babel-core": "6.26.0",
|
||||
"babel-eslint": "8.0.3",
|
||||
"babel-helper-vue-jsx-merge-props": "2.0.3",
|
||||
"babel-loader": "7.1.2",
|
||||
"babel-plugin-syntax-jsx": "6.18.0",
|
||||
"babel-plugin-transform-runtime": "6.23.0",
|
||||
"babel-plugin-transform-vue-jsx": "3.5.0",
|
||||
"babel-preset-env": "1.6.1",
|
||||
"babel-preset-stage-2": "6.24.1",
|
||||
"chalk": "2.3.0",
|
||||
"copy-webpack-plugin": "4.3.0",
|
||||
"cross-env": "5.1.1",
|
||||
"css-loader": "0.28.7",
|
||||
"eslint": "4.13.1",
|
||||
"eslint-friendly-formatter": "3.0.0",
|
||||
"eslint-loader": "1.9.0",
|
||||
"eslint-plugin-html": "4.0.1",
|
||||
"extract-text-webpack-plugin": "3.0.2",
|
||||
"file-loader": "1.1.5",
|
||||
"friendly-errors-webpack-plugin": "1.6.1",
|
||||
"html-webpack-plugin": "2.30.1",
|
||||
"node-notifier": "5.1.2",
|
||||
"node-sass": "^4.7.2",
|
||||
"optimize-css-assets-webpack-plugin": "3.2.0",
|
||||
"ora": "1.3.0",
|
||||
"portfinder": "1.0.13",
|
||||
"postcss-import": "11.0.0",
|
||||
"postcss-loader": "2.0.9",
|
||||
"postcss-url": "7.3.0",
|
||||
"pushstate-server": "3.0.1",
|
||||
"rimraf": "2.6.2",
|
||||
"sass-loader": "6.0.6",
|
||||
"script-loader": "0.7.2",
|
||||
"semver": "5.4.1",
|
||||
"shelljs": "0.7.8",
|
||||
"svg-sprite-loader": "3.5.2",
|
||||
"uglifyjs-webpack-plugin": "1.1.3",
|
||||
"url-loader": "0.6.2",
|
||||
"vue-loader": "13.5.0",
|
||||
"vue-style-loader": "3.0.3",
|
||||
"vue-template-compiler": "2.5.10",
|
||||
"webpack": "3.10.0",
|
||||
"webpack-bundle-analyzer": "2.9.1",
|
||||
"webpack-dev-server": "2.9.7",
|
||||
"webpack-merge": "4.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 4.0.0",
|
||||
"npm": ">= 3.0.0"
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions",
|
||||
"not ie <= 8"
|
||||
]
|
||||
}
|
||||
11
litemall-admin/src/App.vue
Normal file
@@ -0,0 +1,11 @@
|
||||
<template>
|
||||
<div id="app">
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
name: 'APP'
|
||||
}
|
||||
</script>
|
||||
41
litemall-admin/src/api/ad.js
Normal file
@@ -0,0 +1,41 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function listAd(query) {
|
||||
return request({
|
||||
url: '/ad/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
export function createAd(data) {
|
||||
return request({
|
||||
url: '/ad/create',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function readAd(data) {
|
||||
return request({
|
||||
url: '/ad/read',
|
||||
method: 'get',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function updateAd(data) {
|
||||
return request({
|
||||
url: '/ad/update',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteAd(data) {
|
||||
return request({
|
||||
url: '/ad/delete',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
41
litemall-admin/src/api/address.js
Normal file
@@ -0,0 +1,41 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function listAddress(query) {
|
||||
return request({
|
||||
url: '/address/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
export function createAddress(data) {
|
||||
return request({
|
||||
url: '/address/create',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function readAddress(data) {
|
||||
return request({
|
||||
url: '/address/read',
|
||||
method: 'get',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function updateAddress(data) {
|
||||
return request({
|
||||
url: '/address/update',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteAddress(data) {
|
||||
return request({
|
||||
url: '/address/delete',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
41
litemall-admin/src/api/admin.js
Normal file
@@ -0,0 +1,41 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function listAdmin(query) {
|
||||
return request({
|
||||
url: '/admin/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
export function createAdmin(data) {
|
||||
return request({
|
||||
url: '/admin/create',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function readminAdmin(data) {
|
||||
return request({
|
||||
url: '/admin/readmin',
|
||||
method: 'get',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function updateAdmin(data) {
|
||||
return request({
|
||||
url: '/admin/update',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteAdmin(data) {
|
||||
return request({
|
||||
url: '/admin/delete',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
41
litemall-admin/src/api/brand.js
Normal file
@@ -0,0 +1,41 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function listBrand(query) {
|
||||
return request({
|
||||
url: '/brand/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
export function createBrand(data) {
|
||||
return request({
|
||||
url: '/brand/create',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function readBrand(data) {
|
||||
return request({
|
||||
url: '/brand/read',
|
||||
method: 'get',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function updateBrand(data) {
|
||||
return request({
|
||||
url: '/brand/update',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteBrand(data) {
|
||||
return request({
|
||||
url: '/brand/delete',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
41
litemall-admin/src/api/cart.js
Normal file
@@ -0,0 +1,41 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function listCart(query) {
|
||||
return request({
|
||||
url: '/cart/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
export function createCart(data) {
|
||||
return request({
|
||||
url: '/cart/create',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function readCart(data) {
|
||||
return request({
|
||||
url: '/cart/read',
|
||||
method: 'get',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function updateCart(data) {
|
||||
return request({
|
||||
url: '/cart/update',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteCart(data) {
|
||||
return request({
|
||||
url: '/cart/delete',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
48
litemall-admin/src/api/category.js
Normal file
@@ -0,0 +1,48 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function listCategory(query) {
|
||||
return request({
|
||||
url: '/category/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
export function listCatL1() {
|
||||
return request({
|
||||
url: '/category/l1',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function createCategory(data) {
|
||||
return request({
|
||||
url: '/category/create',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function readCategory(data) {
|
||||
return request({
|
||||
url: '/category/read',
|
||||
method: 'get',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function updateCategory(data) {
|
||||
return request({
|
||||
url: '/category/update',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteCategory(data) {
|
||||
return request({
|
||||
url: '/category/delete',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
41
litemall-admin/src/api/collect.js
Normal file
@@ -0,0 +1,41 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function listCollect(query) {
|
||||
return request({
|
||||
url: '/collect/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
export function createCollect(data) {
|
||||
return request({
|
||||
url: '/collect/create',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function readCollect(data) {
|
||||
return request({
|
||||
url: '/collect/read',
|
||||
method: 'get',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function updateCollect(data) {
|
||||
return request({
|
||||
url: '/collect/update',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteCollect(data) {
|
||||
return request({
|
||||
url: '/collect/delete',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
41
litemall-admin/src/api/comment.js
Normal file
@@ -0,0 +1,41 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function listComment(query) {
|
||||
return request({
|
||||
url: '/comment/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
export function createComment(data) {
|
||||
return request({
|
||||
url: '/comment/create',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function readComment(data) {
|
||||
return request({
|
||||
url: '/comment/read',
|
||||
method: 'get',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function updateComment(data) {
|
||||
return request({
|
||||
url: '/comment/update',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteComment(data) {
|
||||
return request({
|
||||
url: '/comment/delete',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
9
litemall-admin/src/api/dashboard.js
Normal file
@@ -0,0 +1,9 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function info(query) {
|
||||
return request({
|
||||
url: '/dashboard',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
41
litemall-admin/src/api/footprint.js
Normal file
@@ -0,0 +1,41 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function listFootprint(query) {
|
||||
return request({
|
||||
url: '/footprint/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
export function createFootprint(data) {
|
||||
return request({
|
||||
url: '/footprint/create',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function readFootprint(data) {
|
||||
return request({
|
||||
url: '/footprint/read',
|
||||
method: 'get',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function updateFootprint(data) {
|
||||
return request({
|
||||
url: '/footprint/update',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteFootprint(data) {
|
||||
return request({
|
||||
url: '/footprint/delete',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||