feat(project): 添加 POC 测试功能并优化项目信息相关逻辑- 在项目信息页面添加 POC 测试选项和相关记录

- 实现 POC 测试选项的动态显示和隐藏
- 添加 POC 记录的验证逻辑- 优化项目信息的查询和统计
- 调整项目高亮逻辑,使用最后一次工作更新时间
- 修复部分页面样式问题
master
chenhao 2025-06-17 11:20:24 +08:00
parent 8051d95ad4
commit 3ccb79a31d
12 changed files with 144 additions and 76 deletions

View File

@ -50,14 +50,14 @@
width:100px;
padding:0;
height: 30px;
background-color: #e74c3c;
background-color: #1c84c6;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color: #c0392b;
border-color: #1a7bb9;
}
.topBox{
display: flex;
@ -107,7 +107,7 @@
</div>
<div style="font-size: 20px;text-align: left;width: 70vw;margin: 10px 0">查询结果</div>
<div style="font-size: 16px;text-align: left;width: 70vw;font-weight: 600;"><blockquote style="border-left-color: #dd242a">产品信息</blockquote> </div>
<div style="font-size: 16px;text-align: left;width: 70vw;font-weight: 600;"><blockquote style="border-left-color: #1c84c6">产品信息</blockquote> </div>
<table class="tableBOx" id="tableBOx">
<thead>
<tr>
@ -123,7 +123,7 @@
</table>
<div >
<div style="margin: 20px 0;">
<span id="tab1" class="tabBtn" onclick="changeTab(0)" style="background: #dd242a;color: #fff">相关合同</span>
<span id="tab1" class="tabBtn" onclick="changeTab(0)" style="background:#1c84c6;color: #fff">相关合同</span>
<span id="tab2" class="tabBtn" onclick="changeTab(1)">标准保修</span>
</div>
<table class="tableBOx" id="tableBOx2">
@ -174,7 +174,7 @@
res.data.forEach((ele)=>{
str+=`<tr>
<td>${ele.serialNumber}</td>
<td>${ele.model}</td>
<td>${ele.productCode}</td>
<td>${ele.description}</td>
<td>${ele.productName}</td>
<td>CN</td>
@ -222,7 +222,7 @@
}
function changeTab(show) {
if(!show){
$('#tab1').css({'background': '#dd242a','color':'#fff'})
$('#tab1').css({'background': '#1c84c6','color':'#fff'})
$('#tab2').css({'background': '#fff','color':'#333'})
$('#tableBOx2').show()
@ -230,7 +230,7 @@
}else{
$('#tableBOx3').show()
$('#tableBOx2').hide()
$('#tab2').css({'background': '#dd242a','color':'#fff'})
$('#tab2').css({'background': '#1c84c6','color':'#fff'})
$('#tab1').css({'background': '#fff','color':'#333'})
}

View File

@ -223,10 +223,9 @@
></td>
<td>POC测试</td>
<td>
<select name="poc" class="form-control" value="0">
<option value="">请选择</option>
<option value="1"></option>
<select name="poc" id="poc" class="form-control" value="0" onchange="changePoc()">
<option value="0"></option>
<option value="1"></option>
</select>
</td>
</tr>
@ -279,7 +278,7 @@
<div class="layui-tab">
<ul class="layui-tab-title">
<li class="layui-this" lay-id="11">工作进度</li>
<li lay-id="22">POC测试</li>
<li lay-id="22" style="display: none" id="pocLogTab">POC测试</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
@ -351,8 +350,21 @@
displayInput.value = Number(rawValue).toLocaleString('en-US');
}
}
function changePoc() {
let val = $('#poc').val();
if (val==='0'){
$('#pocLogTab').attr('style','display:none')
}else{
$('#pocLogTab').attr('style','display:inline')
}
}
function submitHandler() {
let activeTabIndex=$('.layui-tab-title .layui-this').index();
if (activeTabIndex!==1 && $('#poc').val() ==='1' && validatePoc()){
$.modal.alertWarning("请完善POC记录信息");
return ;
}
if ($.validate.form()) {
$.operate.save(prefix + "/add", $('#form-product-add').serialize());
} else {

View File

@ -31,87 +31,87 @@
</style>
<body>
<div id="config-info-component" th:fragment="pocLog()">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<div id="poc-info-component" th:fragment="pocLog()">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<input name="projectPocInfo.id" type="hidden">
<table>
<tr>
<td class="shortTd" style=" text-align: right;">服务器配置<span class="is-required">*</span></td>
<td colspan="5"><input type="text"
<td colspan="5"><input type="text" required
name="projectPocInfo.serverConfig"
placeholder="服务器配置"
class="form-control"></td>
</tr>
<tr>
<td class="shortTd" style=" text-align: right;">云桌面版本<span class="is-required">*</span></td>
<td class="inputTd"><input type="text"
<td class="inputTd"><input type="text" required
name="projectPocInfo.vdiVersion"
placeholder="云桌面版本"
class="form-control"></td>
<td class="shortTd" style=" text-align: right;">配置终端<span class="is-required">*</span></td>
<td class="inputTd"><input type="text"
<td class="inputTd"><input type="text" required
name="projectPocInfo.terminalConfig"
placeholder="配置终端"
class="form-control"></td>
<td class="shortTd" style=" text-align: right;">操作系统<span class="is-required">*</span></td>
<td class="inputTd"><input type="text"
<td class="inputTd"><input type="text" required
name="projectPocInfo.operateSystem"
placeholder="操作系统"
class="form-control"></td>
</tr>
<tr>
<td class="shortTd" style=" text-align: right;">H3C接口人<span class="is-required">*</span></td>
<td colspan="2"><input type="text"
<td colspan="2"><input type="text" required
name="projectPocInfo.h3cPerson"
placeholder="H3C接口人"
class="form-control"></td>
<td class="shortTd" style=" text-align: right;">H3C TEL<span class="is-required">*</span></td>
<td colspan="2"><input type="text" name="projectPocInfo.h3cPhone"
placeholder="H3C TEL"
placeholder="H3C TEL" required
class="form-control"></td>
</tr>
<tr>
<td class="shortTd" style=" text-align: right;">汇智接口人<span class="is-required">*</span></td>
<td colspan="2"><input type="text"
<td colspan="2"><input type="text" required
name="projectPocInfo.hzInterfacePerson"
placeholder="汇智接口人"
class="form-control"></td>
<td class="shortTd" style=" text-align: right;">汇智 TEL<span class="is-required">*</span></td>
<td colspan="2"><input type="text"
<td colspan="2"><input type="text" required
name="projectPocInfo.hzInterfacePhone"
placeholder="汇智 TEL"
class="form-control"></td>
</tr>
<tr>
<td class="shortTd" style=" text-align: right;">研发接口人<span class="is-required">*</span></td>
<td colspan="2"><input name="projectPocInfo.processPerson" placeholder="研发接口人"
<td colspan="2"><input name="projectPocInfo.processPerson" placeholder="研发接口人" required
class="form-control" type="text">
<td class="shortTd" style=" text-align: right;">研发 TEL<span class="is-required">*</span></td>
<td colspan="2"><input name="projectPocInfo.processPhone" placeholder="研发 TEL"
<td colspan="2"><input name="projectPocInfo.processPhone" placeholder="研发 TEL" required
class="form-control" type="text"></td>
</tr>
<tr>
<td class="shortTd" style=" text-align: right;">现场接口人<span class="is-required">*</span></td>
<td colspan="2"><input name="projectPocInfo.handlePerson" placeholder="现场接口人"
<td colspan="2"><input name="projectPocInfo.handlePerson" placeholder="现场接口人" required
class="form-control" type="text">
<td class="shortTd" style=" text-align: right;">现场 TEL<span class="is-required">*</span></td>
<td colspan="2"><input name="projectPocInfo.handlePhone" placeholder="现场 TEL"
<td colspan="2"><input name="projectPocInfo.handlePhone" placeholder="现场 TEL" required
class="form-control" type="text"></td>
</tr>
<tr>
<td class="shortTd" style=" text-align: right;">启动时间<span class="is-required">*</span></td>
<td><input name="projectPocInfo.startDate"
<td><input name="projectPocInfo.startDate" required
autocomplete="off"
class="form-control" placeholder="yyyy-MM-dd" type="text">
</td>
<td class="shortTd" style=" text-align: right;">预计完成时间<span class="is-required">*</span></td>
<td><input name="projectPocInfo.planFinishTime"
<td><input name="projectPocInfo.planFinishTime" required
autocomplete="off"
class="form-control" placeholder="yyyy-MM-dd" type="text">
</td>
<td class="shortTd" style=" text-align: right;">实际完成时间<span class="is-required">*</span></td>
<td><input name="projectPocInfo.realFinishTime"
<td><input name="projectPocInfo.realFinishTime" required
autocomplete="off"
class="form-control" placeholder="yyyy-MM-dd" type="text">
</td>
@ -137,8 +137,8 @@
<!-- 可动态添加行 -->
</table>
</div>
</div>
<th:block th:include="include :: footer"/>
<th:block th:include="include :: datetimepicker-js"/>
@ -150,7 +150,7 @@
<tr>
<td style="text-align: center;">${length + 1}</td>
<td><input type="hidden" value="${data.id || ''}" name="projectPocInfo.projectPocInfoDetailList[${length}].id">
<input type="text" onclick="showDetailValue(this)" name="projectPocInfo.projectPocInfoDetailList[${length}].testProgress" class="form-control" required value="${data.testProgress || ''}"></input></td>
<input type="text" required onclick="showDetailValue(this)" name="projectPocInfo.projectPocInfoDetailList[${length}].testProgress" class="form-control" required value="${data.testProgress || ''}"></input></td>
<td><input type="text" class="form-control" placeholder="保存后自动填入" value="${data.createByName || ''}" readonly></td>
<td><input type="text" class="form-control" placeholder="保存后自动填入" value="${data.createTime||''}" readonly></td>
</tr>`)
@ -211,6 +211,19 @@
}
});
function validatePoc() {
let result = false;
const pocDiv = $('#poc-info-component')
pocDiv.find('input').each(function () {
if ($(this).attr('required')) {
if (!$(this).val().trim()) {
result = true;
return false
}
}
})
return result
}
/*]]>*/

View File

@ -242,10 +242,9 @@
th:value="${#dates.format(projectInfo.estimatedOrderTime, 'yyyy-MM-dd')}"></td>
<td>POC测试</td>
<td>
<select name="poc" class="form-control" th:field="*{poc}" disabled>
<option value="">根据POC记录变化</option>
<option value="1"></option>
<select name="poc" id="poc" class="form-control" th:field="*{poc}" onchange="changePoc()">
<option value="0"></option>
<option value="1"></option>
</select>
</td>
</tr>
@ -299,7 +298,7 @@
<ul class="layui-tab-title">
<li class="layui-this" lay-id="11">工作进度</li>
<li lay-id="33">POC记录</li>
<li lay-id="33" id="pocLogTab">POC记录</li>
<li lay-id="22">操作日志</li>
</ul>
<div class="layui-tab-content">
@ -403,7 +402,23 @@
displayInput.value = "";
}
}
function changePoc() {
let val = $('#poc').val();
console.log('----------------------------------')
console.log(val)
if (val==='0'){
$('#pocLogTab').attr('style','display:none')
}else{
$('#pocLogTab').attr('style','display:inline')
}
}
function submitHandler() {
let activeTabIndex=$('.layui-tab-title .layui-this').index();
if (activeTabIndex!==1 && $('#poc').val() ==='1' && validatePoc()){
$.modal.alertWarning("请完善POC记录信息");
return ;
}
if ($.validate.form()) {
$.operate.save(prefix + "/edit", $('#form-product-add').serialize());
} else {
@ -411,11 +426,17 @@
}
}
$(function () {
let amount = [[${projectInfo.estimatedAmount}]] || ''
if (amount) {
document.getElementById('displayEstimatedAmount').value=amount.toLocaleString('en-US');
}
let pocVal = [[${projectInfo.poc}]];
if (pocVal==='0'){
$('#pocLogTab').attr('style','display:none')
}
initProductList()
$("input[name='estimatedOrderTime']").datetimepicker({
format: "yyyy-mm-dd",
@ -573,19 +594,7 @@
}
function addLog(data) {
let length = $('#workLog tbody').find('tr').length
let tr = $(`
<tr>
<td style="text-align: center;">${length + 1}</td>
<td><input type="hidden" value="${data.id || ''}" name="projectWorkProgressList[${length}].id">
<input type="text" onclick="showDetailValue(this)" name="projectWorkProgressList[${length}].workContent" class="form-control" required value="${data.workContent || ''}"></input></td>
<td><input type="text" class="form-control" placeholder="保存后自动填入" value="${data.userName || ''}" readonly></td>
<td><input type="text" class="form-control" placeholder="保存后自动填入" value="${data.workTime || ''}" readonly></td>
</tr>`)
$('#workLog tbody').append(tr)
}
function showDetailValue(ele, canUpdate) {

View File

@ -291,7 +291,7 @@
width: 140
},
{
field: 'updateTime',
field: 'lastWorkUpdateTime',
title: '更新时间',
class: 'time3',
width: 160,
@ -380,7 +380,7 @@
function changeSort(ele, index) {
let arr = ['estimated_orderTime', 'estimated_deliverTime', 'update_time']
let arr = ['estimated_orderTime', 'estimated_deliverTime', 'last_work_update_time']
$('.sortBox').find('.timeAction').removeClass('timeAction')
$(ele).addClass('timeAction')
$('input[name="orderByColumn"]').val(arr[index])
@ -397,8 +397,10 @@
$('#laydate-startTime').attr('name', 'estimatedDeliverTimeStart')
$('#laydate-endTime').attr('name', 'estimatedDeliverTimeEnd')
} else if (timeType == 2) {
$('#laydate-startTime').attr('name', 'updateTimeStart')
$('#laydate-endTime').attr('name', 'updateTimeEnd')
// $('#laydate-startTime').attr('name', 'updateTimeStart')
// $('#laydate-endTime').attr('name', 'updateTimeEnd')
$('#laydate-startTime').attr('name', 'lastWorkUpdateTimeStart')
$('#laydate-endTime').attr('name', 'lastWorkUpdateTimeEnd')
}
}

View File

@ -108,6 +108,7 @@ public class ProjectInfo extends BaseEntity
private Date estimatedOrderTimeStart;
private Date estimatedOrderTimeEnd;
@Excel(name = "POC测试")
private String poc;
private String contactEmail;
@ -158,11 +159,13 @@ public class ProjectInfo extends BaseEntity
private Date estimatedDeliverTimeEnd;
private Date updateTimeStart;
private Date updateTimeEnd;
private Date updateTime;
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date updateTime;
private Date lastWorkUpdateTime;
private Date lastWorkUpdateTimeStart;
private Date lastWorkUpdateTimeEnd;

View File

@ -210,8 +210,8 @@ public class DeliveryListServiceImpl implements IDeliveryListService {
private void updateDeliveryInfoVo(DeliveryInfoVo deliveryInfoVo, Map<Long, List<ProductInfo>> maintenanceTypeMap, List<ProductInfo> productInfos) {
List<ProductInfo> productInfoList = maintenanceTypeMap.get(deliveryInfoVo.getOrderId());
List<DeliveryInfoVo.ServiceInfo> serviceInfoList = new ArrayList<>();
if (CollUtil.isNotEmpty(productInfoList)) {
Date startTime = deliveryInfoVo.getServiceStartTime();
if (CollUtil.isNotEmpty(productInfoList)) {
if (ProductInfo.ProductTypeEnum.SOFTWARE.getType().equals(deliveryInfoVo.getProductType())) {
for (ProductInfo productInfo : productInfoList) {
if (ProductInfo.ProductTypeEnum.SOFTWARE_MAINTENANCE.getType().equals(productInfo.getType()) && StringUtils.isNotEmpty(productInfo.getValue())) {
@ -228,6 +228,7 @@ public class DeliveryListServiceImpl implements IDeliveryListService {
}
}
}
}
if (CollUtil.isEmpty(serviceInfoList) && ProductInfo.ProductTypeEnum.HARDWARE.getType().equals(deliveryInfoVo.getProductType())
&& CollUtil.isNotEmpty(productInfos)) {
@ -238,7 +239,7 @@ public class DeliveryListServiceImpl implements IDeliveryListService {
}
deliveryInfoVo.setServiceInfo(serviceInfoList);
}
}
private static Date updateStartTimeAndAddList(DeliveryInfoVo deliveryInfoVo, ProductInfo productInfo, Date startTime, List<DeliveryInfoVo.ServiceInfo> serviceInfoList) {

View File

@ -349,7 +349,7 @@ public class OrderInfoServiceImpl implements IOrderInfoService
if (orderList.getDiscount() == null) {
throw new ServiceException("折扣不能为空");
}
if (orderList.getDiscount().compareTo(BigDecimal.ONE) > 0 || orderList.getDiscount().compareTo(BigDecimal.ZERO) <= 0) {
if (orderList.getDiscount().compareTo(BigDecimal.ONE) > 0 || orderList.getDiscount().compareTo(BigDecimal.ZERO) < 0) {
throw new ServiceException("折扣区间需在0-1之间");
}
if (orderList.getPrice() == null) {

View File

@ -18,6 +18,8 @@ import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.sip.domain.*;
import com.ruoyi.sip.dto.HomepageQueryDto;
import com.ruoyi.sip.dto.StatisticsDto;
import com.ruoyi.sip.mapper.ProjectInfoMapper;
import com.ruoyi.sip.service.*;
import lombok.extern.slf4j.Slf4j;
@ -129,10 +131,16 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
Map<Long, ProjectOrderInfo> orderInfoMap = projectOrderInfos.stream().collect(Collectors.toMap(ProjectOrderInfo::getProjectId, Function.identity(), (v1, v2) -> v1));
LocalDate now = LocalDate.now();
for (ProjectInfo info : projectInfos) {
LocalDate localDate = info.getUpdateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
info.setCanGenerate(orderInfoMap.get(info.getId()) == null);
if (info.getLastWorkUpdateTime() != null) {
LocalDate localDate = info.getLastWorkUpdateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
Period between = Period.between(localDate, now);
info.setHighlight(between.getMonths() >= 2);
info.setCanGenerate(orderInfoMap.get(info.getId()) == null);
} else {
info.setHighlight(false);
}
}
return projectInfos;
}
@ -153,9 +161,6 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
if (CollUtil.isNotEmpty(projectInfo.getCompetitorList())) {
projectInfo.setCompetitor(projectInfo.getCompetitorList().stream().filter(StringUtils::isNotEmpty).collect(Collectors.joining(",")));
}
if (projectInfo.getProjectPocInfo()!=null && CollUtil.isNotEmpty(projectInfo.getProjectPocInfo().getProjectPocInfoDetailList())){
projectInfo.setPoc("1");
}
int i = projectInfoMapper.insertProjectInfo(projectInfo);
saveOtherInfo(projectInfo);
return i;
@ -229,18 +234,9 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
//如果没有 变更编码 是否考虑高并发加锁
setProjectCode(projectInfo);
}
int newWorkSize = projectInfo.getProjectWorkProgressList() == null ? 0 : projectInfo.getProjectWorkProgressList().size();
int existWorkSize = oldProjectInfo.getProjectWorkProgressList() == null ? 0 : oldProjectInfo.getProjectWorkProgressList().size();
boolean changeWork = newWorkSize > existWorkSize;
// 更新项目信息
if (changeWork) {
projectInfo.setUpdateTime(DateUtils.getNowDate());
}
if (projectInfo.getProjectPocInfo()!=null && CollUtil.isNotEmpty(projectInfo.getProjectPocInfo().getProjectPocInfoDetailList())){
projectInfo.setPoc("1");
}
projectInfo.setUpdateBy(ShiroUtils.getUserId().toString());
int result = projectInfoMapper.updateProjectInfo(projectInfo);
//变更其它信息
saveOtherInfo(projectInfo);
@ -284,6 +280,7 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
formatterDate(projectInfo.getEstimatedOrderTime()));
// logIndex = compareField(logContent, logIndex, "预计发货时间", formatterDate(oldProjectInfo.getEstimatedDeliverTime()), formatterDate(projectInfo.getEstimatedDeliverTime()));
logIndex = compareField(logContent, logIndex, "竞争对手", oldProjectInfo.getCompetitor(), projectInfo.getCompetitor());
logIndex = compareField(logContent, logIndex, "poc记录", oldProjectInfo.getPoc(), projectInfo.getPoc());
logIndex = compareField(logContent, logIndex, "关键技术问题", oldProjectInfo.getKeyProblem(), projectInfo.getKeyProblem());
logIndex = compareField(logContent, logIndex, "项目简述", oldProjectInfo.getProjectDesc(), projectInfo.getProjectDesc());
if (logIndex > 1) {

View File

@ -327,7 +327,7 @@ public class ProjectOrderInfoServiceImpl implements IProjectOrderInfoService {
Sheet sheet = writeSheetHolder.getSheet();
// 基础列范围(前 25 列)
if (columnIndex >= 0 && columnIndex <= 25) {
if (columnIndex >= 0 && columnIndex <= 26) {
// 自适应列宽逻辑
sheet.setColumnWidth(columnIndex, 256 * 30); // 设置固定宽度为 20 个字符
}

View File

@ -1,5 +1,7 @@
package com.ruoyi.sip.service.impl;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Collections;
import java.util.List;
import java.util.Set;
@ -117,7 +119,18 @@ public class ProjectProductInfoServiceImpl implements IProjectProductInfoService
if (stringJoiner.length() > 0) {
throw new ServiceException(StringUtils.format("产品编码[{}]在产品库中未找到,请确认后重试", stringJoiner.toString()));
}
for (ProjectProductInfo info : list) {
//计算价格 防止前端价格计算错误
if (info.getGuidanceDiscount() != null && info.getDiscount() == null) {
info.setDiscount(info.getGuidanceDiscount());
}
if (info.getCataloguePrice() != null && info.getDiscount() != null) {
info.setPrice(info.getCataloguePrice().multiply(info.getDiscount()).setScale(2, RoundingMode.HALF_UP));
}
if (info.getPrice() != null && info.getQuantity() != null) {
info.setAllPrice(info.getPrice().multiply(new BigDecimal(info.getQuantity())).setScale(2, RoundingMode.HALF_UP));
}
}
List<ProjectProductInfo> projectProductInfos = projectProductInfoMapper.selectProjectProductInfoListByProjectId(Collections.singletonList(list.get(0).getProjectId()));
Set<Long> idSet = list.stream().map(ProjectProductInfo::getId).collect(Collectors.toSet());

View File

@ -70,10 +70,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
t1.update_time,
t1.customer_user_name,t1.customer_phone,t1.partner_email,t1.partner_user_name,t1.h3c_person,t1.poc,t1.h3c_phone,
t2.agent_name,t2.contact_email,t2.contact_phone,t2.contact_person,
t3.user_name as hz_support_user_name
t3.user_name as hz_support_user_name,
t4.work_time as last_work_update_time
from project_info t1
left join agent_info t2 on t1.agent_code = t2.agent_code
left join sys_user t3 on t1.hz_support_user=t3.user_id
left join (select max(work_time) work_time,project_id from project_work_progress group by project_id) t4 ON t1.id=t4.project_id
</sql>
<select id="selectProjectInfoList" parameterType="ProjectInfo" resultMap="ProjectInfoResult">
@ -144,6 +147,21 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</choose>
</if>
<if test="lastWorkUpdateTimeStart != null or lastWorkUpdateTimeEnd != null">
<choose>
<when test="lastWorkUpdateTimeStart != null and lastWorkUpdateTimeEnd != null">
and t4.work_time between date_format(#{lastWorkUpdateTimeStart}, '%Y-%m-%d 00:00:00') and date_format(#{lastWorkUpdateTimeEnd}, '%Y-%m-%d 23:59:59')
</when>
<when test="lastWorkUpdateTimeStart != null">
and t4.work_time <![CDATA[ >= ]]> date_format(#{lastWorkUpdateTimeStart}, '%Y-%m-%d 00:00:00')
</when>
<when test="lastWorkUpdateTimeEnd != null">
and t4.work_time <![CDATA[ <= ]]> date_format(#{lastWorkUpdateTimeEnd}, '%Y-%m-%d 23:59:59')
</when>
</choose>
</if>
<if test="competitor != null and competitor != ''"> and t1.competitor = #{competitor}</if>
<if test="countryProduct != null and countryProduct != ''"> and t1.country_product = #{countryProduct}</if>