1
This commit is contained in:
parent
ee76489951
commit
fdc3c03216
@ -133,6 +133,12 @@
|
||||
<artifactId>spring-websocket</artifactId>
|
||||
<version>5.3.31</version>
|
||||
</dependency>
|
||||
<!-- ip2region-->
|
||||
<dependency>
|
||||
<groupId>org.lionsoul</groupId>
|
||||
<artifactId>ip2region</artifactId>
|
||||
<version>2.7.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -3,14 +3,18 @@ package com.ruoyi.base.controller;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.ruoyi.base.domain.BaseInquiry;
|
||||
import com.ruoyi.base.domain.BasePic;
|
||||
import com.ruoyi.base.domain.BaseSiteInfo;
|
||||
import com.ruoyi.base.service.IBaseInquiryService;
|
||||
import com.ruoyi.base.service.IBasePicService;
|
||||
import com.ruoyi.base.service.IBaseSiteInfoService;
|
||||
import com.ruoyi.busi.domain.BusiCategory;
|
||||
import com.ruoyi.busi.domain.BusiInquiryItem;
|
||||
import com.ruoyi.busi.domain.BusiProdNew;
|
||||
import com.ruoyi.busi.service.IBusiCategoryService;
|
||||
import com.ruoyi.busi.service.IBusiProdNewService;
|
||||
import com.ruoyi.busi.utils.CommonUtils;
|
||||
import com.ruoyi.busi.vo.BusiCategoryVO;
|
||||
import com.ruoyi.busi.vo.ProdNewVO;
|
||||
import com.ruoyi.busi.vo.WebDetailVO;
|
||||
@ -27,8 +31,11 @@ import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.HttpRequestHandler;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import springfox.documentation.annotations.ApiIgnore;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.*;
|
||||
|
||||
@ -48,11 +55,15 @@ public class WebController extends BaseController {
|
||||
@Autowired
|
||||
private IBasePicService basePicService;
|
||||
@Autowired
|
||||
private IBaseInquiryService baseInquiryService;
|
||||
@Autowired
|
||||
private IBusiCategoryService categoryService;
|
||||
@Autowired
|
||||
private IBaseSiteInfoService siteInfoService;
|
||||
@Autowired
|
||||
private IBusiProdNewService prodNewService;
|
||||
@Autowired
|
||||
private CommonUtils commonUtils;
|
||||
|
||||
/**
|
||||
* 导航栏接口--所有分类
|
||||
@ -286,4 +297,43 @@ public class WebController extends BaseController {
|
||||
Page<BusiProdNew> page = new Page<>(pageNum,pageSize);
|
||||
return R.ok(prodNewService.searchTextAll(tenantId,text,page));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询盘设置-都有哪些字段需要填写,是否必填
|
||||
* @author vinjor-M
|
||||
* @date 10:04 2025/7/8
|
||||
* @return com.ruoyi.common.core.domain.AjaxResult
|
||||
**/
|
||||
@ApiOperation("查询盘设置-都有哪些字段需要填写,是否必填")
|
||||
@ApiImplicitParam(name = "tenantId", value = "站点唯一码", required = true, dataType = "string", paramType = "query", dataTypeClass = String.class)
|
||||
@GetMapping("/inquirySet")
|
||||
public R<BaseInquiry> inquirySet(@RequestParam(required = true) String tenantId, HttpServletRequest request){
|
||||
String ip = CommonUtils.getIpAddr(request);
|
||||
System.out.println(ip);
|
||||
System.out.println(CommonUtils.getAddr(ip));
|
||||
return R.ok(baseInquiryService.getInquiry(tenantId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交在线询盘表单
|
||||
* @author vinjor-M
|
||||
* @date 10:04 2025/7/8
|
||||
* @return com.ruoyi.common.core.domain.AjaxResult
|
||||
**/
|
||||
@ApiOperation("提交在线询盘表单")
|
||||
@ApiImplicitParams(value = {
|
||||
@ApiImplicitParam(name = "companyName", value = "公司名称", required = false, paramType = "body"),
|
||||
@ApiImplicitParam(name = "name", value = "姓名", required = false, paramType = "body"),
|
||||
@ApiImplicitParam(name = "tel", value = "电话或WhatsApp", required = false, paramType = "body"),
|
||||
@ApiImplicitParam(name = "title", value = "标题", required = false, paramType = "body"),
|
||||
@ApiImplicitParam(name = "content", value = "内容", required = true, paramType = "body"),
|
||||
@ApiImplicitParam(name = "email", value = "email", required = false, paramType = "body"),
|
||||
@ApiImplicitParam(name = "tenantId", value = "公司名称", required = true, paramType = "body")
|
||||
})
|
||||
@PostMapping("/inquirySave")
|
||||
public R<BaseInquiry> inquirySave(@ApiIgnore @RequestBody BusiInquiryItem inquiryItem, HttpServletRequest request){
|
||||
String ip = CommonUtils.getIpAddr(request);
|
||||
System.out.println(CommonUtils.getAddr(ip));
|
||||
return R.ok();
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,8 @@ import com.ruoyi.common.annotation.Excel;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.*;
|
||||
import com.ruoyi.common.core.domain.DlBaseEntity;
|
||||
|
||||
@ -20,52 +22,74 @@ import com.ruoyi.common.core.domain.DlBaseEntity;
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@ApiModel(value = "BaseInquiry", description = "询盘设置实体")
|
||||
public class BaseInquiry extends DlBaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 主键 */
|
||||
@TableId(type = IdType.ASSIGN_UUID)
|
||||
@ApiModelProperty("主键")
|
||||
private String id;
|
||||
|
||||
/** 是否开启填写公司名称 */
|
||||
@Excel(name = "公司名称")
|
||||
@ApiModelProperty("公司名称字段是否显示")
|
||||
private Boolean company;
|
||||
|
||||
/** 公司名称是否必填 */
|
||||
@Excel(name = "公司名称是否必填")
|
||||
@ApiModelProperty("公司名称是否必填")
|
||||
private Boolean companyMust;
|
||||
|
||||
/** 是否开启填写email */
|
||||
@Excel(name = "是否开启填写email")
|
||||
@ApiModelProperty("email字段是否显示")
|
||||
private Boolean email;
|
||||
|
||||
/** email是否必填 */
|
||||
@Excel(name = "email是否必填")
|
||||
@ApiModelProperty("email字段是否必填")
|
||||
private Boolean emailMust;
|
||||
|
||||
/** 是否开启填写电话/WhatsApp */
|
||||
@Excel(name = "电话/WhatsApp")
|
||||
@ApiModelProperty("电话/WhatsApp字段是否显示")
|
||||
private Boolean tel;
|
||||
|
||||
/** 是否必填 */
|
||||
@Excel(name = "是否必填")
|
||||
@ApiModelProperty("电话/WhatsApp字段是否必填")
|
||||
private Boolean telMust;
|
||||
|
||||
/** 是否开启填写标题 */
|
||||
@Excel(name = "标题")
|
||||
@ApiModelProperty("标题字段是否显示")
|
||||
private Boolean title;
|
||||
|
||||
/** 是否必填 */
|
||||
@Excel(name = "是否必填")
|
||||
@ApiModelProperty("标题字段是否必填")
|
||||
private Boolean titleMust;
|
||||
|
||||
/** 是否开启填写姓名 */
|
||||
@Excel(name = "姓名")
|
||||
@ApiModelProperty("姓名字段是否显示")
|
||||
private Boolean name;
|
||||
|
||||
/** 是否必填 */
|
||||
@Excel(name = "是否必填")
|
||||
@ApiModelProperty("姓名字段是否必填")
|
||||
private Boolean nameMust;
|
||||
|
||||
/** 提示文字(内容) */
|
||||
@Excel(name = "提示文字", readConverterExp = "内=容")
|
||||
@ApiModelProperty("提示文字(以placeholder形式显示在多行文本框中,要求输入内容时,这个提示以其他方式显示在多行文本框上方或下方)")
|
||||
private String content;
|
||||
|
||||
/** 站点唯一编码(租户id) */
|
||||
@Excel(name = "站点唯一编码", readConverterExp = "租=户id")
|
||||
@ApiModelProperty("站点唯一编码")
|
||||
private String tenantId;
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,112 @@
|
||||
package com.ruoyi.busi.controller;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import com.ruoyi.busi.domain.BusiInquiryItem;
|
||||
import com.ruoyi.busi.service.IBusiInquiryItemService;
|
||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
|
||||
/**
|
||||
* 在线询盘记录Controller
|
||||
*
|
||||
* @author vinjor-m
|
||||
* @date 2025-07-10
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/busi/inquiryItem")
|
||||
public class BusiInquiryItemController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private IBusiInquiryItemService busiInquiryItemService;
|
||||
|
||||
/**
|
||||
* 查询在线询盘记录列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('busi:inquiryItem:list')")
|
||||
@GetMapping("/list")
|
||||
public AjaxResult list(BusiInquiryItem busiInquiryItem,
|
||||
@RequestParam(name = "pageNum", defaultValue = "1") Integer pageNum,
|
||||
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize)
|
||||
{
|
||||
Page<BusiInquiryItem> page = new Page<>(pageNum, pageSize);
|
||||
IPage<BusiInquiryItem> list = busiInquiryItemService.queryListPage(busiInquiryItem,page);
|
||||
return success(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出在线询盘记录列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('busi:inquiryItem:export')")
|
||||
@Log(title = "在线询盘记录", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(HttpServletResponse response, BusiInquiryItem busiInquiryItem)
|
||||
{
|
||||
List<BusiInquiryItem> list = busiInquiryItemService.list();
|
||||
ExcelUtil<BusiInquiryItem> util = new ExcelUtil<BusiInquiryItem>(BusiInquiryItem.class);
|
||||
util.exportExcel(response, list, "在线询盘记录数据");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取在线询盘记录详细信息
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('busi:inquiryItem:query')")
|
||||
@GetMapping(value = "/{id}")
|
||||
public AjaxResult getInfo(@PathVariable("id") String id)
|
||||
{
|
||||
return success(busiInquiryItemService.getById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增在线询盘记录
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('busi:inquiryItem:add')")
|
||||
@Log(title = "在线询盘记录", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@RequestBody BusiInquiryItem busiInquiryItem)
|
||||
{
|
||||
return toAjax(busiInquiryItemService.save(busiInquiryItem));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改在线询盘记录
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('busi:inquiryItem:edit')")
|
||||
@Log(title = "在线询盘记录", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@RequestBody BusiInquiryItem busiInquiryItem)
|
||||
{
|
||||
return toAjax(busiInquiryItemService.updateById(busiInquiryItem));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除在线询盘记录
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('busi:inquiryItem:remove')")
|
||||
@Log(title = "在线询盘记录", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{ids}")
|
||||
public AjaxResult remove(@PathVariable String[] ids)
|
||||
{
|
||||
List<String> list = new ArrayList<>(Arrays.asList(ids));
|
||||
return toAjax(busiInquiryItemService.removeByIds(list));
|
||||
}
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
package com.ruoyi.busi.domain;
|
||||
|
||||
import com.ruoyi.common.annotation.Excel;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.*;
|
||||
import com.ruoyi.common.core.domain.DlBaseEntity;
|
||||
|
||||
/**
|
||||
* 在线询盘记录对象 dl_busi_inquiry_item
|
||||
*
|
||||
* @author vinjor-m
|
||||
* @date 2025-07-10
|
||||
*/
|
||||
@TableName("dl_busi_inquiry_item")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@ApiModel(value = "BusiInquiryItem", description = "在线询盘实体")
|
||||
public class BusiInquiryItem extends DlBaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 主键 */
|
||||
@TableId(type = IdType.ASSIGN_UUID)
|
||||
private String id;
|
||||
|
||||
/** 公司名称 */
|
||||
@Excel(name = "公司名称")
|
||||
@ApiModelProperty("公司名称")
|
||||
private String companyName;
|
||||
|
||||
/** 姓名 */
|
||||
@Excel(name = "姓名")
|
||||
@ApiModelProperty("姓名")
|
||||
private String name;
|
||||
|
||||
/** 电话 */
|
||||
@Excel(name = "电话")
|
||||
@ApiModelProperty("电话")
|
||||
private String tel;
|
||||
|
||||
/** 标题 */
|
||||
@Excel(name = "标题")
|
||||
@ApiModelProperty("标题")
|
||||
private String title;
|
||||
|
||||
/** 内容 */
|
||||
@Excel(name = "内容")
|
||||
@ApiModelProperty("内容")
|
||||
private String content;
|
||||
|
||||
/** 电子邮件 */
|
||||
@Excel(name = "电子邮件")
|
||||
@ApiModelProperty("电子邮件")
|
||||
private String email;
|
||||
|
||||
/** 来源IP */
|
||||
@Excel(name = "来源IP")
|
||||
@ApiModelProperty("来源IP")
|
||||
private String ip;
|
||||
|
||||
/** 来源国家 */
|
||||
@Excel(name = "来源国家")
|
||||
@ApiModelProperty("来源国家")
|
||||
private String national;
|
||||
|
||||
/** 洲 */
|
||||
@Excel(name = "洲")
|
||||
@ApiModelProperty("洲")
|
||||
private String oceania;
|
||||
|
||||
/** 页面路径 */
|
||||
@Excel(name = "页面路径")
|
||||
private String pageUrl;
|
||||
|
||||
/** 站点唯一编码(租户id) */
|
||||
@Excel(name = "站点唯一编码", readConverterExp = "租=户id")
|
||||
@ApiModelProperty("站点唯一编码")
|
||||
private String tenantId;
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.ruoyi.busi.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.ruoyi.busi.domain.BusiInquiryItem;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 在线询盘记录Mapper接口
|
||||
*
|
||||
* @author vinjor-m
|
||||
* @date 2025-07-10
|
||||
*/
|
||||
@Mapper
|
||||
public interface BusiInquiryItemMapper extends BaseMapper<BusiInquiryItem>
|
||||
{
|
||||
IPage<BusiInquiryItem> queryListPage(@Param("entity") BusiInquiryItem entity, Page<BusiInquiryItem> page);
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.ruoyi.busi.service;
|
||||
|
||||
import java.util.List;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.ruoyi.busi.domain.BusiInquiryItem;
|
||||
|
||||
/**
|
||||
* 在线询盘记录Service接口
|
||||
*
|
||||
* @author vinjor-m
|
||||
* @date 2025-07-10
|
||||
*/
|
||||
public interface IBusiInquiryItemService extends IService<BusiInquiryItem>
|
||||
{
|
||||
IPage<BusiInquiryItem> queryListPage(BusiInquiryItem pageReqVO, Page<BusiInquiryItem> page);
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package com.ruoyi.busi.service.impl;
|
||||
|
||||
import java.util.List;
|
||||
import com.ruoyi.common.utils.DateUtils;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.ruoyi.busi.mapper.BusiInquiryItemMapper;
|
||||
import com.ruoyi.busi.domain.BusiInquiryItem;
|
||||
import com.ruoyi.busi.service.IBusiInquiryItemService;
|
||||
|
||||
/**
|
||||
* 在线询盘记录Service业务层处理
|
||||
*
|
||||
* @author vinjor-m
|
||||
* @date 2025-07-10
|
||||
*/
|
||||
@Service
|
||||
public class BusiInquiryItemServiceImpl extends ServiceImpl<BusiInquiryItemMapper,BusiInquiryItem> implements IBusiInquiryItemService
|
||||
{
|
||||
@Autowired
|
||||
private BusiInquiryItemMapper busiInquiryItemMapper;
|
||||
|
||||
@Override
|
||||
public IPage<BusiInquiryItem> queryListPage(BusiInquiryItem pageReqVO, Page<BusiInquiryItem> page) {
|
||||
return busiInquiryItemMapper.queryListPage(pageReqVO, page);
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
package com.ruoyi.busi.utils;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.poi.util.IOUtils;
|
||||
import org.lionsoul.ip2region.xdb.Searcher;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.InputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
/**
|
||||
* 通用方法
|
||||
* @author 马文杰
|
||||
* @version 1.0
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class CommonUtils {
|
||||
|
||||
private static final String UNKNOWN = "unknown";
|
||||
|
||||
/**
|
||||
* 获取 IP地址
|
||||
* 使用 Nginx等反向代理软件, 则不能通过 request.getRemoteAddr()获取 IP地址
|
||||
* 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,
|
||||
* X-Forwarded-For中第一个非 unknown的有效IP字符串,则为真实IP地址
|
||||
*/
|
||||
public static String getIpAddr(HttpServletRequest request) {
|
||||
String ip = request.getHeader("x-forwarded-for");
|
||||
if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("Proxy-Client-IP");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("WL-Proxy-Client-IP");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
|
||||
ip = request.getRemoteAddr();
|
||||
}
|
||||
return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static String getAddr(String ip){
|
||||
ClassPathResource resource = new ClassPathResource("ip2region.xdb");
|
||||
InputStream inputStream = resource.getInputStream();
|
||||
String dbPath = "src/main/resources/ip2region.xdb";
|
||||
// 1、从 dbPath 加载整个 xdb 到内存。
|
||||
byte[] cBuff;
|
||||
try {
|
||||
cBuff = IOUtils.toByteArray(inputStream);
|
||||
} catch (Exception e) {
|
||||
log.info("failed to load content from %s: %s\n", dbPath, e);
|
||||
return null;
|
||||
}
|
||||
|
||||
// 2、使用上述的 cBuff 创建一个完全基于内存的查询对象。
|
||||
Searcher searcher;
|
||||
try {
|
||||
searcher = Searcher.newWithBuffer(cBuff);
|
||||
} catch (Exception e) {
|
||||
log.info("failed to create content cached searcher: %s\n", e);
|
||||
return null;
|
||||
}
|
||||
// 3、查询
|
||||
try {
|
||||
String region = searcher.search(ip);
|
||||
return region;
|
||||
} catch (Exception e) {
|
||||
log.info("failed to search(%s): %s\n", ip, e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
package com.ruoyi.busi.utils;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
/**
|
||||
* 文本相似度对比
|
||||
* @author 朱春云
|
||||
* @version 1.0
|
||||
*/
|
||||
@Component
|
||||
public class NoticeUtils {
|
||||
|
||||
/**
|
||||
* 比较两个文本字符串的相似度
|
||||
* @param str1 文本1
|
||||
* @param str2 文本2
|
||||
* @return 相似度值,范围在0到1之间,值越大相似度越高
|
||||
*/
|
||||
public static double computeJaccardSimilarity(String str1, String str2) {
|
||||
if (str1 == null || str2 == null || (str1.isEmpty() && str2.isEmpty())) {
|
||||
return 1.0; // 空字符串认为完全相同
|
||||
}
|
||||
if (str1.isEmpty() || str2.isEmpty()) {
|
||||
return 0.0; // 一个为空另一个非空,认为完全不同
|
||||
}
|
||||
|
||||
Set<String> set1 = Arrays.stream(str1.split("\\s+")).collect(Collectors.toSet());
|
||||
Set<String> set2 = Arrays.stream(str2.split("\\s+")).collect(Collectors.toSet());
|
||||
|
||||
Set<String> intersection = new HashSet<>(set1);
|
||||
intersection.retainAll(set2);
|
||||
|
||||
Set<String> union = new HashSet<>(set1);
|
||||
union.addAll(set2); // 正确的并集
|
||||
|
||||
if (union.isEmpty()) {
|
||||
return 0.0; // 安全处理,避免除以零
|
||||
}
|
||||
|
||||
return (double) intersection.size() / union.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* 翻译通告的博主类型字典
|
||||
* @author vinjor-M
|
||||
* @date 17:10 2025/3/25
|
||||
* @return java.lang.String
|
||||
**/
|
||||
public String translateBloggerTypes(String bloggerTypes, Map<String,String> categoryMap){
|
||||
List<String> rtnList = new ArrayList<>();
|
||||
List<String> bloggerTypeList = Arrays.asList(bloggerTypes.split(StrUtil.COMMA));
|
||||
bloggerTypeList.forEach(item->{
|
||||
if(categoryMap.get(item)!=null){
|
||||
rtnList.add(categoryMap.get(item));
|
||||
}
|
||||
});
|
||||
return String.join(" ",rtnList);
|
||||
}
|
||||
|
||||
|
||||
}
|
38
dl_admin/ruoyi-admin/src/main/java/com/ruoyi/xdb/Header.java
Normal file
38
dl_admin/ruoyi-admin/src/main/java/com/ruoyi/xdb/Header.java
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright 2022 The Ip2Region Authors. All rights reserved.
|
||||
// Use of this source code is governed by a Apache2.0-style
|
||||
// license that can be found in the LICENSE file.
|
||||
// @Author Lion <chenxin619315@gmail.com>
|
||||
// @Date 2022/06/23
|
||||
|
||||
package com.ruoyi.xdb;
|
||||
|
||||
import org.lionsoul.ip2region.xdb.Searcher;
|
||||
|
||||
public class Header {
|
||||
public final int version;
|
||||
public final int indexPolicy;
|
||||
public final int createdAt;
|
||||
public final int startIndexPtr;
|
||||
public final int endIndexPtr;
|
||||
public final byte[] buffer;
|
||||
|
||||
public Header(byte[] buff) {
|
||||
assert buff.length >= 16;
|
||||
version = Searcher.getInt2(buff, 0);
|
||||
indexPolicy = Searcher.getInt2(buff, 2);
|
||||
createdAt = Searcher.getInt(buff, 4);
|
||||
startIndexPtr = Searcher.getInt(buff, 8);
|
||||
endIndexPtr = Searcher.getInt(buff, 12);
|
||||
buffer = buff;
|
||||
}
|
||||
|
||||
@Override public String toString() {
|
||||
return "{" +
|
||||
"Version: " + version + ',' +
|
||||
"IndexPolicy: " + indexPolicy + ',' +
|
||||
"CreatedAt: " + createdAt + ',' +
|
||||
"StartIndexPtr: " + startIndexPtr + ',' +
|
||||
"EndIndexPtr: " + endIndexPtr +
|
||||
'}';
|
||||
}
|
||||
}
|
281
dl_admin/ruoyi-admin/src/main/java/com/ruoyi/xdb/Searcher.java
Normal file
281
dl_admin/ruoyi-admin/src/main/java/com/ruoyi/xdb/Searcher.java
Normal file
@ -0,0 +1,281 @@
|
||||
// Copyright 2022 The Ip2Region Authors. All rights reserved.
|
||||
// Use of this source code is governed by a Apache2.0-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package com.ruoyi.xdb;
|
||||
|
||||
// xdb searcher (Not thread safe implementation)
|
||||
// @Author Lion <chenxin619315@gmail.com>
|
||||
// @Date 2022/06/23
|
||||
|
||||
|
||||
import org.lionsoul.ip2region.xdb.Header;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
|
||||
public class Searcher {
|
||||
// constant defined copied from the xdb maker
|
||||
public static final int HeaderInfoLength = 256;
|
||||
public static final int VectorIndexRows = 256;
|
||||
public static final int VectorIndexCols = 256;
|
||||
public static final int VectorIndexSize = 8;
|
||||
public static final int SegmentIndexSize = 14;
|
||||
|
||||
// random access file handle for file based search
|
||||
private final RandomAccessFile handle;
|
||||
|
||||
private int ioCount = 0;
|
||||
|
||||
// vector index.
|
||||
// use the byte[] instead of VectorIndex entry array to keep
|
||||
// the minimal memory allocation.
|
||||
private final byte[] vectorIndex;
|
||||
|
||||
// xdb content buffer, used for in-memory search
|
||||
private final byte[] contentBuff;
|
||||
|
||||
// --- static method to create searchers
|
||||
|
||||
public static Searcher newWithFileOnly(String dbPath) throws IOException {
|
||||
return new Searcher(dbPath, null, null);
|
||||
}
|
||||
|
||||
public static Searcher newWithVectorIndex(String dbPath, byte[] vectorIndex) throws IOException {
|
||||
return new Searcher(dbPath, vectorIndex, null);
|
||||
}
|
||||
|
||||
public static Searcher newWithBuffer(byte[] cBuff) throws IOException {
|
||||
return new Searcher(null, null, cBuff);
|
||||
}
|
||||
|
||||
// --- End of creator
|
||||
|
||||
public Searcher(String dbFile, byte[] vectorIndex, byte[] cBuff) throws IOException {
|
||||
if (cBuff != null) {
|
||||
this.handle = null;
|
||||
this.vectorIndex = null;
|
||||
this.contentBuff = cBuff;
|
||||
} else {
|
||||
this.handle = new RandomAccessFile(dbFile, "r");
|
||||
this.vectorIndex = vectorIndex;
|
||||
this.contentBuff = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
if (this.handle != null) {
|
||||
this.handle.close();
|
||||
}
|
||||
}
|
||||
|
||||
public int getIOCount() {
|
||||
return ioCount;
|
||||
}
|
||||
|
||||
public String search(String ipStr) throws Exception {
|
||||
long ip = checkIP(ipStr);
|
||||
return search(ip);
|
||||
}
|
||||
|
||||
public String search(long ip) throws IOException {
|
||||
// reset the global counter
|
||||
this.ioCount = 0;
|
||||
|
||||
// locate the segment index block based on the vector index
|
||||
long sPtr = 0, ePtr = 0;
|
||||
int il0 = (int) ((ip >> 24) & 0xFF);
|
||||
int il1 = (int) ((ip >> 16) & 0xFF);
|
||||
int idx = il0 * VectorIndexCols * VectorIndexSize + il1 * VectorIndexSize;
|
||||
// System.out.printf("il0: %d, il1: %d, idx: %d\n", il0, il1, idx);
|
||||
if (vectorIndex != null) {
|
||||
sPtr = getIntLong(vectorIndex, idx);
|
||||
ePtr = getIntLong(vectorIndex, idx + 4);
|
||||
} else if (contentBuff != null) {
|
||||
sPtr = getIntLong(contentBuff, HeaderInfoLength + idx);
|
||||
ePtr = getIntLong(contentBuff, HeaderInfoLength + idx + 4);
|
||||
} else {
|
||||
final byte[] buff = new byte[VectorIndexSize];
|
||||
read(HeaderInfoLength + idx, buff);
|
||||
sPtr = getIntLong(buff, 0);
|
||||
ePtr = getIntLong(buff, 4);
|
||||
}
|
||||
|
||||
// System.out.printf("sPtr: %d, ePtr: %d\n", sPtr, ePtr);
|
||||
|
||||
// binary search the segment index block to get the region info
|
||||
final byte[] buff = new byte[SegmentIndexSize];
|
||||
int dataLen = -1;
|
||||
long dataPtr = -1, l = 0, h = (ePtr - sPtr) / SegmentIndexSize;
|
||||
while (l <= h) {
|
||||
long m = (l + h) >> 1;
|
||||
long p = sPtr + m * SegmentIndexSize;
|
||||
|
||||
// read the segment index
|
||||
read(p, buff);
|
||||
long sip = getIntLong(buff, 0);
|
||||
if (ip < sip) {
|
||||
h = m - 1;
|
||||
} else {
|
||||
long eip = getIntLong(buff, 4);
|
||||
if (ip > eip) {
|
||||
l = m + 1;
|
||||
} else {
|
||||
dataLen = getInt2(buff, 8);
|
||||
dataPtr = getIntLong(buff, 10);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// empty match interception
|
||||
// System.out.printf("dataLen: %d, dataPtr: %d\n", dataLen, dataPtr);
|
||||
if (dataPtr < 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// load and return the region data
|
||||
final byte[] regionBuff = new byte[dataLen];
|
||||
read(dataPtr, regionBuff);
|
||||
return new String(regionBuff, "utf-8");
|
||||
}
|
||||
|
||||
protected void read(long offset, byte[] buffer) throws IOException {
|
||||
// check the in-memory buffer first
|
||||
if (contentBuff != null) {
|
||||
// @TODO: reduce data copying, directly decode the data ?
|
||||
// @TODO: added by Leon at 2025/06/10, when offset is negative and the content byte is not going to work.
|
||||
// we need a better solution for the content buffer which is greater than (2^31 - 1 << 2)
|
||||
int int_idx = (int) offset;
|
||||
if (int_idx < 0) {
|
||||
throw new IOException("No content buffer policy for NOW since the xdb is too large, use file or vectorIndex instead");
|
||||
}
|
||||
|
||||
System.arraycopy(contentBuff, int_idx, buffer, 0, buffer.length);
|
||||
return;
|
||||
}
|
||||
|
||||
// read from the file handle
|
||||
assert handle != null;
|
||||
handle.seek(offset);
|
||||
|
||||
this.ioCount++;
|
||||
int rLen = handle.read(buffer);
|
||||
if (rLen != buffer.length) {
|
||||
throw new IOException("incomplete read: read bytes should be " + buffer.length);
|
||||
}
|
||||
}
|
||||
|
||||
// --- static cache util function
|
||||
|
||||
public static org.lionsoul.ip2region.xdb.Header loadHeader(RandomAccessFile handle) throws IOException {
|
||||
handle.seek(0);
|
||||
final byte[] buff = new byte[HeaderInfoLength];
|
||||
handle.read(buff);
|
||||
return new org.lionsoul.ip2region.xdb.Header(buff);
|
||||
}
|
||||
|
||||
public static org.lionsoul.ip2region.xdb.Header loadHeaderFromFile(String dbPath) throws IOException {
|
||||
final RandomAccessFile handle = new RandomAccessFile(dbPath, "r");
|
||||
final Header header = loadHeader(handle);
|
||||
handle.close();
|
||||
return header;
|
||||
}
|
||||
|
||||
public static byte[] loadVectorIndex(RandomAccessFile handle) throws IOException {
|
||||
handle.seek(HeaderInfoLength);
|
||||
int len = VectorIndexRows * VectorIndexCols * VectorIndexSize;
|
||||
final byte[] buff = new byte[len];
|
||||
int rLen = handle.read(buff);
|
||||
if (rLen != len) {
|
||||
throw new IOException("incomplete read: read bytes should be " + len);
|
||||
}
|
||||
|
||||
return buff;
|
||||
}
|
||||
|
||||
public static byte[] loadVectorIndexFromFile(String dbPath) throws IOException {
|
||||
final RandomAccessFile handle = new RandomAccessFile(dbPath, "r");
|
||||
final byte[] vIndex = loadVectorIndex(handle);
|
||||
handle.close();
|
||||
return vIndex;
|
||||
}
|
||||
|
||||
public static byte[] loadContent(RandomAccessFile handle) throws IOException {
|
||||
handle.seek(0);
|
||||
final byte[] buff = new byte[(int) handle.length()];
|
||||
int rLen = handle.read(buff);
|
||||
if (rLen != buff.length) {
|
||||
throw new IOException("incomplete read: read bytes should be " + buff.length);
|
||||
}
|
||||
|
||||
return buff;
|
||||
}
|
||||
|
||||
public static byte[] loadContentFromFile(String dbPath) throws IOException {
|
||||
final RandomAccessFile handle = new RandomAccessFile(dbPath, "r");
|
||||
final byte[] content = loadContent(handle);
|
||||
handle.close();
|
||||
return content;
|
||||
}
|
||||
|
||||
// --- End cache load util function
|
||||
|
||||
// --- static util method
|
||||
|
||||
/* get an int from a byte array start from the specified offset */
|
||||
public static long getIntLong(byte[] b, int offset) {
|
||||
return (
|
||||
((b[offset++] & 0x000000FFL)) |
|
||||
((b[offset++] << 8) & 0x0000FF00L) |
|
||||
((b[offset++] << 16) & 0x00FF0000L) |
|
||||
((b[offset ] << 24) & 0xFF000000L)
|
||||
);
|
||||
}
|
||||
|
||||
public static int getInt(byte[] b, int offset) {
|
||||
return (
|
||||
((b[offset++] & 0x000000FF)) |
|
||||
((b[offset++] << 8) & 0x0000FF00) |
|
||||
((b[offset++] << 16) & 0x00FF0000) |
|
||||
((b[offset ] << 24) & 0xFF000000)
|
||||
);
|
||||
}
|
||||
|
||||
public static int getInt2(byte[] b, int offset) {
|
||||
return (
|
||||
((b[offset++] & 0x000000FF)) |
|
||||
((b[offset ] << 8) & 0x0000FF00)
|
||||
);
|
||||
}
|
||||
|
||||
/* long int to ip string */
|
||||
public static String long2ip( long ip )
|
||||
{
|
||||
return String.valueOf((ip >> 24) & 0xFF) + '.' +
|
||||
((ip >> 16) & 0xFF) + '.' + ((ip >> 8) & 0xFF) + '.' + ((ip) & 0xFF);
|
||||
}
|
||||
|
||||
public static final byte[] shiftIndex = {24, 16, 8, 0};
|
||||
|
||||
/* check the specified ip address */
|
||||
public static long checkIP(String ip) throws Exception {
|
||||
String[] ps = ip.split("\\.");
|
||||
if (ps.length != 4) {
|
||||
throw new Exception("invalid ip address `" + ip + "`");
|
||||
}
|
||||
|
||||
long ipDst = 0;
|
||||
for (int i = 0; i < ps.length; i++) {
|
||||
int val = Integer.parseInt(ps[i]);
|
||||
if (val > 255) {
|
||||
throw new Exception("ip part `"+ps[i]+"` should be less then 256");
|
||||
}
|
||||
|
||||
ipDst |= ((long) val << shiftIndex[i]);
|
||||
}
|
||||
|
||||
return ipDst & 0xFFFFFFFFL;
|
||||
}
|
||||
|
||||
}
|
BIN
dl_admin/ruoyi-admin/src/main/resources/ip2region.xdb
Normal file
BIN
dl_admin/ruoyi-admin/src/main/resources/ip2region.xdb
Normal file
Binary file not shown.
BIN
dl_admin/ruoyi-admin/src/main/resources/ip2region/ip2region.xdb
Normal file
BIN
dl_admin/ruoyi-admin/src/main/resources/ip2region/ip2region.xdb
Normal file
Binary file not shown.
@ -8,6 +8,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<result property="id" column="id" />
|
||||
<result property="company" column="company" />
|
||||
<result property="companyMust" column="company_must" />
|
||||
<result property="email" column="email" />
|
||||
<result property="emailMust" column="email_must" />
|
||||
<result property="tel" column="tel" />
|
||||
<result property="telMust" column="tel_must" />
|
||||
<result property="title" column="title" />
|
||||
@ -24,7 +26,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectBaseInquiryVo">
|
||||
select id, company, company_must, tel, tel_must, title, title_must, name, name_must, content, tenant_id, creator, create_time, updater, update_time, del_flag from dl_base_inquiry
|
||||
select id, company, company_must,email,email_must, tel, tel_must, title, title_must, name, name_must, content, tenant_id, creator, create_time, updater, update_time, del_flag from dl_base_inquiry
|
||||
</sql>
|
||||
|
||||
<select id="queryListPage" parameterType="BaseInquiry" resultMap="BaseInquiryResult">
|
||||
|
@ -0,0 +1,47 @@
|
||||
<?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.ruoyi.busi.mapper.BusiInquiryItemMapper">
|
||||
|
||||
<resultMap type="BusiInquiryItem" id="BusiInquiryItemResult">
|
||||
<result property="id" column="id" />
|
||||
<result property="companyName" column="company_name" />
|
||||
<result property="name" column="name" />
|
||||
<result property="tel" column="tel" />
|
||||
<result property="title" column="title" />
|
||||
<result property="content" column="content" />
|
||||
<result property="email" column="email" />
|
||||
<result property="ip" column="ip" />
|
||||
<result property="national" column="national" />
|
||||
<result property="oceania" column="oceania" />
|
||||
<result property="pageUrl" column="page_url" />
|
||||
<result property="tenantId" column="tenant_id" />
|
||||
<result property="creator" column="creator" />
|
||||
<result property="createTime" column="create_time" />
|
||||
<result property="updater" column="updater" />
|
||||
<result property="updateTime" column="update_time" />
|
||||
<result property="delFlag" column="del_flag" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectBusiInquiryItemVo">
|
||||
select id, company_name, name, tel, title, content, email, ip, national, oceania, page_url, tenant_id, creator, create_time, updater, update_time, del_flag from dl_busi_inquiry_item
|
||||
</sql>
|
||||
|
||||
<select id="queryListPage" parameterType="BusiInquiryItem" resultMap="BusiInquiryItemResult">
|
||||
<include refid="selectBusiInquiryItemVo"/>
|
||||
<where>
|
||||
<if test="entity.companyName != null and entity.companyName != ''"> and company_name like concat('%', #{entity.companyName}, '%')</if>
|
||||
<if test="entity.name != null and entity.name != ''"> and name like concat('%', #{entity.name}, '%')</if>
|
||||
<if test="entity.tel != null and entity.tel != ''"> and tel = #{entity.tel}</if>
|
||||
<if test="entity.title != null and entity.title != ''"> and title = #{entity.title}</if>
|
||||
<if test="entity.content != null and entity.content != ''"> and content = #{entity.content}</if>
|
||||
<if test="entity.email != null and entity.email != ''"> and email = #{entity.email}</if>
|
||||
<if test="entity.ip != null and entity.ip != ''"> and ip = #{entity.ip}</if>
|
||||
<if test="entity.national != null and entity.national != ''"> and national = #{entity.national}</if>
|
||||
<if test="entity.oceania != null and entity.oceania != ''"> and oceania = #{entity.oceania}</if>
|
||||
<if test="entity.pageUrl != null and entity.pageUrl != ''"> and page_url = #{entity.pageUrl}</if>
|
||||
<if test="entity.tenantId != null and entity.tenantId != ''"> and tenant_id = #{entity.tenantId}</if>
|
||||
</where>
|
||||
</select>
|
||||
</mapper>
|
44
dl_vue/src/api/busi/inquiryItem.js
Normal file
44
dl_vue/src/api/busi/inquiryItem.js
Normal file
@ -0,0 +1,44 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询在线询盘记录列表
|
||||
export function listInquiryItem(query) {
|
||||
return request({
|
||||
url: '/busi/inquiryItem/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询在线询盘记录详细
|
||||
export function getInquiryItem(id) {
|
||||
return request({
|
||||
url: '/busi/inquiryItem/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增在线询盘记录
|
||||
export function addInquiryItem(data) {
|
||||
return request({
|
||||
url: '/busi/inquiryItem',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改在线询盘记录
|
||||
export function updateInquiryItem(data) {
|
||||
return request({
|
||||
url: '/busi/inquiryItem',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除在线询盘记录
|
||||
export function delInquiryItem(id) {
|
||||
return request({
|
||||
url: '/busi/inquiryItem/' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
@ -8,6 +8,33 @@
|
||||
<el-divider></el-divider>
|
||||
<!-- 添加或修改在线询盘设置对话框 -->
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="200px">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item prop="name">
|
||||
<template v-slot:label>
|
||||
<span>姓名</span>
|
||||
<el-tooltip class="item" effect="dark" content="开启后代表客户可以填写姓名" placement="bottom">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-switch
|
||||
v-model="form.name"
|
||||
active-text="开启"
|
||||
inactive-text="关闭"
|
||||
></el-switch>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="标题是否必填">
|
||||
<el-switch
|
||||
v-model="form.nameMust"
|
||||
active-text="必填"
|
||||
inactive-text="非必填"
|
||||
>
|
||||
</el-switch>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item prop="company">
|
||||
@ -35,6 +62,33 @@
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item prop="company">
|
||||
<template v-slot:label>
|
||||
<span>Email</span>
|
||||
<el-tooltip class="item" effect="dark" content="开启后代表客户可以填写Email" placement="bottom">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-switch
|
||||
v-model="form.email"
|
||||
active-text="开启"
|
||||
inactive-text="关闭"
|
||||
></el-switch>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="Email是否必填">
|
||||
<el-switch
|
||||
v-model="form.emailMust"
|
||||
active-text="必填"
|
||||
inactive-text="非必填"
|
||||
>
|
||||
</el-switch>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item prop="tel">
|
||||
@ -89,33 +143,7 @@
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item prop="name">
|
||||
<template v-slot:label>
|
||||
<span>姓名</span>
|
||||
<el-tooltip class="item" effect="dark" content="开启后代表客户可以填写姓名" placement="bottom">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-switch
|
||||
v-model="form.name"
|
||||
active-text="开启"
|
||||
inactive-text="关闭"
|
||||
></el-switch>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="标题是否必填">
|
||||
<el-switch
|
||||
v-model="form.nameMust"
|
||||
active-text="必填"
|
||||
inactive-text="非必填"
|
||||
>
|
||||
</el-switch>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="提示文字" prop="content">
|
||||
@ -147,6 +175,8 @@ export default {
|
||||
id: null,
|
||||
company: null,
|
||||
companyMust: null,
|
||||
email: null,
|
||||
emailMust: null,
|
||||
tel: null,
|
||||
telMust: null,
|
||||
title: null,
|
||||
|
382
dl_vue/src/views/busi/inquiryItem/index.vue
Normal file
382
dl_vue/src/views/busi/inquiryItem/index.vue
Normal file
@ -0,0 +1,382 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
|
||||
<el-form-item label="公司名称" prop="companyName">
|
||||
<el-input
|
||||
v-model="queryParams.companyName"
|
||||
placeholder="请输入公司名称"
|
||||
clearable
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="姓名" prop="name">
|
||||
<el-input
|
||||
v-model="queryParams.name"
|
||||
placeholder="请输入姓名"
|
||||
clearable
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="电话" prop="tel">
|
||||
<el-input
|
||||
v-model="queryParams.tel"
|
||||
placeholder="请输入电话"
|
||||
clearable
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="标题" prop="title">
|
||||
<el-input
|
||||
v-model="queryParams.title"
|
||||
placeholder="请输入标题"
|
||||
clearable
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="电子邮件" prop="email">
|
||||
<el-input
|
||||
v-model="queryParams.email"
|
||||
placeholder="请输入电子邮件"
|
||||
clearable
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="来源IP" prop="ip">
|
||||
<el-input
|
||||
v-model="queryParams.ip"
|
||||
placeholder="请输入来源IP"
|
||||
clearable
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="来源国家" prop="national">
|
||||
<el-input
|
||||
v-model="queryParams.national"
|
||||
placeholder="请输入来源国家"
|
||||
clearable
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="洲" prop="oceania">
|
||||
<el-input
|
||||
v-model="queryParams.oceania"
|
||||
placeholder="请输入洲"
|
||||
clearable
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="页面路径" prop="pageUrl">
|
||||
<el-input
|
||||
v-model="queryParams.pageUrl"
|
||||
placeholder="请输入页面路径"
|
||||
clearable
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="站点唯一编码" prop="tenantId">
|
||||
<el-input
|
||||
v-model="queryParams.tenantId"
|
||||
placeholder="请输入站点唯一编码"
|
||||
clearable
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
icon="el-icon-plus"
|
||||
size="mini"
|
||||
@click="handleAdd"
|
||||
v-hasPermi="['busi:inquiryItem:add']"
|
||||
>新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
icon="el-icon-edit"
|
||||
size="mini"
|
||||
:disabled="single"
|
||||
@click="handleUpdate"
|
||||
v-hasPermi="['busi:inquiryItem:edit']"
|
||||
>修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="danger"
|
||||
plain
|
||||
icon="el-icon-delete"
|
||||
size="mini"
|
||||
:disabled="multiple"
|
||||
@click="handleDelete"
|
||||
v-hasPermi="['busi:inquiryItem:remove']"
|
||||
>删除</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="warning"
|
||||
plain
|
||||
icon="el-icon-download"
|
||||
size="mini"
|
||||
@click="handleExport"
|
||||
v-hasPermi="['busi:inquiryItem:export']"
|
||||
>导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
|
||||
<el-table v-loading="loading" :data="inquiryItemList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="主键" align="center" prop="id" />
|
||||
<el-table-column label="公司名称" align="center" prop="companyName" />
|
||||
<el-table-column label="姓名" align="center" prop="name" />
|
||||
<el-table-column label="电话" align="center" prop="tel" />
|
||||
<el-table-column label="标题" align="center" prop="title" />
|
||||
<el-table-column label="内容" align="center" prop="content" />
|
||||
<el-table-column label="电子邮件" align="center" prop="email" />
|
||||
<el-table-column label="来源IP" align="center" prop="ip" />
|
||||
<el-table-column label="来源国家" align="center" prop="national" />
|
||||
<el-table-column label="洲" align="center" prop="oceania" />
|
||||
<el-table-column label="页面路径" align="center" prop="pageUrl" />
|
||||
<el-table-column label="站点唯一编码" align="center" prop="tenantId" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
icon="el-icon-edit"
|
||||
@click="handleUpdate(scope.row)"
|
||||
v-hasPermi="['busi:inquiryItem:edit']"
|
||||
>修改</el-button>
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
icon="el-icon-delete"
|
||||
@click="handleDelete(scope.row)"
|
||||
v-hasPermi="['busi:inquiryItem:remove']"
|
||||
>删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination
|
||||
v-show="total>0"
|
||||
:total="total"
|
||||
:page.sync="queryParams.pageNum"
|
||||
:limit.sync="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
|
||||
<!-- 添加或修改在线询盘记录对话框 -->
|
||||
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
||||
<el-form-item label="公司名称" prop="companyName">
|
||||
<el-input v-model="form.companyName" placeholder="请输入公司名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="姓名" prop="name">
|
||||
<el-input v-model="form.name" placeholder="请输入姓名" />
|
||||
</el-form-item>
|
||||
<el-form-item label="电话" prop="tel">
|
||||
<el-input v-model="form.tel" placeholder="请输入电话" />
|
||||
</el-form-item>
|
||||
<el-form-item label="标题" prop="title">
|
||||
<el-input v-model="form.title" placeholder="请输入标题" />
|
||||
</el-form-item>
|
||||
<el-form-item label="内容" prop="content">
|
||||
<el-input v-model="form.content" type="textarea" placeholder="请输入内容" />
|
||||
</el-form-item>
|
||||
<el-form-item label="电子邮件" prop="email">
|
||||
<el-input v-model="form.email" placeholder="请输入电子邮件" />
|
||||
</el-form-item>
|
||||
<el-form-item label="来源IP" prop="ip">
|
||||
<el-input v-model="form.ip" placeholder="请输入来源IP" />
|
||||
</el-form-item>
|
||||
<el-form-item label="来源国家" prop="national">
|
||||
<el-input v-model="form.national" placeholder="请输入来源国家" />
|
||||
</el-form-item>
|
||||
<el-form-item label="洲" prop="oceania">
|
||||
<el-input v-model="form.oceania" placeholder="请输入洲" />
|
||||
</el-form-item>
|
||||
<el-form-item label="页面路径" prop="pageUrl">
|
||||
<el-input v-model="form.pageUrl" placeholder="请输入页面路径" />
|
||||
</el-form-item>
|
||||
<el-form-item label="站点唯一编码" prop="tenantId">
|
||||
<el-input v-model="form.tenantId" placeholder="请输入站点唯一编码" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listInquiryItem, getInquiryItem, delInquiryItem, addInquiryItem, updateInquiryItem } from "@/api/busi/inquiryItem";
|
||||
|
||||
export default {
|
||||
name: "InquiryItem",
|
||||
data() {
|
||||
return {
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
// 选中数组
|
||||
ids: [],
|
||||
// 非单个禁用
|
||||
single: true,
|
||||
// 非多个禁用
|
||||
multiple: true,
|
||||
// 显示搜索条件
|
||||
showSearch: true,
|
||||
// 总条数
|
||||
total: 0,
|
||||
// 在线询盘记录表格数据
|
||||
inquiryItemList: [],
|
||||
// 弹出层标题
|
||||
title: "",
|
||||
// 是否显示弹出层
|
||||
open: false,
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
companyName: null,
|
||||
name: null,
|
||||
tel: null,
|
||||
title: null,
|
||||
content: null,
|
||||
email: null,
|
||||
ip: null,
|
||||
national: null,
|
||||
oceania: null,
|
||||
pageUrl: null,
|
||||
tenantId: null,
|
||||
},
|
||||
// 表单参数
|
||||
form: {},
|
||||
// 表单校验
|
||||
rules: {
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
/** 查询在线询盘记录列表 */
|
||||
getList() {
|
||||
this.loading = true;
|
||||
listInquiryItem(this.queryParams).then(response => {
|
||||
this.inquiryItemList = response.data.records;
|
||||
this.total = response.data.total;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
// 取消按钮
|
||||
cancel() {
|
||||
this.open = false;
|
||||
this.reset();
|
||||
},
|
||||
// 表单重置
|
||||
reset() {
|
||||
this.form = {
|
||||
id: null,
|
||||
companyName: null,
|
||||
name: null,
|
||||
tel: null,
|
||||
title: null,
|
||||
content: null,
|
||||
email: null,
|
||||
ip: null,
|
||||
national: null,
|
||||
oceania: null,
|
||||
pageUrl: null,
|
||||
tenantId: null,
|
||||
creator: null,
|
||||
createTime: null,
|
||||
updater: null,
|
||||
updateTime: null,
|
||||
delFlag: null
|
||||
};
|
||||
this.resetForm("form");
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.queryParams.pageNum = 1;
|
||||
this.getList();
|
||||
},
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.resetForm("queryForm");
|
||||
this.handleQuery();
|
||||
},
|
||||
// 多选框选中数据
|
||||
handleSelectionChange(selection) {
|
||||
this.ids = selection.map(item => item.id)
|
||||
this.single = selection.length!==1
|
||||
this.multiple = !selection.length
|
||||
},
|
||||
/** 新增按钮操作 */
|
||||
handleAdd() {
|
||||
this.reset();
|
||||
this.open = true;
|
||||
this.title = "添加在线询盘记录";
|
||||
},
|
||||
/** 修改按钮操作 */
|
||||
handleUpdate(row) {
|
||||
this.reset();
|
||||
const id = row.id || this.ids
|
||||
getInquiryItem(id).then(response => {
|
||||
this.form = response.data;
|
||||
this.open = true;
|
||||
this.title = "修改在线询盘记录";
|
||||
});
|
||||
},
|
||||
/** 提交按钮 */
|
||||
submitForm() {
|
||||
this.$refs["form"].validate(valid => {
|
||||
if (valid) {
|
||||
if (this.form.id != null) {
|
||||
updateInquiryItem(this.form).then(response => {
|
||||
this.$modal.msgSuccess("修改成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
});
|
||||
} else {
|
||||
addInquiryItem(this.form).then(response => {
|
||||
this.$modal.msgSuccess("新增成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/** 删除按钮操作 */
|
||||
handleDelete(row) {
|
||||
const ids = row.id || this.ids;
|
||||
this.$modal.confirm('是否确认删除在线询盘记录编号为"' + ids + '"的数据项?').then(function() {
|
||||
return delInquiryItem(ids);
|
||||
}).then(() => {
|
||||
this.getList();
|
||||
this.$modal.msgSuccess("删除成功");
|
||||
}).catch(() => {});
|
||||
},
|
||||
/** 导出按钮操作 */
|
||||
handleExport() {
|
||||
this.download('busi/inquiryItem/export', {
|
||||
...this.queryParams
|
||||
}, `inquiryItem_${new Date().getTime()}.xlsx`)
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
Loading…
Reference in New Issue
Block a user