This commit is contained in:
PQZ 2025-11-21 16:08:59 +08:00
parent db4e26f946
commit bc61944330
5 changed files with 161 additions and 66 deletions

View File

@ -13,7 +13,7 @@ public class CusBankImportDTO {
private String taxId;
@Excel(name = "银行名称")
private String bankName;
@Excel(name = "银行账")
@Excel(name = "银行账")
private String bankAccount;
@Excel(name = "分支机构代码")
private String branchCode;

View File

@ -15,4 +15,13 @@ import com.ruoyi.cus.domain.CusContacts;
*/
public interface ICusContactsService extends IService<CusContacts> {
IPage<CusContacts> queryListPage(CusContacts pageReqVO, Page<CusContacts> page);
/**
* 批量保存客户联系人信息
*
* @param cusContactsList List<CusContacts>
* @author PQZ
* @date 9:32 2025/11/21
**/
void saveOrUpdateByCusName(List<CusContacts> cusContactsList);
}

View File

@ -1,8 +1,15 @@
package com.ruoyi.cus.service.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
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.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@ -26,4 +33,60 @@ public class CusContactsServiceImpl extends ServiceImpl<CusContactsMapper,CusCon
public IPage<CusContacts> queryListPage(CusContacts pageReqVO, Page<CusContacts> page) {
return cusContactsMapper.queryListPage(pageReqVO, page);
}
/**
* 批量保存客户联系人信息
*
* @param cusContactsList List<CusContacts>
* @author PQZ
* @date 9:32 2025/11/21
**/
@Override
public void saveOrUpdateByCusName(List<CusContacts> cusContactsList) {
if(cusContactsList == null || cusContactsList.isEmpty()) {
return;
}
// 1. 提取有效的客户名称并去重
List<String> cusNames = cusContactsList.stream()
.map(CusContacts::getCusName)
.filter(StringUtils::isNotEmpty)
.distinct()
.collect(Collectors.toList());
//2. 查询数据库中已有的客户联系人信息,并按照客户名称+姓名分组
Map<String,CusContacts> existingCusContactMap = new HashMap<>();
List<CusContacts> existingContactsList = this.list(new LambdaQueryWrapper<CusContacts>()
.in(CusContacts::getCusName, cusNames));
existingCusContactMap = existingContactsList.stream()
.collect(Collectors.toMap(
contact -> contact.getCusName() + "_" + contact.getName(),
contact -> contact,
// 保留第一个忽略后续重复项
(existing, replacement) -> existing
));
// 3. 分离需要新增和更新的数据
List<CusContacts> toSaveList = new ArrayList<>();
List<CusContacts> toUpdateList = new ArrayList<>();
for(CusContacts cusContacts : cusContactsList) {
String key = cusContacts.getCusName() + "_" + cusContacts.getName();
CusContacts existing = existingCusContactMap.get(key);
if(existing != null) {
// 存在就更新
cusContacts.setId(existing.getId());
//保留原来的客户id
cusContacts.setCusId(existing.getCusId());
toUpdateList.add(cusContacts);
} else {
// 不存在就新增
toSaveList.add(cusContacts);
}
}
// 4. 批量保存与更新
if(!toSaveList.isEmpty()) {
this.saveBatch(toSaveList);
}
if(!toUpdateList.isEmpty()) {
this.updateBatchById(toUpdateList);
}
}
}

View File

@ -203,7 +203,7 @@ public class CusImportServiceImpl implements ICusImportService {
}
// 批量保存客户联系人信息
if (!cusContactsList.isEmpty()) {
cusContactsService.saveBatch(cusContactsList);
cusContactsService.saveOrUpdateByCusName(cusContactsList);
}
//批量保存银行账户信息
if (!cusBankList.isEmpty()) {

View File

@ -61,7 +61,8 @@
size="mini"
@click="handleExport"
v-hasPermi="['cus:main:export']"
>导出</el-button>
>导出
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
@ -70,7 +71,8 @@
icon="el-icon-upload2"
size="mini"
@click="handleImport"
>导入</el-button>
>导入
</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
@ -93,7 +95,9 @@
</el-table-column>
<el-table-column label="星标" align="center" prop="ifStar">
<template slot-scope="scope">
<i v-if="scope.row.ifStar" class="el-icon-star-on" style="color: rgb(64, 158, 255);font-size: 18px;cursor: pointer"></i>
<i v-if="scope.row.ifStar" class="el-icon-star-on"
style="color: rgb(64, 158, 255);font-size: 18px;cursor: pointer"
></i>
<i v-else class="el-icon-star-off" style="cursor: pointer"></i>
</template>
</el-table-column>
@ -219,13 +223,15 @@
type="text"
@click="handleUpdate(scope.row)"
v-hasPermi="['cus:main:edit']"
>修改</el-button>
>修改
</el-button>
<el-button
size="mini"
type="text"
@click="handleUpdate(scope.row)"
v-hasPermi="['cus:main:edit']"
>发邮件</el-button>
>发邮件
</el-button>
<el-dropdown @command="handleOpt">
<span class="el-dropdown-link">
更多<i class="el-icon-arrow-down el-icon--right"></i>
@ -253,7 +259,10 @@
<draw-form ref="drawForm"></draw-form>
<!-- 客户信息导入对话框 -->
<el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
<el-upload ref="upload" :limit="1" accept=".xlsx, .xls" :headers="upload.headers" :action="upload.url + '?updateSupport=' + upload.updateSupport" :disabled="upload.isUploading" :on-progress="handleFileUploadProgress" :on-success="handleFileSuccess" :auto-upload="false" drag>
<el-upload ref="upload" :limit="1" accept=".xlsx, .xls" :headers="upload.headers"
:action="upload.url + '?updateSupport=' + upload.updateSupport" :disabled="upload.isUploading"
:on-progress="handleFileUploadProgress" :on-success="handleFileSuccess" :auto-upload="false" drag
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处<em>点击上传</em></div>
<div class="el-upload__tip text-center" slot="tip">
@ -270,12 +279,12 @@
</template>
<script>
import { listMain, getMain, delMain, addMain, updateMain } from "@/api/cus/main";
import { listMain, getMain, delMain, addMain, updateMain } from '@/api/cus/main'
import DrawForm from './drawForm'
import { getToken } from "@/utils/auth";
import { getToken } from '@/utils/auth'
export default {
name: "Main",
name: 'Main',
components: { DrawForm },
dicts: ['cus_main_product', 'cus_label', 'cus_type', 'sys_user_sex', 'cus_from', 'cus_level', 'cus_busi_type', 'cus_follow_step'],
data() {
@ -300,43 +309,55 @@ export default {
shortName: null,
cusType: null,
country: null,
mainProds: null,
mainProds: null
},
//
upload: {
//
open: false,
//
title: "",
title: '',
//
isUploading: false,
//
updateSupport: 0,
//
headers: { Authorization: "Bearer " + getToken() },
headers: { Authorization: 'Bearer ' + getToken() },
//
url: process.env.VUE_APP_BASE_API + "/cus/main/importCus"
},
};
url: process.env.VUE_APP_BASE_API + '/cus/main/importCus'
}
}
},
activated() {
//
this.getList();
this.getList()
},
created() {
this.getList();
this.getList()
},
methods: {
//
handleFileUploadProgress(event, file, fileList) {
this.upload.isUploading = true
},
//
handleFileSuccess(response, file, fileList) {
this.upload.open = false
this.upload.isUploading = false
this.$refs.upload.clearFiles()
this.$alert('<div style=\'overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;\'>' + response.msg + '</div>', '导入结果', { dangerouslyUseHTMLString: true })
this.getList()
},
//
submitFileForm() {
this.$refs.upload.submit();
this.$refs.upload.submit()
},
/** 导入按钮操作 */
handleImport() {
this.upload.title = "用户导入";
this.upload.open = true;
this.upload.title = '用户导入'
this.upload.open = true
},
/** 客户代码点击事件 */
@ -345,30 +366,30 @@ export default {
},
/** 查询客户信息列表 */
getList() {
this.loading = true;
this.loading = true
listMain(this.queryParams).then(response => {
this.mainList = response.data.records;
this.total = response.data.total;
this.loading = false;
});
this.mainList = response.data.records
this.total = response.data.total
this.loading = false
})
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
this.resetForm('queryForm')
this.handleQuery()
},
/**
* 新建操作集成按钮
*/
handleCommand(command) {
if("quick"==command){
if ('quick' == command) {
this.handleAddQuick()
}else if("add"){
} else if ('add') {
this.handleAdd()
}
},
@ -377,11 +398,11 @@ export default {
*/
handleOpt(command) {
switch (command) {
case "del":
this.handleDelete();
break;
case 'del':
this.handleDelete()
break
default:
break;
break
}
},
/** 新增按钮操作 */
@ -399,33 +420,34 @@ export default {
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
this.$refs['form'].validate(valid => {
if (valid) {
if (this.form.id != null) {
updateMain(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
this.$modal.msgSuccess('修改成功')
this.open = false
this.getList()
})
} else {
addMain(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
this.$modal.msgSuccess('新增成功')
this.open = false
this.getList()
})
}
}
});
})
},
/** 删除按钮操作 */
handleDelete(row) {
const id = row.cusCode
this.$modal.confirm('是否确认删除客户编号为"' + id + '"的数据项?').then(function() {
return delMain(ids);
return delMain(ids)
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
this.getList()
this.$modal.msgSuccess('删除成功')
}).catch(() => {
})
},
/** 导出按钮操作 */
handleExport() {
@ -434,7 +456,7 @@ export default {
}, `main_${new Date().getTime()}.xlsx`)
}
}
};
}
</script>
<style scoped>
/* 可点击的客户代码样式 */
@ -447,6 +469,7 @@ export default {
.clickable-code:hover {
color: #40a9ff;
}
/* 核心优化:使用固定容器 + 绝对定位避免布局抖动 */
.tag-cell-container {
display: flex;