目录
前言:
用例图设计:
系统设计
开发方式:
技术架构
系统结构:
API文档:
工程搭建:
搭建父项目
pom:
创建公共子模块:
返回实体:
分布式id生成器:
创建实体类模块:
pom:
创建company子模块:
pom:
CompanyApplication:
Company类:
department类:
deplistResult类(封装部门列表)
Controller:
CompanyController:
DepartmentController:
Dao:
CompanyDao:
Service:
CompanyService:
DepartmentService:
Application:
此时子模块目录如下:
前言:
等实训周一到,哥们就把名字改过来,不然要被真实,此外,本项目除了SSM外以外,会用到其他刚学的插件,这下不得狠狠地在别人面前装一把,由于刚新建文件夹,请容我分成好几个博客来放出
用例图设计:
简单画一下,后面应该会扩展或者大改
系统设计
开发方式:
采用前后端分离(前端用啥还没想好,想好了我就把这里改了)
技术架构
前端:还没想好用啥
后端:spring全家桶(SpringBoot+SpringCloud+SpringMVC+SpringData)
ps:要是来不及我就改了
系统结构:
后面画
API文档:
没有
工程搭建:
搭建父项目
pom:
<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.flowerfog</groupId><artifactId>staff_parent</artifactId><version>1.0-SNAPSHOT</version><packaging>jar</packaging><name>staff_parent</name><url>http://maven.apache.org</url><description>staff-flowerfog</description><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.5.RELEASE</version><relativePath/></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>17</java.version><fastjson.version>1.2.47</fastjson.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>${fastjson.version}</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.16.16</version></dependency></dependencies><repositories><repository><id>spring-snapshots</id><name>Spring Snapshots</name><url>https://repo.spring.io/snapshot</url><snapshots><enabled>true</enabled></snapshots></repository><repository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url><snapshots><enabled>false</enabled></snapshots></repository></repositories><pluginRepositories><pluginRepository><id>spring-snapshots</id><name>Spring Snapshots</name><url>https://repo.spring.io/snapshot</url><snapshots><enabled>true</enabled></snapshots></pluginRepository><pluginRepository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url><snapshots><enabled>false</enabled></snapshots></pluginRepository></pluginRepositories><build><plugins><!--编译插件--><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.1</version><configuration><source>${java.version}</source><target>${java.version}</target></configuration></plugin><!--单元测试插件--><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>2.12.4</version><configuration><skipTests>true</skipTests></configuration></plugin></plugins></build>
</project>
创建公共子模块:
返回实体:
resultCode:
package org.flowerfog.entity;/*** 全局返回码*/
public enum ResultCode {SUCCESS(true,10000,"操作成功!"),//---系统错误返回码-----FAIL(false,10001,"操作失败"),UNAUTHENTICATED(false,10002,"您还未登录"),UNAUTHORISE(false,10003,"权限不足"),SERVER_ERROR(false,99999,"抱歉,系统繁忙,请稍后重试!");//其他操作码暂定//操作是否成功boolean success;//操作代码int code;//提示信息String message;ResultCode(boolean success,int code, String message){this.success = success;this.code = code;this.message = message;}public boolean success() {return success;}public int code() {return code;}public String message() {return message;}}
其他code暂定
result:
package org.flowerfog.entity;import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;/*** 响应对象**/@Data
@NoArgsConstructor
public class Result {private boolean success;//是否成功private Integer code;//返回码private String message;//返回信息private Object data;//返回数据public Result(ResultCode code) {this.success = code.success;this.code = code.code;this.message = code.message;}public Result(ResultCode code,Object data) {this.success = code.success;this.code = code.code;this.message = code.message;this.data = data;}public Result(Integer code,String message,boolean success) {this.code = code;this.message = message;this.success = success;}public static Result SUCCESS(){return new Result(ResultCode.SUCCESS);}public static Result ERROR(){return new Result(ResultCode.SERVER_ERROR);}public static Result FAIL(){return new Result(ResultCode.FAIL);}
}
分布式id生成器:
雪花算法:
package org.flowerfog.utils;import java.lang.management.ManagementFactory;
import java.net.InetAddress;
import java.net.NetworkInterface;//雪花算法代码实现
public class IdWorker {// 时间起始标记点,作为基准,一般取系统的最近时间(一旦确定不能变动)private final static long twepoch = 1288834974657L;// 机器标识位数private final static long workerIdBits = 5L;// 数据中心标识位数private final static long datacenterIdBits = 5L;// 机器ID最大值private final static long maxWorkerId = -1L ^ (-1L << workerIdBits);// 数据中心ID最大值private final static long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);// 毫秒内自增位private final static long sequenceBits = 12L;// 机器ID偏左移12位private final static long workerIdShift = sequenceBits;// 数据中心ID左移17位private final static long datacenterIdShift = sequenceBits + workerIdBits;// 时间毫秒左移22位private final static long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;private final static long sequenceMask = -1L ^ (-1L << sequenceBits);/* 上次生产id时间戳 */private static long lastTimestamp = -1L;// 0,并发控制private long sequence = 0L;private final long workerId;// 数据标识id部分private final long datacenterId;public IdWorker(){this.datacenterId = getDatacenterId(maxDatacenterId);this.workerId = getMaxWorkerId(datacenterId, maxWorkerId);}/*** @param workerId* 工作机器ID* @param datacenterId* 序列号*/public IdWorker(long workerId, long datacenterId) {if (workerId > maxWorkerId || workerId < 0) {throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));}if (datacenterId > maxDatacenterId || datacenterId < 0) {throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));}this.workerId = workerId;this.datacenterId = datacenterId;}/*** 获取下一个ID** @return*/public synchronized long nextId() {long timestamp = timeGen();if (timestamp < lastTimestamp) {throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));}if (lastTimestamp == timestamp) {// 当前毫秒内,则+1sequence = (sequence + 1) & sequenceMask;if (sequence == 0) {// 当前毫秒内计数满了,则等待下一秒timestamp = tilNextMillis(lastTimestamp);}} else {sequence = 0L;}lastTimestamp = timestamp;// ID偏移组合生成最终的ID,并返回IDlong nextId = ((timestamp - twepoch) << timestampLeftShift)| (datacenterId << datacenterIdShift)| (workerId << workerIdShift) | sequence;return nextId;}private long tilNextMillis(final long lastTimestamp) {long timestamp = this.timeGen();while (timestamp <= lastTimestamp) {timestamp = this.timeGen();}return timestamp;}private long timeGen() {return System.currentTimeMillis();}/*** <p>* 获取 maxWorkerId* </p>*/protected static long getMaxWorkerId(long datacenterId, long maxWorkerId) {StringBuffer mpid = new StringBuffer();mpid.append(datacenterId);String name = ManagementFactory.getRuntimeMXBean().getName();if (!name.isEmpty()) {/** GET jvmPid*/mpid.append(name.split("@")[0]);}/** MAC + PID 的 hashcode 获取16个低位*/return (mpid.toString().hashCode() & 0xffff) % (maxWorkerId + 1);}/*** <p>* 数据标识id部分* </p>*/protected static long getDatacenterId(long maxDatacenterId) {long id = 0L;try {InetAddress ip = InetAddress.getLocalHost();NetworkInterface network = NetworkInterface.getByInetAddress(ip);if (network == null) {id = 1L;} else {byte[] mac = network.getHardwareAddress();id = ((0x000000FF & (long) mac[mac.length - 1])| (0x0000FF00 & (((long) mac[mac.length - 2]) << 8))) >> 6;id = id % (maxDatacenterId + 1);}} catch (Exception e) {System.out.println(" getDatacenterId: " + e.getMessage());}return id;}
}
创建实体类模块:
跟上面一样的步骤
pom:
<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/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.flowerfog</groupId><artifactId>staff_parent</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>staff-common-model</artifactId><packaging>war</packaging><name>staff-common-model Maven Webapp</name><url>http://maven.apache.org</url><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>org.flowerfog</groupId><artifactId>staff-common</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies><build><finalName>staff-common-model</finalName></build>
</project>
创建company子模块:
pom:
<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/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.flowerfog</groupId><artifactId>staff_parent</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>staff-company</artifactId><packaging>war</packaging><name>staff-company Maven Webapp</name><url>http://maven.apache.org</url><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>org.flowerfog</groupId><artifactId>staff-common</artifactId><version>1.0-SNAPSHOT</version></dependency><dependency><groupId>org.flowerfog</groupId><artifactId>staff-common-model</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies><build><finalName>staff-company</finalName></build>
</project>
CompanyApplication:
package org.flowerfog.company;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;//1.扫描包
@SpringBootApplication(scanBasePackages = "org.flowerfog.company")
//2.jap注解扫描
@EntityScan(value = "org.flowerfog.domain.company")
public class CompanyApplication {/*** 启动方法*/public static void main(String[] args) {SpringApplication.run(CompanyApplication.class,args);}}
Company类:
package org.flowerfog.domain.company;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import java.io.Serializable;
import java.util.Date;@Data
@AllArgsConstructor
public class Company implements Serializable {private static final long serialVersionUID = 594829320797158219L;//ID@Idprivate String id;/*** 公司名称*/private String name;/*** 企业登录账号ID*/private String managerId;/*** 当前版本*/private String version;/*** 续期时间*/private Date renewalDate;/*** 到期时间*/private Date expirationDate;/*** 公司地区*/private String companyArea;/*** 公司地址*/private String companyAddress;/*** 营业执照-图片ID*/private String businessLicenseId;/*** 法人代表*/private String legalRepresentative;/*** 公司电话*/private String companyPhone;/*** 邮箱*/private String mailbox;/*** 公司规模*/private String companySize;/*** 所属行业*/private String industry;/*** 备注*/private String remarks;/*** 审核状态*/private String auditState;/*** 状态*/private Integer state;/*** 当前余额*/private Double balance;/*** 创建时间*/private Date createTime;
}
department类:
package org.flowerfog.domain.company;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Transient;
import java.io.Serializable;
import java.util.Date;
import java.util.List;/*** (Department)实体类*/
@Entity
@Table(name = "co_department")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Department implements Serializable {private static final long serialVersionUID = -9084332495284489553L;//ID@Idprivate String id;/*** 父级ID*/private String pid;/*** 企业ID*/private String companyId;/*** 部门名称*/private String name;/*** 部门编码,同级部门不可重复*/private String code;/*** 负责人ID*/private String managerId;/*** 负责人名称*/private String manager;/*** 介绍*/private String introduce;/*** 创建时间*/private Date createTime;
}
deplistResult类(封装部门列表)
package org.flowerfog.domain.company.response;import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.flowerfog.domain.company.Company;
import org.flowerfog.domain.company.Department;import java.util.List;@Getter
@Setter
@NoArgsConstructor
public class DeptListResult {private String companyId;private String companyName;private String companyManage;private List<Department> depts;public DeptListResult(Company company,List depts){this.companyId = company.getId();this.companyName = company.getName();this.companyManage = company.getLegalRepresentative();//公司联系人this.depts = depts;}}
Controller:
CompanyController:
package org.flowerfog.company.controller;import org.flowerfog.company.service.CompanyService;
import org.flowerfog.domain.company.Company;
import org.flowerfog.entity.Result;
import org.flowerfog.entity.ResultCode;
import org.flowerfog.exception.CommonException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;import java.util.List;//解决跨域
@CrossOrigin
@RestController
@RequestMapping(value = "/company")
public class CompanyController {@Autowiredprivate CompanyService companyService;//保存企业@RequestMapping(value = "",method = RequestMethod.POST)public Result save(@RequestBody Company company){//业务companyService.add(company);return new Result(ResultCode.SUCCESS);}//根据id更新企业@RequestMapping(value = "/{id}",method = RequestMethod.PUT)public Result update(@PathVariable(value = "id") String id,@RequestBody Company company){//业务company.setId(id);companyService.update(company);return new Result(ResultCode.SUCCESS);}//删除企业@RequestMapping(value = "/{id}",method = RequestMethod.DELETE)public Result delete(@PathVariable(value = "id") String id){companyService.deleteById(id);return new Result(ResultCode.SUCCESS);}//查询@RequestMapping(value = "/{id}",method = RequestMethod.GET)public Result findById(@PathVariable(value = "id") String id) throws CommonException {Company company = companyService.findById(id);Result result = new Result((ResultCode.SUCCESS));result.setData(company);return result;}//查询列表@RequestMapping(value = "",method = RequestMethod.GET)public Result findAll(){// int i = 1/0;List<Company> List = companyService.findAll();Result result = new Result(ResultCode.SUCCESS);result.setData(List);return result;}
}
DepartmentController:
package org.flowerfog.company.controller;import com.sun.xml.internal.bind.v2.TODO;
import org.flowerfog.company.service.CompanyService;
import org.flowerfog.company.service.DepartmentService;
import org.flowerfog.controller.BaseController;
import org.flowerfog.domain.company.Company;
import org.flowerfog.domain.company.Department;
import org.flowerfog.domain.company.response.DeptListResult;
import org.flowerfog.entity.Result;
import org.flowerfog.entity.ResultCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;import java.util.List;@CrossOrigin
@RequestMapping(value = "/company")
@RestController
public class DepartmentController extends BaseController {@Autowiredprivate DepartmentService departmentService;@Autowiredprivate CompanyService companyService;/*** 保存* @param department* @return*/@RequestMapping(value = "/department",method = RequestMethod.POST)public Result save(@RequestBody Department department){//设置id/*** 企业id:使用固定值*/department.setCompanyId(companyId);//调用servicedepartmentService.save(department);return new Result(ResultCode.SUCCESS);}/*** 查询部门列表* @return*/@RequestMapping(value = "/department",method = RequestMethod.GET)public Result findAll(){// idCompany company = companyService.findById(companyId);List<Department> list = departmentService.findAll(companyId);//返回DeptListResult deptListResult = new DeptListResult(company,list);return new Result(ResultCode.SUCCESS,deptListResult);}@RequestMapping(value = "/department/{id}",method = RequestMethod.GET)public Result findById(@PathVariable(value = "id") String id){Department department = departmentService.findById(id);return new Result(ResultCode.SUCCESS,department);}@RequestMapping(value = "/department/{id}",method = RequestMethod.POST)public Result update(@PathVariable(value = "id") String id,@RequestBody Department department){Department dep = departmentService.findById(id);dep.setId(department.getId());departmentService.update(dep);return new Result(ResultCode.SUCCESS);}@RequestMapping(value = "/department/{id}",method = RequestMethod.DELETE)public Result delete(@PathVariable(value = "id") String id){departmentService.deleteById(id);return new Result(ResultCode.SUCCESS);}
}
Dao:
CompanyDao:
package org.flowerfog.company.dao;import org.flowerfog.domain.company.Company;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;/*** 自定义dao接口继承* JpaRepository<实体类,主键>* JpaSpecificationExecutor<实体类>*/
public interface CompanyDao extends JpaRepository<Company,String> ,JpaSpecificationExecutor<Company> {
}
DepartmentDao就不放了,跟上面同理
Service:
CompanyService:
package org.flowerfog.company.service;import org.flowerfog.company.dao.CompanyDao;
import org.flowerfog.domain.company.Company;
import org.flowerfog.utils.IdWorker;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;@Service
public class CompanyService {@Autowiredprivate CompanyDao companyDao;@Autowiredprivate IdWorker idWorker;/*** 保存企业* 1.配置idwork到工程* 2.在service中注入idwork* 3.通过idwork生成id* 4.保存企业*/public void add(Company company) {//基本属性的设置String id = idWorker.nextId()+"";company.setId(id);//默认的状态company.setAuditState("0");//0:未审核,1:已审核company.setState(1); //0.未激活,1:已激活companyDao.save(company);}/*** 更新企业* 1.参数:Company* 2.根据id查询企业对象* 3.设置修改的属性* 4.调用dao完成更新*/public void update(Company company) {Company temp = companyDao.findById(company.getId()).get();temp.setName(company.getName());temp.setCompanyPhone(company.getCompanyPhone());companyDao.save(temp);}/*** 删除企业*/public void deleteById(String id) {companyDao.deleteById(id);}/*** 根据id查询企业*/public Company findById(String id) {return companyDao.findById(id).get();}/*** 查询企业列表*/public List<Company> findAll() {return companyDao.findAll();}
}
DepartmentService:
package org.flowerfog.company.service;import org.flowerfog.company.dao.DepartmentDao;
import org.flowerfog.domain.company.Department;
import org.flowerfog.service.BaseService;
import org.flowerfog.utils.IdWorker;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.List;@Service
public class DepartmentService extends BaseService {@Autowiredprivate DepartmentDao departmentDao;@Autowiredprivate IdWorker idWorker;/*** 保存部门*/public void save(Department department){//设置主键值String id =idWorker.nextId()+"";department.setId(id);//调用dao保存departmentDao.save(department);}/*** 更新部门*/public void update(Department department){//查询Department dept = departmentDao.findById(department.getId()).get();//设置修改属性dept.setCode(department.getCode());dept.setIntroduce(department.getIntroduce());dept.setName(department.getName());//更新部门departmentDao.save(dept);}/*** 根据id查询*/public Department findById(String id){return departmentDao.findById(id).get();}/*** 查询全部*///TODOpublic List<Department> findAll(String companyId){
// Specification<Department> spec = new Specification<Department>() {
//
// @Override
// public Predicate toPredicate(Root<Department> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
// //根据id查询
// return cb.equal(root.get("companyId").as(String.class),id);
// }
// };return departmentDao.findAll(getSpec(companyId));}/*** id删除部门*/public void deleteById(String id){departmentDao.deleteById(id);}
}
Application:
package org.flowerfog.company;import org.flowerfog.utils.IdWorker;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.Bean;//1.配置springboot的包扫描
@SpringBootApplication(scanBasePackages = "org.flowerfog")
//2.配置jpa注解的扫描
@EntityScan(value="org.flowerfog.domain.company")
public class CompanyApplication {/*** 启动方法*/public static void main(String[] args) {SpringApplication.run(CompanyApplication.class,args);}@Beanpublic IdWorker idWorker() {return new IdWorker();}
}
此时子模块目录如下:
至此,Company子模块构建成功