新增房产AI
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
package com.gxwebsoft.house.controller;
|
||||
|
||||
import com.gxwebsoft.common.core.utils.JSONUtil;
|
||||
import com.gxwebsoft.common.core.web.ApiResult;
|
||||
import com.gxwebsoft.common.core.web.BaseController;
|
||||
import com.gxwebsoft.common.core.websocket.WebSocketServer;
|
||||
import com.gxwebsoft.house.entity.HouseAiChatRequest;
|
||||
import com.gxwebsoft.house.entity.HouseAiChatResponse;
|
||||
import com.gxwebsoft.house.service.HouseAiChatService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
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 javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* AI找房聊天控制器
|
||||
*/
|
||||
@Tag(name = "AI找房问答")
|
||||
@RestController
|
||||
@RequestMapping("/api/house/ai-chat")
|
||||
public class HouseAiChatController extends BaseController {
|
||||
|
||||
@Resource
|
||||
private HouseAiChatService houseAiChatService;
|
||||
@Resource
|
||||
private WebSocketServer webSocketServer;
|
||||
|
||||
@Operation(summary = "发送AI找房问题")
|
||||
@PostMapping("/message")
|
||||
public ApiResult<?> message(@RequestBody HouseAiChatRequest request) {
|
||||
if (request.getUserId() == null || request.getQuestion() == null || request.getQuestion().trim().isEmpty()) {
|
||||
return fail("提问内容不能为空");
|
||||
}
|
||||
try {
|
||||
HouseAiChatResponse response = houseAiChatService.answer(request);
|
||||
webSocketServer.sendMessage(String.valueOf(request.getUserId()), JSONUtil.toJSONString(response));
|
||||
return success("处理成功");
|
||||
} catch (Exception e) {
|
||||
return fail("AI服务暂时不可用,请稍后再试。");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
package com.gxwebsoft.house.controller;
|
||||
|
||||
import com.gxwebsoft.common.core.annotation.OperationLog;
|
||||
import com.gxwebsoft.common.core.web.ApiResult;
|
||||
import com.gxwebsoft.common.core.web.BaseController;
|
||||
import com.gxwebsoft.common.core.web.BatchParam;
|
||||
import com.gxwebsoft.common.core.web.PageResult;
|
||||
import com.gxwebsoft.house.entity.HouseAiConfig;
|
||||
import com.gxwebsoft.house.param.HouseAiConfigParam;
|
||||
import com.gxwebsoft.house.service.HouseAiConfigService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* AI找房配置控制器
|
||||
*/
|
||||
@Tag(name = "AI找房配置管理")
|
||||
@RestController
|
||||
@RequestMapping("/api/house/ai-config")
|
||||
public class HouseAiConfigController extends BaseController {
|
||||
|
||||
@Resource
|
||||
private HouseAiConfigService houseAiConfigService;
|
||||
|
||||
@Operation(summary = "分页查询AI找房配置")
|
||||
@GetMapping("/page")
|
||||
public ApiResult<PageResult<HouseAiConfig>> page(HouseAiConfigParam param) {
|
||||
return success(houseAiConfigService.pageRel(param));
|
||||
}
|
||||
|
||||
@Operation(summary = "查询全部AI找房配置")
|
||||
@GetMapping()
|
||||
public ApiResult<List<HouseAiConfig>> list(HouseAiConfigParam param) {
|
||||
return success(houseAiConfigService.listRel(param));
|
||||
}
|
||||
|
||||
@Operation(summary = "查询当前租户AI找房配置")
|
||||
@GetMapping("/current")
|
||||
public ApiResult<HouseAiConfig> current() {
|
||||
return success(houseAiConfigService.getCurrentConfig(getTenantId()));
|
||||
}
|
||||
|
||||
@Operation(summary = "根据id查询AI找房配置")
|
||||
@GetMapping("/{id}")
|
||||
public ApiResult<HouseAiConfig> get(@PathVariable("id") Integer id) {
|
||||
return success(houseAiConfigService.getByIdRel(id));
|
||||
}
|
||||
|
||||
@OperationLog
|
||||
@Operation(summary = "添加AI找房配置")
|
||||
@PostMapping()
|
||||
public ApiResult<?> save(@RequestBody HouseAiConfig houseAiConfig) {
|
||||
if (houseAiConfigService.save(houseAiConfig)) {
|
||||
return success("添加成功");
|
||||
}
|
||||
return fail("添加失败");
|
||||
}
|
||||
|
||||
@OperationLog
|
||||
@Operation(summary = "修改AI找房配置")
|
||||
@PutMapping()
|
||||
public ApiResult<?> update(@RequestBody HouseAiConfig houseAiConfig) {
|
||||
if (houseAiConfigService.updateById(houseAiConfig)) {
|
||||
return success("修改成功");
|
||||
}
|
||||
return fail("修改失败");
|
||||
}
|
||||
|
||||
@OperationLog
|
||||
@Operation(summary = "删除AI找房配置")
|
||||
@DeleteMapping("/{id}")
|
||||
public ApiResult<?> remove(@PathVariable("id") Integer id) {
|
||||
if (houseAiConfigService.removeById(id)) {
|
||||
return success("删除成功");
|
||||
}
|
||||
return fail("删除失败");
|
||||
}
|
||||
|
||||
@OperationLog
|
||||
@Operation(summary = "批量修改AI找房配置")
|
||||
@PutMapping("/batch")
|
||||
public ApiResult<?> updateBatch(@RequestBody BatchParam<HouseAiConfig> batchParam) {
|
||||
if (batchParam.update(houseAiConfigService, "config_id")) {
|
||||
return success("修改成功");
|
||||
}
|
||||
return fail("修改失败");
|
||||
}
|
||||
|
||||
@OperationLog
|
||||
@Operation(summary = "批量删除AI找房配置")
|
||||
@DeleteMapping("/batch")
|
||||
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
|
||||
if (houseAiConfigService.removeByIds(ids)) {
|
||||
return success("删除成功");
|
||||
}
|
||||
return fail("删除失败");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
package com.gxwebsoft.house.controller;
|
||||
|
||||
import com.gxwebsoft.common.core.annotation.OperationLog;
|
||||
import com.gxwebsoft.common.core.web.ApiResult;
|
||||
import com.gxwebsoft.common.core.web.BaseController;
|
||||
import com.gxwebsoft.common.core.web.BatchParam;
|
||||
import com.gxwebsoft.common.core.web.PageResult;
|
||||
import com.gxwebsoft.common.system.entity.User;
|
||||
import com.gxwebsoft.house.entity.HouseFaq;
|
||||
import com.gxwebsoft.house.param.HouseFaqParam;
|
||||
import com.gxwebsoft.house.service.HouseFaqService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* AI找房常见问题控制器
|
||||
*/
|
||||
@Tag(name = "AI找房常见问题管理")
|
||||
@RestController
|
||||
@RequestMapping("/api/house/house-faq")
|
||||
public class HouseFaqController extends BaseController {
|
||||
|
||||
@Resource
|
||||
private HouseFaqService houseFaqService;
|
||||
|
||||
@Operation(summary = "分页查询AI找房常见问题")
|
||||
@GetMapping("/page")
|
||||
public ApiResult<PageResult<HouseFaq>> page(HouseFaqParam param) {
|
||||
return success(houseFaqService.pageRel(param));
|
||||
}
|
||||
|
||||
@Operation(summary = "查询全部AI找房常见问题")
|
||||
@GetMapping()
|
||||
public ApiResult<List<HouseFaq>> list(HouseFaqParam param) {
|
||||
return success(houseFaqService.listRel(param));
|
||||
}
|
||||
|
||||
@Operation(summary = "根据id查询AI找房常见问题")
|
||||
@GetMapping("/{id}")
|
||||
public ApiResult<HouseFaq> get(@PathVariable("id") Integer id) {
|
||||
return success(houseFaqService.getByIdRel(id));
|
||||
}
|
||||
|
||||
@OperationLog
|
||||
@Operation(summary = "添加AI找房常见问题")
|
||||
@PostMapping()
|
||||
public ApiResult<?> save(@RequestBody HouseFaq houseFaq) {
|
||||
User loginUser = getLoginUser();
|
||||
if (loginUser != null) {
|
||||
houseFaq.setUserId(loginUser.getUserId());
|
||||
}
|
||||
if (houseFaqService.save(houseFaq)) {
|
||||
return success("添加成功");
|
||||
}
|
||||
return fail("添加失败");
|
||||
}
|
||||
|
||||
@OperationLog
|
||||
@Operation(summary = "修改AI找房常见问题")
|
||||
@PutMapping()
|
||||
public ApiResult<?> update(@RequestBody HouseFaq houseFaq) {
|
||||
if (houseFaqService.updateById(houseFaq)) {
|
||||
return success("修改成功");
|
||||
}
|
||||
return fail("修改失败");
|
||||
}
|
||||
|
||||
@OperationLog
|
||||
@Operation(summary = "删除AI找房常见问题")
|
||||
@DeleteMapping("/{id}")
|
||||
public ApiResult<?> remove(@PathVariable("id") Integer id) {
|
||||
if (houseFaqService.removeById(id)) {
|
||||
return success("删除成功");
|
||||
}
|
||||
return fail("删除失败");
|
||||
}
|
||||
|
||||
@OperationLog
|
||||
@Operation(summary = "批量添加AI找房常见问题")
|
||||
@PostMapping("/batch")
|
||||
public ApiResult<?> saveBatch(@RequestBody List<HouseFaq> list) {
|
||||
if (houseFaqService.saveBatch(list)) {
|
||||
return success("添加成功");
|
||||
}
|
||||
return fail("添加失败");
|
||||
}
|
||||
|
||||
@OperationLog
|
||||
@Operation(summary = "批量修改AI找房常见问题")
|
||||
@PutMapping("/batch")
|
||||
public ApiResult<?> updateBatch(@RequestBody BatchParam<HouseFaq> batchParam) {
|
||||
if (batchParam.update(houseFaqService, "faq_id")) {
|
||||
return success("修改成功");
|
||||
}
|
||||
return fail("修改失败");
|
||||
}
|
||||
|
||||
@OperationLog
|
||||
@Operation(summary = "批量删除AI找房常见问题")
|
||||
@DeleteMapping("/batch")
|
||||
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
|
||||
if (houseFaqService.removeByIds(ids)) {
|
||||
return success("删除成功");
|
||||
}
|
||||
return fail("删除失败");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
package com.gxwebsoft.house.controller;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.gxwebsoft.common.core.annotation.OperationLog;
|
||||
import com.gxwebsoft.common.core.web.ApiResult;
|
||||
import com.gxwebsoft.common.core.web.BaseController;
|
||||
import com.gxwebsoft.common.core.web.BatchParam;
|
||||
import com.gxwebsoft.common.core.web.PageResult;
|
||||
import com.gxwebsoft.common.system.entity.User;
|
||||
import com.gxwebsoft.house.entity.HouseMessage;
|
||||
import com.gxwebsoft.house.param.HouseMessageParam;
|
||||
import com.gxwebsoft.house.service.HouseMessageService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* AI找房留言控制器
|
||||
*/
|
||||
@Tag(name = "AI找房留言管理")
|
||||
@RestController
|
||||
@RequestMapping("/api/house/house-message")
|
||||
public class HouseMessageController extends BaseController {
|
||||
|
||||
private static final Pattern PHONE_PATTERN = Pattern.compile("^1[3-9]\\d{9}$");
|
||||
private static final Pattern WECHAT_PATTERN = Pattern.compile("^[a-zA-Z][-_a-zA-Z0-9]{5,19}$");
|
||||
|
||||
@Resource
|
||||
private HouseMessageService houseMessageService;
|
||||
|
||||
@Operation(summary = "分页查询AI找房留言")
|
||||
@GetMapping("/page")
|
||||
public ApiResult<PageResult<HouseMessage>> page(HouseMessageParam param) {
|
||||
return success(houseMessageService.pageRel(param));
|
||||
}
|
||||
|
||||
@Operation(summary = "查询全部AI找房留言")
|
||||
@GetMapping()
|
||||
public ApiResult<List<HouseMessage>> list(HouseMessageParam param) {
|
||||
return success(houseMessageService.listRel(param));
|
||||
}
|
||||
|
||||
@Operation(summary = "根据id查询AI找房留言")
|
||||
@GetMapping("/{id}")
|
||||
public ApiResult<HouseMessage> get(@PathVariable("id") Integer id) {
|
||||
return success(houseMessageService.getByIdRel(id));
|
||||
}
|
||||
|
||||
@OperationLog
|
||||
@Operation(summary = "添加AI找房留言")
|
||||
@PostMapping()
|
||||
public ApiResult<?> save(@RequestBody HouseMessage houseMessage) {
|
||||
String error = validateMessage(houseMessage);
|
||||
if (error != null) {
|
||||
return fail(error);
|
||||
}
|
||||
User loginUser = getLoginUser();
|
||||
if (loginUser != null) {
|
||||
houseMessage.setUserId(loginUser.getUserId());
|
||||
}
|
||||
houseMessage.setRealName(houseMessage.getRealName().trim());
|
||||
houseMessage.setPhone(StrUtil.trimToNull(houseMessage.getPhone()));
|
||||
houseMessage.setWechat(StrUtil.trimToNull(houseMessage.getWechat()));
|
||||
houseMessage.setSource(StrUtil.blankToDefault(houseMessage.getSource(), "ai_house"));
|
||||
if (houseMessage.getStatus() == null) {
|
||||
houseMessage.setStatus(0);
|
||||
}
|
||||
if (houseMessageService.save(houseMessage)) {
|
||||
return success("提交成功");
|
||||
}
|
||||
return fail("提交失败");
|
||||
}
|
||||
|
||||
@OperationLog
|
||||
@Operation(summary = "修改AI找房留言")
|
||||
@PutMapping()
|
||||
public ApiResult<?> update(@RequestBody HouseMessage houseMessage) {
|
||||
String error = validateMessage(houseMessage);
|
||||
if (error != null) {
|
||||
return fail(error);
|
||||
}
|
||||
houseMessage.setRealName(houseMessage.getRealName().trim());
|
||||
houseMessage.setPhone(StrUtil.trimToNull(houseMessage.getPhone()));
|
||||
houseMessage.setWechat(StrUtil.trimToNull(houseMessage.getWechat()));
|
||||
if (houseMessageService.updateById(houseMessage)) {
|
||||
return success("修改成功");
|
||||
}
|
||||
return fail("修改失败");
|
||||
}
|
||||
|
||||
@OperationLog
|
||||
@Operation(summary = "删除AI找房留言")
|
||||
@DeleteMapping("/{id}")
|
||||
public ApiResult<?> remove(@PathVariable("id") Integer id) {
|
||||
if (houseMessageService.removeById(id)) {
|
||||
return success("删除成功");
|
||||
}
|
||||
return fail("删除失败");
|
||||
}
|
||||
|
||||
@OperationLog
|
||||
@Operation(summary = "批量修改AI找房留言")
|
||||
@PutMapping("/batch")
|
||||
public ApiResult<?> updateBatch(@RequestBody BatchParam<HouseMessage> batchParam) {
|
||||
if (batchParam.update(houseMessageService, "message_id")) {
|
||||
return success("修改成功");
|
||||
}
|
||||
return fail("修改失败");
|
||||
}
|
||||
|
||||
@OperationLog
|
||||
@Operation(summary = "批量删除AI找房留言")
|
||||
@DeleteMapping("/batch")
|
||||
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
|
||||
if (houseMessageService.removeByIds(ids)) {
|
||||
return success("删除成功");
|
||||
}
|
||||
return fail("删除失败");
|
||||
}
|
||||
|
||||
private String validateMessage(HouseMessage houseMessage) {
|
||||
if (houseMessage == null || StrUtil.isBlank(houseMessage.getRealName())) {
|
||||
return "请输入姓名";
|
||||
}
|
||||
if (houseMessage.getRealName().trim().length() > 30) {
|
||||
return "姓名不能超过30个字符";
|
||||
}
|
||||
boolean hasPhone = StrUtil.isNotBlank(houseMessage.getPhone());
|
||||
boolean hasWechat = StrUtil.isNotBlank(houseMessage.getWechat());
|
||||
if (!hasPhone && !hasWechat) {
|
||||
return "手机号和微信号请至少填写一项";
|
||||
}
|
||||
if (hasPhone && !PHONE_PATTERN.matcher(houseMessage.getPhone().trim()).matches()) {
|
||||
return "手机号格式不正确";
|
||||
}
|
||||
if (hasWechat && !WECHAT_PATTERN.matcher(houseMessage.getWechat().trim()).matches()) {
|
||||
return "微信号格式不正确";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.gxwebsoft.house.entity;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* AI找房提问请求
|
||||
*/
|
||||
@Data
|
||||
@Schema(name = "HouseAiChatRequest对象", description = "AI找房提问请求")
|
||||
public class HouseAiChatRequest implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "会话ID")
|
||||
private String conversationId;
|
||||
|
||||
@Schema(description = "用户ID")
|
||||
private Integer userId;
|
||||
|
||||
@Schema(description = "问题")
|
||||
private String question;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.gxwebsoft.house.entity;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* AI找房应答
|
||||
*/
|
||||
@Data
|
||||
@Schema(name = "HouseAiChatResponse对象", description = "AI找房应答")
|
||||
public class HouseAiChatResponse implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "消息类型")
|
||||
private String type = "house_ai_result";
|
||||
|
||||
@Schema(description = "回答文本")
|
||||
private String answer;
|
||||
|
||||
@Schema(description = "命中的常见问题")
|
||||
private List<HouseFaq> faqs = new ArrayList<>();
|
||||
|
||||
@Schema(description = "推荐房源")
|
||||
private List<HouseAiHouseCard> houses = new ArrayList<>();
|
||||
|
||||
@Schema(description = "语义解析结果")
|
||||
private HouseAiIntent intent;
|
||||
|
||||
@Schema(description = "来源 faq/house/ai")
|
||||
private String source;
|
||||
}
|
||||
53
src/main/java/com/gxwebsoft/house/entity/HouseAiConfig.java
Normal file
53
src/main/java/com/gxwebsoft/house/entity/HouseAiConfig.java
Normal file
@@ -0,0 +1,53 @@
|
||||
package com.gxwebsoft.house.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* AI找房配置
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Schema(name = "HouseAiConfig对象", description = "AI找房配置")
|
||||
public class HouseAiConfig implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "主键ID")
|
||||
@TableId(value = "config_id", type = IdType.AUTO)
|
||||
private Integer configId;
|
||||
|
||||
@Schema(description = "AI形象照")
|
||||
private String aiAvatar;
|
||||
|
||||
@Schema(description = "首页AI入口图")
|
||||
private String aiEntryImage;
|
||||
|
||||
@Schema(description = "首页AI悬浮图")
|
||||
private String aiFloatImage;
|
||||
|
||||
@Schema(description = "欢迎词")
|
||||
private String welcomeMessage;
|
||||
|
||||
@Schema(description = "状态 0正常 1禁用")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "是否删除, 0否, 1是")
|
||||
@TableLogic
|
||||
private Integer deleted;
|
||||
|
||||
@Schema(description = "租户ID")
|
||||
private Integer tenantId;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
private Date createTime;
|
||||
|
||||
@Schema(description = "更新时间")
|
||||
private Date updateTime;
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.gxwebsoft.house.entity;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* AI找房返回的轻量房源卡片
|
||||
*/
|
||||
@Data
|
||||
@Schema(name = "HouseAiHouseCard对象", description = "AI找房返回的轻量房源卡片")
|
||||
public class HouseAiHouseCard implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "房源ID")
|
||||
private Integer houseId;
|
||||
|
||||
@Schema(description = "房源标题")
|
||||
private String houseTitle;
|
||||
|
||||
@Schema(description = "户型")
|
||||
private String houseType;
|
||||
|
||||
@Schema(description = "面积")
|
||||
private String extent;
|
||||
|
||||
@Schema(description = "楼层")
|
||||
private String floor;
|
||||
|
||||
@Schema(description = "朝向")
|
||||
private String toward;
|
||||
|
||||
@Schema(description = "月租金")
|
||||
private String monthlyRent;
|
||||
|
||||
@Schema(description = "所在城市")
|
||||
private String city;
|
||||
|
||||
@Schema(description = "所在辖区")
|
||||
private String region;
|
||||
|
||||
@Schema(description = "详细地址")
|
||||
private String address;
|
||||
|
||||
@Schema(description = "图片附件")
|
||||
private String files;
|
||||
|
||||
@Schema(description = "办公室配套")
|
||||
private String supporting;
|
||||
}
|
||||
87
src/main/java/com/gxwebsoft/house/entity/HouseAiIntent.java
Normal file
87
src/main/java/com/gxwebsoft/house/entity/HouseAiIntent.java
Normal file
@@ -0,0 +1,87 @@
|
||||
package com.gxwebsoft.house.entity;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* AI找房语义解析结果
|
||||
*/
|
||||
@Data
|
||||
@Schema(name = "HouseAiIntent对象", description = "AI找房语义解析结果")
|
||||
public class HouseAiIntent implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "原始问题")
|
||||
private String originalQuestion;
|
||||
|
||||
@Schema(description = "意图类型 faq/house/mixed/unknown")
|
||||
private String intentType;
|
||||
|
||||
@Schema(description = "归一化问题")
|
||||
private String normalizedQuestion;
|
||||
|
||||
@Schema(description = "面积最小值")
|
||||
private Integer extentMin;
|
||||
|
||||
@Schema(description = "面积最大值")
|
||||
private Integer extentMax;
|
||||
|
||||
@Schema(description = "楼层最小值")
|
||||
private Integer floorMin;
|
||||
|
||||
@Schema(description = "楼层最大值")
|
||||
private Integer floorMax;
|
||||
|
||||
@Schema(description = "月租最小值")
|
||||
private BigDecimal monthlyRentMin;
|
||||
|
||||
@Schema(description = "月租最大值")
|
||||
private BigDecimal monthlyRentMax;
|
||||
|
||||
@Schema(description = "售价最小值")
|
||||
private BigDecimal salePriceMin;
|
||||
|
||||
@Schema(description = "售价最大值")
|
||||
private BigDecimal salePriceMax;
|
||||
|
||||
@Schema(description = "总价最小值")
|
||||
private BigDecimal totalPriceMin;
|
||||
|
||||
@Schema(description = "总价最大值")
|
||||
private BigDecimal totalPriceMax;
|
||||
|
||||
@Schema(description = "区域/地段")
|
||||
private String regionKeyword;
|
||||
|
||||
@Schema(description = "城市")
|
||||
private String cityKeyword;
|
||||
|
||||
@Schema(description = "租售类型 rent/sale")
|
||||
private String tradeType;
|
||||
|
||||
@Schema(description = "装修类型")
|
||||
private String decorationType;
|
||||
|
||||
@Schema(description = "配套要求")
|
||||
private String supportingKeyword;
|
||||
|
||||
@Schema(description = "朝向")
|
||||
private String toward;
|
||||
|
||||
@Schema(description = "房型")
|
||||
private String houseType;
|
||||
|
||||
@Schema(description = "AI生成的SQL筛选条件片段")
|
||||
private String whereSql;
|
||||
|
||||
@Schema(description = "AI生成的SQL排序片段")
|
||||
private String orderSql;
|
||||
|
||||
@Schema(description = "其他关键词")
|
||||
private List<String> tags = new ArrayList<>();
|
||||
}
|
||||
59
src/main/java/com/gxwebsoft/house/entity/HouseFaq.java
Normal file
59
src/main/java/com/gxwebsoft/house/entity/HouseFaq.java
Normal file
@@ -0,0 +1,59 @@
|
||||
package com.gxwebsoft.house.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* AI找房常见问题
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Schema(name = "HouseFaq对象", description = "AI找房常见问题")
|
||||
public class HouseFaq implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "主键ID")
|
||||
@TableId(value = "faq_id", type = IdType.AUTO)
|
||||
private Integer faqId;
|
||||
|
||||
@Schema(description = "问题")
|
||||
private String question;
|
||||
|
||||
@Schema(description = "关键词,多个用逗号分隔")
|
||||
private String keywords;
|
||||
|
||||
@Schema(description = "标准回答")
|
||||
private String answer;
|
||||
|
||||
@Schema(description = "分类")
|
||||
private String category;
|
||||
|
||||
@Schema(description = "排序号")
|
||||
private Integer sortNumber;
|
||||
|
||||
@Schema(description = "状态 0正常 1禁用")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "创建用户ID")
|
||||
private Integer userId;
|
||||
|
||||
@Schema(description = "是否删除, 0否, 1是")
|
||||
@TableLogic
|
||||
private Integer deleted;
|
||||
|
||||
@Schema(description = "租户ID")
|
||||
private Integer tenantId;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
private Date createTime;
|
||||
|
||||
@Schema(description = "更新时间")
|
||||
private Date updateTime;
|
||||
}
|
||||
62
src/main/java/com/gxwebsoft/house/entity/HouseMessage.java
Normal file
62
src/main/java/com/gxwebsoft/house/entity/HouseMessage.java
Normal file
@@ -0,0 +1,62 @@
|
||||
package com.gxwebsoft.house.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* AI找房留言
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Schema(name = "HouseMessage对象", description = "AI找房留言")
|
||||
public class HouseMessage implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "主键ID")
|
||||
@TableId(value = "message_id", type = IdType.AUTO)
|
||||
private Integer messageId;
|
||||
|
||||
@Schema(description = "用户ID")
|
||||
private Integer userId;
|
||||
|
||||
@Schema(description = "姓名")
|
||||
private String realName;
|
||||
|
||||
@Schema(description = "手机号")
|
||||
private String phone;
|
||||
|
||||
@Schema(description = "微信号")
|
||||
private String wechat;
|
||||
|
||||
@Schema(description = "来源")
|
||||
private String source;
|
||||
|
||||
@Schema(description = "备注")
|
||||
private String comments;
|
||||
|
||||
@Schema(description = "状态 0未处理 1已处理")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "是否删除, 0否, 1是")
|
||||
@TableLogic
|
||||
private Integer deleted;
|
||||
|
||||
@Schema(description = "租户ID")
|
||||
private Integer tenantId;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "更新时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime updateTime;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.gxwebsoft.house.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.gxwebsoft.house.entity.HouseAiConfig;
|
||||
import com.gxwebsoft.house.param.HouseAiConfigParam;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* AI找房配置Mapper
|
||||
*/
|
||||
public interface HouseAiConfigMapper extends BaseMapper<HouseAiConfig> {
|
||||
|
||||
List<HouseAiConfig> selectPageRel(@Param("page") IPage<HouseAiConfig> page, @Param("param") HouseAiConfigParam param);
|
||||
|
||||
List<HouseAiConfig> selectListRel(@Param("param") HouseAiConfigParam param);
|
||||
}
|
||||
19
src/main/java/com/gxwebsoft/house/mapper/HouseFaqMapper.java
Normal file
19
src/main/java/com/gxwebsoft/house/mapper/HouseFaqMapper.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package com.gxwebsoft.house.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.gxwebsoft.house.entity.HouseFaq;
|
||||
import com.gxwebsoft.house.param.HouseFaqParam;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* AI找房常见问题Mapper
|
||||
*/
|
||||
public interface HouseFaqMapper extends BaseMapper<HouseFaq> {
|
||||
|
||||
List<HouseFaq> selectPageRel(@Param("page") IPage<HouseFaq> page, @Param("param") HouseFaqParam param);
|
||||
|
||||
List<HouseFaq> selectListRel(@Param("param") HouseFaqParam param);
|
||||
}
|
||||
@@ -34,4 +34,9 @@ public interface HouseInfoMapper extends BaseMapper<HouseInfo> {
|
||||
*/
|
||||
List<HouseInfo> selectListRel(@Param("param") HouseInfoParam param);
|
||||
|
||||
/**
|
||||
* 执行AI生成的受控查询条件
|
||||
*/
|
||||
List<HouseInfo> selectListByAiSql(@Param("whereSql") String whereSql, @Param("orderSql") String orderSql);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.gxwebsoft.house.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.gxwebsoft.house.entity.HouseMessage;
|
||||
import com.gxwebsoft.house.param.HouseMessageParam;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* AI找房留言Mapper
|
||||
*/
|
||||
public interface HouseMessageMapper extends BaseMapper<HouseMessage> {
|
||||
|
||||
List<HouseMessage> selectPageRel(@Param("page") IPage<HouseMessage> page, @Param("param") HouseMessageParam param);
|
||||
|
||||
List<HouseMessage> selectListRel(@Param("param") HouseMessageParam param);
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.gxwebsoft.house.mapper.HouseAiConfigMapper">
|
||||
|
||||
<sql id="selectSql">
|
||||
SELECT a.*
|
||||
FROM house_ai_config a
|
||||
<where>
|
||||
<if test="param.configId != null">
|
||||
AND a.config_id = #{param.configId}
|
||||
</if>
|
||||
<if test="param.aiAvatar != null and param.aiAvatar != ''">
|
||||
AND a.ai_avatar LIKE CONCAT('%', #{param.aiAvatar}, '%')
|
||||
</if>
|
||||
<if test="param.aiEntryImage != null and param.aiEntryImage != ''">
|
||||
AND a.ai_entry_image LIKE CONCAT('%', #{param.aiEntryImage}, '%')
|
||||
</if>
|
||||
<if test="param.aiFloatImage != null and param.aiFloatImage != ''">
|
||||
AND a.ai_float_image LIKE CONCAT('%', #{param.aiFloatImage}, '%')
|
||||
</if>
|
||||
<if test="param.welcomeMessage != null and param.welcomeMessage != ''">
|
||||
AND a.welcome_message LIKE CONCAT('%', #{param.welcomeMessage}, '%')
|
||||
</if>
|
||||
<if test="param.status != null">
|
||||
AND a.status = #{param.status}
|
||||
</if>
|
||||
<if test="param.deleted != null">
|
||||
AND a.deleted = #{param.deleted}
|
||||
</if>
|
||||
<if test="param.deleted == null">
|
||||
AND a.deleted = 0
|
||||
</if>
|
||||
<if test="param.tenantId != null">
|
||||
AND a.tenant_id = #{param.tenantId}
|
||||
</if>
|
||||
<if test="param.keywords != null and param.keywords != ''">
|
||||
AND (
|
||||
a.welcome_message LIKE CONCAT('%', #{param.keywords}, '%')
|
||||
OR a.ai_avatar LIKE CONCAT('%', #{param.keywords}, '%')
|
||||
OR a.ai_entry_image LIKE CONCAT('%', #{param.keywords}, '%')
|
||||
OR a.ai_float_image LIKE CONCAT('%', #{param.keywords}, '%')
|
||||
)
|
||||
</if>
|
||||
</where>
|
||||
ORDER BY a.config_id DESC
|
||||
</sql>
|
||||
|
||||
<select id="selectPageRel" resultType="com.gxwebsoft.house.entity.HouseAiConfig">
|
||||
<include refid="selectSql"></include>
|
||||
</select>
|
||||
|
||||
<select id="selectListRel" resultType="com.gxwebsoft.house.entity.HouseAiConfig">
|
||||
<include refid="selectSql"></include>
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.gxwebsoft.house.mapper.HouseFaqMapper">
|
||||
|
||||
<sql id="selectSql">
|
||||
SELECT a.*
|
||||
FROM house_faq a
|
||||
<where>
|
||||
<if test="param.faqId != null">
|
||||
AND a.faq_id = #{param.faqId}
|
||||
</if>
|
||||
<if test="param.question != null and param.question != ''">
|
||||
AND a.question LIKE CONCAT('%', #{param.question}, '%')
|
||||
</if>
|
||||
<if test="param.keywordsText != null and param.keywordsText != ''">
|
||||
AND a.keywords LIKE CONCAT('%', #{param.keywordsText}, '%')
|
||||
</if>
|
||||
<if test="param.answer != null and param.answer != ''">
|
||||
AND a.answer LIKE CONCAT('%', #{param.answer}, '%')
|
||||
</if>
|
||||
<if test="param.category != null and param.category != ''">
|
||||
AND a.category LIKE CONCAT('%', #{param.category}, '%')
|
||||
</if>
|
||||
<if test="param.sortNumber != null">
|
||||
AND a.sort_number = #{param.sortNumber}
|
||||
</if>
|
||||
<if test="param.status != null">
|
||||
AND a.status = #{param.status}
|
||||
</if>
|
||||
<if test="param.userId != null">
|
||||
AND a.user_id = #{param.userId}
|
||||
</if>
|
||||
<if test="param.deleted != null">
|
||||
AND a.deleted = #{param.deleted}
|
||||
</if>
|
||||
<if test="param.deleted == null">
|
||||
AND a.deleted = 0
|
||||
</if>
|
||||
<if test="param.createTimeStart != null">
|
||||
AND a.create_time >= #{param.createTimeStart}
|
||||
</if>
|
||||
<if test="param.createTimeEnd != null">
|
||||
AND a.create_time <= #{param.createTimeEnd}
|
||||
</if>
|
||||
<if test="param.keywords != null and param.keywords != ''">
|
||||
AND (
|
||||
a.question LIKE CONCAT('%', #{param.keywords}, '%')
|
||||
OR a.keywords LIKE CONCAT('%', #{param.keywords}, '%')
|
||||
OR a.answer LIKE CONCAT('%', #{param.keywords}, '%')
|
||||
OR a.category LIKE CONCAT('%', #{param.keywords}, '%')
|
||||
)
|
||||
</if>
|
||||
</where>
|
||||
ORDER BY a.sort_number ASC, a.faq_id DESC
|
||||
</sql>
|
||||
|
||||
<select id="selectPageRel" resultType="com.gxwebsoft.house.entity.HouseFaq">
|
||||
<include refid="selectSql"></include>
|
||||
</select>
|
||||
|
||||
<select id="selectListRel" resultType="com.gxwebsoft.house.entity.HouseFaq">
|
||||
<include refid="selectSql"></include>
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@@ -172,4 +172,25 @@
|
||||
<include refid="selectSql"></include>
|
||||
</select>
|
||||
|
||||
<!-- AI受控查询 -->
|
||||
<select id="selectListByAiSql" resultType="com.gxwebsoft.house.entity.HouseInfo">
|
||||
SELECT a.*,
|
||||
b.nickname,b.avatar,b.grade_id, b.phone as userPhone
|
||||
FROM house_info a
|
||||
LEFT JOIN gxwebsoft_core.sys_user b ON a.user_id = b.user_id
|
||||
<where>
|
||||
a.deleted = 0
|
||||
AND a.status = 0
|
||||
<if test="whereSql != null and whereSql != ''">
|
||||
AND ${whereSql}
|
||||
</if>
|
||||
</where>
|
||||
<if test="orderSql != null and orderSql != ''">
|
||||
ORDER BY ${orderSql}
|
||||
</if>
|
||||
<if test="orderSql == null or orderSql == ''">
|
||||
ORDER BY a.sort_number asc, a.create_time desc
|
||||
</if>
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.gxwebsoft.house.mapper.HouseMessageMapper">
|
||||
|
||||
<sql id="selectSql">
|
||||
SELECT a.*
|
||||
FROM house_message a
|
||||
<where>
|
||||
<if test="param.messageId != null">
|
||||
AND a.message_id = #{param.messageId}
|
||||
</if>
|
||||
<if test="param.userId != null">
|
||||
AND a.user_id = #{param.userId}
|
||||
</if>
|
||||
<if test="param.realName != null and param.realName != ''">
|
||||
AND a.real_name LIKE CONCAT('%', #{param.realName}, '%')
|
||||
</if>
|
||||
<if test="param.phone != null and param.phone != ''">
|
||||
AND a.phone LIKE CONCAT('%', #{param.phone}, '%')
|
||||
</if>
|
||||
<if test="param.wechat != null and param.wechat != ''">
|
||||
AND a.wechat LIKE CONCAT('%', #{param.wechat}, '%')
|
||||
</if>
|
||||
<if test="param.source != null and param.source != ''">
|
||||
AND a.source = #{param.source}
|
||||
</if>
|
||||
<if test="param.comments != null and param.comments != ''">
|
||||
AND a.comments LIKE CONCAT('%', #{param.comments}, '%')
|
||||
</if>
|
||||
<if test="param.status != null">
|
||||
AND a.status = #{param.status}
|
||||
</if>
|
||||
<if test="param.deleted != null">
|
||||
AND a.deleted = #{param.deleted}
|
||||
</if>
|
||||
<if test="param.deleted == null">
|
||||
AND a.deleted = 0
|
||||
</if>
|
||||
<if test="param.createTimeStart != null">
|
||||
AND a.create_time >= #{param.createTimeStart}
|
||||
</if>
|
||||
<if test="param.createTimeEnd != null">
|
||||
AND a.create_time <= #{param.createTimeEnd}
|
||||
</if>
|
||||
<if test="param.keywords != null and param.keywords != ''">
|
||||
AND (
|
||||
a.real_name LIKE CONCAT('%', #{param.keywords}, '%')
|
||||
OR a.phone LIKE CONCAT('%', #{param.keywords}, '%')
|
||||
OR a.wechat LIKE CONCAT('%', #{param.keywords}, '%')
|
||||
OR a.comments LIKE CONCAT('%', #{param.keywords}, '%')
|
||||
)
|
||||
</if>
|
||||
</where>
|
||||
</sql>
|
||||
|
||||
<select id="selectPageRel" resultType="com.gxwebsoft.house.entity.HouseMessage">
|
||||
<include refid="selectSql"></include>
|
||||
</select>
|
||||
|
||||
<select id="selectListRel" resultType="com.gxwebsoft.house.entity.HouseMessage">
|
||||
<include refid="selectSql"></include>
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.gxwebsoft.house.param;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.gxwebsoft.common.core.annotation.QueryField;
|
||||
import com.gxwebsoft.common.core.annotation.QueryType;
|
||||
import com.gxwebsoft.common.core.web.BaseParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* AI找房配置查询参数
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
@Schema(name = "HouseAiConfigParam对象", description = "AI找房配置查询参数")
|
||||
public class HouseAiConfigParam extends BaseParam {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "主键ID")
|
||||
@QueryField(type = QueryType.EQ)
|
||||
private Integer configId;
|
||||
|
||||
@Schema(description = "AI形象照")
|
||||
private String aiAvatar;
|
||||
|
||||
@Schema(description = "首页AI入口图")
|
||||
private String aiEntryImage;
|
||||
|
||||
@Schema(description = "首页AI悬浮图")
|
||||
private String aiFloatImage;
|
||||
|
||||
@Schema(description = "欢迎词")
|
||||
private String welcomeMessage;
|
||||
|
||||
@Schema(description = "状态 0正常 1禁用")
|
||||
@QueryField(type = QueryType.EQ)
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "是否删除, 0否, 1是")
|
||||
@QueryField(type = QueryType.EQ)
|
||||
private Integer deleted;
|
||||
}
|
||||
57
src/main/java/com/gxwebsoft/house/param/HouseFaqParam.java
Normal file
57
src/main/java/com/gxwebsoft/house/param/HouseFaqParam.java
Normal file
@@ -0,0 +1,57 @@
|
||||
package com.gxwebsoft.house.param;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.gxwebsoft.common.core.annotation.QueryField;
|
||||
import com.gxwebsoft.common.core.annotation.QueryType;
|
||||
import com.gxwebsoft.common.core.web.BaseParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* AI找房常见问题查询参数
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
@Schema(name = "HouseFaqParam对象", description = "AI找房常见问题查询参数")
|
||||
public class HouseFaqParam extends BaseParam {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "主键ID")
|
||||
@QueryField(type = QueryType.EQ)
|
||||
private Integer faqId;
|
||||
|
||||
@Schema(description = "问题")
|
||||
private String question;
|
||||
|
||||
@Schema(description = "关键词")
|
||||
private String keywordsText;
|
||||
|
||||
@Schema(description = "回答")
|
||||
private String answer;
|
||||
|
||||
@Schema(description = "分类")
|
||||
private String category;
|
||||
|
||||
@Schema(description = "排序号")
|
||||
@QueryField(type = QueryType.EQ)
|
||||
private Integer sortNumber;
|
||||
|
||||
@Schema(description = "状态 0正常 1禁用")
|
||||
@QueryField(type = QueryType.EQ)
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "创建用户ID")
|
||||
@QueryField(type = QueryType.EQ)
|
||||
private Integer userId;
|
||||
|
||||
@Schema(description = "是否删除, 0否, 1是")
|
||||
@QueryField(type = QueryType.EQ)
|
||||
private Integer deleted;
|
||||
|
||||
@Schema(description = "语义搜索原句")
|
||||
@TableField(exist = false)
|
||||
private String queryText;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.gxwebsoft.house.param;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.gxwebsoft.common.core.annotation.QueryField;
|
||||
import com.gxwebsoft.common.core.annotation.QueryType;
|
||||
import com.gxwebsoft.common.core.web.BaseParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* AI找房留言查询参数
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
@Schema(name = "HouseMessageParam对象", description = "AI找房留言查询参数")
|
||||
public class HouseMessageParam extends BaseParam {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "主键ID")
|
||||
@QueryField(type = QueryType.EQ)
|
||||
private Integer messageId;
|
||||
|
||||
@Schema(description = "用户ID")
|
||||
@QueryField(type = QueryType.EQ)
|
||||
private Integer userId;
|
||||
|
||||
@Schema(description = "姓名")
|
||||
private String realName;
|
||||
|
||||
@Schema(description = "手机号")
|
||||
private String phone;
|
||||
|
||||
@Schema(description = "微信号")
|
||||
private String wechat;
|
||||
|
||||
@Schema(description = "来源")
|
||||
private String source;
|
||||
|
||||
@Schema(description = "备注")
|
||||
private String comments;
|
||||
|
||||
@Schema(description = "状态 0未处理 1已处理")
|
||||
@QueryField(type = QueryType.EQ)
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "是否删除, 0否, 1是")
|
||||
@QueryField(type = QueryType.EQ)
|
||||
private Integer deleted;
|
||||
|
||||
@Schema(description = "关键词")
|
||||
private String keywords;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.gxwebsoft.house.service;
|
||||
|
||||
import com.gxwebsoft.house.entity.HouseAiChatRequest;
|
||||
import com.gxwebsoft.house.entity.HouseAiChatResponse;
|
||||
import com.gxwebsoft.house.entity.HouseAiIntent;
|
||||
|
||||
/**
|
||||
* AI找房问答Service
|
||||
*/
|
||||
public interface HouseAiChatService {
|
||||
|
||||
HouseAiIntent analyzeIntent(String question);
|
||||
|
||||
HouseAiChatResponse answer(HouseAiChatRequest request);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.gxwebsoft.house.service;
|
||||
|
||||
import com.github.yulichang.base.MPJBaseService;
|
||||
import com.gxwebsoft.common.core.web.PageResult;
|
||||
import com.gxwebsoft.house.entity.HouseAiConfig;
|
||||
import com.gxwebsoft.house.param.HouseAiConfigParam;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* AI找房配置Service
|
||||
*/
|
||||
public interface HouseAiConfigService extends MPJBaseService<HouseAiConfig> {
|
||||
|
||||
PageResult<HouseAiConfig> pageRel(HouseAiConfigParam param);
|
||||
|
||||
List<HouseAiConfig> listRel(HouseAiConfigParam param);
|
||||
|
||||
HouseAiConfig getByIdRel(Integer configId);
|
||||
|
||||
HouseAiConfig getCurrentConfig(Integer tenantId);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.gxwebsoft.house.service;
|
||||
|
||||
import com.github.yulichang.base.MPJBaseService;
|
||||
import com.gxwebsoft.common.core.web.PageResult;
|
||||
import com.gxwebsoft.house.entity.HouseFaq;
|
||||
import com.gxwebsoft.house.param.HouseFaqParam;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* AI找房常见问题Service
|
||||
*/
|
||||
public interface HouseFaqService extends MPJBaseService<HouseFaq> {
|
||||
|
||||
PageResult<HouseFaq> pageRel(HouseFaqParam param);
|
||||
|
||||
List<HouseFaq> listRel(HouseFaqParam param);
|
||||
|
||||
HouseFaq getByIdRel(Integer faqId);
|
||||
|
||||
List<HouseFaq> findBestMatches(String queryText, int limit);
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.gxwebsoft.house.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.gxwebsoft.common.core.web.PageResult;
|
||||
import com.gxwebsoft.house.entity.HouseMessage;
|
||||
import com.gxwebsoft.house.param.HouseMessageParam;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* AI找房留言Service
|
||||
*/
|
||||
public interface HouseMessageService extends IService<HouseMessage> {
|
||||
|
||||
PageResult<HouseMessage> pageRel(HouseMessageParam param);
|
||||
|
||||
List<HouseMessage> listRel(HouseMessageParam param);
|
||||
|
||||
HouseMessage getByIdRel(Integer messageId);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,52 @@
|
||||
package com.gxwebsoft.house.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.gxwebsoft.common.core.web.PageParam;
|
||||
import com.gxwebsoft.common.core.web.PageResult;
|
||||
import com.gxwebsoft.house.entity.HouseAiConfig;
|
||||
import com.gxwebsoft.house.mapper.HouseAiConfigMapper;
|
||||
import com.gxwebsoft.house.param.HouseAiConfigParam;
|
||||
import com.gxwebsoft.house.service.HouseAiConfigService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* AI找房配置Service实现
|
||||
*/
|
||||
@Service
|
||||
public class HouseAiConfigServiceImpl extends ServiceImpl<HouseAiConfigMapper, HouseAiConfig> implements HouseAiConfigService {
|
||||
|
||||
@Override
|
||||
public PageResult<HouseAiConfig> pageRel(HouseAiConfigParam param) {
|
||||
PageParam<HouseAiConfig, HouseAiConfigParam> page = new PageParam<>(param);
|
||||
page.setDefaultOrder("config_id desc");
|
||||
List<HouseAiConfig> list = baseMapper.selectPageRel(page, param);
|
||||
return new PageResult<>(list, page.getTotal());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HouseAiConfig> listRel(HouseAiConfigParam param) {
|
||||
return baseMapper.selectListRel(param);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HouseAiConfig getByIdRel(Integer configId) {
|
||||
HouseAiConfigParam param = new HouseAiConfigParam();
|
||||
param.setConfigId(configId);
|
||||
return param.getOne(baseMapper.selectListRel(param));
|
||||
}
|
||||
|
||||
@Override
|
||||
public HouseAiConfig getCurrentConfig(Integer tenantId) {
|
||||
HouseAiConfigParam param = new HouseAiConfigParam();
|
||||
param.setStatus(0);
|
||||
param.setTenantId(tenantId);
|
||||
HouseAiConfig config = param.getOne(baseMapper.selectListRel(param));
|
||||
if (config != null) {
|
||||
return config;
|
||||
}
|
||||
param.setTenantId(null);
|
||||
return param.getOne(baseMapper.selectListRel(param));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
package com.gxwebsoft.house.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.gxwebsoft.common.core.web.PageParam;
|
||||
import com.gxwebsoft.common.core.web.PageResult;
|
||||
import com.gxwebsoft.house.entity.HouseFaq;
|
||||
import com.gxwebsoft.house.mapper.HouseFaqMapper;
|
||||
import com.gxwebsoft.house.param.HouseFaqParam;
|
||||
import com.gxwebsoft.house.service.HouseFaqService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* AI找房常见问题Service实现
|
||||
*/
|
||||
@Service
|
||||
public class HouseFaqServiceImpl extends ServiceImpl<HouseFaqMapper, HouseFaq> implements HouseFaqService {
|
||||
|
||||
@Override
|
||||
public PageResult<HouseFaq> pageRel(HouseFaqParam param) {
|
||||
PageParam<HouseFaq, HouseFaqParam> page = new PageParam<>(param);
|
||||
page.setDefaultOrder("sort_number asc, faq_id desc");
|
||||
List<HouseFaq> list = baseMapper.selectPageRel(page, param);
|
||||
return new PageResult<>(list, page.getTotal());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HouseFaq> listRel(HouseFaqParam param) {
|
||||
return baseMapper.selectListRel(param);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HouseFaq getByIdRel(Integer faqId) {
|
||||
HouseFaqParam param = new HouseFaqParam();
|
||||
param.setFaqId(faqId);
|
||||
return param.getOne(baseMapper.selectListRel(param));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HouseFaq> findBestMatches(String queryText, int limit) {
|
||||
HouseFaqParam param = new HouseFaqParam();
|
||||
param.setStatus(0);
|
||||
List<HouseFaq> all = baseMapper.selectListRel(param);
|
||||
if (StrUtil.isBlank(queryText) || all == null || all.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
final String normalizedQuery = normalizeText(queryText);
|
||||
return all.stream()
|
||||
.map(item -> new ScoredFaq(item, score(item, normalizedQuery)))
|
||||
.filter(item -> item.score > 0)
|
||||
.sorted(Comparator.comparingInt(ScoredFaq::getScore).reversed()
|
||||
.thenComparing(item -> item.faq.getSortNumber() == null ? Integer.MAX_VALUE : item.faq.getSortNumber()))
|
||||
.limit(limit)
|
||||
.map(ScoredFaq::getFaq)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private int score(HouseFaq faq, String normalizedQuery) {
|
||||
int score = 0;
|
||||
String question = normalizeText(faq.getQuestion());
|
||||
String keywords = normalizeText(faq.getKeywords());
|
||||
String answer = normalizeText(faq.getAnswer());
|
||||
String category = normalizeText(faq.getCategory());
|
||||
if (StrUtil.isBlank(normalizedQuery)) {
|
||||
return score;
|
||||
}
|
||||
if (question.contains(normalizedQuery)) {
|
||||
score += 120;
|
||||
}
|
||||
if (keywords.contains(normalizedQuery)) {
|
||||
score += 100;
|
||||
}
|
||||
if (answer.contains(normalizedQuery)) {
|
||||
score += 40;
|
||||
}
|
||||
if (category.contains(normalizedQuery)) {
|
||||
score += 30;
|
||||
}
|
||||
for (String token : tokenize(normalizedQuery)) {
|
||||
if (token.length() < 2) {
|
||||
continue;
|
||||
}
|
||||
if (question.contains(token)) {
|
||||
score += 20;
|
||||
}
|
||||
if (keywords.contains(token)) {
|
||||
score += 18;
|
||||
}
|
||||
if (answer.contains(token)) {
|
||||
score += 8;
|
||||
}
|
||||
if (category.contains(token)) {
|
||||
score += 6;
|
||||
}
|
||||
}
|
||||
return score;
|
||||
}
|
||||
|
||||
private List<String> tokenize(String text) {
|
||||
String normalized = normalizeText(text);
|
||||
List<String> tokens = new ArrayList<>();
|
||||
for (String item : normalized.split("[,,\\s+/|]+")) {
|
||||
if (StrUtil.isNotBlank(item)) {
|
||||
tokens.add(item);
|
||||
}
|
||||
}
|
||||
return tokens;
|
||||
}
|
||||
|
||||
private String normalizeText(String text) {
|
||||
if (text == null) {
|
||||
return "";
|
||||
}
|
||||
return text.replace(" ", " ")
|
||||
.replace(",", ",")
|
||||
.replace("。", " ")
|
||||
.replace(";", " ")
|
||||
.replace(":", " ")
|
||||
.replace("(", "(")
|
||||
.replace(")", ")")
|
||||
.replace("㎡", "平")
|
||||
.replace("m²", "平")
|
||||
.replace("M²", "平")
|
||||
.toLowerCase(Locale.ROOT)
|
||||
.trim();
|
||||
}
|
||||
|
||||
private static class ScoredFaq {
|
||||
private final HouseFaq faq;
|
||||
private final int score;
|
||||
|
||||
private ScoredFaq(HouseFaq faq, int score) {
|
||||
this.faq = faq;
|
||||
this.score = score;
|
||||
}
|
||||
|
||||
public HouseFaq getFaq() {
|
||||
return faq;
|
||||
}
|
||||
|
||||
public int getScore() {
|
||||
return score;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.gxwebsoft.house.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.gxwebsoft.common.core.web.PageParam;
|
||||
import com.gxwebsoft.common.core.web.PageResult;
|
||||
import com.gxwebsoft.house.entity.HouseMessage;
|
||||
import com.gxwebsoft.house.mapper.HouseMessageMapper;
|
||||
import com.gxwebsoft.house.param.HouseMessageParam;
|
||||
import com.gxwebsoft.house.service.HouseMessageService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* AI找房留言Service实现
|
||||
*/
|
||||
@Service
|
||||
public class HouseMessageServiceImpl extends ServiceImpl<HouseMessageMapper, HouseMessage> implements HouseMessageService {
|
||||
|
||||
@Override
|
||||
public PageResult<HouseMessage> pageRel(HouseMessageParam param) {
|
||||
PageParam<HouseMessage, HouseMessageParam> page = new PageParam<>(param);
|
||||
page.setDefaultOrder("create_time desc, message_id desc");
|
||||
List<HouseMessage> list = baseMapper.selectPageRel(page, param);
|
||||
return new PageResult<>(list, page.getTotal());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HouseMessage> listRel(HouseMessageParam param) {
|
||||
List<HouseMessage> list = baseMapper.selectListRel(param);
|
||||
PageParam<HouseMessage, HouseMessageParam> page = new PageParam<>();
|
||||
page.setDefaultOrder("create_time desc, message_id desc");
|
||||
return page.sortRecords(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HouseMessage getByIdRel(Integer messageId) {
|
||||
HouseMessageParam param = new HouseMessageParam();
|
||||
param.setMessageId(messageId);
|
||||
return param.getOne(baseMapper.selectListRel(param));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user