docs(deployment): 更新部署文档并添加自动化部署脚本
- 更新了 DEPLOYMENT.md 文档,增加了更多部署细节和说明 - 添加了 Linux 和 Windows 平台的自动化部署脚本 - 更新了 README.md,增加了部署相关说明 - 调整了 .env 文件配置,以适应新的部署流程 - 移除了部分不必要的代码和配置
This commit is contained in:
56
backend-java/animal-service/pom.xml
Normal file
56
backend-java/animal-service/pom.xml
Normal file
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
|
||||
http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.jiebanke</groupId>
|
||||
<artifactId>backend-java</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>animal-service</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<!-- Spring Boot Web -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Eureka Client -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- MyBatis Plus -->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- MySQL -->
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 结伴客公共模块 -->
|
||||
<dependency>
|
||||
<groupId>com.jiebanke</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.jiebanke.animal;
|
||||
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableDiscoveryClient
|
||||
@EnableFeignClients
|
||||
@MapperScan("com.jiebanke.animal.mapper")
|
||||
@ComponentScan(basePackages = "com.jiebanke")
|
||||
public class AnimalApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(AnimalApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
package com.jiebanke.animal.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.jiebanke.animal.entity.Animal;
|
||||
import com.jiebanke.animal.service.AnimalService;
|
||||
import com.jiebanke.common.vo.ApiResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/animals")
|
||||
public class AnimalController {
|
||||
|
||||
@Autowired
|
||||
private AnimalService animalService;
|
||||
|
||||
/**
|
||||
* 搜索动物(公开接口)
|
||||
*/
|
||||
@GetMapping("/search")
|
||||
public ApiResponse<Map<String, Object>> searchAnimals(
|
||||
@RequestParam(required = false) String keyword,
|
||||
@RequestParam(required = false) String species,
|
||||
@RequestParam(required = false) Double minPrice,
|
||||
@RequestParam(required = false) Double maxPrice,
|
||||
@RequestParam(defaultValue = "1") Integer page,
|
||||
@RequestParam(defaultValue = "10") Integer pageSize) {
|
||||
|
||||
IPage<Animal> animals = animalService.searchAnimals(keyword, species, minPrice, maxPrice, page, pageSize);
|
||||
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("animals", animals.getRecords());
|
||||
result.put("pagination", Map.of(
|
||||
"page", animals.getCurrent(),
|
||||
"pageSize", animals.getSize(),
|
||||
"total", animals.getTotal(),
|
||||
"totalPages", animals.getPages()
|
||||
));
|
||||
|
||||
return ApiResponse.success(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取动物列表(商家)
|
||||
*/
|
||||
@GetMapping
|
||||
public ApiResponse<Map<String, Object>> getAnimals(
|
||||
@RequestHeader("userId") Long merchantId,
|
||||
@RequestParam(defaultValue = "1") Integer page,
|
||||
@RequestParam(defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(required = false) String species,
|
||||
@RequestParam(required = false) String status) {
|
||||
|
||||
IPage<Animal> animals = animalService.getAnimals(merchantId, page, pageSize, species, status);
|
||||
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("animals", animals.getRecords());
|
||||
result.put("pagination", Map.of(
|
||||
"page", animals.getCurrent(),
|
||||
"pageSize", animals.getSize(),
|
||||
"total", animals.getTotal(),
|
||||
"totalPages", animals.getPages()
|
||||
));
|
||||
|
||||
return ApiResponse.success(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取动物统计信息
|
||||
*/
|
||||
@GetMapping("/stats")
|
||||
public ApiResponse<Map<String, Object>> getAnimalStatistics() {
|
||||
Map<String, Object> statistics = animalService.getAnimalStatistics();
|
||||
return ApiResponse.success(statistics);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单个动物详情
|
||||
*/
|
||||
@GetMapping("/{animalId}")
|
||||
public ApiResponse<Animal> getAnimal(@PathVariable Long animalId) {
|
||||
Animal animal = animalService.getAnimalById(animalId);
|
||||
return ApiResponse.success(animal);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建动物信息
|
||||
*/
|
||||
@PostMapping
|
||||
public ApiResponse<Map<String, Object>> createAnimal(
|
||||
@RequestHeader("userId") Long merchantId,
|
||||
@RequestBody Animal animal) {
|
||||
|
||||
animal.setMerchantId(merchantId);
|
||||
Long animalId = animalService.createAnimal(animal);
|
||||
Animal createdAnimal = animalService.getAnimalById(animalId);
|
||||
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("animal", createdAnimal);
|
||||
result.put("message", "动物信息创建成功");
|
||||
|
||||
return ApiResponse.success(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新动物信息
|
||||
*/
|
||||
@PutMapping("/{animalId}")
|
||||
public ApiResponse<Map<String, Object>> updateAnimal(
|
||||
@PathVariable Long animalId,
|
||||
@RequestBody Animal animal) {
|
||||
|
||||
Animal updatedAnimal = animalService.updateAnimal(animalId, animal);
|
||||
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("animal", updatedAnimal);
|
||||
result.put("message", "动物信息更新成功");
|
||||
|
||||
return ApiResponse.success(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除动物信息
|
||||
*/
|
||||
@DeleteMapping("/{animalId}")
|
||||
public ApiResponse<Map<String, Object>> deleteAnimal(@PathVariable Long animalId) {
|
||||
boolean deleted = animalService.deleteAnimal(animalId);
|
||||
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("message", "动物信息删除成功");
|
||||
result.put("animalId", animalId);
|
||||
|
||||
return ApiResponse.success(result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.jiebanke.animal.entity;
|
||||
|
||||
import com.jiebanke.common.entity.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class Animal extends BaseEntity {
|
||||
private Long merchantId;
|
||||
private String name;
|
||||
private String species;
|
||||
private String breed;
|
||||
private LocalDate birthDate;
|
||||
private String personality;
|
||||
private String farmLocation;
|
||||
private BigDecimal price;
|
||||
private Integer claimCount;
|
||||
private String status;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.jiebanke.animal.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.jiebanke.animal.entity.Animal;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface AnimalMapper extends BaseMapper<Animal> {
|
||||
|
||||
/**
|
||||
* 根据商家ID获取动物列表
|
||||
* @param merchantId 商家ID
|
||||
* @return 动物列表
|
||||
*/
|
||||
@Select("SELECT * FROM animals WHERE merchant_id = #{merchantId} ORDER BY created_at DESC")
|
||||
List<Animal> selectByMerchantId(@Param("merchantId") Long merchantId);
|
||||
|
||||
/**
|
||||
* 根据物种获取动物列表
|
||||
* @param species 物种
|
||||
* @return 动物列表
|
||||
*/
|
||||
@Select("SELECT * FROM animals WHERE species = #{species} ORDER BY created_at DESC")
|
||||
List<Animal> selectBySpecies(@Param("species") String species);
|
||||
|
||||
/**
|
||||
* 根据状态获取动物列表
|
||||
* @param status 状态
|
||||
* @return 动物列表
|
||||
*/
|
||||
@Select("SELECT * FROM animals WHERE status = #{status} ORDER BY created_at DESC")
|
||||
List<Animal> selectByStatus(@Param("status") String status);
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.jiebanke.animal.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.jiebanke.animal.entity.Animal;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface AnimalService extends IService<Animal> {
|
||||
|
||||
/**
|
||||
* 获取动物列表
|
||||
* @param merchantId 商家ID
|
||||
* @param page 页码
|
||||
* @param pageSize 每页数量
|
||||
* @param species 物种
|
||||
* @param status 状态
|
||||
* @return 动物分页列表
|
||||
*/
|
||||
IPage<Animal> getAnimals(Long merchantId, Integer page, Integer pageSize, String species, String status);
|
||||
|
||||
/**
|
||||
* 获取单个动物详情
|
||||
* @param animalId 动物ID
|
||||
* @return 动物信息
|
||||
*/
|
||||
Animal getAnimalById(Long animalId);
|
||||
|
||||
/**
|
||||
* 创建动物
|
||||
* @param animal 动物信息
|
||||
* @return 创建的动物ID
|
||||
*/
|
||||
Long createAnimal(Animal animal);
|
||||
|
||||
/**
|
||||
* 更新动物信息
|
||||
* @param animalId 动物ID
|
||||
* @param animal 更新的动物信息
|
||||
* @return 更新后的动物信息
|
||||
*/
|
||||
Animal updateAnimal(Long animalId, Animal animal);
|
||||
|
||||
/**
|
||||
* 删除动物
|
||||
* @param animalId 动物ID
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
boolean deleteAnimal(Long animalId);
|
||||
|
||||
/**
|
||||
* 获取动物统计信息
|
||||
* @return 统计信息
|
||||
*/
|
||||
Map<String, Object> getAnimalStatistics();
|
||||
|
||||
/**
|
||||
* 搜索动物
|
||||
* @param keyword 关键词
|
||||
* @param species 物种
|
||||
* @param minPrice 最低价格
|
||||
* @param maxPrice 最高价格
|
||||
* @param page 页码
|
||||
* @param pageSize 每页数量
|
||||
* @return 动物分页列表
|
||||
*/
|
||||
IPage<Animal> searchAnimals(String keyword, String species, Double minPrice, Double maxPrice, Integer page, Integer pageSize);
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
package com.jiebanke.animal.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.jiebanke.animal.entity.Animal;
|
||||
import com.jiebanke.animal.mapper.AnimalMapper;
|
||||
import com.jiebanke.animal.service.AnimalService;
|
||||
import com.jiebanke.common.exception.BusinessException;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Service
|
||||
public class AnimalServiceImpl extends ServiceImpl<AnimalMapper, Animal> implements AnimalService {
|
||||
|
||||
@Override
|
||||
public IPage<Animal> getAnimals(Long merchantId, Integer page, Integer pageSize, String species, String status) {
|
||||
QueryWrapper<Animal> queryWrapper = new QueryWrapper<>();
|
||||
|
||||
if (merchantId != null) {
|
||||
queryWrapper.eq("merchant_id", merchantId);
|
||||
}
|
||||
|
||||
if (species != null && !species.isEmpty()) {
|
||||
queryWrapper.eq("species", species);
|
||||
}
|
||||
|
||||
if (status != null && !status.isEmpty()) {
|
||||
queryWrapper.eq("status", status);
|
||||
}
|
||||
|
||||
queryWrapper.orderByDesc("created_at");
|
||||
|
||||
Page<Animal> pageObj = new Page<>(page != null ? page : 1, pageSize != null ? pageSize : 10);
|
||||
return this.page(pageObj, queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Animal getAnimalById(Long animalId) {
|
||||
Animal animal = this.getById(animalId);
|
||||
if (animal == null) {
|
||||
throw new BusinessException("动物不存在");
|
||||
}
|
||||
return animal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long createAnimal(Animal animal) {
|
||||
this.save(animal);
|
||||
return animal.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Animal updateAnimal(Long animalId, Animal animal) {
|
||||
Animal existingAnimal = this.getById(animalId);
|
||||
if (existingAnimal == null) {
|
||||
throw new BusinessException("动物不存在");
|
||||
}
|
||||
|
||||
// 更新字段
|
||||
if (animal.getName() != null) {
|
||||
existingAnimal.setName(animal.getName());
|
||||
}
|
||||
if (animal.getSpecies() != null) {
|
||||
existingAnimal.setSpecies(animal.getSpecies());
|
||||
}
|
||||
if (animal.getBreed() != null) {
|
||||
existingAnimal.setBreed(animal.getBreed());
|
||||
}
|
||||
if (animal.getBirthDate() != null) {
|
||||
existingAnimal.setBirthDate(animal.getBirthDate());
|
||||
}
|
||||
if (animal.getPersonality() != null) {
|
||||
existingAnimal.setPersonality(animal.getPersonality());
|
||||
}
|
||||
if (animal.getFarmLocation() != null) {
|
||||
existingAnimal.setFarmLocation(animal.getFarmLocation());
|
||||
}
|
||||
if (animal.getPrice() != null) {
|
||||
existingAnimal.setPrice(animal.getPrice());
|
||||
}
|
||||
if (animal.getStatus() != null) {
|
||||
existingAnimal.setStatus(animal.getStatus());
|
||||
}
|
||||
|
||||
this.updateById(existingAnimal);
|
||||
return existingAnimal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteAnimal(Long animalId) {
|
||||
return this.removeById(animalId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getAnimalStatistics() {
|
||||
// 获取动物总数
|
||||
int total = Math.toIntExact(this.count());
|
||||
|
||||
// 按物种统计
|
||||
QueryWrapper<Animal> speciesWrapper = new QueryWrapper<>();
|
||||
speciesWrapper.select("species", "COUNT(*) as count");
|
||||
speciesWrapper.groupBy("species");
|
||||
List<Map<String, Object>> speciesStats = this.listMaps(speciesWrapper);
|
||||
|
||||
// 按状态统计
|
||||
QueryWrapper<Animal> statusWrapper = new QueryWrapper<>();
|
||||
statusWrapper.select("status", "COUNT(*) as count");
|
||||
statusWrapper.groupBy("status");
|
||||
List<Map<String, Object>> statusStats = this.listMaps(statusWrapper);
|
||||
|
||||
// 构建返回结果
|
||||
Map<String, Object> statistics = new HashMap<>();
|
||||
statistics.put("total", total);
|
||||
statistics.put("bySpecies", speciesStats);
|
||||
statistics.put("byStatus", statusStats);
|
||||
|
||||
return statistics;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPage<Animal> searchAnimals(String keyword, String species, Double minPrice, Double maxPrice, Integer page, Integer pageSize) {
|
||||
QueryWrapper<Animal> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("status", "available");
|
||||
|
||||
if (keyword != null && !keyword.isEmpty()) {
|
||||
queryWrapper.and(wrapper -> wrapper
|
||||
.like("name", keyword)
|
||||
.or()
|
||||
.like("personality", keyword)
|
||||
.or()
|
||||
.like("species", keyword));
|
||||
}
|
||||
|
||||
if (species != null && !species.isEmpty()) {
|
||||
queryWrapper.eq("species", species);
|
||||
}
|
||||
|
||||
if (minPrice != null) {
|
||||
queryWrapper.ge("price", minPrice);
|
||||
}
|
||||
|
||||
if (maxPrice != null) {
|
||||
queryWrapper.le("price", maxPrice);
|
||||
}
|
||||
|
||||
queryWrapper.orderByDesc("created_at");
|
||||
|
||||
Page<Animal> pageObj = new Page<>(page != null ? page : 1, pageSize != null ? pageSize : 10);
|
||||
return this.page(pageObj, queryWrapper);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
server:
|
||||
port: 8084
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: animal-service
|
||||
datasource:
|
||||
url: jdbc:mysql://localhost:3306/jiebanke?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
|
||||
username: root
|
||||
password: root
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
redis:
|
||||
host: localhost
|
||||
port: 6379
|
||||
database: 0
|
||||
rabbitmq:
|
||||
host: localhost
|
||||
port: 5672
|
||||
username: guest
|
||||
password: guest
|
||||
|
||||
eureka:
|
||||
client:
|
||||
service-url:
|
||||
defaultZone: http://localhost:8761/eureka/
|
||||
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||
global-config:
|
||||
db-config:
|
||||
id-type: auto
|
||||
Reference in New Issue
Block a user