feat(sip): 优化代理商编码生成逻辑

- 添加生成代理商编码的方法 generateCode
- 在插入和更新代理商信息时,根据所在省份自动生成编码
- 优化了编码的格式,使用 "AGT-" 前缀和四位顺序号
- 增加了对省份为空和未配置的情况的异常处理
dev_1.0.0
chenhao 2025-09-10 09:12:07 +08:00
parent 7cbf3dba95
commit 6a3b274856
41 changed files with 917 additions and 228 deletions

View File

@ -1,7 +1,11 @@
package com.ruoyi.web.controller.system; package com.ruoyi.web.controller.system;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import cn.hutool.core.lang.Dict;
import com.ruoyi.common.utils.mail.TemplateMailUtil;
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ArrayUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -228,13 +232,19 @@ public class SysUserController extends BaseController
userService.checkUserAllowed(user); userService.checkUserAllowed(user);
userService.checkUserDataScope(user.getUserId()); userService.checkUserDataScope(user.getUserId());
user.setSalt(ShiroUtils.randomSalt()); user.setSalt(ShiroUtils.randomSalt());
user.setPassword(passwordService.encryptPassword(user.getLoginName(), user.getPassword(), user.getSalt())); String realPassword = user.getPassword();
user.setPassword(passwordService.encryptPassword(user.getLoginName(), realPassword, user.getSalt()));
if (userService.resetUserPwd(user) > 0) if (userService.resetUserPwd(user) > 0)
{ {
SysUser dbUser = userService.selectUserById(user.getUserId());
if (dbUser!=null && StringUtils.isNotEmpty(dbUser.getEmail())){
TemplateMailUtil.sendTemplateMail(Collections.singletonList(dbUser.getEmail()),"密码重置", TemplateMailUtil.MailTemplate.PASSWORD_RESET, Dict.of("password", realPassword));
}
if (ShiroUtils.getUserId().longValue() == user.getUserId().longValue()) if (ShiroUtils.getUserId().longValue() == user.getUserId().longValue())
{ {
setSysUser(userService.selectUserById(user.getUserId())); setSysUser(dbUser);
} }
return success(); return success();
} }
return error(); return error();

View File

@ -21,6 +21,14 @@ $(document).ready(function(){
var tel = /^(0\d{2,3}-)?\d{7,8}$/g;//区号3,4位,号码7,8位 var tel = /^(0\d{2,3}-)?\d{7,8}$/g;//区号3,4位,号码7,8位
return this.optional(element) || (tel.test(value)); return this.optional(element) || (tel.test(value));
},"请填写正确的座机号码"); },"请填写正确的座机号码");
// 手机号码验证身份证正则合并:(^\d{15}$)|(^\d{17}([0-9]|X)$)
jQuery.validator.addMethod("isTelNumber",function(value,element) {
debugger
var length = value.length;
const phone = /^1[3-9]\d{9}$/;
const tel = /^(0\d{2,3}-)?\d{7,8}$/g;//区号3,4位,号码7,8位
return this.optional(element)||(length === 11 && phone.test(value)) || (tel.test(value));
},"请填写正确的手机号或座机号");
// 姓名校验 // 姓名校验
jQuery.validator.addMethod("isName",function(value,element) { jQuery.validator.addMethod("isName",function(value,element) {
var name = /^[\u4e00-\u9fa5]{2,6}$/; var name = /^[\u4e00-\u9fa5]{2,6}$/;

View File

@ -24,7 +24,24 @@
</li> </li>
<li> <li>
<label>制造商:</label> <label>制造商:</label>
<input type="text" name="vendorName"/> <select name="vendorCode" class="form-control" th:with="type=${vendorList}">
<option value="">请选择</option>
<option th:each="dict : ${type}" th:text="${dict.vendorName}"
th:value="${dict.vendorCode}"></option>
</select>
</li>
</li>
<li>
<label>仓库:</label>
<select name="warehouseId" class="form-control" th:with="type=${warehouseList}">
<option value="">请选择</option>
<option th:each="dict : ${type}" th:text="${dict.warehouseName}"
th:value="${dict.id}"></option>
</select>
</li> </li>
<li> <li>
<a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i class="fa fa-search"></i>&nbsp;搜索</a> <a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i class="fa fa-search"></i>&nbsp;搜索</a>
@ -93,11 +110,18 @@
field: 'productName', field: 'productName',
title: '产品名称' title: '产品名称'
}, },
{
field: 'warehouseName',
title: '仓库',
},
{ {
field: 'availableCount', field: 'availableCount',
title: '实时库存', title: '实时库存',
formatter: function (value, row, index) { formatter: function (value, row, index) {
let showValue = value ?? 0; let showValue = value ?? 0;
if (showValue >= 0 && (row.inventoryCount ?? 0) > 0) {
showValue = row.inventoryCount
}
let showHtml='' let showHtml=''
if (value>200){ if (value>200){
showHtml= `<span style="color: #1ab394">${showValue}</span>` showHtml= `<span style="color: #1ab394">${showValue}</span>`
@ -125,8 +149,8 @@
align: 'center', align: 'center',
formatter: function(value, row, index) { formatter: function(value, row, index) {
var actions = []; var actions = [];
actions.push('<a class="btn btn-success btn-xs " href="javascript:void(0)" onclick="showInnerLog(\''+row.productCode+'\')"><i class="fa fa-edit"></i>入库记录</a> '); actions.push('<a class="btn btn-success btn-xs " href="javascript:void(0)" onclick="showInnerLog(\'' + row.productCode + '\',\'' + row.warehouseId + '\')"><i class="fa fa-edit"></i>入库记录</a> ');
actions.push(`<a class="btn btn-default btn-xs " href="javascript:void(0)" onclick="showOuterLog('${row.productCode}')"><i class="fa fa-edit"></i>出库记录</a>`); actions.push(`<a class="btn btn-default btn-xs " href="javascript:void(0)" onclick="showOuterLog('${row.productCode}','${row.warehouseId}')"><i class="fa fa-edit"></i>出库记录</a>`);
return actions.join(''); return actions.join('');
} }
}] }]
@ -134,12 +158,19 @@
$.table.init(options); $.table.init(options);
}); });
function showInnerLog(productCode){ function showInnerLog(productCode, warehouseId) {
var url = prefix + "/innerLog/" + productCode; if (!warehouseId) {
$.modal.errorMsg("仓库不能为空");
}
var url = prefix + "/innerLog/" + productCode + "/" + warehouseId;
$.modal.openFull("入库记录表", url); $.modal.openFull("入库记录表", url);
} }
function showOuterLog(productCode){
var url = prefix + "/outerLog/" + productCode; function showOuterLog(productCode, warehouseId) {
if (!warehouseId) {
$.modal.errorMsg("仓库不能为空");
}
var url = prefix + "/outerLog/" + productCode + "/" + warehouseId;
$.modal.openFull("入库记录表", url); $.modal.openFull("入库记录表", url);
} }
</script> </script>

View File

@ -9,6 +9,7 @@
<form id="formId"> <form id="formId">
<div class="select-list"> <div class="select-list">
<input type="hidden" name="productCode" th:value="${productCode}"/> <input type="hidden" name="productCode" th:value="${productCode}"/>
<input type="hidden" name="warehouseId" th:value="${warehouseId}"/>
</div> </div>
</form> </form>
</div> </div>

View File

@ -9,6 +9,7 @@
<form id="formId"> <form id="formId">
<div class="select-list"> <div class="select-list">
<input type="hidden" name="productCode" th:value="${productCode}"/> <input type="hidden" name="productCode" th:value="${productCode}"/>
<input type="hidden" name="warehouseId" th:value="${warehouseId}"/>
</div> </div>
</form> </form>
</div> </div>

View File

@ -180,7 +180,7 @@
<div class="form-group"> <div class="form-group">
<label class="col-sm-4 control-label is-required">该批次起始SN码</label> <label class="col-sm-4 control-label is-required">该批次起始SN码</label>
<div class="col-sm-8"> <div class="col-sm-8">
<input id="productSn" name="productSn" onchange="calcSn()" class="form-control" type="text" required> <input id="productSn" name="productSn" onchange="calcSn()" oninput="validateProductSn(this)" placeholder="只能输入数字和字母" class="form-control" type="text" required>
</div> </div>
</div> </div>
@ -213,6 +213,11 @@
} }
}) })
} }
// 限制productSn只能输入数字和字母
function validateProductSn(input) {
// 只允许数字和字母
input.value = input.value.replace(/[^a-zA-Z0-9]/g, '');
}
function clearAddInventory(){ function clearAddInventory(){
$('#productCodeQuery').val('') $('#productCodeQuery').val('')
$('#addInventory input[type="text"]').each(function() { $('#addInventory input[type="text"]').each(function() {
@ -451,7 +456,7 @@
align: 'center', align: 'center',
formatter: function (value, row, index) { formatter: function (value, row, index) {
var actions = []; var actions = [];
actions.push('<a class="btn btn-danger btn-xs " href="javascript:void(0)" onclick="removeRow(' + row.productSn + ')"><i class="fa fa-remove"></i>删除</a>'); actions.push('<a class="btn btn-danger btn-xs " href="javascript:void(0)" onclick="removeRow(\'' + row.productSn + '\')"><i class="fa fa-remove"></i>删除</a>');
return actions.join(''); return actions.join('');
} }
}] }]

View File

@ -686,9 +686,12 @@
} }
function updateStatus(id, outerCode, orderCode,productCode) { function updateStatus(id, outerCode, orderCode,productCode) {
$.modal.confirm("请确认sn码的准确性,当日24点后无法更改", function () {
$.operate.post(deliveryPrefix + '/status', {id: id, outerCode: outerCode, orderCode: orderCode,productCode:productCode}, res => { $.operate.post(deliveryPrefix + '/status', {id: id, outerCode: outerCode, orderCode: orderCode,productCode:productCode}, res => {
refreshTable(); refreshTable();
}) })
})
} }

View File

@ -313,7 +313,7 @@
<td class="product-bom-code-column"> <input type="hidden" name="${submitName}[${length}].id" value="${data.id || ''}"><input class="form-control productBomCode" type="text" onclick="selectProduct('${queryParam}','${title}',this)" value="${data.productBomCode || ''}" name="${submitName}[${length}].productBomCode"></td> <td class="product-bom-code-column"> <input type="hidden" name="${submitName}[${length}].id" value="${data.id || ''}"><input class="form-control productBomCode" type="text" onclick="selectProduct('${queryParam}','${title}',this)" value="${data.productBomCode || ''}" name="${submitName}[${length}].productBomCode"></td>
<td class="model-column"><input readonly class="form-control model" type="text" onclick="selectProduct('${queryParam}','${title}',this)" value="${data.model || ''}" name="${submitName}[${length}].model"></td> <td class="model-column"><input readonly class="form-control model" type="text" onclick="selectProduct('${queryParam}','${title}',this)" value="${data.model || ''}" name="${submitName}[${length}].model"></td>
<td class="product-desc-column"><textarea name="${submitName}[${length}].productDesc" required class="form-control productDesc" placeholder="自动带入" readonly>${data.productDesc || ''}</textarea></td> <td class="product-desc-column"><textarea name="${submitName}[${length}].productDesc" required class="form-control productDesc" placeholder="自动带入" readonly>${data.productDesc || ''}</textarea></td>
<td class="quantity-column"><input value="${data.quantity || ''}" name="${submitName}[${length}].quantity" type="number" class="form-control quantity" step="${quantityStepFlag ? 0.1 : 1}" required></td> <td class="quantity-column"><input value="${data.quantity || ''}" name="${submitName}[${length}].quantity" type="number" min="0" class="form-control quantity" step="${quantityStepFlag ? 0.1 : 1}" required></td>
<td class="catalogue-price-column"><input value="${data.cataloguePrice || ''}" name="${submitName}[${length}].cataloguePrice" readonly type="hidden" class="form-control cataloguePrice" required> <td class="catalogue-price-column"><input value="${data.cataloguePrice || ''}" name="${submitName}[${length}].cataloguePrice" readonly type="hidden" class="form-control cataloguePrice" required>
<input value="${data.cataloguePriceFormmat || ''}" ${flag?"readonly":''} onfocus="getData(this,'cataloguePrice')" onblur="this.value=formatAmountNumber(this.value)" type="text" class="form-control catalogue-price-format" required> <input value="${data.cataloguePriceFormmat || ''}" ${flag?"readonly":''} onfocus="getData(this,'cataloguePrice')" onblur="this.value=formatAmountNumber(this.value)" type="text" class="form-control catalogue-price-format" required>
</td> </td>

View File

@ -173,7 +173,7 @@
<td><input type="text" name="businessEmail" <td><input type="text" name="businessEmail"
class="form-control"></td> class="form-control"></td>
<td>联系方式<span class="is-required">*</span></td> <td>联系方式<span class="is-required">*</span></td>
<td><input name="businessPhone" class="form-control" type="text" required></td> <td><input id="businessPhone" name="businessPhone" class="form-control" type="text" required></td>
</tr> </tr>
<tr> <tr>
@ -252,7 +252,7 @@
<td><input type="text" name="dutyEmail" <td><input type="text" name="dutyEmail"
class="form-control"></td> class="form-control"></td>
<td>联系方式<span class="is-required">*</span></td> <td>联系方式<span class="is-required">*</span></td>
<td><input name="dutyPhone" class="form-control" type="text" required></td> <td><input id="dutyPhone" name="dutyPhone" class="form-control" type="text" required></td>
</tr> </tr>
<tr> <tr>
@ -280,9 +280,25 @@
<td><input type="text" name="partnerEmail" <td><input type="text" name="partnerEmail"
class="form-control"></td> class="form-control"></td>
<td>联系方式<span class="is-required">*</span></td> <td>联系方式<span class="is-required">*</span></td>
<td><input name="partnerPhone" class="form-control" type="text" required></td> <td><input id="partnerPhone" name="partnerPhone" class="form-control" type="text" required></td>
</tr> </tr>
<tr>
<td>收货地址<span class="is-required">*</span></td>
<td colspan="5">
<input name="notifierAddress" required class="form-control" type="text" >
</td>
</tr>
<tr>
<td>收货人</td>
<td><input name="notifier" class="form-control" type="text" ></td>
<td>Email</td>
<td><input type="text" name="notifierEmail"
class="form-control"></td>
<td>联系方式<span class="is-required">*</span></td>
<td><input id="notifierPhone" name="notifierPhone" class="form-control" type="text" required >
</td>
</tr>
<tr>
<tr> <tr>
<td>其他特别说明</td> <td>其他特别说明</td>
<td colspan="5"> <td colspan="5">
@ -346,7 +362,21 @@
<script th:inline="javascript"> <script th:inline="javascript">
var prefix = ctx + "project/order" var prefix = ctx + "project/order"
$("#form-order-add").validate({ $("#form-order-add").validate({
focusCleanup: true focusCleanup: true,
rules: {
businessPhone:{
isTelNumber:true
},
dutyPhone:{
isTelNumber:true
},
partnerPhone:{
isTelNumber:true
},
notifierPhone:{
isTelNumber:true
},
}
}); });
var softwareProjectProductInfoList = [] var softwareProjectProductInfoList = []
var hardwareProjectProductInfoList = [] var hardwareProjectProductInfoList = []

View File

@ -200,7 +200,7 @@
<td><input type="text" name="businessEmail" th:field="*{businessEmail}" <td><input type="text" name="businessEmail" th:field="*{businessEmail}"
class="form-control"></td> class="form-control"></td>
<td>联系方式<span class="is-required">*</span></td> <td>联系方式<span class="is-required">*</span></td>
<td><input name="businessPhone" class="form-control" th:field="*{businessPhone}" type="text" required> <td><input id="businessPhone" name="businessPhone" class="form-control" th:field="*{businessPhone}" type="text" required>
</td> </td>
</tr> </tr>
@ -303,7 +303,7 @@
<td><input type="text" name="dutyEmail" th:field="*{dutyEmail}" <td><input type="text" name="dutyEmail" th:field="*{dutyEmail}"
class="form-control"></td> class="form-control"></td>
<td>联系方式<span class="is-required">*</span></td> <td>联系方式<span class="is-required">*</span></td>
<td><input name="dutyPhone" class="form-control" th:field="*{dutyPhone}" type="text" required></td> <td><input id="dutyPhone" name="dutyPhone" class="form-control" th:field="*{dutyPhone}" type="text" required></td>
</tr> </tr>
<tr> <tr>
@ -330,7 +330,7 @@
<td><input type="text" name="partnerEmail" th:field="*{partnerEmail}" <td><input type="text" name="partnerEmail" th:field="*{partnerEmail}"
class="form-control"></td> class="form-control"></td>
<td>联系方式<span class="is-required">*</span></td> <td>联系方式<span class="is-required">*</span></td>
<td><input name="partnerPhone" class="form-control" type="text" required th:field="*{partnerPhone}"> <td><input id="partnerPhone" name="partnerPhone" class="form-control" type="text" required th:field="*{partnerPhone}">
</td> </td>
</tr> </tr>
<tr> <tr>
@ -346,7 +346,7 @@
<td><input type="text" name="notifierEmail" th:field="*{notifierEmail}" <td><input type="text" name="notifierEmail" th:field="*{notifierEmail}"
class="form-control"></td> class="form-control"></td>
<td>联系方式<span class="is-required">*</span></td> <td>联系方式<span class="is-required">*</span></td>
<td><input name="notifierPhone" class="form-control" type="text" required th:field="*{notifierPhone}"> <td><input id="notifierPhone" name="notifierPhone" class="form-control" type="text" required th:field="*{notifierPhone}">
</td> </td>
</tr> </tr>
<tr> <tr>
@ -566,7 +566,21 @@
const canUpdate = [[${canUpdate}]] const canUpdate = [[${canUpdate}]]
const viewFlag = [[${view}]] const viewFlag = [[${view}]]
$("#form-order-edit").validate({ $("#form-order-edit").validate({
focusCleanup: true focusCleanup: true,
rules: {
businessPhone:{
isTelNumber:true
},
dutyPhone:{
isTelNumber:true
},
partnerPhone:{
isTelNumber:true
},
notifierPhone:{
isTelNumber:true
},
}
}); });
const file_log_arr = ["(请上传合同信息).pdf/.jpg/.png", "(请上传商务折扣审批邮件信息).pdf/.jpg/.png", "(请上传现金折扣审批邮件信息).pdf/.jpg/.png", "(补充附件).zip/.rar/.jpg/.png"] const file_log_arr = ["(请上传合同信息).pdf/.jpg/.png", "(请上传商务折扣审批邮件信息).pdf/.jpg/.png", "(请上传现金折扣审批邮件信息).pdf/.jpg/.png", "(补充附件).zip/.rar/.jpg/.png"]
var softwareProjectProductInfoList = [] var softwareProjectProductInfoList = []
@ -600,12 +614,12 @@
}); });
} }
function initCommitSelect(){ function initCommitSelect(data){
$('#element').cxSelect({ $('#element').cxSelect({
required:true, required:true,
selects: ['type', 'router'], selects: ['type', 'router'],
jsonValue: 'v', jsonValue: 'v',
data: [ data: data??[
{ {
n: '直签合同', n: '直签合同',
v: '0', v: '0',
@ -619,14 +633,6 @@
}] }]
}, },
{
n: '总代合同',
v: '1',
s:[{
n: '电子订单',
v: '0'
}]
},
{ {
n: '定制开发合同', n: '定制开发合同',
v: '2', v: '2',
@ -678,15 +684,21 @@
} }
function changeSaveType(name,val) { function changeSaveType(name,val) {
console.log(name,val)
$('[name="'+name+'"]').val(val) $('[name="'+name+'"]').val(val)
} }
function saveSelect() { function saveSelect() {
// let value = [[${projectOrderInfo.processType }]] || 0 var value = $('#orderChannel').val()
// let value2 = [[${projectOrderInfo.processTemplate}]] ||0
// changeSaveType('processType',value) initCommitSelect( value==='1'?[{
// changeSaveType('processTemplate',value2) n: '总代合同',
v: '1',
s:[{
n: '电子订单',
v: '0'
}]
}]:undefined)
var options = { var options = {
title: "确认并提交订单", title: "确认并提交订单",
maxmin: false, maxmin: false,

View File

@ -184,6 +184,10 @@
function viewDetail(id){ function viewDetail(id){
$.modal.openFull("订单详情", ctx + "project/order/view/"+id) $.modal.openFull("订单详情", ctx + "project/order/view/"+id)
} }
function viewApproveLog(id) {
$.modal.open("订单详情", ctx + "project/order/approveLog/" + id)
}
function viewProjectDetail(id){ function viewProjectDetail(id){
$.modal.openFull("项目详情", ctx + "sip/project/view/"+id) $.modal.openFull("项目详情", ctx + "sip/project/view/"+id)
} }
@ -300,9 +304,14 @@
width:200, width:200,
formatter: function(value, row, index) { formatter: function(value, row, index) {
var actions = []; var actions = [];
if (row.showLog) {
actions.push('<a class="btn btn-success btn-xs " href="javascript:void(0)" onclick="viewApproveLog(\'' + row.id + '\')"><i class="fa fa-edit"></i>审批历史</a> ');
} else {
actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.editFull(\'' + row.id + '\')"><i class="fa fa-edit"></i>编辑</a> '); actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.editFull(\'' + row.id + '\')"><i class="fa fa-edit"></i>编辑</a> ');
// actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="viewDetail(\'' + row.id + '\')"><i class="fa fa-edit"></i>详情</a> '); // actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="viewDetail(\'' + row.id + '\')"><i class="fa fa-edit"></i>详情</a> ');
actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="$.operate.remove(\'' + row.id + '\')"><i class="fa fa-remove"></i>删除</a>'); actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="$.operate.remove(\'' + row.id + '\')"><i class="fa fa-remove"></i>删除</a>');
}
return actions.join(''); return actions.join('');
} }
}] }]

View File

@ -0,0 +1,81 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<th:block th:include="include :: header('选择项目')"/>
</head>
<style>
.select-list li {
display: inline-block;
}
.select-list li label {
width: 88px !important;
}
</style>
<body class="gray-bg">
<div class="container-div">
<div class="row">
<div class="layui-tab-item">
<ul class="nav nav-tabs">
<li th:each="entry : ${projectOrderInfo.contractTableData.entrySet()}"
th:class="${entry.key == projectOrderInfo.versionCode ? 'active' : ''}">
<a data-toggle="tab" th:href="'#tab-approve-'+${entry.key}" aria-expanded="true">
版本号Rev.[[${entry.key}]]</a>
</li>
</ul>
<div class="tab-content">
<div th:each="entry : ${projectOrderInfo.contractTableData.entrySet()}"
th:id="'tab-approve-'+${entry.key}"
th:class="'tab-pane '+${entry.key == projectOrderInfo.versionCode ? 'active current-version' : ''}">
<div id="vertical-timeline" class="vertical-container light-timeline">
<div class="vertical-timeline-block" th:each="log : ${approveLog}"
th:if="${log.extendField1==entry.key}">
<div class="vertical-timeline-icon blue-bg">
<i class="fa fa-file-text"></i>
</div>
<div>
<div class="vertical-timeline-content">
<div class="col-lg-2 col-md-2 col-sm-2" style="max-width: 300px;min-width: 100px">
<h2 class="padding-top-20">[[${log.approveUserName}]]</h2>
<p>[[${log.roleName}]]</p>
</div>
<div style="margin-left: 50px">
<h2 class="padding-top-20">[[${log.approveOpinion}]]</h2>
<!-- <p>审批意见:[[${log.approveOpinion}]]</p>-->
<p > 接收人:[[${log.taskName == '公司领导'?log.applyUserName:
log.nextAllApproveUserName} ]]</p>
<span class="vertical-date">
<p> <small>[[${#dates.format(log.approveTime,'yyyy-MM-dd HH:mm:ss')}]]</small> <span
style="margin-left: 20px">[ [[${log.roleName}]] / [[${log.approveStatus==3?'批准':log.approveStatus==2?'驳回':'提交审批'}]]]</span></p>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<th:block th:include="include :: footer"/>
<script th:inline="javascript">
var prefix = ctx + "sip/project";
$(function () {
});
</script>
</body>
</html>

View File

@ -42,14 +42,23 @@
</select> </select>
</li> </li>
<li> <li>
<label>所属行业</label> <label>BG</label>
<select name="industryType" class="form-control" <select name="bgProperty" class="form-control" th:with="type=${@dict.getType('bg_type')}"
th:with="type=${@dict.getType('industry_code')}" required> onchange="changeBg()" required>
<option value="">所有</option> <option value="">请选择BG</option>
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" <option th:each="dict : ${type}" th:text="${dict.dictLabel}"
th:value="${dict.dictValue}"></option> th:value="${dict.dictValue}"></option>
</select> </select>
</li> </li>
<li>
<label>行业:</label>
<div id="industryTypeBox" style="float: right">
<select name="industryType" class="form-control" required>
<option value="">请先选择BG</option>
</select>
</div>
</li>
<li> <li>
<a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i <a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i
class="fa fa-search"></i>&nbsp;搜索</a> class="fa fa-search"></i>&nbsp;搜索</a>
@ -87,7 +96,34 @@
var editFlag = [[${@permission.hasPermi('system:customer:edit')}]]; var editFlag = [[${@permission.hasPermi('system:customer:edit')}]];
var removeFlag = [[${@permission.hasPermi('system:customer:remove')}]]; var removeFlag = [[${@permission.hasPermi('system:customer:remove')}]];
var prefix = ctx + "system/customer"; var prefix = ctx + "system/customer";
function changeBg() {
if ($('[name="bgProperty"]').val() != 'YYS') {
let datas = [[${@dict.getType('bg_hysy')}]]
let str = ``
datas.forEach((ele) => {
str += `<option value="${ele.dictValue}">${ele.dictLabel}</option> `
})
$('#industryTypeBox').html(`
<select name="industryType" class="form-control" required>
<option value="">请选择行业</option>
${str}
</select>
`)
} else {
let datas = [[${@dict.getType('bg_yys')}]]
let str = ``
datas.forEach((ele) => {
str += `<option value="${ele.dictValue}">${ele.dictLabel}</option> `
})
$('#industryTypeBox').html(`
<select name="industryType" class="form-control" required>
<option value="">请选择行业</option>
${str}
</select>
`)
}
}
$(function () { $(function () {
var options = { var options = {
url: prefix + "/list", url: prefix + "/list",

View File

@ -12,9 +12,9 @@
<form class="form-horizontal m" id="form-partner-add"> <form class="form-horizontal m" id="form-partner-add">
<div class="col-xs-6"> <div class="col-xs-6">
<div class="form-group"> <div class="form-group">
<label class="col-sm-4 control-label is-required">代理商编码:</label> <label class="col-sm-4 control-label">代理商编码:</label>
<div class="col-sm-8"> <div class="col-sm-8">
<input name="partnerCode" class="form-control" type="text" required> <input name="partnerCode" readonly placeholder="编码自动生成" class="form-control" type="text" >
</div> </div>
</div> </div>
</div> </div>
@ -140,9 +140,23 @@
$.modal.alertWarning("请选择一个用户"); $.modal.alertWarning("请选择一个用户");
return; return;
} }
let $name = $('[name="contactEmail"]');
if (!$name.val()) {
$name.val(rows[0].email);
}
$('[name="systemUserId"]').val(rows[0].userId); $('[name="systemUserId"]').val(rows[0].userId);
$('[name="systemUserName"]').val(rows[0].userName); $('[name="systemUserName"]').val(rows[0].userName);
let $contactPerson = $('[name="contactPerson"]');
if (!$contactPerson.val()) {
$contactPerson.val(rows[0].userName);
}
let $contactPhone = $('[name="contactPhone"]');
if (!$contactPhone.val()) {
$contactPhone.val(rows[0].phonenumber);
}
$.modal.close(index); $.modal.close(index);
} }
</script> </script>

View File

@ -11,7 +11,7 @@
<div class="form-group"> <div class="form-group">
<label class="col-sm-4 control-label is-required">代理商编码:</label> <label class="col-sm-4 control-label is-required">代理商编码:</label>
<div class="col-sm-8"> <div class="col-sm-8">
<input name="partnerCode" th:field="*{partnerCode}" class="form-control" type="text" required> <input name="partnerCode" th:field="*{partnerCode}" readonly class="form-control" type="text" required>
</div> </div>
</div> </div>
</div> </div>
@ -136,9 +136,23 @@
$.modal.alertWarning("请选择一个用户"); $.modal.alertWarning("请选择一个用户");
return; return;
} }
let $name = $('[name="contactEmail"]');
if (!$name.val()) {
$name.val(rows[0].email);
}
$('[name="systemUserId"]').val(rows[0].userId); $('[name="systemUserId"]').val(rows[0].userId);
$('[name="systemUserName"]').val(rows[0].userName); $('[name="systemUserName"]').val(rows[0].userName);
let $contactPerson = $('[name="contactPerson"]');
if (!$contactPerson.val()) {
$contactPerson.val(rows[0].userName);
}
let $contactPhone = $('[name="contactPhone"]');
if (!$contactPhone.val()) {
$contactPhone.val(rows[0].phonenumber);
}
$.modal.close(index); $.modal.close(index);
} }

View File

@ -28,6 +28,35 @@
</div> </div>
<th:block th:include="include :: footer" /> <th:block th:include="include :: footer" />
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function() {
// 生成6位包含数字和字母的密码
var defaultPassword = generateDefaultPassword(6);
$('#password').val(defaultPassword);
});
// 生成默认密码函数
function generateDefaultPassword(length) {
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
var password = "";
var hasDigit = false;
var hasLetter = false;
// 确保至少包含一个数字和一个字母
while (!hasDigit || !hasLetter) {
password = "";
hasDigit = false;
hasLetter = false;
for (var i = 0; i < length; i++) {
var char = chars.charAt(Math.floor(Math.random() * chars.length));
password += char;
if (/[0-9]/.test(char)) hasDigit = true;
if (/[a-zA-Z]/.test(char)) hasLetter = true;
}
}
return password;
}
$("#form-user-resetPwd").validate({ $("#form-user-resetPwd").validate({
rules:{ rules:{
password:{ password:{

View File

@ -0,0 +1,219 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<th:block th:include="include :: header('UNISSENSE云终端')" />
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 20px;
background-color: #f9f9f9;
}
.container {
/*width: 100%;*/
margin: 0;
padding: 10px 0;
background-color: white;
border-radius: 8px;
display: flex;
flex-direction: row;
gap: 30px;
justify-content: center;
}
h1 {
text-align: center;
color: #e74c3c;
}
.form-group {
margin-bottom: 15px;
display: flex;
flex-direction: row;
align-items: center;
}
.tableBOx{
width:70vw;
}
label {
margin-bottom: 0;
width: 80px;
font-weight: 600;
}
input[type="text"] {
width: 100%;
padding:5px 10px;
border: 1px solid #ccc;
border-radius: 4px;
}
button {
width:100px;
padding:0;
height: 30px;
background-color: #1c84c6;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
border-color: #1a7bb9;
}
.topBox{
display: flex;
flex-direction: row;
gap: 20px;
margin: 30px 0 10px;
align-items: center;
}
.topBox .title{
font-size: 24px;
font-weight: 600;
}
.table-striped {
display: flex;justify-content: flex-start;flex-direction: column;align-items: center
}
.table-striped thead{
background: #f5f5f5 !important;
}
.table-striped thead th{
padding: 10px;
}
.table-striped tbody td{
padding: 10px;
}
.tabBtn{
display: inline-block;
padding:8px 10px;
cursor: pointer;
width: 80px;
text-align: center;
}
.form-group label{
width: 100px;
}
@media (max-width: 768px) {
.tableBOx {
width: 100%;
}
.container,.topBox{
display: none;
}
.table-striped thead {
display: none; /* 隐藏表头 */
}
.table-striped tbody tr {
display: flex;
flex-direction: column;
border-bottom: 1px solid #ddd;
margin-bottom: 10px;
}
.table-striped tbody td {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px 10px;
border-bottom: 1px solid #eee;
}
/*.table-striped tbody tr td:first-child {*/
/* font-weight: bold;*/
/* min-width: 100px;*/
/* max-width: 120px;*/
/*}*/
/* 新增样式:为每个 td 添加伪元素来显示表头 */
.table-striped tbody tr td::before {
content: attr(data-th); /* 使用 data-th 属性来显示表头 */
font-weight: bold;
display: inline-block;
min-width: 100px;
max-width: 100px;
margin-right: 10px;
}
}
</style>
</head>
<body class="gray-bg">
<div class="col-sm-12 select-table table-striped" >
<div class="topBox">
<div class="title">UNISSENSE云终端 </div>
<!-- <div style="color: #dd242a">H3C产品保修条款</div>-->
</div>
<div class="container">
<!-- <div class="form-group">-->
<!-- <label for="partnerCode">代理商代码</label>-->
<!-- <input type="text" th:value="${code}" id="partnerCode" placeholder="请输入代理商代码">-->
<!-- </div>-->
<!-- <button type="button" onclick="getData()">查询</button>-->
</div>
<div style="font-size: 16px;text-align: left;width: 82vw;font-weight: 600;"><blockquote style="border-left-color: #1c84c6">UNISSENSE云终端售后联系方式</blockquote> </div>
<div style="width: 82svw;overflow-x: auto">
<table class="tableBOx" id="tableBOx">
<thead>
<tr>
<th style="min-width: 100px">制造商名称</th>
<th style="min-width: 100px">产品</th>
<th style="min-width: 100px">售后电话</th>
<th style="min-width: 100px">邮箱地址</th>
</tr>
</thead>
<tbody>
<tr>
<td data-th="制造商名称">紫光汇智信息技术有限公司</td>
<td data-th="产品">UNISSENSE云终端</td>
<td data-th="售后电话">193571916585*8小时</td>
<td data-th="邮箱地址">jiachenming@unisinsight.com</td>
</tr>
</tbody>
</table>
</div>
</div>
<th:block th:include="include :: footer" />
<script th:inline="javaScript">
var prefix = ctx + "system/partner";
$(function() {
// getData()
});
function getData() {
let partnerCode = $('#partnerCode').val()
$.operate.get(`/system/partner/list/query?partnerCode=${partnerCode}`, function (res) {
let str = `<tr><td colspan="8" style="text-align: center">暂无数据</td></tr>`
if (res.data.length) {
str = ``
res.data.forEach((ele) => {
str += `<tr>
<td data-th="代理商编码">${ele.partnerCode}</td>
<td data-th="代理商名称">${ele.partnerName}</td>
<td data-th="省">${ele.province}</td>
<td data-th="市">${ele.city}</td>
<td data-th="地址">${ele.address}</td>
<td data-th="联系人">${ele.contactPerson}</td>
<td data-th="联系电话">${ele.contactPhone}</td>
<td data-th="认证级别">${ele.levelName}</td>
</tr>`
})
}
$('#tableBOx tbody').html(str)
})
}
</script>
</body>
</html>

View File

@ -17,10 +17,13 @@
</div> </div>
<div class="col-xs-12"> <div class="col-xs-12">
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label is-required">仓库编码</label> <label class="col-sm-3 control-label is-required">类型</label>
<div class="col-sm-8"> <div class="col-sm-8">
<input name="warehouseCode" th:field="*{warehouseCode}" class="form-control" type="text" required> <select name="warehouseType" class="form-control" th:with="type=${@dict.getType('warehouse_type')}" required>
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}" th:field="*{warehouseType}"></option>
</select>
</div> </div>
</div> </div>
</div> </div>
<div class="col-xs-12"> <div class="col-xs-12">

View File

@ -105,6 +105,19 @@
<artifactId>easyexcel</artifactId> <artifactId>easyexcel</artifactId>
<version>2.2.6</version> <version>2.2.6</version>
</dependency> </dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-extra</artifactId>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.5.1</version>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -1,6 +1,7 @@
package com.ruoyi.sip.utils; package com.ruoyi.common.utils.mail;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.resource.InputStreamResource; import cn.hutool.core.io.resource.InputStreamResource;
import cn.hutool.core.lang.Dict; import cn.hutool.core.lang.Dict;
import cn.hutool.extra.mail.Mail; import cn.hutool.extra.mail.Mail;
@ -12,7 +13,6 @@ import cn.hutool.extra.template.engine.thymeleaf.ThymeleafEngine;
import com.ruoyi.common.utils.spring.SpringUtils; import com.ruoyi.common.utils.spring.SpringUtils;
import lombok.Getter; import lombok.Getter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import java.util.List; import java.util.List;
@ -42,6 +42,10 @@ public class TemplateMailUtil {
* @Date 2025/07/29 09:55 * @Date 2025/07/29 09:55
*/ */
public static void sendTemplateMail(List<String> toEmail, String title, MailTemplate path, Dict dict) { public static void sendTemplateMail(List<String> toEmail, String title, MailTemplate path, Dict dict) {
sendTemplateMail(toEmail, title, path, dict, null);
}
public static void sendTemplateMail(List<String> toEmail, String title, MailTemplate path, Dict dict, List<String> toCssEmail) {
String enabled = SpringUtils.getProperty("unis.mail.enabled", "false"); String enabled = SpringUtils.getProperty("unis.mail.enabled", "false");
if (!Boolean.parseBoolean(enabled)) { if (!Boolean.parseBoolean(enabled)) {
log.warn("邮件发送开关未开启"); log.warn("邮件发送开关未开启");
@ -62,6 +66,9 @@ public class TemplateMailUtil {
.setTitle(title) .setTitle(title)
.setContent(result) .setContent(result)
.setHtml(true); .setHtml(true);
if (CollUtil.isNotEmpty(toCssEmail)) {
mail.setCcs(toCssEmail.toArray(new String[0]));
}
mail.addImage("signature",imageResource.getStream()); mail.addImage("signature",imageResource.getStream());
mail.send(); mail.send();
} catch (Exception e) { } catch (Exception e) {
@ -77,6 +84,7 @@ public class TemplateMailUtil {
*/ */
ORDER_DELIVERY("mailOrderDeliveryTemplate.html","供应商通知发货单"), ORDER_DELIVERY("mailOrderDeliveryTemplate.html","供应商通知发货单"),
ORDER_PARTNER("mailPartnerTemplate.html","代理商商通知"), ORDER_PARTNER("mailPartnerTemplate.html","代理商商通知"),
PASSWORD_RESET("passwordTemplate.html", "密码重置"),
; ;

View File

@ -31,19 +31,7 @@
<groupId>org.projectlombok</groupId> <groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId> <artifactId>lombok</artifactId>
</dependency> </dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-extra</artifactId>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.5.1</version>
</dependency>
<dependency> <dependency>
<groupId>org.flowable</groupId> <groupId>org.flowable</groupId>
<artifactId>flowable-spring-boot-starter</artifactId> <artifactId>flowable-spring-boot-starter</artifactId>

View File

@ -54,7 +54,7 @@ public class ExternalController {
if (!API_KEY.equals(apiKey)) { if (!API_KEY.equals(apiKey)) {
return AjaxResult.error("鉴权失败"); return AjaxResult.error("鉴权失败");
} }
return AjaxResult.success(orderInfoService.getOrderInfo(dto)); return AjaxResult.success(projectOrderInfoService.getOrderInfo(dto));
} }
@GetMapping("/v1/number/info") @GetMapping("/v1/number/info")
@ -66,6 +66,6 @@ public class ExternalController {
if (!API_KEY.equals(apiKey)){ if (!API_KEY.equals(apiKey)){
return AjaxResult.error("鉴权失败"); return AjaxResult.error("鉴权失败");
} }
return AjaxResult.success(deliveryListService.getNumberInfo(dto)); return AjaxResult.success(deliveryService.getNumberInfo(dto));
} }
} }

View File

@ -5,12 +5,8 @@ import java.util.List;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import com.ruoyi.common.utils.ShiroUtils; import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.sip.domain.ProductInfo; import com.ruoyi.sip.domain.*;
import com.ruoyi.sip.domain.ProjectInfo; import com.ruoyi.sip.service.*;
import com.ruoyi.sip.domain.VendorInfo;
import com.ruoyi.sip.service.IInventoryAuthService;
import com.ruoyi.sip.service.IProductInfoService;
import com.ruoyi.sip.service.IVendorInfoService;
import liquibase.pro.packaged.A; import liquibase.pro.packaged.A;
import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -23,8 +19,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.sip.domain.InventoryInfo;
import com.ruoyi.sip.service.IInventoryInfoService;
import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.common.utils.poi.ExcelUtil;
@ -48,11 +42,17 @@ public class InventoryInfoController extends BaseController
private IProductInfoService productInfoService; private IProductInfoService productInfoService;
@Autowired @Autowired
private IInventoryAuthService inventoryAuthService; private IInventoryAuthService inventoryAuthService;
@Autowired
private IOmsWarehouseInfoService warehouseInfoService;
@RequiresPermissions("inventory:info:view") @RequiresPermissions("inventory:info:view")
@GetMapping() @GetMapping()
public String info() public String info(ModelMap mmap)
{ {
OmsWarehouseInfo queryWarehouseParam = new OmsWarehouseInfo();
queryWarehouseParam.setWarehouseStatus(OmsWarehouseInfo.WarehouseStatusEnum.NORMAL.getValue());
mmap.put("warehouseList", warehouseInfoService.selectOmsWarehouseInfoList(queryWarehouseParam));
mmap.put("vendorList", inventoryAuthService.currentVendor());
return prefix + "/info"; return prefix + "/info";
} }
@ -89,7 +89,7 @@ public class InventoryInfoController extends BaseController
info.setProductCodeList(productCodeList); info.setProductCodeList(productCodeList);
} }
startPage(); startPage();
List<ProductInfo> list = productInfoService.selectProductInfoList(info); List<ProductInfo> list = productInfoService.listInventory(info);
return getDataTable(list); return getDataTable(list);
} }
@ -153,17 +153,19 @@ public class InventoryInfoController extends BaseController
{ {
return toAjax(inventoryInfoService.updateInventoryInfo(inventoryInfo)); return toAjax(inventoryInfoService.updateInventoryInfo(inventoryInfo));
} }
@GetMapping("/innerLog/{productCode}") @GetMapping("/innerLog/{productCode}/{warehouseId}")
public String innerLog(@PathVariable("productCode") String productCode, ModelMap mmap) { public String innerLog(@PathVariable("productCode") String productCode,@PathVariable("warehouseId") Long warehouseId, ModelMap mmap) {
mmap.put("productCode", productCode); mmap.put("productCode", productCode);
mmap.put("warehouseId", warehouseId);
return prefix + "/innerLog"; return prefix + "/innerLog";
} }
@GetMapping("/outerLog/{productCode}") @GetMapping("/outerLog/{productCode}/{warehouseId}")
public String outerLog(@PathVariable("productCode") String productCode, ModelMap mmap) { public String outerLog(@PathVariable("productCode") String productCode,@PathVariable("warehouseId") Long warehouseId, ModelMap mmap) {
mmap.put("productCode", productCode); mmap.put("productCode", productCode);
mmap.put("warehouseId", warehouseId);
return prefix + "/outerLog"; return prefix + "/outerLog";
} }
/** /**

View File

@ -13,6 +13,7 @@ import java.util.Map;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import com.ruoyi.common.config.RuoYiConfig; import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils; import com.ruoyi.common.utils.ShiroUtils;
@ -203,12 +204,43 @@ public class ProjectOrderInfoController extends BaseController
List<Todo> todoCompletedList = todoService.selectTodoCompletedList(todo); List<Todo> todoCompletedList = todoService.selectTodoCompletedList(todo);
mmap.put("approveLog", todoCompletedList); mmap.put("approveLog", todoCompletedList);
//判断商务角色 并且是产品或自己审批 //判断商务角色 并且是产品或自己审批
boolean updateFlag = CollUtil.isNotEmpty(todoCompletedList) ? boolean updateFlag = CollUtil.isNotEmpty(todoCompletedList) && ProjectOrderInfo.OrderStatus.WAIT_APPROVE.getCode().equals(projectOrderInfo.getOrderStatus()) ?
("产品经理".equals(todoCompletedList.get(0).getTaskName()) || "售前".equals(todoCompletedList.get(0).getTaskName())) ("产品经理".equals(todoCompletedList.get(0).getTaskName()) || "售前".equals(todoCompletedList.get(0).getTaskName()))
: true; : (boolean) mmap.get("canUpdate");
mmap.put("updateFile", (ShiroUtils.getSubject().hasRole("sale_assistant")||ShiroUtils.getSubject().hasRole("business")) && updateFlag); mmap.put("updateFile", (ShiroUtils.getSubject().hasRole("sale_assistant")||ShiroUtils.getSubject().hasRole("business") ||ShiroUtils.getSysUser().isAdmin()) && updateFlag);
return prefix + "/edit"; return prefix + "/edit";
} }
/**
*
*/
@GetMapping("/approveLog/{id}")
public String approveLog(@PathVariable("id") Long id, ModelMap mmap)
{
ProjectOrderInfo projectOrderInfo = projectOrderInfoService.selectProjectOrderInfoById(id);
mmap.put("projectOrderInfo", projectOrderInfo);
mmap.put("user", ShiroUtils.getSysUser());
mmap.put("canUpdate", ProjectOrderInfo.OrderStatus.WAIT_COMMIT.getCode().equals(projectOrderInfo.getOrderStatus()) ||ProjectOrderInfo.OrderStatus.APPROVE_REJECT.getCode().equals(projectOrderInfo.getOrderStatus()));
// boolean showFileFlag=!ProjectOrderInfo.OrderStatus.WAIT_COMMIT.getCode().equals(projectOrderInfo.getOrderStatus())
// && !ProjectOrderInfo.OrderStatus.APPROVE_REJECT.getCode().equals(projectOrderInfo.getOrderStatus())
// && !"1".equals(projectOrderInfo.getProcessTemplate());
mmap.put("showFileFlag", true);
ProjectOrderFileLog fileLog = new ProjectOrderFileLog();
fileLog.setOrderId(projectOrderInfo.getId());
fileLog.setFileType(ProjectOrderFileLog.FileTypeEnum.CONTRACT_BAK.getCode());
mmap.put("orderBakFile", projectOrderFileLogService.mapBakFile(fileLog));
Todo todo = new Todo();
todo.setBusinessKey(projectOrderInfo.getOrderCode());
List<Todo> todoCompletedList = todoService.selectTodoCompletedList(todo);
mmap.put("approveLog", todoCompletedList);
//判断商务角色 并且是产品或自己审批
boolean updateFlag = CollUtil.isNotEmpty(todoCompletedList) && ProjectOrderInfo.OrderStatus.WAIT_APPROVE.getCode().equals(projectOrderInfo.getOrderStatus()) ?
("产品经理".equals(todoCompletedList.get(0).getTaskName()) || "售前".equals(todoCompletedList.get(0).getTaskName()))
: (boolean) mmap.get("canUpdate");
mmap.put("updateFile", (ShiroUtils.getSubject().hasRole("sale_assistant")||ShiroUtils.getSubject().hasRole("business") ||ShiroUtils.getSysUser().isAdmin()) && updateFlag);
return prefix + "/orderApproveLog";
}
@GetMapping("/view/{id}") @GetMapping("/view/{id}")
public String viewDetail(@PathVariable("id") Long id, ModelMap mmap) { public String viewDetail(@PathVariable("id") Long id, ModelMap mmap) {

View File

@ -69,7 +69,7 @@ public class VendorInfoController extends BaseController
public String partnerQuery(@RequestParam(value = "code",required = false)String code, ModelMap modelMap) public String partnerQuery(@RequestParam(value = "code",required = false)String code, ModelMap modelMap)
{ {
modelMap.put("code",code); modelMap.put("code",code);
return prefix + "/vendorQuery"; return prefix + "/vendorQueryStatic";
} }
@GetMapping("/list/query") @GetMapping("/list/query")
@ResponseBody @ResponseBody

View File

@ -83,6 +83,7 @@ public class InventoryOuter extends BaseEntity
/** 发货时间选择(0:立即发货 1:自定义) */ /** 发货时间选择(0:立即发货 1:自定义) */
// @Excel(name = "发货时间选择(0:立即发货 1:自定义)") // @Excel(name = "发货时间选择(0:立即发货 1:自定义)")
private String deliveryTimeType; private String deliveryTimeType;
private Long warehouseId;
private List<InventoryOuterDetail> detailList; private List<InventoryOuterDetail> detailList;

View File

@ -68,6 +68,9 @@ public class ProductInfo extends BaseEntity
private String vendorName; private String vendorName;
private Long availableCount; private Long availableCount;
private Long cumulativeCount; private Long cumulativeCount;
private Long inventoryCount;
private Long warehouseId;
private String warehouseName;
@Getter @Getter
public enum ProductTypeEnum { public enum ProductTypeEnum {
/** /**

View File

@ -103,6 +103,7 @@ public class ProjectOrderInfo extends BaseEntity {
*/ */
// @Excel(name = "进货商商务接口人姓名") // @Excel(name = "进货商商务接口人姓名")
private String businessPerson; private String businessPerson;
private Boolean showLog;
/** /**
* *

View File

@ -62,4 +62,6 @@ public interface PartnerInfoMapper
public int selectCountByCode(PartnerInfo partnerInfo); public int selectCountByCode(PartnerInfo partnerInfo);
List<PartnerInfo> listByOrderCode(List<String> orderCodeList); List<PartnerInfo> listByOrderCode(List<String> orderCodeList);
int selectMaxByPrefix(String string);
} }

View File

@ -77,4 +77,6 @@ public interface ProductInfoMapper
List<String> authProductCode(VendorInfo productInfo); List<String> authProductCode(VendorInfo productInfo);
void updateCount(List<ProductInfo> values); void updateCount(List<ProductInfo> values);
List<ProductInfo> listInventory(ProductInfo info);
} }

View File

@ -71,4 +71,6 @@ public interface IProductInfoService
void updateCount(List<ProductInfo> values); void updateCount(List<ProductInfo> values);
List<ProductInfo> listInventory(ProductInfo info);
} }

View File

@ -80,7 +80,7 @@ public class CustomerInfoServiceImpl implements ICustomerInfoService
cnarea.setLevel("1"); cnarea.setLevel("1");
List<Cnarea> cnareas = cnareaService.queryAll(cnarea); List<Cnarea> cnareas = cnareaService.queryAll(cnarea);
if (CollUtil.isEmpty(cnareas)) { if (CollUtil.isEmpty(cnareas)) {
throw new ServiceException("省市未配置,生成订单编号出错,请联系管理员"); throw new ServiceException("省市未配置,生成客户编码出错,请联系管理员");
} }
String shortCode = cnareas.get(0).getShortCode(); String shortCode = cnareas.get(0).getShortCode();
StringBuilder result = new StringBuilder(); StringBuilder result = new StringBuilder();

View File

@ -3,7 +3,6 @@ package com.ruoyi.sip.service.impl;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
@ -17,7 +16,7 @@ import com.ruoyi.sip.domain.*;
import com.ruoyi.sip.dto.inventory.ProductWarehouseInfo; import com.ruoyi.sip.dto.inventory.ProductWarehouseInfo;
import com.ruoyi.sip.mapper.InventoryOuterDetailMapper; import com.ruoyi.sip.mapper.InventoryOuterDetailMapper;
import com.ruoyi.sip.service.*; import com.ruoyi.sip.service.*;
import com.ruoyi.sip.utils.TemplateMailUtil; import com.ruoyi.common.utils.mail.TemplateMailUtil;
import com.ruoyi.sip.vo.OuterDeliveryProductVo; import com.ruoyi.sip.vo.OuterDeliveryProductVo;
import com.ruoyi.sip.vo.OuterDeliveryVo; import com.ruoyi.sip.vo.OuterDeliveryVo;
import com.ruoyi.sip.vo.OuterViewVo; import com.ruoyi.sip.vo.OuterViewVo;

View File

@ -6,6 +6,10 @@ import java.util.List;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.ShiroUtils; import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.sip.domain.Cnarea;
import com.ruoyi.sip.domain.CustomerInfo;
import com.ruoyi.sip.service.ICnareaService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.ruoyi.sip.mapper.PartnerInfoMapper; import com.ruoyi.sip.mapper.PartnerInfoMapper;
@ -24,7 +28,8 @@ public class PartnerInfoServiceImpl implements IPartnerInfoService
{ {
@Autowired @Autowired
private PartnerInfoMapper partnerInfoMapper; private PartnerInfoMapper partnerInfoMapper;
@Autowired
private ICnareaService cnareaService;
/** /**
* *
* *
@ -67,6 +72,9 @@ public class PartnerInfoServiceImpl implements IPartnerInfoService
public int insertPartnerInfo(PartnerInfo partnerInfo) public int insertPartnerInfo(PartnerInfo partnerInfo)
{ {
partnerInfo.setCreateBy(ShiroUtils.getUserId().toString()); partnerInfo.setCreateBy(ShiroUtils.getUserId().toString());
//生成编码
partnerInfo.setPartnerCode(generateCode(partnerInfo.getProvince()));
int i = partnerInfoMapper.selectCountByCode(partnerInfo); int i = partnerInfoMapper.selectCountByCode(partnerInfo);
if (i>0){ if (i>0){
throw new ServiceException("该编码已存在"); throw new ServiceException("该编码已存在");
@ -74,6 +82,29 @@ public class PartnerInfoServiceImpl implements IPartnerInfoService
return partnerInfoMapper.insertPartnerInfo(partnerInfo); return partnerInfoMapper.insertPartnerInfo(partnerInfo);
} }
private String generateCode(String province) {
if (StringUtils.isEmpty(province)) {
throw new ServiceException("客户所属省为空,无法生成代理商编码");
}
Cnarea cnarea = new Cnarea();
cnarea.setName(province);
cnarea.setLevel("1");
List<Cnarea> cnareas = cnareaService.queryAll(cnarea);
if (CollUtil.isEmpty(cnareas)) {
throw new ServiceException("省市未配置,生成代理商编码出错,请联系管理员");
}
String shortCode = cnareas.get(0).getShortCode();
StringBuilder result = new StringBuilder();
result.append("AGT-");
result.append(shortCode);
result.append("-");
int count = partnerInfoMapper.selectMaxByPrefix(result.toString());
// 生成顺序编码,不足四位补零
String sequence = String.format("%04d", count + 1);
result.append(sequence);
return result.toString();
}
/** /**
* *
* *
@ -84,6 +115,12 @@ public class PartnerInfoServiceImpl implements IPartnerInfoService
public int updatePartnerInfo(PartnerInfo partnerInfo) public int updatePartnerInfo(PartnerInfo partnerInfo)
{ {
partnerInfo.setUpdateBy(ShiroUtils.getUserId().toString()); partnerInfo.setUpdateBy(ShiroUtils.getUserId().toString());
// 如果省份发生变化,需要重新生成客户编码
PartnerInfo existsInfo = partnerInfoMapper.selectPartnerInfoById(partnerInfo.getId());
if (existsInfo != null && !existsInfo.getProvince().equals(partnerInfo.getProvince())) {
String newPartnerCode = generateCode(partnerInfo.getProvince());
partnerInfo.setPartnerCode(newPartnerCode);
}
int i = partnerInfoMapper.selectCountByCode(partnerInfo); int i = partnerInfoMapper.selectCountByCode(partnerInfo);
if (i>0){ if (i>0){
throw new ServiceException("该编码已存在"); throw new ServiceException("该编码已存在");

View File

@ -148,4 +148,10 @@ public class ProductInfoServiceImpl implements IProductInfoService
public void updateCount(List<ProductInfo> values) { public void updateCount(List<ProductInfo> values) {
productInfoMapper.updateCount(values); productInfoMapper.updateCount(values);
} }
@Override
public List<ProductInfo> listInventory(ProductInfo info) {
return productInfoMapper.listInventory(info);
}
} }

View File

@ -26,6 +26,7 @@ import com.ruoyi.common.utils.DictUtils;
import com.ruoyi.common.utils.ShiroUtils; import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.sip.domain.*; import com.ruoyi.sip.domain.*;
import com.ruoyi.sip.dto.ApiDataQueryDto; import com.ruoyi.sip.dto.ApiDataQueryDto;
import com.ruoyi.sip.flowable.domain.Todo; import com.ruoyi.sip.flowable.domain.Todo;
@ -38,7 +39,7 @@ import com.ruoyi.sip.service.*;
import com.ruoyi.sip.flowable.service.DeleteFlowableProcessInstanceCmd; import com.ruoyi.sip.flowable.service.DeleteFlowableProcessInstanceCmd;
import com.ruoyi.sip.flowable.service.TodoCommonTemplate; import com.ruoyi.sip.flowable.service.TodoCommonTemplate;
import com.ruoyi.sip.flowable.service.TodoService; import com.ruoyi.sip.flowable.service.TodoService;
import com.ruoyi.sip.utils.TemplateMailUtil; import com.ruoyi.common.utils.mail.TemplateMailUtil;
import com.ruoyi.sip.vo.OrderInfoVo; import com.ruoyi.sip.vo.OrderInfoVo;
import com.ruoyi.system.service.ISysUserService; import com.ruoyi.system.service.ISysUserService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -104,6 +105,9 @@ public class ProjectOrderInfoServiceImpl implements IProjectOrderInfoService, To
@Autowired @Autowired
private TaskService taskService; private TaskService taskService;
private static final List<String> CSS_EMAIL_LIST = Arrays.asList("wangxiaojun@pcitech.com", "sunxuepu@pcitech.com", "huiwang@pcitech.com", "zhaoqian1@pcitech.com", "pci-ict@pcitech.com");
@Autowired @Autowired
private IBuApproveConfigService approveConfigService; private IBuApproveConfigService approveConfigService;
@Value("${unis.order.endHour:96}") @Value("${unis.order.endHour:96}")
@ -215,7 +219,33 @@ public class ProjectOrderInfoServiceImpl implements IProjectOrderInfoService, To
*/ */
@Override @Override
public List<ProjectOrderInfo> selectProjectOrderInfoList(ProjectOrderInfo projectOrderInfo) { public List<ProjectOrderInfo> selectProjectOrderInfoList(ProjectOrderInfo projectOrderInfo) {
return projectOrderInfoMapper.selectProjectOrderInfoList(projectOrderInfo); SysUser sysUser = getSysUser();
boolean showLog = false;
if (sysUser.getDept() != null && sysUser.getDept().getAncestors().startsWith("0,100,200")) {
StringBuilder authSql = new StringBuilder();
if ("总代".equals(sysUser.getDept().getDeptName())) {
//总代
authSql.append(" and ( ");
authSql.append(" t1.order_channel = 1 ");
authSql.append(" )");
} else {
showLog = true;
authSql.append(" and t1.partner_code in (");
authSql.append(" select partner_code from partner_info where system_user_id = ").append(sysUser.getUserId());
authSql.append(" )");
}
projectOrderInfo.setParams(new HashMap<String, Object>() {{
put("authSql", authSql.toString());
}});
}
List<ProjectOrderInfo> projectOrderInfos = projectOrderInfoMapper.selectProjectOrderInfoList(projectOrderInfo);
for (ProjectOrderInfo orderInfo : projectOrderInfos) {
//省代看总代合同
orderInfo.setShowLog(showLog && "1".equals(orderInfo.getOrderChannel()));
}
return projectOrderInfos;
} }
/** /**
@ -1142,7 +1172,7 @@ public class ProjectOrderInfoServiceImpl implements IProjectOrderInfoService, To
return null; return null;
} }
private void sendPartnerMail(List<String> toEmail, ProjectOrderInfo projectOrderInfo){ public void sendPartnerMail(List<String> toEmail, ProjectOrderInfo projectOrderInfo){
if (CollUtil.isEmpty(toEmail)){ if (CollUtil.isEmpty(toEmail)){
log.info("发货邮件发送失败,收件人为空"); log.info("发货邮件发送失败,收件人为空");
return; return;
@ -1150,8 +1180,16 @@ public class ProjectOrderInfoServiceImpl implements IProjectOrderInfoService, To
String templateTile="{}-紫光汇智云桌面-{}-进供货执行通知"; String templateTile="{}-紫光汇智云桌面-{}-进供货执行通知";
String title = StringUtils.format(templateTile, projectOrderInfo.getOrderCode(), projectOrderInfo.getProjectName()); String title = StringUtils.format(templateTile, projectOrderInfo.getOrderCode(), projectOrderInfo.getProjectName());
String activeProfile = SpringUtils.getActiveProfile();
if ("dev".equals(activeProfile)){
//开发环境不抄送领导
TemplateMailUtil.sendTemplateMail(toEmail,title, TemplateMailUtil.sendTemplateMail(toEmail,title,
TemplateMailUtil.MailTemplate.ORDER_PARTNER,Dict.create()); TemplateMailUtil.MailTemplate.ORDER_PARTNER,Dict.create());
}else{
TemplateMailUtil.sendTemplateMail(toEmail,title,
TemplateMailUtil.MailTemplate.ORDER_PARTNER,Dict.create(),CSS_EMAIL_LIST);
}
} }
@Override @Override

View File

@ -96,6 +96,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="deliveryStatus != null and deliveryStatus != ''">and t1.delivery_status = #{deliveryStatus}</if> <if test="deliveryStatus != null and deliveryStatus != ''">and t1.delivery_status = #{deliveryStatus}</if>
<if test="contactAddress != null and contactAddress != ''">and t1.contact_address = #{contactAddress}</if> <if test="contactAddress != null and contactAddress != ''">and t1.contact_address = #{contactAddress}</if>
<if test="deliveryTime != null ">and t1.delivery_time = #{deliveryTime}</if> <if test="deliveryTime != null ">and t1.delivery_time = #{deliveryTime}</if>
<if test="warehouseId != null ">and t1.outer_code in (select outer_code from oms_inventory_outer_detail
where warehouse_id=#{warehouseId})
</if>
<if test="deliveryTimeType != null and deliveryTimeType != ''">and t1.delivery_time_type = <if test="deliveryTimeType != null and deliveryTimeType != ''">and t1.delivery_time_type =
#{deliveryTimeType} #{deliveryTimeType}
</if> </if>

View File

@ -71,7 +71,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
select ifnull(max(SUBSTR(customer_code FROM LENGTH(#{prefix}) + 1 FOR 4)), 0) select ifnull(max(SUBSTR(customer_code FROM LENGTH(#{prefix}) + 1 FOR 4)), 0)
from customer_info from customer_info
WHERE customer_code like concat(#{prefix}, '%'); WHERE customer_code like concat(#{prefix}, '%') and LENGTH(ifnull(SUBSTR(customer_code FROM LENGTH(#{prefix}) + 1 FOR 4), '0000'))=4
</select> </select>

View File

@ -67,7 +67,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<select id="selectProjectOrderInfoList" parameterType="ProjectOrderInfo" resultMap="ProjectOrderInfoResult"> <select id="selectProjectOrderInfoList" parameterType="ProjectOrderInfo" resultMap="ProjectOrderInfoResult">
<include refid="selectProjectOrderInfoRelationVo"/> <include refid="selectProjectOrderInfoRelationVo"/>
<where> where 1=1
<if test="projectId != null ">and t1.project_id = #{projectId}</if> <if test="projectId != null ">and t1.project_id = #{projectId}</if>
<if test="projectCode != null and projectCode!='' ">and t2.project_code like <if test="projectCode != null and projectCode!='' ">and t2.project_code like
concat('%',#{projectCode},'%') concat('%',#{projectCode},'%')
@ -112,7 +112,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="deliveryStatus != null and deliveryStatus != ''">and t1.delivery_status = #{deliveryStatus}</if> <if test="deliveryStatus != null and deliveryStatus != ''">and t1.delivery_status = #{deliveryStatus}</if>
<if test="outerStatus != null and outerStatus != ''">and t1.outer_status = #{outerStatus}</if> <if test="outerStatus != null and outerStatus != ''">and t1.outer_status = #{outerStatus}</if>
<if test="signStatus != null and signStatus != ''">and t1.sign_status = #{signStatus}</if> <if test="signStatus != null and signStatus != ''">and t1.sign_status = #{signStatus}</if>
<if test="keyword != null and keyword != ''">and (t1.order_code like concat('%',#{keyword},'%') or t2.project_name like concat('%',#{keyword},'%') or t2.customer_name like concat('%',#{keyword},'%'))</if> <if test="keyword != null and keyword != ''">and (t1.order_code like concat('%',#{keyword},'%') or
t2.project_name like concat('%',#{keyword},'%') or t2.customer_name like concat('%',#{keyword},'%'))
</if>
<if test="deliveryTimeStart != null or deliveryTimeEnd != null"> <if test="deliveryTimeStart != null or deliveryTimeEnd != null">
<choose> <choose>
<when test="deliveryTimeStart != null and deliveryTimeEnd != null"> <when test="deliveryTimeStart != null and deliveryTimeEnd != null">
@ -195,13 +197,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
task_name != '售前') task_name != '售前')
</if> </if>
<if test="productCodeList!=null and productCodeList.size>0"> <if test="productCodeList!=null and productCodeList.size>0">
and t1.project_id in (select distinct t2.project_id from project_product_info t2 where t2.product_bom_code in and t1.project_id in (select distinct t2.project_id from project_product_info t2 where t2.product_bom_code
in
<foreach item="item" collection="productCodeList" separator="," open="(" close=")"> <foreach item="item" collection="productCodeList" separator="," open="(" close=")">
#{item} #{item}
</foreach> </foreach>
) )
</if> </if>
</where> ${params.authSql}
</select> </select>
<select id="selectProjectOrderInfoById" parameterType="Long" resultMap="ProjectOrderInfoResult"> <select id="selectProjectOrderInfoById" parameterType="Long" resultMap="ProjectOrderInfoResult">

View File

@ -63,6 +63,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</foreach> </foreach>
) )
</select> </select>
<select id="selectMaxByPrefix" resultType="java.lang.Integer">
select ifnull(max(SUBSTR(partner_code FROM LENGTH(#{prefix}) + 1 FOR 4)), 0)
from partner_info
WHERE partner_code like concat(#{prefix}, '%') and LENGTH(ifnull(SUBSTR(partner_code FROM LENGTH(#{prefix}) + 1 FOR 4), '0000'))=4
</select>
<insert id="insertPartnerInfo" parameterType="PartnerInfo" useGeneratedKeys="true" keyProperty="id"> <insert id="insertPartnerInfo" parameterType="PartnerInfo" useGeneratedKeys="true" keyProperty="id">
insert into partner_info insert into partner_info

View File

@ -110,6 +110,42 @@
</if> </if>
</where> </where>
</select> </select>
<select id="listInventory" resultType="com.ruoyi.sip.domain.ProductInfo">
SELECT t4.warehouse_name,
ifnull(t2.warehouse_id, t3.warehouse_id) as warehouse_id,
t3.vendor_name,
t1.*,
t2.inventory_count
FROM product_info t1
LEFT JOIN (SELECT product_code, warehouse_id, count(1) as inventory_count
FROM oms_inventory_info
WHERE inventory_status = 0
GROUP BY product_code, warehouse_id) t2 ON t1.product_code = t2.product_code
left join oms_vendor_info t3 on t1.vendor_code = t3.vendor_code
left join oms_warehouse_info t4 on t4.id = ifnull(t2.warehouse_id, t3.warehouse_id)
<where>
<if test="productCode != null and productCode != ''">and t1.product_code like concat('%', #{productCode},
'%')
</if>
<if test="productCodeList != null and productCodeList.size>0 ">and t1.product_code in
<foreach item="item" index="index" collection="productCodeList" separator="," open="(" close=")">
#{item}
</foreach>
</if>
<if test="productName != null and productName != ''">and t1.product_name like concat('%', #{productName},
'%')
</if>
<if test="model != null and model != ''">and t1.model like concat('%', #{model}, '%')</if>
<if test="type != null and type != ''">and find_in_set(t1.type , #{type})</if>
<if test="vendorName != null and vendorName != ''">and t3.vendor_name like concat('%', #{vendorName},
'%')
</if>
<if test="vendorCode != null and vendorCode != ''">and t1.vendor_code = #{vendorCode}</if>
<if test="warehouseId != null">
and ifnull(t2.warehouse_id, t3.warehouse_id) = #{warehouseId}
</if>
</where>
</select>
<insert id="insertProductInfo" parameterType="ProductInfo" useGeneratedKeys="true" keyProperty="id"> <insert id="insertProductInfo" parameterType="ProductInfo" useGeneratedKeys="true" keyProperty="id">