admin/package-lock.json
@@ -6,7 +6,7 @@ "dependencies": { "@amap/amap-jsapi-loader": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@amap/amap-jsapi-loader/-/amap-jsapi-loader-1.0.1.tgz", "resolved": "https://registry.npmmirror.com/@amap/amap-jsapi-loader/-/amap-jsapi-loader-1.0.1.tgz", "integrity": "sha512-nPyLKt7Ow/ThHLkSvn2etQlUzqxmTVgK7bIgwdBRTg2HK5668oN7xVxkaiRe3YZEzGzfV2XgH5Jmu2T73ljejw==" }, "@babel/code-frame": { admin/src/api/Inspection/ywPatrolPoint.js
@@ -12,6 +12,16 @@ trim: true }) } // 二维码列表 export function exportQrcodes (data) { return request.post('/visitsAdmin/cloudService/business/ywPatrolPoint/exportQrcodes',data, { trim: true, download: true }) } // 导出Excel export function exportExcel (data) { return request.post('/visitsAdmin/cloudService/business/ywPatrolPoint/exportExcel', data, { admin/src/components/base/BaseTable.vue
@@ -182,7 +182,7 @@ containChildrenRows.push(row[this.configData['field.main']]) } } if (containChildrenRows.length > 0) { if (containChildrenRows.length > 0) {我 message = '本次将删除该数据及其子数据,确认删除吗?' } } admin/src/views/Inspection/components/OperaYwPatrolPointWindow.vue
@@ -1,8 +1,8 @@ <template> <GlobalWindow :title="title" :visible.sync="visible" width="620px" :confirm-working="isWorking" @confirm="confirm"> <el-form :model="form" ref="form" :rules="rules"> <el-form-item label="巡检点编码" prop="code"> <el-input v-model="form.code" placeholder="请输入名称" v-trim /> <el-form-item label="巡检点编码" required > <el-input v-model="form.code" disabled readonly placeholder="系统自动生成" v-trim /> </el-form-item> <el-form-item label="巡检点名称" prop="name"> <el-input v-model="form.name" placeholder="请输入巡检点名称" v-trim /> @@ -67,7 +67,6 @@ // 验证规则 rules: { name: [{ required: true, message: '请输入' }], code: [{ required: true, message: '请输入' }], }, isUploading: false, } @@ -87,7 +86,7 @@ this.$nextTick(() => { this.form = { name: '', code: '', // code: '', content: '', imgurl: '', areaId: 0, @@ -182,4 +181,4 @@ margin-bottom: 20px; float: left; } </style> </style> admin/src/views/Inspection/dot.vue
@@ -20,9 +20,11 @@ </el-form> <!-- 表格和分页 --> <template v-slot:table-wrap> <ul class="toolbar" v-permissions="['business:ywpatrolpoint:create', 'business:ywpatrolpoint:delete']"> <ul class="toolbar" v-permissions="['business:ywpatrolpoint:create', 'business:ywpatrolpoint:qrcode', 'business:ywpatrolpoint:delete']"> <li><el-button type="primary" @click="editClick()" icon="el-icon-plus" v-permissions="['business:ywpatrolpoint:create']">新建</el-button></li> <li><el-button type="primary" @click="exportQrcodes()" icon="el-icon-download" v-permissions="['business:ywpatrolpoint:qrcode']">导出全量二维码</el-button></li> <!-- <li><el-button @click="deleteByIdInBatch" icon="el-icon-delete" v-permissions="['business:ywpatrolpoint:delete']">删除</el-button></li> --> </ul> @@ -32,9 +34,11 @@ <el-table-column prop="name" label="巡检点名称" min-width="100px"></el-table-column> <el-table-column prop="deviceName" label="关联设备" min-width="100px"></el-table-column> <el-table-column prop="areaName" label="巡检区域" min-width="100px"></el-table-column> <el-table-column v-if="containPermissions(['business:ywpatrolpoint:update', 'business:ywpatrolpoint:delete'])" label="操作" min-width="120" fixed="right"> <el-table-column v-if="containPermissions(['business:ywpatrolpoint:update','business:ywpatrolpoint:qrcode', 'business:ywpatrolpoint:delete'])" label="操作" min-width="160" fixed="right"> <template slot-scope="{row}"> <el-button type="text" @click="exportQrcodes(row.id)" icon="el-icon-download" v-permissions="['business:ywpatrolpoint:qrcode']">下载二维码</el-button> <el-button type="text" @click="editClick(row)" icon="el-icon-edit" v-permissions="['business:ywpatrolpoint:update']">编辑</el-button> <el-button type="text" @click="deleteById(row)" icon="el-icon-delete" @@ -56,11 +60,12 @@ import Pagination from '@/components/common/Pagination' import OperaYwPatrolPointWindow from './components/OperaYwPatrolPointWindow' import { fetchList } from '@/api/business/category' import { exportQrcodes } from '@/api/Inspection/ywPatrolPoint' export default { name: 'YwPatrolPoint', extends: BaseTable, components: { TableLayout, Pagination, OperaYwPatrolPointWindow }, data() { data () { return { // 搜索 searchForm: { @@ -71,7 +76,7 @@ areaList: [] } }, created() { created () { this.config({ module: '运维巡检点信息表', api: '/Inspection/ywPatrolPoint', @@ -82,7 +87,24 @@ this.getProject() }, methods: { reset() { exportQrcodes (id) { this.$dialog.actionConfirm( '您确认进行该操作吗?','下载操作提示') .then(() => { exportQrcodes({id:id}) .then(response => { this.download(response) }) .catch(e => { this.$tip.apiFailed(e) }) .finally(() => { this.isWorking.export = false }) }) .catch(() => {}) }, reset () { this.searchForm = { name: '', areaId: '', @@ -90,16 +112,16 @@ } this.search() }, getProject() { getProject () { fetchList({ model: { type: 4 }, capacity: 1000, page: 1, page: 1 }).then(res => { this.areaList = res.records || [] }) }, editClick(row) { editClick (row) { if (row && row.id) { this.$refs.operaYwPatrolPointWindow.open('编辑巡检点', row) } else { @@ -107,7 +129,7 @@ } // this.$refs.operaYwPatrolPointWindow.initData() }, changeSel(e) { changeSel (e) { if (e && e.length == 1) { } else if (e && e.length == 2) { this.$set(this.searchForm, 'areaId', e[1]) @@ -115,7 +137,7 @@ } this.search() }, } } } </script> server/system_gateway/src/main/resources/application-dev.yml
@@ -1,9 +1,9 @@ spring: # 数据源配置 datasource: url: jdbc:mysql://sh-cdb-aiskr3vy.sql.tencentcdb.com:62443/funingyunwei?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai username: doumee password: rtjgfEr@&0c0m url: jdbc:mysql://112.26.66.25:3306/funingyunwei?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=GMT%2B8 username: root password: Doumee@168&QWERT driver-class-name: com.mysql.cj.jdbc.Driver type: com.alibaba.druid.pool.DruidDataSource server/system_gateway/src/main/resources/bootstrap.yml
@@ -1,6 +1,6 @@ spring: profiles: active: pro active: dev application: name: system_gateway # 安全配置 server/system_service/src/main/java/com/doumee/biz/system/impl/SystemRoleBizImpl.java
@@ -22,6 +22,7 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import java.util.ArrayList; import java.util.List; @Service @@ -94,14 +95,16 @@ SystemRolePermission deleteDto = new SystemRolePermission(); deleteDto.setRoleId(dto.getRoleId()); systemRolePermissionService.delete(deleteDto); List<SystemRolePermission> newList = new ArrayList<>(); // 新增新的权限 for (Integer permissionId : dto.getPermissionIds()) { SystemRolePermission newRolePermission = new SystemRolePermission(); newRolePermission.setRoleId(dto.getRoleId()); newRolePermission.setPermissionId(permissionId); newRolePermission.setCreateUser(dto.getCreateUser()); systemRolePermissionService.create(newRolePermission); newList.add(newRolePermission); } systemRolePermissionService.createList(newList); } @Override server/system_service/src/main/java/com/doumee/core/utils/Constants.java
@@ -159,6 +159,11 @@ public static final String EVENT_FILES_PRIVATE_DOMAIN ="EVENT_FILES_PRIVATE_DOMAIN" ; public static final String EVENT_FILES_PUBLIC_DOMAIN ="EVENT_FILES_PUBLIC_DOMAIN" ; public static final String YW_CONTRACT_FILE = "YW_CONTRACT_FILE"; public static final String XUNJIAN ="XUNJIAN" ; public static final String XJ_POINT_PREFIX ="XJ_POINT_PREFIX" ; public static final String XJ_POINT_CODE_LENGTH ="XJ_POINT_CODE_LENGTH" ; public static final String XJ_POINT_QRCODE_URL ="XJ_POINT_QRCODE_URL" ; public static final String XJ_RERIRECT_URI ="XJ_RERIRECT_URI" ; public static boolean DEALING_HK_SYNCPRIVILEGE= false; public static boolean DEALING_HK_SYNCDEVICE = false; public static boolean DEALING_HK_SYNCPLATFORM = false; @@ -250,6 +255,12 @@ return sb.toString(); } public static String formartNumString(int length, long l) { return String.format("%0"+length+"d",l ); } public interface VisitIccmStatus{ //访客状态(0:未签到,1:已签到,2:已签退,3:滞留,4:未访问,5:自动签离,6:未签退) int waitSign = 0; @@ -508,6 +519,7 @@ public static final String WX_PLATFORM = "WX_PLATFORM"; public static final String WX_PLATFORM_ACCESS_TOKEN = "WX_PLATFORM_ACCESS_TOKEN"; public static final String WX_AUTH_URL = "WX_AUTH_URL"; public static final String WX_PLATFORM_APPID = "WX_PLATFORM_APPID"; public static final String WX_PLATFORM_SECRET = "WX_PLATFORM_SECRET"; public static final String WX_PLATFORM_AUDIT_VISIT = "WX_PLATFORM_AUDIT_VISIT"; @@ -809,8 +821,8 @@ } public static void main(String[] args) { System.out.println(Constants.checkCarNo("皖A10991")); System.out.println(Constants.checkCarNo("皖AA10991")); System.out.println(Constants.formartNumString(8,1023492384023480l)); // System.out.println(Constants.checkCarNo("皖AA10991")); // System.out.println(Constants.getVehiclePlateNo("湘B140D17").getDescription()); // System.out.println(Constants.getVehiclePlateNo("宿AP0637").getDescription()); server/system_service/src/main/java/com/doumee/service/system/SystemRolePermissionService.java
@@ -88,4 +88,6 @@ * @date 2023/03/21 14:49 */ long count(SystemRolePermission systemRolePermission); Integer createList(List<SystemRolePermission> newList); } server/system_service/src/main/java/com/doumee/service/system/impl/SystemRolePermissionServiceImpl.java
@@ -34,6 +34,14 @@ systemRolePermissionMapper.insert(systemRolePermission); return systemRolePermission.getId(); } @Override public Integer createList(List<SystemRolePermission> list) { if(list ==null || list.size() == 0){ return null; } systemRolePermissionMapper.insert(list); return list.size(); } @Override public void deleteById(Integer id) { server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/YwPatrolPointCloudController.java
@@ -12,6 +12,7 @@ import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import com.doumee.config.annotation.CloudRequiredPermission; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -70,6 +71,14 @@ return ApiResponse.success(null); } @ApiOperation("批量导出二维码") @PostMapping("/exportQrcodes") @CloudRequiredPermission("business:ywpatrolpoint:qrcode") public void exportQrcodes(@RequestBody YwPatrolPoint ywPatrolPoint,HttpServletResponse response,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) { ywPatrolPointService.exportQrcodes(ywPatrolPoint.getId(),response); } @ApiOperation("分页查询") @PostMapping("/page") @CloudRequiredPermission("business:ywpatrolpoint:query") server/visits/dmvisit_admin/src/main/resources/bootstrap.yml
@@ -1,6 +1,6 @@ spring: profiles: active: test active: pro application: name: visitsAdmin # 安全配置 server/visits/dmvisit_service/src/main/java/com/doumee/service/business/YwPatrolPointService.java
@@ -4,6 +4,8 @@ import com.doumee.core.model.PageData; import com.doumee.core.model.PageWrap; import com.doumee.dao.business.model.YwPatrolPoint; import javax.servlet.http.HttpServletResponse; import java.util.List; /** @@ -48,6 +50,7 @@ * @param ywPatrolPoint 实体对象 */ void updateById(YwPatrolPoint ywPatrolPoint); void exportQrcodes(Integer id, HttpServletResponse ywPatrolPoint); /** * 批量主键更新 server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/YwPatrolPointServiceImpl.java
@@ -22,14 +22,32 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.github.yulichang.wrapper.MPJLambdaWrapper; import com.google.zxing.BarcodeFormat; import com.google.zxing.EncodeHintType; import com.google.zxing.MultiFormatWriter; import com.google.zxing.client.j2se.MatrixToImageWriter; import com.google.zxing.common.BitMatrix; import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; import com.google.zxing.qrcode.encoder.ByteMatrix; import com.google.zxing.qrcode.encoder.Encoder; import com.google.zxing.qrcode.encoder.QRCode; import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import java.util.Date; import java.util.List; import java.util.Objects; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.net.URLEncoder; import java.nio.charset.Charset; import java.nio.file.FileSystems; import java.nio.file.Path; import java.util.*; /** * 运维巡检点信息表Service实现 @@ -49,15 +67,21 @@ @Override public Integer create(YwPatrolPoint ywPatrolPoint) { if(Objects.isNull(ywPatrolPoint) || Objects.isNull(ywPatrolPoint.getCode()) // || Objects.isNull(ywPatrolPoint.getCode()) || Objects.isNull(ywPatrolPoint.getName()) ){ throw new BusinessException(ResponseStatus.BAD_REQUEST); } if(ywPatrolPointMapper.selectCount(new QueryWrapper<YwPatrolPoint>().lambda().eq(YwPatrolPoint::getIsdeleted,Constants.ZERO) .eq(YwPatrolPoint::getCode,ywPatrolPoint.getCode()))>Constants.ZERO){ throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"巡检点编码重复!"); String pre = systemDictDataBiz.queryByCode(Constants.XUNJIAN,Constants.XJ_POINT_PREFIX).getCode(); int length = 8; try { length = Integer.parseInt(systemDictDataBiz.queryByCode(Constants.XUNJIAN,Constants.XJ_POINT_CODE_LENGTH).getCode()); }catch (Exception e){ } long num = ywPatrolPointMapper.selectCount(new QueryWrapper<YwPatrolPoint>()); ywPatrolPoint.setCode(pre+Constants.formartNumString (length,(num+1))); LoginUserInfo loginUserInfo = ywPatrolPoint.getLoginUserInfo(); ywPatrolPoint.setCreateDate(new Date()); ywPatrolPoint.setCreator(loginUserInfo.getId()); @@ -82,10 +106,11 @@ @Override public void deleteById(Integer id, LoginUserInfo user) { ywPatrolPointMapper.update(new UpdateWrapper<YwPatrolPoint>().lambda().set(YwPatrolPoint::getIsdeleted,Constants.ONE) ywPatrolPointMapper.update(new UpdateWrapper<YwPatrolPoint>().lambda() .set(YwPatrolPoint::getIsdeleted,Constants.ONE) .set(YwPatrolPoint::getEditDate, DateUtil.getCurrDateTime()) .set(YwPatrolPoint::getEditor,user.getId()) .eq(YwPatrolPoint::getId,user.getId()) .eq(YwPatrolPoint::getId,id) ); } @@ -94,7 +119,120 @@ UpdateWrapper<YwPatrolPoint> deleteWrapper = new UpdateWrapper<>(ywPatrolPoint); ywPatrolPointMapper.delete(deleteWrapper); } @Override public void exportQrcodes(Integer id, HttpServletResponse response){ try { List<File> fileList = new ArrayList<>(); List<YwPatrolPoint> bikesList = ywPatrolPointMapper.selectList(new QueryWrapper<YwPatrolPoint>().lambda() .eq(YwPatrolPoint::getIsdeleted,Constants.ZERO) .eq(id!=null,YwPatrolPoint::getId,id) ); if(bikesList== null || bikesList.size() == 0){ throw new BusinessException(ResponseStatus.DATA_EMPTY); } // 创建临时文件的前缀和后缀 String path = systemDictDataBiz.queryByCode(Constants.WX_PLATFORM,Constants.WX_AUTH_URL).getCode(); String uri = systemDictDataBiz.queryByCode(Constants.XUNJIAN,Constants.XJ_RERIRECT_URI).getCode(); String appId = systemDictDataBiz.queryByCode(Constants.WX_PLATFORM,Constants.WX_PLATFORM_APPID).getCode() ; // 创建临时文件 for(YwPatrolPoint l : bikesList){ if(StringUtils.isNotBlank(l.getCode())){ String redirectUri = uri.replace("${ywid}",l.getCode()); String url = path.replace("${url}",URLEncoder.encode(redirectUri)).replace("${appid}",appId); File file = generateQRCodeImage(url,100,100,l.getCode()+".png"); if(file!=null && file.isFile()){ fileList.add(file); } } } if(fileList == null || fileList.size() == 0){ throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(),"对不起,下载内容为空,操作失败!"); } String fileName = "巡检点二维码导出_"+System.currentTimeMillis()+".zip" ; String encodeFileName =URLEncoder.encode(fileName, Charset.forName("UTF-8").toString())+".zip"; response.setHeader("Content-Disposition","attachment;filename=" + encodeFileName); response.setContentType("application/octet-stream"); response.setHeader("eva-opera-type", "download"); response.setHeader("eva-download-filename", encodeFileName); packFilesToZip(fileList,response.getOutputStream()); } catch (IOException e) { throw new BusinessException(ResponseStatus.EXPORT_EXCEL_ERROR, e); } } public static File generateQRCodeImage(String text, int width, int height, String fileName) { try { // 创建二维码数据矩阵 Map<EncodeHintType, Object> hints = new HashMap<>(); hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); // 设置字符编码为UTF-8 hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 设置纠错等级为H hints.put(EncodeHintType.MARGIN, 0); // 设置白边为0 BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE , width, height, hints); // 保存二维码图片到文件系统 File f = new File("temp/"); if(!f.exists()){ f.mkdirs(); } // bitMatrix = renderResult(bitMatrix,width,height); Path path = FileSystems.getDefault().getPath("temp/"+fileName); MatrixToImageWriter.writeToPath(bitMatrix, "PNG", path); // 保存为PNG格式的图片 return path.toFile(); }catch (Exception e){ e.printStackTrace(); } return null; } public static void main(String[] args) { File f =generateQRCodeImage("dj少时诵诗书少时诵诗书是撒是撒是撒",100,100,UUID.randomUUID().toString()+".png"); System.out.println(f.getAbsolutePath()); } private static BitMatrix renderResult(BitMatrix input, int width, int height) { if (input == null) { return null; } int inputWidth = input.getWidth(); int inputHeight = input.getHeight(); // 依据用户的输入宽高,计算最后的输出宽高 int outputWidth = Math.max(width, inputWidth); int outputHeight = Math.max(height, inputHeight); //计算缩放比例 int multiple = Math.min(outputWidth / inputWidth, outputHeight / inputHeight); BitMatrix output = new BitMatrix(outputWidth, outputHeight); int inputY = 0; // 嵌套循环,将ByteMatrix的内容计算padding后转换成BitMatrix for (int outputY = 0; inputY < inputHeight; outputY += multiple) { int inputX = 0; for (int outputX = 0; inputX < inputWidth; outputX += multiple) { if (input.get(inputX, inputY)) { output.setRegion(outputX, outputY, multiple, multiple); } inputX++; } inputY++; } return output; } public static void packFilesToZip(List<File> files, ServletOutputStream os) throws IOException { try (ZipArchiveOutputStream zipOutputStream = new ZipArchiveOutputStream(os)) { for (File file : files) { ZipArchiveEntry entry = new ZipArchiveEntry(file.getName()); zipOutputStream.putArchiveEntry(entry); try (FileInputStream fileInputStream = new FileInputStream(file)) { byte[] buffer = new byte[1024]; int length; while ((length = fileInputStream.read(buffer)) > 0) { zipOutputStream.write(buffer, 0, length); } } zipOutputStream.closeArchiveEntry(); } } } @Override public void deleteByIdInBatch(List<Integer> ids, LoginUserInfo user) { if (CollectionUtils.isEmpty(ids)) { server/visits/dmvisit_service/src/main/resources/application-dev.yml
@@ -1,9 +1,9 @@ spring: # 数据源配置 datasource: url: jdbc:mysql://sh-cdb-aiskr3vy.sql.tencentcdb.com:62443/funingyunwei?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai username: doumee password: rtjgfEr@&0c0m url: jdbc:mysql://112.26.66.25:3306/funingyunwei?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=GMT%2B8 username: root password: Doumee@168&QWERT driver-class-name: com.mysql.cj.jdbc.Driver type: com.alibaba.druid.pool.DruidDataSource redis: