会员批量导入功能
parent
e17411b470
commit
39c8a49d43
|
|
@ -53,7 +53,9 @@ public interface CouponTemplateMapper extends BaseMapperX<CouponTemplateDO> {
|
||||||
}
|
}
|
||||||
|
|
||||||
default List<CouponTemplateDO> selectListByTakeType(Integer takeType) {
|
default List<CouponTemplateDO> selectListByTakeType(Integer takeType) {
|
||||||
return selectList(CouponTemplateDO::getTakeType, takeType, CouponTemplateDO::getStatus, CommonStatusEnum.ENABLE.getStatus());
|
return selectList(new LambdaQueryWrapperX<CouponTemplateDO>()
|
||||||
|
.eq(CouponTemplateDO::getStatus, CommonStatusEnum.ENABLE.getStatus())
|
||||||
|
.eq(CouponTemplateDO::getTakeType, takeType));
|
||||||
}
|
}
|
||||||
|
|
||||||
default List<CouponTemplateDO> selectList(List<Integer> canTakeTypes, Integer productScope, Long productScopeValue, Integer count) {
|
default List<CouponTemplateDO> selectList(List<Integer> canTakeTypes, Integer productScope, Long productScopeValue, Integer count) {
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil;
|
||||||
import com.yanzhu.framework.common.pojo.CommonResult;
|
import com.yanzhu.framework.common.pojo.CommonResult;
|
||||||
import com.yanzhu.framework.common.pojo.PageResult;
|
import com.yanzhu.framework.common.pojo.PageResult;
|
||||||
import com.yanzhu.module.member.controller.admin.user.vo.*;
|
import com.yanzhu.module.member.controller.admin.user.vo.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import com.yanzhu.module.member.convert.user.MemberUserConvert;
|
import com.yanzhu.module.member.convert.user.MemberUserConvert;
|
||||||
import com.yanzhu.module.member.dal.dataobject.group.MemberGroupDO;
|
import com.yanzhu.module.member.dal.dataobject.group.MemberGroupDO;
|
||||||
import com.yanzhu.module.member.dal.dataobject.level.MemberLevelDO;
|
import com.yanzhu.module.member.dal.dataobject.level.MemberLevelDO;
|
||||||
|
|
@ -28,6 +29,8 @@ import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.io.IOException;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static com.yanzhu.framework.common.pojo.CommonResult.success;
|
import static com.yanzhu.framework.common.pojo.CommonResult.success;
|
||||||
|
|
@ -128,4 +131,19 @@ public class MemberUserController {
|
||||||
return success(MemberUserConvert.INSTANCE.convertPage(pageResult, tags, levels, groups));
|
return success(MemberUserConvert.INSTANCE.convertPage(pageResult, tags, levels, groups));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("/import")
|
||||||
|
@Operation(summary = "导入会员用户")
|
||||||
|
@PreAuthorize("@ss.hasPermission('member:user:import')")
|
||||||
|
public CommonResult<MemberUserImportRespVO> importUser(MultipartFile file) {
|
||||||
|
MemberUserImportRespVO respVO = memberUserService.importUser(file);
|
||||||
|
return success(respVO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/import-template")
|
||||||
|
@Operation(summary = "下载会员导入模板")
|
||||||
|
@PreAuthorize("@ss.hasPermission('member:user:import')")
|
||||||
|
public void downloadImportTemplate(HttpServletResponse response) throws IOException {
|
||||||
|
memberUserService.downloadImportTemplate(response);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.yanzhu.module.member.controller.admin.user.vo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会员用户导入响应 VO
|
||||||
|
*
|
||||||
|
* @author 研筑科技
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class MemberUserImportRespVO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 成功导入数量
|
||||||
|
*/
|
||||||
|
private int successCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 失败导入数量
|
||||||
|
*/
|
||||||
|
private int failCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 失败原因
|
||||||
|
*/
|
||||||
|
private String failReason;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -5,12 +5,15 @@ import com.yanzhu.framework.common.pojo.PageResult;
|
||||||
import com.yanzhu.framework.common.validation.Mobile;
|
import com.yanzhu.framework.common.validation.Mobile;
|
||||||
import com.yanzhu.module.member.controller.admin.user.vo.MemberUserBaseVO;
|
import com.yanzhu.module.member.controller.admin.user.vo.MemberUserBaseVO;
|
||||||
import com.yanzhu.module.member.controller.admin.user.vo.MemberUserCreateRespVO;
|
import com.yanzhu.module.member.controller.admin.user.vo.MemberUserCreateRespVO;
|
||||||
|
import com.yanzhu.module.member.controller.admin.user.vo.MemberUserImportRespVO;
|
||||||
import com.yanzhu.module.member.controller.admin.user.vo.MemberUserPageReqVO;
|
import com.yanzhu.module.member.controller.admin.user.vo.MemberUserPageReqVO;
|
||||||
import com.yanzhu.module.member.controller.admin.user.vo.MemberUserUpdateReqVO;
|
import com.yanzhu.module.member.controller.admin.user.vo.MemberUserUpdateReqVO;
|
||||||
import com.yanzhu.module.member.controller.app.user.vo.*;
|
import com.yanzhu.module.member.controller.app.user.vo.*;
|
||||||
import com.yanzhu.module.member.dal.dataobject.user.MemberUserDO;
|
import com.yanzhu.module.member.dal.dataobject.user.MemberUserDO;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
@ -197,4 +200,20 @@ public interface MemberUserService {
|
||||||
*/
|
*/
|
||||||
boolean updateUserPoint(Long userId, Integer point);
|
boolean updateUserPoint(Long userId, Integer point);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【管理员】导入会员用户
|
||||||
|
*
|
||||||
|
* @param file Excel文件
|
||||||
|
* @return 导入结果
|
||||||
|
*/
|
||||||
|
MemberUserImportRespVO importUser(MultipartFile file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【管理员】下载会员导入模板
|
||||||
|
*
|
||||||
|
* @param response Http响应
|
||||||
|
* @throws IOException IO异常
|
||||||
|
*/
|
||||||
|
void downloadImportTemplate(javax.servlet.http.HttpServletResponse response) throws IOException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,14 +12,19 @@ import com.yanzhu.framework.common.util.object.BeanUtils;
|
||||||
import com.yanzhu.framework.common.util.servlet.ServletUtils;
|
import com.yanzhu.framework.common.util.servlet.ServletUtils;
|
||||||
import com.yanzhu.module.member.controller.admin.user.vo.MemberUserBaseVO;
|
import com.yanzhu.module.member.controller.admin.user.vo.MemberUserBaseVO;
|
||||||
import com.yanzhu.module.member.controller.admin.user.vo.MemberUserCreateRespVO;
|
import com.yanzhu.module.member.controller.admin.user.vo.MemberUserCreateRespVO;
|
||||||
|
import com.yanzhu.module.member.controller.admin.user.vo.MemberUserImportRespVO;
|
||||||
import com.yanzhu.module.member.controller.admin.user.vo.MemberUserPageReqVO;
|
import com.yanzhu.module.member.controller.admin.user.vo.MemberUserPageReqVO;
|
||||||
import com.yanzhu.module.member.controller.admin.user.vo.MemberUserUpdateReqVO;
|
import com.yanzhu.module.member.controller.admin.user.vo.MemberUserUpdateReqVO;
|
||||||
|
import org.apache.poi.ss.usermodel.*;
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import com.yanzhu.module.member.controller.app.user.vo.*;
|
import com.yanzhu.module.member.controller.app.user.vo.*;
|
||||||
import com.yanzhu.module.member.convert.auth.AuthConvert;
|
import com.yanzhu.module.member.convert.auth.AuthConvert;
|
||||||
import com.yanzhu.module.member.convert.user.MemberUserConvert;
|
import com.yanzhu.module.member.convert.user.MemberUserConvert;
|
||||||
import com.yanzhu.module.member.dal.dataobject.user.MemberUserDO;
|
import com.yanzhu.module.member.dal.dataobject.user.MemberUserDO;
|
||||||
import com.yanzhu.module.member.dal.mysql.user.MemberUserMapper;
|
import com.yanzhu.module.member.dal.mysql.user.MemberUserMapper;
|
||||||
import com.yanzhu.module.member.mq.producer.user.MemberUserProducer;
|
import com.yanzhu.module.member.mq.producer.user.MemberUserProducer;
|
||||||
|
import com.yanzhu.module.member.service.user.MemberUserService;
|
||||||
import com.yanzhu.module.system.api.sms.SmsCodeApi;
|
import com.yanzhu.module.system.api.sms.SmsCodeApi;
|
||||||
import com.yanzhu.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
|
import com.yanzhu.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
|
||||||
import com.yanzhu.module.system.api.social.SocialClientApi;
|
import com.yanzhu.module.system.api.social.SocialClientApi;
|
||||||
|
|
@ -34,7 +39,9 @@ import org.springframework.transaction.support.TransactionSynchronization;
|
||||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
|
import java.io.IOException;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -370,4 +377,205 @@ public class MemberUserServiceImpl implements MemberUserService {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public MemberUserImportRespVO importUser(MultipartFile file) {
|
||||||
|
MemberUserImportRespVO respVO = new MemberUserImportRespVO();
|
||||||
|
int successCount = 0;
|
||||||
|
int failCount = 0;
|
||||||
|
StringBuilder failReason = new StringBuilder();
|
||||||
|
|
||||||
|
try (Workbook workbook = new XSSFWorkbook(file.getInputStream())) {
|
||||||
|
Sheet sheet = workbook.getSheetAt(0);
|
||||||
|
int rowCount = sheet.getPhysicalNumberOfRows();
|
||||||
|
|
||||||
|
// 跳过表头,从第二行开始读取数据
|
||||||
|
for (int i = 1; i < rowCount; i++) {
|
||||||
|
Row row = sheet.getRow(i);
|
||||||
|
if (row == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 读取手机号
|
||||||
|
Cell mobileCell = row.getCell(0);
|
||||||
|
if (mobileCell == null) {
|
||||||
|
failCount++;
|
||||||
|
failReason.append("第").append(i + 1).append("行:手机号为空\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String mobile = mobileCell.getStringCellValue().trim();
|
||||||
|
if (mobile.isEmpty()) {
|
||||||
|
failCount++;
|
||||||
|
failReason.append("第").append(i + 1).append("行:手机号为空\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 读取昵称
|
||||||
|
String nickname = "";
|
||||||
|
Cell nicknameCell = row.getCell(1);
|
||||||
|
if (nicknameCell != null) {
|
||||||
|
nickname = nicknameCell.getStringCellValue().trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 读取姓名
|
||||||
|
String name = "";
|
||||||
|
Cell nameCell = row.getCell(2);
|
||||||
|
if (nameCell != null) {
|
||||||
|
name = nameCell.getStringCellValue().trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 读取性别
|
||||||
|
Integer sex = null;
|
||||||
|
Cell sexCell = row.getCell(3);
|
||||||
|
if (sexCell != null) {
|
||||||
|
String sexStr = sexCell.getStringCellValue().trim();
|
||||||
|
if ("男".equals(sexStr)) {
|
||||||
|
sex = 1;
|
||||||
|
} else if ("女".equals(sexStr)) {
|
||||||
|
sex = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 读取状态
|
||||||
|
Byte status = 1; // 默认启用
|
||||||
|
Cell statusCell = row.getCell(4);
|
||||||
|
if (statusCell != null) {
|
||||||
|
String statusStr = statusCell.getStringCellValue().trim();
|
||||||
|
if ("禁用".equals(statusStr)) {
|
||||||
|
status = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 读取等级ID
|
||||||
|
Long levelId = null;
|
||||||
|
Cell levelIdCell = row.getCell(5);
|
||||||
|
if (levelIdCell != null) {
|
||||||
|
try {
|
||||||
|
levelId = (long) levelIdCell.getNumericCellValue();
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 忽略等级ID解析错误
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 读取分组ID
|
||||||
|
Long groupId = null;
|
||||||
|
Cell groupIdCell = row.getCell(6);
|
||||||
|
if (groupIdCell != null) {
|
||||||
|
try {
|
||||||
|
groupId = (long) groupIdCell.getNumericCellValue();
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 忽略分组ID解析错误
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建会员用户
|
||||||
|
MemberUserBaseVO createReqVO = new MemberUserBaseVO();
|
||||||
|
createReqVO.setMobile(mobile);
|
||||||
|
createReqVO.setNickname(nickname);
|
||||||
|
createReqVO.setName(name);
|
||||||
|
createReqVO.setSex(sex);
|
||||||
|
createReqVO.setStatus(status);
|
||||||
|
createReqVO.setLevelId(levelId);
|
||||||
|
createReqVO.setGroupId(groupId);
|
||||||
|
|
||||||
|
// 校验手机唯一
|
||||||
|
try {
|
||||||
|
validateMobileUnique(null, mobile);
|
||||||
|
|
||||||
|
// 创建用户
|
||||||
|
MemberUserDO user = new MemberUserDO();
|
||||||
|
user.setMobile(mobile);
|
||||||
|
if (status != null) {
|
||||||
|
user.setStatus(Integer.valueOf(status));
|
||||||
|
}
|
||||||
|
user.setNickname(nickname);
|
||||||
|
user.setName(name);
|
||||||
|
user.setSex(sex);
|
||||||
|
|
||||||
|
// 使用手机号码的后6位作为密码
|
||||||
|
String password = mobile.substring(mobile.length() - 6);
|
||||||
|
user.setPassword(encodePassword(password));
|
||||||
|
|
||||||
|
// 设置注册信息
|
||||||
|
user.setRegisterIp(ServletUtils.getClientIP());
|
||||||
|
user.setRegisterTerminal(TerminalEnum.H5.getTerminal());
|
||||||
|
|
||||||
|
// 插入数据库
|
||||||
|
memberUserMapper.insert(user);
|
||||||
|
|
||||||
|
// 发送 MQ 消息:用户创建
|
||||||
|
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
|
||||||
|
@Override
|
||||||
|
public void afterCommit() {
|
||||||
|
memberUserProducer.sendUserCreateMessage(user.getId());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
successCount++;
|
||||||
|
} catch (Exception e) {
|
||||||
|
failCount++;
|
||||||
|
failReason.append("第").append(i + 1).append("行:").append(e.getMessage()).append("\n");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
failCount++;
|
||||||
|
failReason.append("第").append(i + 1).append("行:处理失败,").append(e.getMessage()).append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
respVO.setFailCount(1);
|
||||||
|
respVO.setFailReason("文件解析失败:" + e.getMessage());
|
||||||
|
return respVO;
|
||||||
|
}
|
||||||
|
|
||||||
|
respVO.setSuccessCount(successCount);
|
||||||
|
respVO.setFailCount(failCount);
|
||||||
|
respVO.setFailReason(failReason.toString());
|
||||||
|
return respVO;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void downloadImportTemplate(HttpServletResponse response) throws IOException {
|
||||||
|
// 创建工作簿
|
||||||
|
try (Workbook workbook = new XSSFWorkbook()) {
|
||||||
|
// 创建工作表
|
||||||
|
Sheet sheet = workbook.createSheet("会员导入模板");
|
||||||
|
|
||||||
|
// 创建表头行
|
||||||
|
Row headerRow = sheet.createRow(0);
|
||||||
|
|
||||||
|
// 设置表头单元格
|
||||||
|
headerRow.createCell(0).setCellValue("手机号");
|
||||||
|
headerRow.createCell(1).setCellValue("昵称");
|
||||||
|
headerRow.createCell(2).setCellValue("姓名");
|
||||||
|
headerRow.createCell(3).setCellValue("性别");
|
||||||
|
headerRow.createCell(4).setCellValue("状态");
|
||||||
|
headerRow.createCell(5).setCellValue("等级ID");
|
||||||
|
headerRow.createCell(6).setCellValue("分组ID");
|
||||||
|
|
||||||
|
// 创建示例数据行
|
||||||
|
Row exampleRow = sheet.createRow(1);
|
||||||
|
exampleRow.createCell(0).setCellValue("13800138000");
|
||||||
|
exampleRow.createCell(1).setCellValue("示例用户1");
|
||||||
|
exampleRow.createCell(2).setCellValue("张三");
|
||||||
|
exampleRow.createCell(3).setCellValue("男");
|
||||||
|
exampleRow.createCell(4).setCellValue("启用");
|
||||||
|
exampleRow.createCell(5).setCellValue(1);
|
||||||
|
exampleRow.createCell(6).setCellValue(1);
|
||||||
|
|
||||||
|
// 自动调整列宽
|
||||||
|
for (int i = 0; i < 7; i++) {
|
||||||
|
sheet.autoSizeColumn(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置响应头
|
||||||
|
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||||
|
response.setHeader("Content-Disposition", "attachment; filename=member_import_template.xlsx");
|
||||||
|
|
||||||
|
// 写入响应
|
||||||
|
workbook.write(response.getOutputStream());
|
||||||
|
response.flushBuffer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -51,3 +51,13 @@ export const updateUserLevel = async (data: any) => {
|
||||||
export const updateUserPoint = async (data: any) => {
|
export const updateUserPoint = async (data: any) => {
|
||||||
return await request.put({ url: `/member/user/update-point`, data })
|
return await request.put({ url: `/member/user/update-point`, data })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 导入会员用户
|
||||||
|
export const importUser = async (data: FormData) => {
|
||||||
|
return await request.post({ url: `/member/user/import`, data, headers: { 'Content-Type': 'multipart/form-data' } })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 下载会员导入模板
|
||||||
|
export const importUserTemplate = () => {
|
||||||
|
return request.download({ url: `/member/user/import-template` })
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,10 +58,14 @@
|
||||||
<MemberGroupSelect v-model="queryParams.groupId" />
|
<MemberGroupSelect v-model="queryParams.groupId" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button v-hasPermi="['member:user:create']" @click="openForm('create')">
|
<el-button @click="openForm('create')">
|
||||||
<Icon class="mr-5px" icon="ep:plus" />
|
<Icon class="mr-5px" icon="ep:plus" />
|
||||||
新增
|
新增
|
||||||
</el-button>
|
</el-button>
|
||||||
|
<el-button @click="handleImport">
|
||||||
|
<Icon class="mr-5px" icon="ep:upload-filled" />
|
||||||
|
导入
|
||||||
|
</el-button>
|
||||||
<el-button @click="handleQuery">
|
<el-button @click="handleQuery">
|
||||||
<Icon class="mr-5px" icon="ep:search" />
|
<Icon class="mr-5px" icon="ep:search" />
|
||||||
搜索
|
搜索
|
||||||
|
|
@ -200,11 +204,62 @@
|
||||||
<UserBalanceUpdateForm ref="UpdateBalanceFormRef" @success="getList" />
|
<UserBalanceUpdateForm ref="UpdateBalanceFormRef" @success="getList" />
|
||||||
<!-- 发送优惠券弹窗 -->
|
<!-- 发送优惠券弹窗 -->
|
||||||
<CouponSendForm ref="couponSendFormRef" />
|
<CouponSendForm ref="couponSendFormRef" />
|
||||||
|
<!-- 导入弹窗 -->
|
||||||
|
<el-dialog
|
||||||
|
v-model="importDialogVisible"
|
||||||
|
title="导入会员"
|
||||||
|
width="500px"
|
||||||
|
destroy-on-close
|
||||||
|
>
|
||||||
|
<el-upload
|
||||||
|
ref="uploadRef"
|
||||||
|
v-model:file-list="fileList"
|
||||||
|
:action="importUrl"
|
||||||
|
:auto-upload="false"
|
||||||
|
:disabled="importLoading"
|
||||||
|
:headers="uploadHeaders"
|
||||||
|
:limit="1"
|
||||||
|
:on-error="submitImportError"
|
||||||
|
:on-exceed="handleExceed"
|
||||||
|
:on-success="submitImportSuccess"
|
||||||
|
accept=".xlsx, .xls"
|
||||||
|
drag
|
||||||
|
>
|
||||||
|
<Icon icon="ep:upload" />
|
||||||
|
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||||
|
<template #tip>
|
||||||
|
<div class="el-upload__tip text-center">
|
||||||
|
<div class="el-upload__tip">
|
||||||
|
<el-checkbox v-model="updateSupport" />
|
||||||
|
是否更新已经存在的用户数据
|
||||||
|
</div>
|
||||||
|
<span>仅允许导入 xls、xlsx 格式文件。</span>
|
||||||
|
<el-link
|
||||||
|
:underline="false"
|
||||||
|
style="font-size: 12px; vertical-align: baseline"
|
||||||
|
type="primary"
|
||||||
|
@click="downloadTemplate"
|
||||||
|
>
|
||||||
|
下载模板
|
||||||
|
</el-link>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-upload>
|
||||||
|
<template #footer>
|
||||||
|
<div class="flex justify-end">
|
||||||
|
<el-button :disabled="importLoading" @click="importDialogVisible = false">取消</el-button>
|
||||||
|
<el-button type="primary" :disabled="importLoading" @click="submitImport" :loading="importLoading">
|
||||||
|
开始导入
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { dateFormatter } from '@/utils/formatTime'
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
import * as UserApi from '@/api/member/user'
|
import * as UserApi from '@/api/member/user'
|
||||||
import { DICT_TYPE } from '@/utils/dict'
|
import { DICT_TYPE } from '@/utils/dict'
|
||||||
|
import download from '@/utils/download'
|
||||||
import UserForm from './UserForm.vue'
|
import UserForm from './UserForm.vue'
|
||||||
import MemberTagSelect from '@/views/member/tag/components/MemberTagSelect.vue'
|
import MemberTagSelect from '@/views/member/tag/components/MemberTagSelect.vue'
|
||||||
import MemberLevelSelect from '@/views/member/level/components/MemberLevelSelect.vue'
|
import MemberLevelSelect from '@/views/member/level/components/MemberLevelSelect.vue'
|
||||||
|
|
@ -279,6 +334,78 @@ const openCoupon = () => {
|
||||||
}
|
}
|
||||||
couponSendFormRef.value.open(selectedIds.value)
|
couponSendFormRef.value.open(selectedIds.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 导入相关
|
||||||
|
import { getAccessToken, getTenantId } from '@/utils/auth'
|
||||||
|
const importDialogVisible = ref(false)
|
||||||
|
const uploadRef = ref()
|
||||||
|
const importLoading = ref(false)
|
||||||
|
const fileList = ref([])
|
||||||
|
const importUrl = import.meta.env.VITE_BASE_URL + import.meta.env.VITE_API_URL + '/member/user/import'
|
||||||
|
const uploadHeaders = ref()
|
||||||
|
const updateSupport = ref(0)
|
||||||
|
|
||||||
|
// 打开导入对话框
|
||||||
|
const handleImport = () => {
|
||||||
|
importDialogVisible.value = true
|
||||||
|
fileList.value = []
|
||||||
|
updateSupport.value = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提交导入
|
||||||
|
const submitImport = async () => {
|
||||||
|
if (fileList.value.length == 0) {
|
||||||
|
message.error('请上传文件')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 提交请求
|
||||||
|
uploadHeaders.value = {
|
||||||
|
Authorization: 'Bearer ' + getAccessToken(),
|
||||||
|
'tenant-id': getTenantId()
|
||||||
|
}
|
||||||
|
importLoading.value = true
|
||||||
|
uploadRef.value!.submit()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文件上传成功
|
||||||
|
const submitImportSuccess = (response: any) => {
|
||||||
|
importLoading.value = false
|
||||||
|
if (response.code !== 0) {
|
||||||
|
message.error(response.msg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 拼接提示语
|
||||||
|
const data = response.data
|
||||||
|
let text = '成功导入数量:' + data.successCount + ';'
|
||||||
|
text += '失败导入数量:' + data.failCount + ';'
|
||||||
|
if (data.failCount > 0) {
|
||||||
|
text += '失败原因:' + data.failReason
|
||||||
|
}
|
||||||
|
message.alert(text)
|
||||||
|
getList() // 重新加载列表
|
||||||
|
importDialogVisible.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上传错误提示
|
||||||
|
const submitImportError = (): void => {
|
||||||
|
importLoading.value = false
|
||||||
|
message.error('上传失败,请您重新上传!')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文件数超出提示
|
||||||
|
const handleExceed = (): void => {
|
||||||
|
message.error('最多只能上传一个文件!')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 下载导入模板
|
||||||
|
const downloadTemplate = async () => {
|
||||||
|
try {
|
||||||
|
const res = await UserApi.importUserTemplate()
|
||||||
|
download.excel(res, '会员导入模板.xlsx')
|
||||||
|
} catch (error) {
|
||||||
|
message.error('下载模板失败:' + error.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
/** 操作分发 */
|
/** 操作分发 */
|
||||||
const handleCommand = (command: string, row: UserApi.UserVO) => {
|
const handleCommand = (command: string, row: UserApi.UserVO) => {
|
||||||
switch (command) {
|
switch (command) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue