Merge pull request 'feature/simcards_checker' (#6) from feature/simcards_checker into develop
Reviewed-on: #6
This commit is contained in:
commit
23a13922ca
@ -1,7 +1,5 @@
|
|||||||
package com.imdroid.secapi.dto;
|
package com.imdroid.secapi.dto;
|
||||||
|
|
||||||
import com.alibaba.excel.annotation.ExcelIgnore;
|
|
||||||
import com.alibaba.excel.annotation.ExcelProperty;
|
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
@ -15,30 +13,13 @@ import java.util.Date;
|
|||||||
public class TrafficRecord {
|
public class TrafficRecord {
|
||||||
|
|
||||||
@TableId(type = IdType.AUTO)
|
@TableId(type = IdType.AUTO)
|
||||||
@ExcelIgnore
|
|
||||||
private Integer id;
|
private Integer id;
|
||||||
|
|
||||||
@ExcelProperty("ICCID")
|
|
||||||
private String iccid;
|
private String iccid;
|
||||||
|
|
||||||
@ExcelProperty("记录时间")
|
|
||||||
private Date recordtime;
|
private Date recordtime;
|
||||||
|
|
||||||
@ExcelProperty("剩余流量(MB)")
|
|
||||||
private Integer remaining; // 剩余流量(MB×1000)
|
private Integer remaining; // 剩余流量(MB×1000)
|
||||||
|
|
||||||
@ExcelProperty("已用流量(MB)")
|
|
||||||
private Integer used; // 已用流量(MB×1000)
|
private Integer used; // 已用流量(MB×1000)
|
||||||
|
|
||||||
@ExcelProperty("总流量(MB)")
|
|
||||||
private Integer total; // 总流量(MB×1000)
|
private Integer total; // 总流量(MB×1000)
|
||||||
|
|
||||||
// Excel 导出用,不是数据库的字段!!!
|
|
||||||
@TableField(exist = false)
|
|
||||||
@ExcelProperty("设备号")
|
|
||||||
private String deviceid;
|
|
||||||
|
|
||||||
@TableField(exist = false)
|
|
||||||
@ExcelProperty("SIM卡号")
|
|
||||||
private String msisdn;
|
|
||||||
}
|
}
|
||||||
@ -1,11 +1,10 @@
|
|||||||
package com.imdroid.beidou.controller;
|
package com.imdroid.beidou.controller;
|
||||||
|
|
||||||
|
import com.alibaba.excel.EasyExcel;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.imdroid.beidou.service.CommonExcelService;
|
|
||||||
import com.imdroid.secapi.dto.*;
|
import com.imdroid.secapi.dto.*;
|
||||||
import org.apache.http.HttpEntity;
|
import org.apache.http.HttpEntity;
|
||||||
import org.apache.http.util.EntityUtils;
|
import org.apache.http.util.EntityUtils;
|
||||||
@ -22,14 +21,14 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
|||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import javax.servlet.http.HttpSession;
|
import javax.servlet.http.HttpSession;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
public class SimCardController extends BasicController implements CommonExcelService<TrafficRecord, TrafficRecord> {
|
public class SimCardController extends BasicController {
|
||||||
@Value("${sim.url}")
|
@Value("${sim.url}")
|
||||||
private String BASE_URL;
|
private String BASE_URL;
|
||||||
@Value("${sim.username}")
|
@Value("${sim.username}")
|
||||||
@ -359,93 +358,6 @@ public class SimCardController extends BasicController implements CommonExcelSer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping("/sim/traffic-records/export")
|
|
||||||
@ResponseBody
|
|
||||||
public void exportTrafficRecords(HttpSession session, HttpServletRequest request, HttpServletResponse response) throws Exception {
|
|
||||||
QueryWrapper<TrafficRecord> queryWrapper = new QueryWrapper<>();
|
|
||||||
|
|
||||||
String searchType = request.getParameter("searchType");
|
|
||||||
String searchContent = request.getParameter("searchContent");
|
|
||||||
String startTime = request.getParameter("startTime");
|
|
||||||
String endTime = request.getParameter("endTime");
|
|
||||||
|
|
||||||
if (!StringUtils.isEmpty(searchContent)) {
|
|
||||||
switch(searchType) {
|
|
||||||
case "deviceId":
|
|
||||||
GnssDevice device = gnssDeviceMapper.queryByDeviceId(searchContent.trim());
|
|
||||||
if (device != null && device.getIccid() != null && !device.getIccid().trim().isEmpty()) {
|
|
||||||
queryWrapper.eq("iccid", device.getIccid());
|
|
||||||
} else {
|
|
||||||
queryWrapper.eq("iccid", "");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "iccid":
|
|
||||||
queryWrapper.like("iccid", searchContent.trim());
|
|
||||||
break;
|
|
||||||
case "simNumber":
|
|
||||||
TrafficCard cardByMsisdn = trafficCardMapper.selectOne(
|
|
||||||
new QueryWrapper<TrafficCard>().like("msisdn", searchContent.trim())
|
|
||||||
);
|
|
||||||
if (cardByMsisdn != null) {
|
|
||||||
queryWrapper.eq("iccid", cardByMsisdn.getIccid());
|
|
||||||
} else {
|
|
||||||
queryWrapper.eq("iccid", "");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!StringUtils.isEmpty(startTime)) {
|
|
||||||
queryWrapper.ge("recordtime", startTime);
|
|
||||||
}
|
|
||||||
if (!StringUtils.isEmpty(endTime)) {
|
|
||||||
queryWrapper.le("recordtime", endTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
queryWrapper.orderByDesc("recordtime");
|
|
||||||
|
|
||||||
List<TrafficRecord> records = trafficRecordMapper.selectList(queryWrapper);
|
|
||||||
|
|
||||||
// 填充导出所需的额外字段
|
|
||||||
for (TrafficRecord record : records) {
|
|
||||||
GnssDevice device = gnssDeviceMapper.selectOne(
|
|
||||||
new QueryWrapper<GnssDevice>().eq("iccid", record.getIccid())
|
|
||||||
);
|
|
||||||
if (device != null) {
|
|
||||||
record.setDeviceid(device.getDeviceid());
|
|
||||||
} else {
|
|
||||||
record.setDeviceid("无绑定设备");
|
|
||||||
}
|
|
||||||
|
|
||||||
TrafficCard trafficCard = trafficCardMapper.findByIccid(record.getIccid());
|
|
||||||
if (trafficCard != null) {
|
|
||||||
record.setMsisdn(trafficCard.getMsisdn());
|
|
||||||
} else {
|
|
||||||
record.setMsisdn("-");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 转换流量单位为MB (除以1000)
|
|
||||||
if (record.getRemaining() != null) {
|
|
||||||
record.setRemaining(record.getRemaining() / 1000);
|
|
||||||
}
|
|
||||||
if (record.getUsed() != null) {
|
|
||||||
record.setUsed(record.getUsed() / 1000);
|
|
||||||
}
|
|
||||||
if (record.getTotal() != null) {
|
|
||||||
record.setTotal(record.getTotal() / 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
response.setContentType("application/vnd.ms-excel");
|
|
||||||
response.setCharacterEncoding("utf-8");
|
|
||||||
String filename = System.currentTimeMillis() + "_流量使用记录.xlsx";
|
|
||||||
response.setHeader("Content-disposition", "attachment;filename=" + filename);
|
|
||||||
|
|
||||||
com.alibaba.excel.EasyExcel.write(response.getOutputStream(), TrafficRecord.class)
|
|
||||||
.sheet("流量使用记录")
|
|
||||||
.doWrite(records);
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping("/sim/device-mapping")
|
@RequestMapping("/sim/device-mapping")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public JSONObject getDeviceMapping(HttpSession session,
|
public JSONObject getDeviceMapping(HttpSession session,
|
||||||
@ -545,30 +457,459 @@ public class SimCardController extends BasicController implements CommonExcelSer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@RequestMapping("/sim/export")
|
||||||
public Class<TrafficRecord> getEntityClass() {
|
@ResponseBody
|
||||||
return TrafficRecord.class;
|
public void exportSimList(HttpServletResponse response, String searchType, String searchContent, Integer status, Boolean exportAll, Integer pageSize) {
|
||||||
|
try {
|
||||||
|
System.out.println("开始导出SIM卡数据, 参数: searchType=" + searchType + ", searchContent=" + searchContent +
|
||||||
|
", status=" + status + ", exportAll=" + exportAll + ", pageSize=" + pageSize);
|
||||||
|
|
||||||
|
QueryWrapper<GnssDevice> deviceQueryWrapper = new QueryWrapper<>();
|
||||||
|
|
||||||
|
if (!StringUtils.isEmpty(searchContent)) {
|
||||||
|
switch(searchType) {
|
||||||
|
case "deviceId":
|
||||||
|
deviceQueryWrapper.like("deviceid", searchContent.trim());
|
||||||
|
break;
|
||||||
|
case "iccid":
|
||||||
|
deviceQueryWrapper.like("iccid", searchContent.trim());
|
||||||
|
break;
|
||||||
|
case "simNumber":
|
||||||
|
// 通过SIM号查找对应的ICCID,然后查询设备
|
||||||
|
TrafficCard cardByMsisdn = trafficCardMapper.selectOne(
|
||||||
|
new QueryWrapper<TrafficCard>().like("msisdn", searchContent.trim())
|
||||||
|
);
|
||||||
|
if (cardByMsisdn != null) {
|
||||||
|
deviceQueryWrapper.eq("iccid", cardByMsisdn.getIccid());
|
||||||
|
} else {
|
||||||
|
deviceQueryWrapper.eq("iccid", "");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
deviceQueryWrapper.isNotNull("iccid");
|
||||||
public BaseMapper<TrafficRecord> getMapper() {
|
deviceQueryWrapper.ne("iccid", "");
|
||||||
return trafficRecordMapper;
|
|
||||||
|
if (status != null) {
|
||||||
|
List<TrafficCard> cardsWithStatus = trafficCardMapper.selectList(
|
||||||
|
new QueryWrapper<TrafficCard>().eq("status", status)
|
||||||
|
);
|
||||||
|
if (!cardsWithStatus.isEmpty()) {
|
||||||
|
List<String> iccids = new ArrayList<>();
|
||||||
|
for (TrafficCard card : cardsWithStatus) {
|
||||||
|
iccids.add(card.getIccid());
|
||||||
|
}
|
||||||
|
deviceQueryWrapper.in("iccid", iccids);
|
||||||
|
} else {
|
||||||
|
deviceQueryWrapper.eq("iccid", "不存在的ICCID");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
deviceQueryWrapper.orderByDesc("deviceid");
|
||||||
public String getOrderByColumn() {
|
|
||||||
return "recordtime";
|
List<GnssDevice> devices;
|
||||||
|
if (Boolean.TRUE.equals(exportAll)) {
|
||||||
|
devices = gnssDeviceMapper.selectList(deviceQueryWrapper);
|
||||||
|
} else {
|
||||||
|
int limit = pageSize != null && pageSize > 0 ? pageSize : 20; // 默认20条,与前端表格默认一致
|
||||||
|
Page<GnssDevice> pageable = new Page<>(1, limit);
|
||||||
|
IPage<GnssDevice> devicePage = gnssDeviceMapper.selectPage(pageable, deviceQueryWrapper);
|
||||||
|
devices = devicePage.getRecords();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
if (devices.isEmpty()) {
|
||||||
public String getOrder() {
|
devices = new ArrayList<>();
|
||||||
return "desc";
|
GnssDevice emptyDevice = new GnssDevice();
|
||||||
|
emptyDevice.setDeviceid("无数据");
|
||||||
|
emptyDevice.setIccid("");
|
||||||
|
devices.add(emptyDevice);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
List<List<Object>> exportList = new ArrayList<>();
|
||||||
public String tenantIdField() {
|
List<String> headList = Arrays.asList("设备号", "ICCID", "SIM卡号", "状态",
|
||||||
return null; // TrafficRecord表没有租户字段
|
"剩余流量(MB)", "总流量(MB)", "已用流量(MB)", "更新时间");
|
||||||
|
|
||||||
|
for (GnssDevice device : devices) {
|
||||||
|
List<Object> rowData = new ArrayList<>();
|
||||||
|
rowData.add(device.getDeviceid());
|
||||||
|
rowData.add(device.getIccid());
|
||||||
|
|
||||||
|
TrafficCard trafficCard = null;
|
||||||
|
if (device.getIccid() != null && !device.getIccid().trim().isEmpty()) {
|
||||||
|
trafficCard = trafficCardMapper.findByIccid(device.getIccid());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (trafficCard != null) {
|
||||||
|
rowData.add(trafficCard.getMsisdn()); // SIM卡号
|
||||||
|
|
||||||
|
String statusStr;
|
||||||
|
switch(trafficCard.getStatus()) {
|
||||||
|
case 1: statusStr = "待激活"; break;
|
||||||
|
case 2: statusStr = "已激活"; break;
|
||||||
|
case 3: statusStr = "停机"; break;
|
||||||
|
case 4: statusStr = "注销"; break;
|
||||||
|
case 5: statusStr = "库存"; break;
|
||||||
|
case 6: statusStr = "可测试"; break;
|
||||||
|
case 7: statusStr = "失效"; break;
|
||||||
|
default: statusStr = "未知";
|
||||||
|
}
|
||||||
|
rowData.add(statusStr);
|
||||||
|
// 单位转换:从KB到MB
|
||||||
|
rowData.add(trafficCard.getRemaining() != null ?
|
||||||
|
String.format("%.2f", trafficCard.getRemaining() / 1000.0) : "0"); // 剩余流量
|
||||||
|
rowData.add(trafficCard.getTotal() != null ?
|
||||||
|
String.format("%.2f", trafficCard.getTotal() / 1000.0) : "0"); // 总流量
|
||||||
|
rowData.add(trafficCard.getUsed() != null ?
|
||||||
|
String.format("%.2f", trafficCard.getUsed() / 1000.0) : "0"); // 已用流量
|
||||||
|
rowData.add(trafficCard.getUpdatetime()); // 更新时间
|
||||||
|
} else {
|
||||||
|
rowData.add("-"); // SIM卡号
|
||||||
|
rowData.add("未知"); // 状态
|
||||||
|
rowData.add("0"); // 剩余流量
|
||||||
|
rowData.add("0"); // 总流量
|
||||||
|
rowData.add("0"); // 已用流量
|
||||||
|
rowData.add(""); // 更新时间
|
||||||
|
}
|
||||||
|
|
||||||
|
exportList.add(rowData);
|
||||||
|
}
|
||||||
|
|
||||||
|
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||||
|
response.setCharacterEncoding("utf-8");
|
||||||
|
String fileName = URLEncoder.encode("SIM卡信息", "UTF-8");
|
||||||
|
response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
|
||||||
|
|
||||||
|
EasyExcel.write(response.getOutputStream())
|
||||||
|
.head(createExcelHead(headList))
|
||||||
|
.sheet("SIM卡信息")
|
||||||
|
.doWrite(exportList);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<List<String>> createExcelHead(List<String> headList) {
|
||||||
|
List<List<String>> result = new ArrayList<>();
|
||||||
|
for (String head : headList) {
|
||||||
|
List<String> column = new ArrayList<>();
|
||||||
|
column.add(head);
|
||||||
|
result.add(column);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping("/sim/traffic-records/export")
|
||||||
|
@ResponseBody
|
||||||
|
public void exportTrafficRecords(HttpServletResponse response, String searchType, String searchContent, String startTime, String endTime) {
|
||||||
|
try {
|
||||||
|
System.out.println("开始导出SIM卡流量记录, 参数: searchType=" + searchType + ", searchContent=" + searchContent +
|
||||||
|
", startTime=" + startTime + ", endTime=" + endTime);
|
||||||
|
|
||||||
|
QueryWrapper<TrafficRecord> queryWrapper = new QueryWrapper<>();
|
||||||
|
|
||||||
|
if (!StringUtils.isEmpty(searchContent)) {
|
||||||
|
switch(searchType) {
|
||||||
|
case "deviceId":
|
||||||
|
GnssDevice device = gnssDeviceMapper.queryByDeviceId(searchContent.trim());
|
||||||
|
if (device != null && device.getIccid() != null && !device.getIccid().trim().isEmpty()) {
|
||||||
|
queryWrapper.eq("iccid", device.getIccid());
|
||||||
|
} else {
|
||||||
|
queryWrapper.eq("iccid", "");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "iccid":
|
||||||
|
queryWrapper.like("iccid", searchContent.trim());
|
||||||
|
break;
|
||||||
|
case "simNumber":
|
||||||
|
TrafficCard cardByMsisdn = trafficCardMapper.selectOne(
|
||||||
|
new QueryWrapper<TrafficCard>().like("msisdn", searchContent.trim())
|
||||||
|
);
|
||||||
|
if (cardByMsisdn != null) {
|
||||||
|
queryWrapper.eq("iccid", cardByMsisdn.getIccid());
|
||||||
|
} else {
|
||||||
|
queryWrapper.eq("iccid", "");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!StringUtils.isEmpty(startTime)) {
|
||||||
|
queryWrapper.ge("recordtime", startTime);
|
||||||
|
}
|
||||||
|
if (!StringUtils.isEmpty(endTime)) {
|
||||||
|
queryWrapper.le("recordtime", endTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
queryWrapper.orderByDesc("recordtime");
|
||||||
|
|
||||||
|
List<TrafficRecord> records = trafficRecordMapper.selectList(queryWrapper);
|
||||||
|
|
||||||
|
System.out.println("查询到流量记录数量: " + records.size());
|
||||||
|
if (records.isEmpty()) {
|
||||||
|
records = new ArrayList<>();
|
||||||
|
TrafficRecord emptyRecord = new TrafficRecord();
|
||||||
|
emptyRecord.setIccid("无数据");
|
||||||
|
records.add(emptyRecord);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<List<Object>> exportList = new ArrayList<>();
|
||||||
|
List<String> headList = Arrays.asList("设备号", "ICCID", "SIM卡号", "记录时间",
|
||||||
|
"剩余流量(MB)", "总流量(MB)", "已用流量(MB)");
|
||||||
|
|
||||||
|
for (TrafficRecord record : records) {
|
||||||
|
List<Object> rowData = new ArrayList<>();
|
||||||
|
|
||||||
|
GnssDevice device = gnssDeviceMapper.selectOne(
|
||||||
|
new QueryWrapper<GnssDevice>().eq("iccid", record.getIccid())
|
||||||
|
);
|
||||||
|
rowData.add(device != null ? device.getDeviceid() : "无绑定设备"); // 设备号
|
||||||
|
rowData.add(record.getIccid()); // ICCID
|
||||||
|
|
||||||
|
TrafficCard trafficCard = trafficCardMapper.findByIccid(record.getIccid());
|
||||||
|
rowData.add(trafficCard != null ? trafficCard.getMsisdn() : "-"); // SIM卡号
|
||||||
|
|
||||||
|
rowData.add(record.getRecordtime()); // 记录时间
|
||||||
|
|
||||||
|
rowData.add(record.getRemaining() != null ?
|
||||||
|
String.format("%.2f", record.getRemaining() / 1000.0) : "0"); // 剩余流量
|
||||||
|
rowData.add(record.getTotal() != null ?
|
||||||
|
String.format("%.2f", record.getTotal() / 1000.0) : "0"); // 总流量
|
||||||
|
rowData.add(record.getUsed() != null ?
|
||||||
|
String.format("%.2f", record.getUsed() / 1000.0) : "0"); // 已用流量
|
||||||
|
|
||||||
|
exportList.add(rowData);
|
||||||
|
}
|
||||||
|
|
||||||
|
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||||
|
response.setCharacterEncoding("utf-8");
|
||||||
|
String fileName = URLEncoder.encode("SIM卡流量记录", "UTF-8");
|
||||||
|
response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
|
||||||
|
|
||||||
|
EasyExcel.write(response.getOutputStream())
|
||||||
|
.head(createExcelHead(headList))
|
||||||
|
.sheet("SIM卡流量记录")
|
||||||
|
.doWrite(exportList);
|
||||||
|
|
||||||
|
System.out.println("导出完成,流量记录数: " + exportList.size());
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
System.err.println("导出流量记录失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping("/sim/device-mapping/export")
|
||||||
|
@ResponseBody
|
||||||
|
public void exportDeviceMapping(HttpServletResponse response, String searchType, String searchContent) {
|
||||||
|
try {
|
||||||
|
QueryWrapper<TrafficDeviceMapping> queryWrapper = new QueryWrapper<>();
|
||||||
|
|
||||||
|
if (!StringUtils.isEmpty(searchContent)) {
|
||||||
|
switch(searchType) {
|
||||||
|
case "deviceId":
|
||||||
|
queryWrapper.like("deviceid", searchContent.trim());
|
||||||
|
break;
|
||||||
|
case "iccid":
|
||||||
|
queryWrapper.like("iccid", searchContent.trim());
|
||||||
|
break;
|
||||||
|
case "simNumber":
|
||||||
|
TrafficCard cardByMsisdn = trafficCardMapper.selectOne(
|
||||||
|
new QueryWrapper<TrafficCard>().like("msisdn", searchContent.trim())
|
||||||
|
);
|
||||||
|
if (cardByMsisdn != null) {
|
||||||
|
queryWrapper.eq("iccid", cardByMsisdn.getIccid());
|
||||||
|
} else {
|
||||||
|
queryWrapper.eq("iccid", "");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
queryWrapper.orderByDesc("starttime");
|
||||||
|
|
||||||
|
List<TrafficDeviceMapping> mappings = trafficDeviceMappingMapper.selectList(queryWrapper);
|
||||||
|
|
||||||
|
if (mappings.isEmpty()) {
|
||||||
|
mappings = new ArrayList<>();
|
||||||
|
TrafficDeviceMapping emptyMapping = new TrafficDeviceMapping();
|
||||||
|
emptyMapping.setDeviceid("无数据");
|
||||||
|
emptyMapping.setIccid("无数据");
|
||||||
|
mappings.add(emptyMapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<List<Object>> exportList = new ArrayList<>();
|
||||||
|
List<String> headList = Arrays.asList("设备号", "ICCID", "SIM卡号", "开始时间", "结束时间", "是否激活");
|
||||||
|
|
||||||
|
for (TrafficDeviceMapping mapping : mappings) {
|
||||||
|
List<Object> rowData = new ArrayList<>();
|
||||||
|
|
||||||
|
rowData.add(mapping.getDeviceid()); // 设备号
|
||||||
|
rowData.add(mapping.getIccid()); // ICCID
|
||||||
|
|
||||||
|
TrafficCard trafficCard = trafficCardMapper.findByIccid(mapping.getIccid());
|
||||||
|
rowData.add(trafficCard != null ? trafficCard.getMsisdn() : "-"); // SIM卡号
|
||||||
|
|
||||||
|
rowData.add(mapping.getStarttime()); // 开始时间
|
||||||
|
rowData.add(mapping.getEndtime()); // 结束时间
|
||||||
|
rowData.add(mapping.getEndtime() == null ? "是" : "否"); // 是否激活
|
||||||
|
|
||||||
|
exportList.add(rowData);
|
||||||
|
}
|
||||||
|
|
||||||
|
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||||
|
response.setCharacterEncoding("utf-8");
|
||||||
|
String fileName = URLEncoder.encode("设备SIM卡映射记录", "UTF-8");
|
||||||
|
response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
|
||||||
|
|
||||||
|
EasyExcel.write(response.getOutputStream())
|
||||||
|
.head(createExcelHead(headList))
|
||||||
|
.sheet("设备SIM卡映射记录")
|
||||||
|
.doWrite(exportList);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
System.err.println("导出设备映射记录失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping("/sim/query/export")
|
||||||
|
@ResponseBody
|
||||||
|
public void exportSimDetail(HttpServletResponse response, String type, String content) {
|
||||||
|
try {
|
||||||
|
JSONObject apiResult = proxySimQuery(type, content);
|
||||||
|
|
||||||
|
if (apiResult.getInteger("Status") != 1 || apiResult.getJSONObject("Data") == null) {
|
||||||
|
response.setContentType("text/html;charset=utf-8");
|
||||||
|
response.getWriter().write("查询失败: " + apiResult.getString("Message"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONObject cardData = apiResult.getJSONObject("Data");
|
||||||
|
List<List<Object>> exportList = new ArrayList<>();
|
||||||
|
|
||||||
|
List<Object> basicInfo = new ArrayList<>();
|
||||||
|
basicInfo.add("基本信息");
|
||||||
|
basicInfo.add("");
|
||||||
|
exportList.add(basicInfo);
|
||||||
|
|
||||||
|
addExportRow(exportList, "运营商", getOperatorText(cardData.getInteger("operatortype")));
|
||||||
|
addExportRow(exportList, "ICCID", cardData.getString("iccid"));
|
||||||
|
addExportRow(exportList, "SIM卡号", cardData.getString("msisdn"));
|
||||||
|
addExportRow(exportList, "IMSI", cardData.getString("imsi"));
|
||||||
|
|
||||||
|
addExportRow(exportList, "套餐信息", "");
|
||||||
|
addExportRow(exportList, "套餐ID", cardData.getString("packageid"));
|
||||||
|
addExportRow(exportList, "套餐名称", cardData.getString("packagename"));
|
||||||
|
|
||||||
|
addExportRow(exportList, "时间信息", "");
|
||||||
|
addExportRow(exportList, "激活时间", cardData.getString("activetime"));
|
||||||
|
addExportRow(exportList, "开始时间", cardData.getString("starttime"));
|
||||||
|
addExportRow(exportList, "结束时间", cardData.getString("stoptime"));
|
||||||
|
addExportRow(exportList, "沉默期结束", cardData.getString("silentdate"));
|
||||||
|
|
||||||
|
addExportRow(exportList, "状态", getStatusText(cardData.getInteger("status")));
|
||||||
|
|
||||||
|
// APN信息
|
||||||
|
if (cardData.getJSONObject("apn") != null) {
|
||||||
|
JSONObject apn = cardData.getJSONObject("apn");
|
||||||
|
addExportRow(exportList, "APN信息", "");
|
||||||
|
addExportRow(exportList, "APN ID", apn.getString("apnid"));
|
||||||
|
addExportRow(exportList, "状态", apn.getString("status").equals("01") ? "在线" : "离线");
|
||||||
|
addExportRow(exportList, "IP", apn.getString("ip"));
|
||||||
|
addExportRow(exportList, "网络", getNetworkText(apn.getString("rat")));
|
||||||
|
addExportRow(exportList, "设备状态", apn.getString("onoffstatus").equals("1") ? "开机" : "关机");
|
||||||
|
}
|
||||||
|
|
||||||
|
// GPRS流量
|
||||||
|
if (cardData.getJSONObject("gprs") != null) {
|
||||||
|
JSONObject gprs = cardData.getJSONObject("gprs");
|
||||||
|
addExportRow(exportList, "GPRS流量", "");
|
||||||
|
addExportRow(exportList, "总流量(MB)", formatDouble(parseDouble(gprs.getString("total"))));
|
||||||
|
addExportRow(exportList, "已用流量(MB)", formatDouble(parseDouble(gprs.getString("used"))));
|
||||||
|
addExportRow(exportList, "剩余流量(MB)", formatDouble(parseDouble(gprs.getString("left"))));
|
||||||
|
}
|
||||||
|
|
||||||
|
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||||
|
response.setCharacterEncoding("utf-8");
|
||||||
|
String fileName = URLEncoder.encode("SIM卡详情-" + content, "UTF-8");
|
||||||
|
response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
|
||||||
|
|
||||||
|
List<List<String>> head = new ArrayList<>();
|
||||||
|
List<String> keyHead = new ArrayList<>();
|
||||||
|
keyHead.add("属性");
|
||||||
|
head.add(keyHead);
|
||||||
|
|
||||||
|
List<String> valueHead = new ArrayList<>();
|
||||||
|
valueHead.add("值");
|
||||||
|
head.add(valueHead);
|
||||||
|
|
||||||
|
EasyExcel.write(response.getOutputStream())
|
||||||
|
.head(head)
|
||||||
|
.sheet("SIM卡详情")
|
||||||
|
.doWrite(exportList);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
System.err.println("导出SIM卡详情失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addExportRow(List<List<Object>> exportList, String key, String value) {
|
||||||
|
List<Object> row = new ArrayList<>();
|
||||||
|
row.add(key);
|
||||||
|
row.add(value != null ? value : "");
|
||||||
|
exportList.add(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getOperatorText(Integer type) {
|
||||||
|
if (type == null) return "未知运营商";
|
||||||
|
switch(type) {
|
||||||
|
case 1: return "中国移动";
|
||||||
|
case 2: return "中国联通";
|
||||||
|
case 3: return "中国电信";
|
||||||
|
default: return "未知运营商";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getStatusText(Integer status) {
|
||||||
|
if (status == null) return "未知状态";
|
||||||
|
switch(status) {
|
||||||
|
case 1: return "待激活";
|
||||||
|
case 2: return "已激活";
|
||||||
|
case 3: return "停机";
|
||||||
|
case 4: return "注销";
|
||||||
|
case 5: return "库存";
|
||||||
|
case 6: return "可测试";
|
||||||
|
case 7: return "失效";
|
||||||
|
default: return "未知状态";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getNetworkText(String rat) {
|
||||||
|
if (rat == null) return "未知网络";
|
||||||
|
switch(rat) {
|
||||||
|
case "1": return "3G";
|
||||||
|
case "2": return "2G";
|
||||||
|
case "6": return "4G";
|
||||||
|
case "8": return "NB";
|
||||||
|
default: return "未知网络";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private double parseDouble(String value) {
|
||||||
|
try {
|
||||||
|
return value != null ? Double.parseDouble(value) : 0.0;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String formatDouble(double value) {
|
||||||
|
return String.format("%.2f", value);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -37,6 +37,7 @@
|
|||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<div class="layui-inline">
|
<div class="layui-inline">
|
||||||
<button type="submit" class="layui-btn layui-btn-primary" lay-submit lay-filter="searchSubmit"><i class="layui-icon"></i> 搜 索</button>
|
<button type="submit" class="layui-btn layui-btn-primary" lay-submit lay-filter="searchSubmit"><i class="layui-icon"></i> 搜 索</button>
|
||||||
|
<button type="submit" class="layui-btn layui-btn-primary" lay-submit lay-filter="data-export-btn"><i class="layui-icon"></i> 导出</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
@ -158,6 +159,20 @@
|
|||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
form.on('submit(data-export-btn)', function (data) {
|
||||||
|
var searchData = data.field;
|
||||||
|
var url = '/sim/device-mapping/export?';
|
||||||
|
if (searchData.searchType) {
|
||||||
|
url += 'searchType=' + searchData.searchType;
|
||||||
|
}
|
||||||
|
if (searchData.searchContent) {
|
||||||
|
url += '&searchContent=' + encodeURIComponent(searchData.searchContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.location.href = url;
|
||||||
|
return false;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
<fieldset class="table-search-fieldset">
|
<fieldset class="table-search-fieldset">
|
||||||
<legend>搜索信息</legend>
|
<legend>搜索信息</legend>
|
||||||
<div style="margin: 10px 10px 10px 10px">
|
<div style="margin: 10px 10px 10px 10px">
|
||||||
<form class="layui-form layui-form-pane" action="" id="searchForm">
|
<form class="layui-form layui-form-pane" action="" id="searchForm" lay-filter="searchForm">
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<div class="layui-inline">
|
<div class="layui-inline">
|
||||||
<label class="layui-form-label">查询类型</label>
|
<label class="layui-form-label">查询类型</label>
|
||||||
@ -52,6 +52,7 @@
|
|||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<div class="layui-inline">
|
<div class="layui-inline">
|
||||||
<button type="submit" class="layui-btn layui-btn-primary" lay-submit lay-filter="searchSubmit"><i class="layui-icon"></i> 搜 索</button>
|
<button type="submit" class="layui-btn layui-btn-primary" lay-submit lay-filter="searchSubmit"><i class="layui-icon"></i> 搜 索</button>
|
||||||
|
<button type="submit" class="layui-btn layui-btn-primary" lay-submit lay-filter="data-export-btn"><i class="layui-icon"></i> 导出</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
@ -265,6 +266,70 @@
|
|||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
form.on('submit(data-export-btn)', function (data) {
|
||||||
|
layer.open({
|
||||||
|
type: 1,
|
||||||
|
title: '导出选项',
|
||||||
|
shadeClose: true,
|
||||||
|
content: `
|
||||||
|
<div style="padding: 20px;">
|
||||||
|
<div class="layui-form" lay-filter="exportForm">
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">导出范围</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="radio" name="exportRange" value="current" title="当前页" checked>
|
||||||
|
<input type="radio" name="exportRange" value="all" title="全部数据">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<button class="layui-btn" lay-submit lay-filter="confirmExport">确定</button>
|
||||||
|
<button type="reset" class="layui-btn layui-btn-primary" onclick="layer.closeAll()">取消</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
success: function(layero, index) {
|
||||||
|
form.render('radio', 'exportForm');
|
||||||
|
|
||||||
|
// 监听导出确认
|
||||||
|
form.on('submit(confirmExport)', function(formData) {
|
||||||
|
var searchData = data.field;
|
||||||
|
var url = '/sim/export?';
|
||||||
|
if (searchData.searchType) {
|
||||||
|
url += 'searchType=' + searchData.searchType;
|
||||||
|
}
|
||||||
|
if (searchData.searchContent) {
|
||||||
|
url += '&searchContent=' + encodeURIComponent(searchData.searchContent);
|
||||||
|
}
|
||||||
|
if (searchData.status) {
|
||||||
|
url += '&status=' + searchData.status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取当前表格的页大小(limit)
|
||||||
|
var currentLimit = layui.table.cache.simTable ? layui.table.cache.simTable.limit : 20;
|
||||||
|
|
||||||
|
// 添加导出范围参数
|
||||||
|
var exportAll = formData.field.exportRange === 'all';
|
||||||
|
url += '&exportAll=' + exportAll;
|
||||||
|
|
||||||
|
// 如果导出当前页,则传递页大小
|
||||||
|
if (!exportAll) {
|
||||||
|
url += '&pageSize=' + currentLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.location.href = url;
|
||||||
|
layer.close(index);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
//监听Tab切换,重新resize图表,否则显示不出来
|
//监听Tab切换,重新resize图表,否则显示不出来
|
||||||
element.on('tab(data-tab)', function(data){
|
element.on('tab(data-tab)', function(data){
|
||||||
if(data.index === 1 && flowChart) {
|
if(data.index === 1 && flowChart) {
|
||||||
|
|||||||
@ -35,6 +35,7 @@
|
|||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<div class="layui-inline">
|
<div class="layui-inline">
|
||||||
<button type="button" class="layui-btn" onclick="searchSIM()" lay-submit lay-filter="searchSubmit"><i class="layui-icon"></i>搜索</button>
|
<button type="button" class="layui-btn" onclick="searchSIM()" lay-submit lay-filter="searchSubmit"><i class="layui-icon"></i>搜索</button>
|
||||||
|
<button type="button" class="layui-btn layui-btn-primary" lay-submit lay-filter="data-export-btn"><i class="layui-icon"></i> 导出</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
@ -63,6 +64,30 @@
|
|||||||
searchSIM();
|
searchSIM();
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
form.on('submit(data-export-btn)', function (data) {
|
||||||
|
const searchInput = document.getElementById('searchInput');
|
||||||
|
const searchContent = searchInput.value.trim();
|
||||||
|
const searchType = document.querySelector('select[name="searchType"]').value;
|
||||||
|
|
||||||
|
if (!searchContent) {
|
||||||
|
layer.msg('请输入搜索内容');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (searchType === 'iccid' && !/^\d{19,20}$/.test(searchContent)) {
|
||||||
|
layer.msg('ICCID必须是19-20位数字');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (searchType === 'simNumber' && !/^\d{11,13}$/.test(searchContent)) {
|
||||||
|
layer.msg('SIM卡号必须是11-13位数字');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.location.href = `/sim/query/export?type=${searchType}&content=${encodeURIComponent(searchContent)}`;
|
||||||
|
return false;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function searchSIM() {
|
function searchSIM() {
|
||||||
|
|||||||
@ -48,7 +48,7 @@
|
|||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<div class="layui-inline">
|
<div class="layui-inline">
|
||||||
<button type="submit" class="layui-btn layui-btn-primary" lay-submit lay-filter="searchSubmit"><i class="layui-icon"></i> 搜 索</button>
|
<button type="submit" class="layui-btn layui-btn-primary" lay-submit lay-filter="searchSubmit"><i class="layui-icon"></i> 搜 索</button>
|
||||||
<button type="submit" class="layui-btn layui-btn-primary" lay-submit lay-filter="exportSubmit"><i class="layui-icon"></i> 导 出</button>
|
<button type="submit" class="layui-btn layui-btn-primary" lay-submit lay-filter="data-export-btn"><i class="layui-icon"></i> 导出</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
@ -159,10 +159,23 @@
|
|||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
form.on('submit(exportSubmit)', function (data) {
|
form.on('submit(data-export-btn)', function (data) {
|
||||||
var result = $('#searchForm').serialize();
|
var searchData = data.field;
|
||||||
var u = "/sim/traffic-records/export?" + result;
|
var url = '/sim/traffic-records/export?';
|
||||||
window.open(u, "_blank");
|
if (searchData.searchType) {
|
||||||
|
url += 'searchType=' + searchData.searchType;
|
||||||
|
}
|
||||||
|
if (searchData.searchContent) {
|
||||||
|
url += '&searchContent=' + encodeURIComponent(searchData.searchContent);
|
||||||
|
}
|
||||||
|
if (searchData.startTime) {
|
||||||
|
url += '&startTime=' + encodeURIComponent(searchData.startTime);
|
||||||
|
}
|
||||||
|
if (searchData.endTime) {
|
||||||
|
url += '&endTime=' + encodeURIComponent(searchData.endTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.location.href = url;
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user