| @@ -1,7 +1,7 @@ | |||||
| spring: | spring: | ||||
| datasource: | datasource: | ||||
| jdbc-url: jdbc:mysql://192.168.1.228:3308/fhsmscdb?useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT%2B8 | |||||
| jdbc-url: jdbc:mysql://192.168.1.228:3308/pet_app?useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT%2B8 | |||||
| username: root | username: root | ||||
| password: secret | password: secret | ||||
| driver-class-name: com.mysql.cj.jdbc.Driver | driver-class-name: com.mysql.cj.jdbc.Driver | ||||
| @@ -1,7 +1,7 @@ | |||||
| spring: | spring: | ||||
| datasource: | datasource: | ||||
| jdbc-url: jdbc:mysql://127.0.0.1:3308/fhsmscdb?useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT%2B8 | |||||
| jdbc-url: jdbc:mysql://127.0.0.1:3308/pet_app?useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT%2B8 | |||||
| username: root | username: root | ||||
| password: secret | password: secret | ||||
| springdoc: | springdoc: | ||||
| @@ -1,7 +1,7 @@ | |||||
| spring: | spring: | ||||
| datasource: | datasource: | ||||
| jdbc-url: jdbc:mysql://127.0.0.1:3308/fhsmscdb?useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT%2B8 | |||||
| jdbc-url: jdbc:mysql://127.0.0.1:3308/pet_app?useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT%2B8 | |||||
| username: root | username: root | ||||
| password: secret | password: secret | ||||
| driver-class-name: com.mysql.cj.jdbc.Driver | driver-class-name: com.mysql.cj.jdbc.Driver | ||||
| @@ -1,7 +1,7 @@ | |||||
| spring: | spring: | ||||
| datasource: | datasource: | ||||
| jdbc-url: jdbc:mysql://192.168.1.228:3308/fhsmscdb?useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT%2B8 | |||||
| jdbc-url: jdbc:mysql://192.168.1.228:3308/pet_app?useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT%2B8 | |||||
| username: root | username: root | ||||
| password: secret | password: secret | ||||
| driver-class-name: com.mysql.cj.jdbc.Driver | driver-class-name: com.mysql.cj.jdbc.Driver | ||||
| @@ -1,7 +1,7 @@ | |||||
| spring: | spring: | ||||
| datasource: | datasource: | ||||
| jdbc-url: jdbc:mysql://127.0.0.1:3308/fhsmscdb?useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT%2B8 | |||||
| jdbc-url: jdbc:mysql://127.0.0.1:3308/pet_app?useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT%2B8 | |||||
| username: root | username: root | ||||
| password: secret | password: secret | ||||
| springdoc: | springdoc: | ||||
| @@ -1,7 +1,7 @@ | |||||
| spring: | spring: | ||||
| datasource: | datasource: | ||||
| jdbc-url: jdbc:mysql://127.0.0.1:3308/fhsmscdb?useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT%2B8 | |||||
| jdbc-url: jdbc:mysql://127.0.0.1:3308/pet_app?useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT%2B8 | |||||
| username: root | username: root | ||||
| password: secret | password: secret | ||||
| driver-class-name: com.mysql.cj.jdbc.Driver | driver-class-name: com.mysql.cj.jdbc.Driver | ||||
| @@ -28,12 +28,13 @@ public class SecurityConfig { | |||||
| public static final String INDEX_URL = "/"; | public static final String INDEX_URL = "/"; | ||||
| public static final String LOGIN_URL = "/login"; | public static final String LOGIN_URL = "/login"; | ||||
| public static final String REFRESH_TOKEN_URL = "/refresh-token"; | public static final String REFRESH_TOKEN_URL = "/refresh-token"; | ||||
| public static final String FOOD_NUTRIENTS_URL = "/food_nutrients/**"; | |||||
| public static final String[] URL_WHITELIST = { | public static final String[] URL_WHITELIST = { | ||||
| INDEX_URL, | INDEX_URL, | ||||
| LOGIN_URL, | LOGIN_URL, | ||||
| REFRESH_TOKEN_URL, | REFRESH_TOKEN_URL, | ||||
| FOOD_NUTRIENTS_URL, | |||||
| }; | }; | ||||
| @Lazy | @Lazy | ||||
| @@ -0,0 +1,53 @@ | |||||
| package com.ffii.fhsmsc.modules.diet_records.entity; | |||||
| import com.ffii.core.entity.BaseEntity; | |||||
| import jakarta.persistence.Column; | |||||
| import jakarta.persistence.Entity; | |||||
| import jakarta.persistence.Table; | |||||
| import java.util.Date; | |||||
| @Entity | |||||
| @Table(name = "diet_records") | |||||
| public class diet_records extends BaseEntity<Long> { | |||||
| @Column(name = "food_id") | |||||
| private Long food_id; | |||||
| @Column(name = "date") | |||||
| private Date date; | |||||
| @Column(name = "meal_type") | |||||
| private String meal_type; | |||||
| @Column(name = "size") | |||||
| private Double size; | |||||
| @Column(name = "user_id") | |||||
| private Long user_id; | |||||
| public Long getFood_id() { | |||||
| return food_id; | |||||
| } | |||||
| public void setFood_id(Long food_id) { | |||||
| this.food_id = food_id; | |||||
| } | |||||
| public Date getDate() { | |||||
| return date; | |||||
| } | |||||
| public void setDate(Date date) { | |||||
| this.date = date; | |||||
| } | |||||
| public String getMeal_type() { | |||||
| return meal_type; | |||||
| } | |||||
| public void setMeal_type(String meal_type) { | |||||
| this.meal_type = meal_type; | |||||
| } | |||||
| public Double getSize() { | |||||
| return size; | |||||
| } | |||||
| public void setSize(Double size) { | |||||
| this.size = size; | |||||
| } | |||||
| public Long getUser_id() { | |||||
| return user_id; | |||||
| } | |||||
| public void setUser_id(Long user_id) { | |||||
| this.user_id = user_id; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,6 @@ | |||||
| package com.ffii.fhsmsc.modules.diet_records.entity; | |||||
| import com.ffii.core.support.AbstractRepository; | |||||
| public interface diet_recordsRepository extends AbstractRepository<diet_records, Long> { | |||||
| } | |||||
| @@ -0,0 +1,50 @@ | |||||
| package com.ffii.fhsmsc.modules.diet_records.req; | |||||
| import java.util.Date; | |||||
| public class diet_recordsReq { | |||||
| private Long id; | |||||
| private Long food_id; | |||||
| private Date date; | |||||
| private String meal_type; | |||||
| private Double size; | |||||
| private Long user_id; | |||||
| public Long getId() { | |||||
| return id; | |||||
| } | |||||
| public void setId(Long id) { | |||||
| this.id = id; | |||||
| } | |||||
| public Long getFood_id() { | |||||
| return food_id; | |||||
| } | |||||
| public void setFood_id(Long food_id) { | |||||
| this.food_id = food_id; | |||||
| } | |||||
| public Date getDate() { | |||||
| return date; | |||||
| } | |||||
| public void setDate(Date date) { | |||||
| this.date = date; | |||||
| } | |||||
| public String getMeal_type() { | |||||
| return meal_type; | |||||
| } | |||||
| public void setMeal_type(String meal_type) { | |||||
| this.meal_type = meal_type; | |||||
| } | |||||
| public Double getSize() { | |||||
| return size; | |||||
| } | |||||
| public void setSize(Double size) { | |||||
| this.size = size; | |||||
| } | |||||
| public Long getUser_id() { | |||||
| return user_id; | |||||
| } | |||||
| public void setUser_id(Long user_id) { | |||||
| this.user_id = user_id; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,99 @@ | |||||
| package com.ffii.fhsmsc.modules.diet_records.service; | |||||
| import java.util.List; | |||||
| import java.util.Map; | |||||
| import org.slf4j.Logger; | |||||
| import org.slf4j.LoggerFactory; | |||||
| import org.springframework.stereotype.Service; | |||||
| import org.springframework.transaction.annotation.Transactional; | |||||
| import com.ffii.core.exception.InternalServerErrorException; | |||||
| import com.ffii.core.support.AbstractBaseEntityService; | |||||
| import com.ffii.core.support.JdbcDao; | |||||
| import com.ffii.core.utils.BeanUtils; | |||||
| import com.ffii.fhsmsc.modules.diet_records.entity.diet_records; | |||||
| import com.ffii.fhsmsc.modules.diet_records.entity.diet_recordsRepository; | |||||
| import com.ffii.fhsmsc.modules.diet_records.req.diet_recordsReq; | |||||
| import jakarta.validation.Valid; | |||||
| @Service | |||||
| public class diet_recordsService extends AbstractBaseEntityService<diet_records, Long, diet_recordsRepository>{ | |||||
| private static final Logger logger = LoggerFactory.getLogger(diet_recordsService.class); | |||||
| public diet_recordsService(JdbcDao jdbcDao, diet_recordsRepository repository) { | |||||
| super(jdbcDao, repository); | |||||
| } | |||||
| public List<Map<String, Object>> search(Map<String, Object> args) { | |||||
| logger.info("Search called with args: {}", args); | |||||
| StringBuilder sql = new StringBuilder("SELECT" | |||||
| + " dr.id," | |||||
| + " dr.food_id," | |||||
| + " dr.date," | |||||
| + " dr.meal_type," | |||||
| + " dr.size," | |||||
| + " dr.user_id" | |||||
| + " FROM diet_records dr" | |||||
| + " WHERE dr.deleted = 0" // 使用 0,因为是 tinyint(1) | |||||
| ); | |||||
| if (args != null) { | |||||
| if (args.containsKey("user_id")) { | |||||
| sql.append(" AND dr.user_id = :user_id"); | |||||
| logger.info("Added user_id filter: {}", args.get("user_id")); | |||||
| } | |||||
| // Add date range filters | |||||
| if (args.containsKey("start_date")) { | |||||
| sql.append(" AND dr.date >= :start_date"); | |||||
| logger.info("Added start_date filter: {}", args.get("start_date")); | |||||
| } | |||||
| if (args.containsKey("end_date")) { | |||||
| sql.append(" AND dr.date <= :end_date"); | |||||
| logger.info("Added end_date filter: {}", args.get("end_date")); | |||||
| } | |||||
| } | |||||
| sql.append(" ORDER BY dr.date, dr.meal_type"); // Changed ordering to make more sense | |||||
| logger.info("Final SQL query: {}", sql.toString()); | |||||
| List<Map<String, Object>> result = jdbcDao.queryForList(sql.toString(), args); | |||||
| logger.info("Query returned {} results", result.size()); | |||||
| return result; | |||||
| } | |||||
| @Transactional(rollbackFor = Exception.class) | |||||
| public diet_records saveOrUpdate(@Valid diet_recordsReq req) { | |||||
| diet_records instance; | |||||
| if (req.getId() != null && req.getId() > 0) { | |||||
| // 更新现有记录 | |||||
| instance = find(req.getId()).orElseThrow(InternalServerErrorException::new); | |||||
| // 只更新非空字段 | |||||
| if (req.getFood_id() != null) { | |||||
| instance.setFood_id(req.getFood_id()); | |||||
| } | |||||
| if (req.getDate() != null) { | |||||
| instance.setDate(req.getDate()); | |||||
| } | |||||
| if (req.getMeal_type() != null) { | |||||
| instance.setMeal_type(req.getMeal_type()); | |||||
| } | |||||
| if (req.getSize() != null) { | |||||
| instance.setSize(req.getSize()); | |||||
| } | |||||
| if (req.getUser_id() != null) { | |||||
| instance.setUser_id(req.getUser_id()); | |||||
| } | |||||
| } else { | |||||
| // 创建新记录 | |||||
| instance = new diet_records(); | |||||
| BeanUtils.copyProperties(req, instance); | |||||
| } | |||||
| saveAndFlush(instance); | |||||
| return instance; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,51 @@ | |||||
| package com.ffii.fhsmsc.modules.diet_records.web; | |||||
| import java.util.Map; | |||||
| import org.slf4j.Logger; | |||||
| import org.slf4j.LoggerFactory; | |||||
| import org.springframework.web.bind.ServletRequestBindingException; | |||||
| import org.springframework.web.bind.annotation.GetMapping; | |||||
| 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 com.ffii.core.response.IdRes; | |||||
| import com.ffii.core.response.RecordsRes; | |||||
| import com.ffii.core.utils.CriteriaArgsBuilder; | |||||
| import com.ffii.fhsmsc.modules.diet_records.req.diet_recordsReq; | |||||
| import com.ffii.fhsmsc.modules.diet_records.service.diet_recordsService; | |||||
| import jakarta.servlet.http.HttpServletRequest; | |||||
| import jakarta.validation.Valid; | |||||
| @RestController | |||||
| @RequestMapping("/diet_records") | |||||
| public class diet_recordsController { | |||||
| private static final Logger logger = LoggerFactory.getLogger(diet_recordsController.class); | |||||
| private diet_recordsService diet_recordsService; | |||||
| public diet_recordsController( | |||||
| diet_recordsService diet_recordsService | |||||
| ) { | |||||
| this.diet_recordsService = diet_recordsService; | |||||
| } | |||||
| @GetMapping("/list") | |||||
| public RecordsRes<Map<String, Object>> listJson(HttpServletRequest request) throws ServletRequestBindingException { | |||||
| logger.info("Received list request with parameters: {}", request.getParameterMap()); | |||||
| Map<String, Object> args = CriteriaArgsBuilder.withRequest(request) | |||||
| .addInteger("user_id") | |||||
| .addDate("start_date") // Add start date parameter | |||||
| .addDate("end_date") // Add end date parameter | |||||
| .build(); | |||||
| logger.info("Built args: {}", args); | |||||
| return new RecordsRes<>(diet_recordsService.search(args)); | |||||
| } | |||||
| @PostMapping("/save") | |||||
| public IdRes saveOrUpdate(@RequestBody @Valid diet_recordsReq req) { | |||||
| return new IdRes(diet_recordsService.saveOrUpdate(req).getId()); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,221 @@ | |||||
| package com.ffii.fhsmsc.modules.food_nutrients.entity; | |||||
| import com.ffii.core.entity.BaseEntity; | |||||
| import jakarta.persistence.Column; | |||||
| import jakarta.persistence.Entity; | |||||
| import jakarta.persistence.Table; | |||||
| @Entity | |||||
| @Table(name = "food_nutrients") | |||||
| public class food_nutrients extends BaseEntity<Long> { | |||||
| @Column(name = "food_name") | |||||
| private String food_name; | |||||
| @Column(name = "brand") | |||||
| private String brand; | |||||
| @Column(name = "size_kg") | |||||
| private Double size_kg; | |||||
| @Column(name = "protein_percent") | |||||
| private Double protein_percent; | |||||
| @Column(name = "fat_percent") | |||||
| private Double fat_percent; | |||||
| @Column(name = "fibre_percent") | |||||
| private Double fibre_percent; | |||||
| @Column(name = "ash_percent") | |||||
| private Double ash_percent; | |||||
| @Column(name = "taurine_percent") | |||||
| private Double taurine_percent; | |||||
| @Column(name = "vitamin_a_iu_kg") | |||||
| private Integer vitamin_a_iu_kg; | |||||
| @Column(name = "vitamin_d_iu_kg") | |||||
| private Integer vitamin_d_iu_kg; | |||||
| @Column(name = "vitamin_e_mg_kg") | |||||
| private Integer vitamin_e_mg_kg; | |||||
| @Column(name = "phosphorus_percent") | |||||
| private Double phosphorus_percent; | |||||
| @Column(name = "calcium_percent") | |||||
| private Double calcium_percent; | |||||
| @Column(name = "magnesium_percent") | |||||
| private Double magnesium_percent; | |||||
| @Column(name = "methionine_percent") | |||||
| private Double methionine_percent; | |||||
| @Column(name = "moisture_percent") | |||||
| private Double moisture_percent; | |||||
| @Column(name = "omega_3_mg_kg") | |||||
| private Double omega_3_mg_kg; | |||||
| @Column(name = "omega_6_mg_kg") | |||||
| private Double omega_6_mg_kg; | |||||
| @Column(name = "vitamin_c_mg_kg") | |||||
| private Integer vitamin_c_mg_kg; | |||||
| @Column(name = "calories_kcal_kg") | |||||
| private Integer calories_kcal_kg; | |||||
| @Column(name = "food_type") | |||||
| private String food_type; | |||||
| @Column(name = "target_age_category") | |||||
| private String target_age_category; | |||||
| @Column(name = "pet") | |||||
| private String pet; | |||||
| @Column(name = "embedding_text") | |||||
| private String embedding_text; | |||||
| @Column(name = "embedding_vector") | |||||
| private String embedding_vector; | |||||
| @Column(name = "description") | |||||
| private String description; | |||||
| public String getFood_name() { | |||||
| return food_name; | |||||
| } | |||||
| public void setFood_name(String food_name) { | |||||
| this.food_name = food_name; | |||||
| } | |||||
| public String getBrand() { | |||||
| return brand; | |||||
| } | |||||
| public void setBrand(String brand) { | |||||
| this.brand = brand; | |||||
| } | |||||
| public Double getSize_kg() { | |||||
| return size_kg; | |||||
| } | |||||
| public void setSize_kg(Double size_kg) { | |||||
| this.size_kg = size_kg; | |||||
| } | |||||
| public Double getProtein_percent() { | |||||
| return protein_percent; | |||||
| } | |||||
| public void setProtein_percent(Double protein_percent) { | |||||
| this.protein_percent = protein_percent; | |||||
| } | |||||
| public Double getFat_percent() { | |||||
| return fat_percent; | |||||
| } | |||||
| public void setFat_percent(Double fat_percent) { | |||||
| this.fat_percent = fat_percent; | |||||
| } | |||||
| public Double getFibre_percent() { | |||||
| return fibre_percent; | |||||
| } | |||||
| public void setFibre_percent(Double fibre_percent) { | |||||
| this.fibre_percent = fibre_percent; | |||||
| } | |||||
| public Double getAsh_percent() { | |||||
| return ash_percent; | |||||
| } | |||||
| public void setAsh_percent(Double ash_percent) { | |||||
| this.ash_percent = ash_percent; | |||||
| } | |||||
| public Double getTaurine_percent() { | |||||
| return taurine_percent; | |||||
| } | |||||
| public void setTaurine_percent(Double taurine_percent) { | |||||
| this.taurine_percent = taurine_percent; | |||||
| } | |||||
| public Integer getVitamin_a_iu_kg() { | |||||
| return vitamin_a_iu_kg; | |||||
| } | |||||
| public void setVitamin_a_iu_kg(Integer vitamin_a_iu_kg) { | |||||
| this.vitamin_a_iu_kg = vitamin_a_iu_kg; | |||||
| } | |||||
| public Integer getVitamin_d_iu_kg() { | |||||
| return vitamin_d_iu_kg; | |||||
| } | |||||
| public void setVitamin_d_iu_kg(Integer vitamin_d_iu_kg) { | |||||
| this.vitamin_d_iu_kg = vitamin_d_iu_kg; | |||||
| } | |||||
| public Integer getVitamin_e_mg_kg() { | |||||
| return vitamin_e_mg_kg; | |||||
| } | |||||
| public void setVitamin_e_mg_kg(Integer vitamin_e_mg_kg) { | |||||
| this.vitamin_e_mg_kg = vitamin_e_mg_kg; | |||||
| } | |||||
| public Double getPhosphorus_percent() { | |||||
| return phosphorus_percent; | |||||
| } | |||||
| public void setPhosphorus_percent(Double phosphorus_percent) { | |||||
| this.phosphorus_percent = phosphorus_percent; | |||||
| } | |||||
| public Double getCalcium_percent() { | |||||
| return calcium_percent; | |||||
| } | |||||
| public void setCalcium_percent(Double calcium_percent) { | |||||
| this.calcium_percent = calcium_percent; | |||||
| } | |||||
| public Double getMagnesium_percent() { | |||||
| return magnesium_percent; | |||||
| } | |||||
| public void setMagnesium_percent(Double magnesium_percent) { | |||||
| this.magnesium_percent = magnesium_percent; | |||||
| } | |||||
| public Double getMethionine_percent() { | |||||
| return methionine_percent; | |||||
| } | |||||
| public void setMethionine_percent(Double methionine_percent) { | |||||
| this.methionine_percent = methionine_percent; | |||||
| } | |||||
| public Double getMoisture_percent() { | |||||
| return moisture_percent; | |||||
| } | |||||
| public void setMoisture_percent(Double moisture_percent) { | |||||
| this.moisture_percent = moisture_percent; | |||||
| } | |||||
| public Double getOmega_3_mg_kg() { | |||||
| return omega_3_mg_kg; | |||||
| } | |||||
| public void setOmega_3_mg_kg(Double omega_3_mg_kg) { | |||||
| this.omega_3_mg_kg = omega_3_mg_kg; | |||||
| } | |||||
| public Double getOmega_6_mg_kg() { | |||||
| return omega_6_mg_kg; | |||||
| } | |||||
| public void setOmega_6_mg_kg(Double omega_6_mg_kg) { | |||||
| this.omega_6_mg_kg = omega_6_mg_kg; | |||||
| } | |||||
| public Integer getVitamin_c_mg_kg() { | |||||
| return vitamin_c_mg_kg; | |||||
| } | |||||
| public void setVitamin_c_mg_kg(Integer vitamin_c_mg_kg) { | |||||
| this.vitamin_c_mg_kg = vitamin_c_mg_kg; | |||||
| } | |||||
| public Integer getCalories_kcal_kg() { | |||||
| return calories_kcal_kg; | |||||
| } | |||||
| public void setCalories_kcal_kg(Integer calories_kcal_kg) { | |||||
| this.calories_kcal_kg = calories_kcal_kg; | |||||
| } | |||||
| public String getFood_type() { | |||||
| return food_type; | |||||
| } | |||||
| public void setFood_type(String food_type) { | |||||
| this.food_type = food_type; | |||||
| } | |||||
| public String getTarget_age_category() { | |||||
| return target_age_category; | |||||
| } | |||||
| public void setTarget_age_category(String target_age_category) { | |||||
| this.target_age_category = target_age_category; | |||||
| } | |||||
| public String getPet() { | |||||
| return pet; | |||||
| } | |||||
| public void setPet(String pet) { | |||||
| this.pet = pet; | |||||
| } | |||||
| public String getEmbedding_text() { | |||||
| return embedding_text; | |||||
| } | |||||
| public void setEmbedding_text(String embedding_text) { | |||||
| this.embedding_text = embedding_text; | |||||
| } | |||||
| public String getEmbedding_vector() { | |||||
| return embedding_vector; | |||||
| } | |||||
| public void setEmbedding_vector(String embedding_vector) { | |||||
| this.embedding_vector = embedding_vector; | |||||
| } | |||||
| public String getDescription() { | |||||
| return description; | |||||
| } | |||||
| public void setDescription(String description) { | |||||
| this.description = description; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,7 @@ | |||||
| package com.ffii.fhsmsc.modules.food_nutrients.entity; | |||||
| import com.ffii.core.support.AbstractRepository; | |||||
| public interface food_nutrientsRepository extends AbstractRepository<food_nutrients, Long> { | |||||
| } | |||||
| @@ -0,0 +1,222 @@ | |||||
| package com.ffii.fhsmsc.modules.food_nutrients.req; | |||||
| import jakarta.persistence.Column; | |||||
| public class food_nutrientsReq { | |||||
| private Long id; | |||||
| @Column(name = "food_name") | |||||
| private String food_name; | |||||
| @Column(name = "brand") | |||||
| private String brand; | |||||
| @Column(name = "size_kg") | |||||
| private Double size_kg; | |||||
| @Column(name = "protein_percent") | |||||
| private Double protein_percent; | |||||
| @Column(name = "fat_percent") | |||||
| private Double fat_percent; | |||||
| @Column(name = "fibre_percent") | |||||
| private Double fibre_percent; | |||||
| @Column(name = "ash_percent") | |||||
| private Double ash_percent; | |||||
| @Column(name = "taurine_percent") | |||||
| private Double taurine_percent; | |||||
| @Column(name = "vitamin_a_iu_kg") | |||||
| private Integer vitamin_a_iu_kg; | |||||
| @Column(name = "vitamin_d_iu_kg") | |||||
| private Integer vitamin_d_iu_kg; | |||||
| @Column(name = "vitamin_e_mg_kg") | |||||
| private Integer vitamin_e_mg_kg; | |||||
| @Column(name = "phosphorus_percent") | |||||
| private Double phosphorus_percent; | |||||
| @Column(name = "calcium_percent") | |||||
| private Double calcium_percent; | |||||
| @Column(name = "magnesium_percent") | |||||
| private Double magnesium_percent; | |||||
| @Column(name = "methionine_percent") | |||||
| private Double methionine_percent; | |||||
| @Column(name = "moisture_percent") | |||||
| private Double moisture_percent; | |||||
| @Column(name = "omega_3_mg_kg") | |||||
| private Double omega_3_mg_kg; | |||||
| @Column(name = "omega_6_mg_kg") | |||||
| private Double omega_6_mg_kg; | |||||
| @Column(name = "vitamin_c_mg_kg") | |||||
| private Integer vitamin_c_mg_kg; | |||||
| @Column(name = "calories_kcal_kg") | |||||
| private Integer calories_kcal_kg; | |||||
| @Column(name = "food_type") | |||||
| private String food_type; | |||||
| @Column(name = "target_age_category") | |||||
| private String target_age_category; | |||||
| @Column(name = "pet") | |||||
| private String pet; | |||||
| @Column(name = "embedding_text") | |||||
| private String embedding_text; | |||||
| @Column(name = "embedding_vector") | |||||
| private String embedding_vector; | |||||
| @Column(name = "description") | |||||
| private String description; | |||||
| public Long getId() { | |||||
| return id; | |||||
| } | |||||
| public void setId(Long id) { | |||||
| this.id = id; | |||||
| } | |||||
| public String getFood_name() { | |||||
| return food_name; | |||||
| } | |||||
| public void setFood_name(String food_name) { | |||||
| this.food_name = food_name; | |||||
| } | |||||
| public String getBrand() { | |||||
| return brand; | |||||
| } | |||||
| public void setBrand(String brand) { | |||||
| this.brand = brand; | |||||
| } | |||||
| public Double getSize_kg() { | |||||
| return size_kg; | |||||
| } | |||||
| public void setSize_kg(Double size_kg) { | |||||
| this.size_kg = size_kg; | |||||
| } | |||||
| public Double getProtein_percent() { | |||||
| return protein_percent; | |||||
| } | |||||
| public void setProtein_percent(Double protein_percent) { | |||||
| this.protein_percent = protein_percent; | |||||
| } | |||||
| public Double getFat_percent() { | |||||
| return fat_percent; | |||||
| } | |||||
| public void setFat_percent(Double fat_percent) { | |||||
| this.fat_percent = fat_percent; | |||||
| } | |||||
| public Double getFibre_percent() { | |||||
| return fibre_percent; | |||||
| } | |||||
| public void setFibre_percent(Double fibre_percent) { | |||||
| this.fibre_percent = fibre_percent; | |||||
| } | |||||
| public Double getAsh_percent() { | |||||
| return ash_percent; | |||||
| } | |||||
| public void setAsh_percent(Double ash_percent) { | |||||
| this.ash_percent = ash_percent; | |||||
| } | |||||
| public Double getTaurine_percent() { | |||||
| return taurine_percent; | |||||
| } | |||||
| public void setTaurine_percent(Double taurine_percent) { | |||||
| this.taurine_percent = taurine_percent; | |||||
| } | |||||
| public Integer getVitamin_a_iu_kg() { | |||||
| return vitamin_a_iu_kg; | |||||
| } | |||||
| public void setVitamin_a_iu_kg(Integer vitamin_a_iu_kg) { | |||||
| this.vitamin_a_iu_kg = vitamin_a_iu_kg; | |||||
| } | |||||
| public Integer getVitamin_d_iu_kg() { | |||||
| return vitamin_d_iu_kg; | |||||
| } | |||||
| public void setVitamin_d_iu_kg(Integer vitamin_d_iu_kg) { | |||||
| this.vitamin_d_iu_kg = vitamin_d_iu_kg; | |||||
| } | |||||
| public Integer getVitamin_e_mg_kg() { | |||||
| return vitamin_e_mg_kg; | |||||
| } | |||||
| public void setVitamin_e_mg_kg(Integer vitamin_e_mg_kg) { | |||||
| this.vitamin_e_mg_kg = vitamin_e_mg_kg; | |||||
| } | |||||
| public Double getPhosphorus_percent() { | |||||
| return phosphorus_percent; | |||||
| } | |||||
| public void setPhosphorus_percent(Double phosphorus_percent) { | |||||
| this.phosphorus_percent = phosphorus_percent; | |||||
| } | |||||
| public Double getCalcium_percent() { | |||||
| return calcium_percent; | |||||
| } | |||||
| public void setCalcium_percent(Double calcium_percent) { | |||||
| this.calcium_percent = calcium_percent; | |||||
| } | |||||
| public Double getMagnesium_percent() { | |||||
| return magnesium_percent; | |||||
| } | |||||
| public void setMagnesium_percent(Double magnesium_percent) { | |||||
| this.magnesium_percent = magnesium_percent; | |||||
| } | |||||
| public Double getMethionine_percent() { | |||||
| return methionine_percent; | |||||
| } | |||||
| public void setMethionine_percent(Double methionine_percent) { | |||||
| this.methionine_percent = methionine_percent; | |||||
| } | |||||
| public Double getMoisture_percent() { | |||||
| return moisture_percent; | |||||
| } | |||||
| public void setMoisture_percent(Double moisture_percent) { | |||||
| this.moisture_percent = moisture_percent; | |||||
| } | |||||
| public Double getOmega_3_mg_kg() { | |||||
| return omega_3_mg_kg; | |||||
| } | |||||
| public void setOmega_3_mg_kg(Double omega_3_mg_kg) { | |||||
| this.omega_3_mg_kg = omega_3_mg_kg; | |||||
| } | |||||
| public Double getOmega_6_mg_kg() { | |||||
| return omega_6_mg_kg; | |||||
| } | |||||
| public void setOmega_6_mg_kg(Double omega_6_mg_kg) { | |||||
| this.omega_6_mg_kg = omega_6_mg_kg; | |||||
| } | |||||
| public Integer getVitamin_c_mg_kg() { | |||||
| return vitamin_c_mg_kg; | |||||
| } | |||||
| public void setVitamin_c_mg_kg(Integer vitamin_c_mg_kg) { | |||||
| this.vitamin_c_mg_kg = vitamin_c_mg_kg; | |||||
| } | |||||
| public Integer getCalories_kcal_kg() { | |||||
| return calories_kcal_kg; | |||||
| } | |||||
| public void setCalories_kcal_kg(Integer calories_kcal_kg) { | |||||
| this.calories_kcal_kg = calories_kcal_kg; | |||||
| } | |||||
| public String getFood_type() { | |||||
| return food_type; | |||||
| } | |||||
| public void setFood_type(String food_type) { | |||||
| this.food_type = food_type; | |||||
| } | |||||
| public String getTarget_age_category() { | |||||
| return target_age_category; | |||||
| } | |||||
| public void setTarget_age_category(String target_age_category) { | |||||
| this.target_age_category = target_age_category; | |||||
| } | |||||
| public String getPet() { | |||||
| return pet; | |||||
| } | |||||
| public void setPet(String pet) { | |||||
| this.pet = pet; | |||||
| } | |||||
| public String getEmbedding_text() { | |||||
| return embedding_text; | |||||
| } | |||||
| public void setEmbedding_text(String embedding_text) { | |||||
| this.embedding_text = embedding_text; | |||||
| } | |||||
| public String getEmbedding_vector() { | |||||
| return embedding_vector; | |||||
| } | |||||
| public void setEmbedding_vector(String embedding_vector) { | |||||
| this.embedding_vector = embedding_vector; | |||||
| } | |||||
| public String getDescription() { | |||||
| return description; | |||||
| } | |||||
| public void setDescription(String description) { | |||||
| this.description = description; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,186 @@ | |||||
| package com.ffii.fhsmsc.modules.food_nutrients.service; | |||||
| import java.util.List; | |||||
| import java.util.Map; | |||||
| import org.slf4j.Logger; | |||||
| import org.slf4j.LoggerFactory; | |||||
| import org.springframework.stereotype.Service; | |||||
| import org.springframework.transaction.annotation.Transactional; | |||||
| import com.ffii.core.exception.InternalServerErrorException; | |||||
| import com.ffii.core.support.AbstractBaseEntityService; | |||||
| import com.ffii.core.support.JdbcDao; | |||||
| import com.ffii.core.utils.BeanUtils; | |||||
| import com.ffii.fhsmsc.modules.food_nutrients.entity.food_nutrients; | |||||
| import com.ffii.fhsmsc.modules.food_nutrients.entity.food_nutrientsRepository; | |||||
| import com.ffii.fhsmsc.modules.food_nutrients.req.food_nutrientsReq; | |||||
| import jakarta.validation.Valid; | |||||
| @Service | |||||
| public class food_nutrientsService extends AbstractBaseEntityService<food_nutrients, Long, food_nutrientsRepository>{ | |||||
| private static final Logger logger = LoggerFactory.getLogger(food_nutrientsService.class); | |||||
| public food_nutrientsService(JdbcDao jdbcDao, food_nutrientsRepository repository) { | |||||
| super(jdbcDao, repository); | |||||
| } | |||||
| public List<Map<String, Object>> search(Map<String, Object> args) { | |||||
| logger.info("Search called with args: {}", args); | |||||
| StringBuilder sql = new StringBuilder(); | |||||
| // Check if we need to fetch records for embedding processing | |||||
| if (args != null && args.containsKey("embedding_text")) { | |||||
| sql.append("SELECT pi.id, pi.embedding_text"); | |||||
| } else if (args != null && args.containsKey("embedding_vector")) { | |||||
| sql.append("SELECT pi.id, pi.embedding_vector"); | |||||
| } else { | |||||
| // Normal case - return all fields except embeddings | |||||
| sql.append("SELECT" | |||||
| + " pi.id," | |||||
| + " pi.food_name," | |||||
| + " pi.brand," | |||||
| + " pi.size_kg," | |||||
| + " pi.protein_percent," | |||||
| + " pi.fat_percent," | |||||
| + " pi.fibre_percent," | |||||
| + " pi.ash_percent," | |||||
| + " pi.taurine_percent," | |||||
| + " pi.vitamin_a_iu_kg," | |||||
| + " pi.vitamin_d_iu_kg," | |||||
| + " pi.vitamin_e_mg_kg," | |||||
| + " pi.phosphorus_percent," | |||||
| + " pi.calcium_percent," | |||||
| + " pi.magnesium_percent," | |||||
| + " pi.methionine_percent," | |||||
| + " pi.moisture_percent," | |||||
| + " pi.omega_3_mg_kg," | |||||
| + " pi.omega_6_mg_kg," | |||||
| + " pi.vitamin_c_mg_kg," | |||||
| + " pi.calories_kcal_kg," | |||||
| + " pi.food_type," | |||||
| + " pi.target_age_category," | |||||
| + " pi.pet," | |||||
| + " pi.description"); | |||||
| } | |||||
| sql.append(" FROM food_nutrients pi") | |||||
| .append(" WHERE pi.deleted = 0"); // 使用 0,因为是 tinyint(1) | |||||
| if (args != null) { | |||||
| if (args.containsKey("food_name")) { | |||||
| sql.append(" AND pi.food_name = :food_name"); | |||||
| logger.info("Added food_name filter: {}", args.get("food_name")); | |||||
| } | |||||
| if (args.containsKey("id")) { | |||||
| sql.append(" AND pi.id = :id"); | |||||
| logger.info("Added id filter: {}", args.get("id")); | |||||
| } | |||||
| } | |||||
| sql.append(" ORDER BY pi.id"); | |||||
| logger.info("Final SQL query: {}", sql.toString()); | |||||
| List<Map<String, Object>> result = jdbcDao.queryForList(sql.toString(), args); | |||||
| logger.info("Query returned {} results", result.size()); | |||||
| return result; | |||||
| } | |||||
| @Transactional(rollbackFor = Exception.class) | |||||
| public food_nutrients saveOrUpdate(@Valid food_nutrientsReq req) { | |||||
| food_nutrients instance; | |||||
| if (req.getId() != null && req.getId() > 0) { | |||||
| // 更新现有记录 | |||||
| instance = find(req.getId()).orElseThrow(InternalServerErrorException::new); | |||||
| // 只更新非空字段 | |||||
| if (req.getFood_name() != null) { | |||||
| instance.setFood_name(req.getFood_name()); | |||||
| } | |||||
| if (req.getBrand() != null) { | |||||
| instance.setBrand(req.getBrand()); | |||||
| } | |||||
| if (req.getSize_kg() != null) { | |||||
| instance.setSize_kg(req.getSize_kg()); | |||||
| } | |||||
| if (req.getProtein_percent() != null) { | |||||
| instance.setProtein_percent(req.getProtein_percent()); | |||||
| } | |||||
| if (req.getFat_percent() != null) { | |||||
| instance.setFat_percent(req.getFat_percent()); | |||||
| } | |||||
| if (req.getFibre_percent() != null) { | |||||
| instance.setFibre_percent(req.getFibre_percent()); | |||||
| } | |||||
| if (req.getAsh_percent() != null) { | |||||
| instance.setAsh_percent(req.getAsh_percent()); | |||||
| } | |||||
| if (req.getTaurine_percent() != null) { | |||||
| instance.setTaurine_percent(req.getTaurine_percent()); | |||||
| } | |||||
| if (req.getVitamin_a_iu_kg() != null) { | |||||
| instance.setVitamin_a_iu_kg(req.getVitamin_a_iu_kg()); | |||||
| } | |||||
| if (req.getVitamin_d_iu_kg() != null) { | |||||
| instance.setVitamin_d_iu_kg(req.getVitamin_d_iu_kg()); | |||||
| } | |||||
| if (req.getVitamin_e_mg_kg() != null) { | |||||
| instance.setVitamin_e_mg_kg(req.getVitamin_e_mg_kg()); | |||||
| } | |||||
| if (req.getPhosphorus_percent() != null) { | |||||
| instance.setPhosphorus_percent(req.getPhosphorus_percent()); | |||||
| } | |||||
| if (req.getCalcium_percent() != null) { | |||||
| instance.setCalcium_percent(req.getCalcium_percent()); | |||||
| } | |||||
| if (req.getMagnesium_percent() != null) { | |||||
| instance.setMagnesium_percent(req.getMagnesium_percent()); | |||||
| } | |||||
| if (req.getMethionine_percent() != null) { | |||||
| instance.setMethionine_percent(req.getMethionine_percent()); | |||||
| } | |||||
| if (req.getMoisture_percent() != null) { | |||||
| instance.setMoisture_percent(req.getMoisture_percent()); | |||||
| } | |||||
| if (req.getOmega_3_mg_kg() != null) { | |||||
| instance.setOmega_3_mg_kg(req.getOmega_3_mg_kg()); | |||||
| } | |||||
| if (req.getOmega_6_mg_kg() != null) { | |||||
| instance.setOmega_6_mg_kg(req.getOmega_6_mg_kg()); | |||||
| } | |||||
| if (req.getVitamin_c_mg_kg() != null) { | |||||
| instance.setVitamin_c_mg_kg(req.getVitamin_c_mg_kg()); | |||||
| } | |||||
| if (req.getCalories_kcal_kg() != null) { | |||||
| instance.setCalories_kcal_kg(req.getCalories_kcal_kg()); | |||||
| } | |||||
| if (req.getFood_type() != null) { | |||||
| instance.setFood_type(req.getFood_type()); | |||||
| } | |||||
| if (req.getTarget_age_category() != null) { | |||||
| instance.setTarget_age_category(req.getTarget_age_category()); | |||||
| } | |||||
| if (req.getPet() != null) { | |||||
| instance.setPet(req.getPet()); | |||||
| } | |||||
| if (req.getEmbedding_text() != null) { | |||||
| instance.setEmbedding_text(req.getEmbedding_text()); | |||||
| } | |||||
| if (req.getEmbedding_vector() != null) { | |||||
| instance.setEmbedding_vector(req.getEmbedding_vector()); | |||||
| } | |||||
| if (req.getDescription() != null) { | |||||
| instance.setDescription(req.getDescription()); | |||||
| } | |||||
| } else { | |||||
| // 创建新记录 | |||||
| instance = new food_nutrients(); | |||||
| BeanUtils.copyProperties(req, instance); | |||||
| } | |||||
| saveAndFlush(instance); | |||||
| return instance; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,54 @@ | |||||
| package com.ffii.fhsmsc.modules.food_nutrients.web; | |||||
| import java.util.Map; | |||||
| import org.slf4j.Logger; | |||||
| import org.slf4j.LoggerFactory; | |||||
| import org.springframework.web.bind.ServletRequestBindingException; | |||||
| import org.springframework.web.bind.annotation.GetMapping; | |||||
| 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 com.ffii.core.response.IdRes; | |||||
| import com.ffii.core.response.RecordsRes; | |||||
| import com.ffii.core.utils.CriteriaArgsBuilder; | |||||
| import com.ffii.fhsmsc.modules.food_nutrients.req.food_nutrientsReq; | |||||
| import com.ffii.fhsmsc.modules.food_nutrients.service.food_nutrientsService; | |||||
| import jakarta.servlet.http.HttpServletRequest; | |||||
| import jakarta.validation.Valid; | |||||
| @RestController | |||||
| @RequestMapping("/food_nutrients") | |||||
| public class food_nutrientsController { | |||||
| private static final Logger logger = LoggerFactory.getLogger(food_nutrientsController.class); | |||||
| private food_nutrientsService food_nutrientsService; | |||||
| public food_nutrientsController( | |||||
| food_nutrientsService food_nutrientsService | |||||
| ) { | |||||
| this.food_nutrientsService = food_nutrientsService; | |||||
| } | |||||
| @GetMapping("/list") | |||||
| public RecordsRes<Map<String, Object>> listJson(HttpServletRequest request) throws ServletRequestBindingException { | |||||
| logger.info("Received list request with parameters: {}", request.getParameterMap()); | |||||
| Map<String, Object> args = CriteriaArgsBuilder.withRequest(request) | |||||
| .addString("food_name") | |||||
| .addBoolean("embedding_text") // Add embedding_text parameter | |||||
| .addBoolean("embedding_vector") | |||||
| .addInteger("id") | |||||
| .build(); | |||||
| logger.info("Built args: {}", args); | |||||
| return new RecordsRes<>(food_nutrientsService.search(args)); | |||||
| } | |||||
| @PostMapping("/save") | |||||
| public IdRes saveOrUpdate(@RequestBody @Valid food_nutrientsReq req) { | |||||
| return new IdRes(food_nutrientsService.saveOrUpdate(req).getId()); | |||||
| } | |||||
| } | |||||
| @@ -5,6 +5,7 @@ import com.ffii.core.entity.BaseEntity; | |||||
| import jakarta.persistence.Column; | import jakarta.persistence.Column; | ||||
| import jakarta.persistence.Entity; | import jakarta.persistence.Entity; | ||||
| import jakarta.persistence.Table; | import jakarta.persistence.Table; | ||||
| import java.util.Date; | |||||
| @Entity | @Entity | ||||
| @Table(name = "pet_information") | @Table(name = "pet_information") | ||||
| public class pet_information extends BaseEntity<Long> { | public class pet_information extends BaseEntity<Long> { | ||||
| @@ -16,4 +17,136 @@ public class pet_information extends BaseEntity<Long> { | |||||
| @Column(name = "gender") | @Column(name = "gender") | ||||
| private String gender; | private String gender; | ||||
| @Column(name = "age_category") | |||||
| private String age_category; | |||||
| @Column(name = "birth_date") | |||||
| private Date birth_date; | |||||
| @Column(name = "breed") | |||||
| private String breed; | |||||
| @Column(name = "weight_kg") | |||||
| private Double weight_kg; | |||||
| @Column(name = "sterilization") | |||||
| private String sterilization; | |||||
| @Column(name = "activity_level") | |||||
| private String activity_level; | |||||
| @Column(name = "health_issues") | |||||
| private String health_issues; | |||||
| @Column(name = "family_health_history") | |||||
| private String family_health_history; | |||||
| @Column(name = "health_goal") | |||||
| private String health_goal; | |||||
| @Column(name = "type") | |||||
| private String type; | |||||
| public Long getOwner_id() { | |||||
| return owner_id; | |||||
| } | |||||
| public void setOwner_id(Long owner_id) { | |||||
| this.owner_id = owner_id; | |||||
| } | |||||
| public String getPet_name() { | |||||
| return pet_name; | |||||
| } | |||||
| public void setPet_name(String pet_name) { | |||||
| this.pet_name = pet_name; | |||||
| } | |||||
| public String getGender() { | |||||
| return gender; | |||||
| } | |||||
| public void setGender(String gender) { | |||||
| this.gender = gender; | |||||
| } | |||||
| public String getAge_category() { | |||||
| return age_category; | |||||
| } | |||||
| public void setAge_category(String age_category) { | |||||
| this.age_category = age_category; | |||||
| } | |||||
| public Date getBirth_date() { | |||||
| return birth_date; | |||||
| } | |||||
| public void setBirth_date(Date birth_date) { | |||||
| this.birth_date = birth_date; | |||||
| } | |||||
| public String getBreed() { | |||||
| return breed; | |||||
| } | |||||
| public void setBreed(String breed) { | |||||
| this.breed = breed; | |||||
| } | |||||
| public Double getWeight_kg() { | |||||
| return weight_kg; | |||||
| } | |||||
| public void setWeight_kg(Double weight_kg) { | |||||
| this.weight_kg = weight_kg; | |||||
| } | |||||
| public String getSterilization() { | |||||
| return sterilization; | |||||
| } | |||||
| public void setSterilization(String sterilization) { | |||||
| this.sterilization = sterilization; | |||||
| } | |||||
| public String getActivity_level() { | |||||
| return activity_level; | |||||
| } | |||||
| public void setActivity_level(String activity_level) { | |||||
| this.activity_level = activity_level; | |||||
| } | |||||
| public String getHealth_issues() { | |||||
| return health_issues; | |||||
| } | |||||
| public void setHealth_issues(String health_issues) { | |||||
| this.health_issues = health_issues; | |||||
| } | |||||
| public String getFamily_health_history() { | |||||
| return family_health_history; | |||||
| } | |||||
| public void setFamily_health_history(String family_health_history) { | |||||
| this.family_health_history = family_health_history; | |||||
| } | |||||
| public String getHealth_goal() { | |||||
| return health_goal; | |||||
| } | |||||
| public void setHealth_goal(String health_goal) { | |||||
| this.health_goal = health_goal; | |||||
| } | |||||
| public String getType() { | |||||
| return type; | |||||
| } | |||||
| public void setType(String type) { | |||||
| this.type = type; | |||||
| } | |||||
| } | } | ||||
| @@ -0,0 +1,153 @@ | |||||
| package com.ffii.fhsmsc.modules.pet_information.req; | |||||
| import java.util.Date; | |||||
| import jakarta.persistence.Column; | |||||
| public class pet_informationReq { | |||||
| private Long id; | |||||
| @Column(name = "owner_id") | |||||
| private Long owner_id; | |||||
| @Column(name = "pet_name") | |||||
| private String pet_name; | |||||
| @Column(name = "gender") | |||||
| private String gender; | |||||
| @Column(name = "age_category") | |||||
| private String age_category; | |||||
| @Column(name = "birth_date") | |||||
| private Date birth_date; | |||||
| @Column(name = "breed") | |||||
| private String breed; | |||||
| @Column(name = "weight_kg") | |||||
| private Double weight_kg; | |||||
| @Column(name = "sterilization") | |||||
| private String sterilization; | |||||
| @Column(name = "activity_level") | |||||
| private String activity_level; | |||||
| @Column(name = "health_issues") | |||||
| private String health_issues; | |||||
| @Column(name = "family_health_history") | |||||
| private String family_health_history; | |||||
| @Column(name = "health_goal") | |||||
| private String health_goal; | |||||
| @Column(name = "type") | |||||
| private String type; | |||||
| public Long getId() { | |||||
| return id; | |||||
| } | |||||
| public void setId(Long id) { | |||||
| this.id = id; | |||||
| } | |||||
| public Long getOwner_id() { | |||||
| return owner_id; | |||||
| } | |||||
| public void setOwner_id(Long owner_id) { | |||||
| this.owner_id = owner_id; | |||||
| } | |||||
| public String getPet_name() { | |||||
| return pet_name; | |||||
| } | |||||
| public void setPet_name(String pet_name) { | |||||
| this.pet_name = pet_name; | |||||
| } | |||||
| public String getGender() { | |||||
| return gender; | |||||
| } | |||||
| public void setGender(String gender) { | |||||
| this.gender = gender; | |||||
| } | |||||
| public String getAge_category() { | |||||
| return age_category; | |||||
| } | |||||
| public void setAge_category(String age_category) { | |||||
| this.age_category = age_category; | |||||
| } | |||||
| public Date getBirth_date() { | |||||
| return birth_date; | |||||
| } | |||||
| public void setBirth_date(Date birth_date) { | |||||
| this.birth_date = birth_date; | |||||
| } | |||||
| public String getBreed() { | |||||
| return breed; | |||||
| } | |||||
| public void setBreed(String breed) { | |||||
| this.breed = breed; | |||||
| } | |||||
| public Double getWeight_kg() { | |||||
| return weight_kg; | |||||
| } | |||||
| public void setWeight_kg(Double weight_kg) { | |||||
| this.weight_kg = weight_kg; | |||||
| } | |||||
| public String getSterilization() { | |||||
| return sterilization; | |||||
| } | |||||
| public void setSterilization(String sterilization) { | |||||
| this.sterilization = sterilization; | |||||
| } | |||||
| public String getActivity_level() { | |||||
| return activity_level; | |||||
| } | |||||
| public void setActivity_level(String activity_level) { | |||||
| this.activity_level = activity_level; | |||||
| } | |||||
| public String getHealth_issues() { | |||||
| return health_issues; | |||||
| } | |||||
| public void setHealth_issues(String health_issues) { | |||||
| this.health_issues = health_issues; | |||||
| } | |||||
| public String getFamily_health_history() { | |||||
| return family_health_history; | |||||
| } | |||||
| public void setFamily_health_history(String family_health_history) { | |||||
| this.family_health_history = family_health_history; | |||||
| } | |||||
| public String getHealth_goal() { | |||||
| return health_goal; | |||||
| } | |||||
| public void setHealth_goal(String health_goal) { | |||||
| this.health_goal = health_goal; | |||||
| } | |||||
| public String getType() { | |||||
| return type; | |||||
| } | |||||
| public void setType(String type) { | |||||
| this.type = type; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,131 @@ | |||||
| package com.ffii.fhsmsc.modules.pet_information.service; | |||||
| import java.util.List; | |||||
| import java.util.Map; | |||||
| import org.slf4j.Logger; | |||||
| import org.slf4j.LoggerFactory; | |||||
| import org.springframework.stereotype.Service; | |||||
| import org.springframework.transaction.annotation.Transactional; | |||||
| import com.ffii.core.exception.InternalServerErrorException; | |||||
| import com.ffii.core.support.AbstractBaseEntityService; | |||||
| import com.ffii.core.support.JdbcDao; | |||||
| import com.ffii.core.utils.BeanUtils; | |||||
| import com.ffii.fhsmsc.modules.pet_information.enity.pet_information; | |||||
| import com.ffii.fhsmsc.modules.pet_information.enity.pet_informationRepository; | |||||
| import com.ffii.fhsmsc.modules.pet_information.req.pet_informationReq; | |||||
| import jakarta.validation.Valid; | |||||
| @Service | |||||
| public class pet_informationService extends AbstractBaseEntityService<pet_information, Long, pet_informationRepository>{ | |||||
| private static final Logger logger = LoggerFactory.getLogger(pet_informationService.class); | |||||
| public pet_informationService(JdbcDao jdbcDao, pet_informationRepository repository) { | |||||
| super(jdbcDao, repository); | |||||
| } | |||||
| public List<Map<String, Object>> search(Map<String, Object> args) { | |||||
| logger.info("Search called with args: {}", args); | |||||
| StringBuilder sql = new StringBuilder("SELECT" | |||||
| + " pi.id," | |||||
| + " pi.owner_id," | |||||
| + " pi.pet_name," | |||||
| + " pi.gender," | |||||
| + " pi.age_category," | |||||
| + " pi.birth_date," | |||||
| + " pi.breed," | |||||
| + " pi.weight_kg," | |||||
| + " pi.sterilization," | |||||
| + " pi.activity_level," | |||||
| + " pi.health_issues," | |||||
| + " pi.family_health_history," | |||||
| + " pi.health_goal," | |||||
| + " pi.type" | |||||
| + " FROM pet_information pi" | |||||
| + " WHERE pi.deleted = 0" // 使用 0,因为是 tinyint(1) | |||||
| ); | |||||
| if (args != null) { | |||||
| if (args.containsKey("owner_id")) { | |||||
| sql.append(" AND pi.owner_id = :owner_id"); | |||||
| logger.info("Added owner_id filter: {}", args.get("owner_id")); | |||||
| } | |||||
| } | |||||
| sql.append(" ORDER BY pi.id"); | |||||
| logger.info("Final SQL query: {}", sql.toString()); | |||||
| List<Map<String, Object>> result = jdbcDao.queryForList(sql.toString(), args); | |||||
| logger.info("Query returned {} results", result.size()); | |||||
| return result; | |||||
| } | |||||
| @Transactional(rollbackFor = Exception.class) | |||||
| public pet_information saveOrUpdate(@Valid pet_informationReq req) { | |||||
| pet_information instance; | |||||
| if (req.getId() != null && req.getId() > 0) { | |||||
| // 更新现有记录 | |||||
| instance = find(req.getId()).orElseThrow(InternalServerErrorException::new); | |||||
| // 只更新非空字段 | |||||
| if (req.getOwner_id() != null) { | |||||
| instance.setOwner_id(req.getOwner_id()); | |||||
| } | |||||
| if (req.getGender() != null) { | |||||
| instance.setGender(req.getGender()); | |||||
| } | |||||
| if (req.getPet_name() != null) { | |||||
| instance.setPet_name(req.getPet_name()); | |||||
| } | |||||
| if (req.getBirth_date() != null) { | |||||
| instance.setBirth_date(req.getBirth_date()); | |||||
| } | |||||
| if (req.getBreed() != null) { | |||||
| instance.setBreed(req.getBreed()); | |||||
| } | |||||
| if (req.getWeight_kg() != null) { | |||||
| instance.setWeight_kg(req.getWeight_kg()); | |||||
| } | |||||
| if (req.getHealth_goal() != null) { | |||||
| instance.setHealth_goal(req.getHealth_goal()); | |||||
| } | |||||
| if (req.getType() != null) { | |||||
| instance.setType(req.getType()); | |||||
| } | |||||
| if (req.getActivity_level() != null) { | |||||
| instance.setActivity_level(req.getActivity_level()); | |||||
| } | |||||
| if (req.getHealth_issues() != null) { | |||||
| instance.setHealth_issues(req.getHealth_issues()); | |||||
| } | |||||
| if (req.getFamily_health_history() != null) { | |||||
| instance.setFamily_health_history(req.getFamily_health_history()); | |||||
| } | |||||
| if (req.getSterilization() != null) { | |||||
| instance.setSterilization(req.getSterilization()); | |||||
| } | |||||
| if (req.getAge_category() != null) { | |||||
| instance.setAge_category(req.getAge_category()); | |||||
| } | |||||
| if (req.getGender() != null) { | |||||
| instance.setGender(req.getGender()); | |||||
| } | |||||
| if (req.getPet_name() != null) { | |||||
| instance.setPet_name(req.getPet_name()); | |||||
| } | |||||
| if (req.getBirth_date() != null) { | |||||
| instance.setBirth_date(req.getBirth_date()); | |||||
| } | |||||
| } else { | |||||
| // 创建新记录 | |||||
| instance = new pet_information(); | |||||
| BeanUtils.copyProperties(req, instance); | |||||
| } | |||||
| saveAndFlush(instance); | |||||
| return instance; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,49 @@ | |||||
| package com.ffii.fhsmsc.modules.pet_information.web; | |||||
| import java.util.Map; | |||||
| import org.slf4j.Logger; | |||||
| import org.slf4j.LoggerFactory; | |||||
| import org.springframework.web.bind.ServletRequestBindingException; | |||||
| import org.springframework.web.bind.annotation.GetMapping; | |||||
| 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 com.ffii.core.response.IdRes; | |||||
| import com.ffii.core.response.RecordsRes; | |||||
| import com.ffii.core.utils.CriteriaArgsBuilder; | |||||
| import com.ffii.fhsmsc.modules.pet_information.req.pet_informationReq; | |||||
| import com.ffii.fhsmsc.modules.pet_information.service.pet_informationService; | |||||
| import jakarta.servlet.http.HttpServletRequest; | |||||
| import jakarta.validation.Valid; | |||||
| @RestController | |||||
| @RequestMapping("/pet_information") | |||||
| public class pet_informationController { | |||||
| private static final Logger logger = LoggerFactory.getLogger(pet_informationController.class); | |||||
| private pet_informationService pet_informationService; | |||||
| public pet_informationController( | |||||
| pet_informationService pet_informationService | |||||
| ) { | |||||
| this.pet_informationService = pet_informationService; | |||||
| } | |||||
| @GetMapping("/list") | |||||
| public RecordsRes<Map<String, Object>> listJson(HttpServletRequest request) throws ServletRequestBindingException { | |||||
| logger.info("Received list request with parameters: {}", request.getParameterMap()); | |||||
| Map<String, Object> args = CriteriaArgsBuilder.withRequest(request) | |||||
| .addInteger("owner_id") | |||||
| .build(); | |||||
| logger.info("Built args: {}", args); | |||||
| return new RecordsRes<>(pet_informationService.search(args)); | |||||
| } | |||||
| @PostMapping("/save") | |||||
| public IdRes saveOrUpdate(@RequestBody @Valid pet_informationReq req) { | |||||
| return new IdRes(pet_informationService.saveOrUpdate(req).getId()); | |||||
| } | |||||
| } | |||||
| @@ -1,7 +1,7 @@ | |||||
| spring: | spring: | ||||
| datasource: | datasource: | ||||
| jdbc-url: jdbc:mysql://192.168.1.228:3308/fhsmscdb?useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT%2B8 | |||||
| jdbc-url: jdbc:mysql://192.168.1.228:3308/pet_app?useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT%2B8 | |||||
| username: root | username: root | ||||
| password: secret | password: secret | ||||
| driver-class-name: com.mysql.cj.jdbc.Driver | driver-class-name: com.mysql.cj.jdbc.Driver | ||||
| @@ -1,7 +1,7 @@ | |||||
| spring: | spring: | ||||
| datasource: | datasource: | ||||
| jdbc-url: jdbc:mysql://127.0.0.1:3308/fhsmscdb?useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT%2B8 | |||||
| jdbc-url: jdbc:mysql://127.0.0.1:3308/pet_app?useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT%2B8 | |||||
| username: root | username: root | ||||
| password: secret | password: secret | ||||
| springdoc: | springdoc: | ||||
| @@ -1,7 +1,7 @@ | |||||
| spring: | spring: | ||||
| datasource: | datasource: | ||||
| jdbc-url: jdbc:mysql://127.0.0.1:3308/fhsmscdb?useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT%2B8 | |||||
| jdbc-url: jdbc:mysql://127.0.0.1:3308/pet_app?useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT%2B8 | |||||
| username: root | username: root | ||||
| password: secret | password: secret | ||||
| driver-class-name: com.mysql.cj.jdbc.Driver | driver-class-name: com.mysql.cj.jdbc.Driver | ||||