diff --git a/eladmin-system/pom.xml b/eladmin-system/pom.xml index 4fc7d50ec..2b9f99844 100644 --- a/eladmin-system/pom.xml +++ b/eladmin-system/pom.xml @@ -19,6 +19,21 @@ + + me.zhengjie + wpsadmin-wpsbill + 2.4 + + + me.zhengjie + eladmin-common + + + me.zhengjie + eladmin-logging + + + me.zhengjie diff --git a/eladmin-system/src/main/java/me/zhengjie/AppRun.java b/eladmin-system/src/main/java/me/zhengjie/AppRun.java index d0540c4f6..03a694265 100644 --- a/eladmin-system/src/main/java/me/zhengjie/AppRun.java +++ b/eladmin-system/src/main/java/me/zhengjie/AppRun.java @@ -67,4 +67,14 @@ public ServletWebServerFactory webServerFactory() { public String index() { return "Backend service started successfully"; } + + /** + * 访问首页提示 + * @return / + */ + @GetMapping("/test") + @AnonymousAccess + public String test() { + return "test"; + } } diff --git a/eladmin-system/src/main/resources/config/application-dev.yml b/eladmin-system/src/main/resources/config/application-dev.yml index 30aa7e046..684465e90 100644 --- a/eladmin-system/src/main/resources/config/application-dev.yml +++ b/eladmin-system/src/main/resources/config/application-dev.yml @@ -4,9 +4,9 @@ spring: druid: db-type: com.alibaba.druid.pool.DruidDataSource driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy - url: jdbc:log4jdbc:mysql://localhost:3306/eladmin?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false - username: root - password: 123456 + url: jdbc:log4jdbc:mysql://192.168.10.10:3306/wps_bill?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false + username: homestead + password: secret # 初始连接数 initial-size: 5 # 最小连接数 diff --git a/eladmin-system/src/main/resources/config/application.yml b/eladmin-system/src/main/resources/config/application.yml index 271051cea..b125533f2 100644 --- a/eladmin-system/src/main/resources/config/application.yml +++ b/eladmin-system/src/main/resources/config/application.yml @@ -1,5 +1,5 @@ server: - port: 8000 + port: 9300 spring: freemarker: @@ -24,7 +24,7 @@ spring: redis: #数据库索引 database: 0 - host: 127.0.0.1 + host: 192.168.10.10 port: 6379 password: #连接超时时间 diff --git a/pom.xml b/pom.xml index baf623aa5..c6f51670c 100644 --- a/pom.xml +++ b/pom.xml @@ -15,6 +15,7 @@ eladmin-system eladmin-tools eladmin-generator + wpsadmin-wpsbill EL-ADMIN后台管理系统 diff --git a/wpsadmin-wpsbill/pom.xml b/wpsadmin-wpsbill/pom.xml new file mode 100644 index 000000000..fe3e539ef --- /dev/null +++ b/wpsadmin-wpsbill/pom.xml @@ -0,0 +1,28 @@ + + + + eladmin + me.zhengjie + 2.4 + + 4.0.0 + + wpsadmin-wpsbill + 账单模块 + + + me.zhengjie + eladmin-common + 2.4 + + + me.zhengjie + eladmin-logging + 2.4 + compile + + + + \ No newline at end of file diff --git a/wpsadmin-wpsbill/src/main/java/me/zhengjie/domain/BillDetail.java b/wpsadmin-wpsbill/src/main/java/me/zhengjie/domain/BillDetail.java new file mode 100644 index 000000000..e53a5441e --- /dev/null +++ b/wpsadmin-wpsbill/src/main/java/me/zhengjie/domain/BillDetail.java @@ -0,0 +1,77 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.domain; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.bean.copier.CopyOptions; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.hibernate.annotations.CreationTimestamp; +import javax.persistence.*; +import javax.validation.constraints.NotBlank; +import java.io.Serializable; +import java.sql.Timestamp; +import java.time.LocalDate; +import java.util.Date; + +/** + * 邮件配置类,数据存覆盖式存入数据存 + * @author Zheng Jie + * @date 2018-12-26 + */ +@Entity +@Data +@Table(name = "bill_origin_detail") +public class BillDetail implements Serializable { + + @Id + @Column(name = "id") + @ApiModelProperty(value = "ID", hidden = true) + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @NotBlank + @ApiModelProperty(value = "厂商") + private String platform; + + @NotBlank + @ApiModelProperty(value = "费用标题") + private String title; + + @NotBlank + @ApiModelProperty(value = "费用类型") + private String type; + + @NotBlank + @ApiModelProperty(value = "标识") + private String key; + + @NotBlank + @ApiModelProperty(value = "费用金额") + private Float fee; + + @NotBlank + @ApiModelProperty(value = "费用日期-年月") + private LocalDate month; + + @CreationTimestamp + @ApiModelProperty(value = "创建日期") + private Timestamp create_time; + + public void copy(BillDetail source){ + BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true)); + } +} diff --git a/wpsadmin-wpsbill/src/main/java/me/zhengjie/excel/KsyunBillExcel.java b/wpsadmin-wpsbill/src/main/java/me/zhengjie/excel/KsyunBillExcel.java new file mode 100644 index 000000000..3915e1f8f --- /dev/null +++ b/wpsadmin-wpsbill/src/main/java/me/zhengjie/excel/KsyunBillExcel.java @@ -0,0 +1,88 @@ +package me.zhengjie.excel; + +import com.alibaba.fastjson.JSON; +import me.zhengjie.domain.BillDetail; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.xssf.usermodel.XSSFRow; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.text.ParseException; +import java.time.LocalDate; +import java.util.*; +import java.util.regex.Pattern; + +public class KsyunBillExcel { + private static boolean isInteger(String str) { + if (null == str || "".equals(str)) { + return false; + } + Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$"); + return pattern.matcher(str).matches(); + } + + private static boolean isDouble(String str) { + if (null == str || "".equals(str)) { + return false; + } + Pattern pattern = Pattern.compile("^[-\\+]?[.\\d]*$"); + return pattern.matcher(str).matches(); + } + + private static boolean isNumberic(String str){ + return isInteger(str) || isDouble(str); + } + + public static List read(File file) throws IOException, ParseException { + XSSFWorkbook hssfWorkBOok = new XSSFWorkbook(new FileInputStream(file)); + XSSFSheet sheet = hssfWorkBOok.getSheetAt(0); + int lastRowNum = sheet.getLastRowNum(); + List list= new ArrayList<>(); + HashMap map = new HashMap<>(); + map.put("title", 6); + map.put("type", 2); + map.put("key", 5); + map.put("fee", 7); + + LocalDate billMonth=LocalDate.now().withDayOfMonth(1); + for (int i = 0; i <= lastRowNum; i++) {//遍历每一行 + //3.获得要解析的行 + XSSFRow row = sheet.getRow(i); + HashMap tmpDetail = new HashMap<>(); + + for(HashMap.Entry enter : map.entrySet()) { + String mapKey = enter.getKey(); + Integer cellIndex = enter.getValue(); + Cell cell = row.getCell(cellIndex); + Object cellValue; + switch (cell.getCellTypeEnum()) { + case NUMERIC: + cellValue = (cell.getNumericCellValue()); + break; + case STRING: + cellValue = cell.getStringCellValue(); + break; + default: + cellValue = ""; + } + + tmpDetail.put(mapKey, cellValue); + } + // 金额非数字、为0,一律过滤 + if(tmpDetail.get("fee").equals("") || tmpDetail.get("fee").equals("0")){ + continue; + } + + BillDetail detail = JSON.parseObject(JSON.toJSONString(tmpDetail), BillDetail.class); + detail.setPlatform("金山云"); + detail.setMonth(billMonth); + + list.add(detail); + } + + return list; + } +} diff --git a/wpsadmin-wpsbill/src/main/java/me/zhengjie/repository/BillDetailRepository.java b/wpsadmin-wpsbill/src/main/java/me/zhengjie/repository/BillDetailRepository.java new file mode 100644 index 000000000..4d39a2345 --- /dev/null +++ b/wpsadmin-wpsbill/src/main/java/me/zhengjie/repository/BillDetailRepository.java @@ -0,0 +1,7 @@ +package me.zhengjie.repository; + +import me.zhengjie.domain.BillDetail; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface BillDetailRepository extends JpaRepository { +} diff --git a/wpsadmin-wpsbill/src/main/java/me/zhengjie/rest/BillController.java b/wpsadmin-wpsbill/src/main/java/me/zhengjie/rest/BillController.java new file mode 100644 index 000000000..c3e9f9fa5 --- /dev/null +++ b/wpsadmin-wpsbill/src/main/java/me/zhengjie/rest/BillController.java @@ -0,0 +1,99 @@ +package me.zhengjie.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import me.zhengjie.annotation.Log; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.domain.BillDetail; +import me.zhengjie.service.BillDetailService; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import me.zhengjie.annotation.AnonymousAccess; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/** + * @author Huangjun + * @date 2020年7月8日 + */ +@Slf4j +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/bill") +@Api(tags = "账单:账单系统") +public class BillController { + private final BillDetailService billDetailService; + + @AnonymousAccess + @ApiOperation("测试代码,仅测试") + @GetMapping("/ts") + public ResponseEntity getCode(){ + // 验证码信息 + Map imgResult = new HashMap(2){{ + put("img", "aaaa"); + put("uuid", "ssss"); + }}; + return ResponseEntity.ok(imgResult); + } + + @AnonymousAccess + @ApiOperation("测试代码,仅测试") + @GetMapping("/list") + public ResponseEntity getList(){ + //从db获取数据 + Map imgResult = new HashMap(2){{ + put("img", "aaaa"); + put("uuid", "ssss"); + }}; + return ResponseEntity.ok(imgResult); + } + + @AnonymousAccess + @ApiOperation("测试代码,仅测试") + @GetMapping("/data") + public ResponseEntity getData(){ + //从db获取数据 + return new ResponseEntity<>(billDetailService.find(), HttpStatus.OK); + } + + @Log("新增账单") + @AnonymousAccess + @ApiOperation(value = "新增账单") + @PostMapping + public ResponseEntity create(@Validated @RequestBody BillDetail resources){ + billDetailService.create(resources); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @Log("修改账单") + @AnonymousAccess + @ApiOperation(value = "修改账单") + @PutMapping + public ResponseEntity update(@Validated @RequestBody BillDetail resources){ + billDetailService.update(resources); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("删除账单") + @AnonymousAccess + @ApiOperation(value = "删除账单") + @DeleteMapping + public ResponseEntity delete(@RequestBody Set ids){ + billDetailService.delete(ids); + return new ResponseEntity<>(HttpStatus.OK); + } + + @ApiOperation("上传账单") + @AnonymousAccess + @PostMapping(value = "/upload") + public ResponseEntity uploadBill(@RequestParam MultipartFile bill) throws IOException { + return new ResponseEntity<>(billDetailService.uploadBill(bill), HttpStatus.OK); + } +} diff --git a/wpsadmin-wpsbill/src/main/java/me/zhengjie/service/BillDetailService.java b/wpsadmin-wpsbill/src/main/java/me/zhengjie/service/BillDetailService.java new file mode 100644 index 000000000..a57a26bfd --- /dev/null +++ b/wpsadmin-wpsbill/src/main/java/me/zhengjie/service/BillDetailService.java @@ -0,0 +1,52 @@ +package me.zhengjie.service; + +import me.zhengjie.domain.BillDetail; +import org.springframework.web.multipart.MultipartFile; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Map; +import java.util.Set; + +public interface BillDetailService { + /** + * 账单更新 + * @param billDetail 账单信息 + * @param old 旧账单 + * @return BillDetail + * @throws Exception + */ + BillDetail config(BillDetail billDetail, BillDetail old) throws Exception; + + + /** + * 查询配置 + * @return EmailConfig 邮件配置 + */ + BillDetail find(); + + /** + * 创建 + * @param billDetail / + */ + void create(BillDetail billDetail); + + /** + * 编辑 + * @param billDetail / + */ + void update(BillDetail billDetail); + + /** + * 删除 + * @param ids / + */ + void delete(Set ids); + + /** + * 上传账单 + * @param file 文件 + * @return / + */ + Map uploadBill(MultipartFile file) throws IOException; +} diff --git a/wpsadmin-wpsbill/src/main/java/me/zhengjie/service/impl/BillDetailServiceImpl.java b/wpsadmin-wpsbill/src/main/java/me/zhengjie/service/impl/BillDetailServiceImpl.java new file mode 100644 index 000000000..4ff21cc98 --- /dev/null +++ b/wpsadmin-wpsbill/src/main/java/me/zhengjie/service/impl/BillDetailServiceImpl.java @@ -0,0 +1,94 @@ +package me.zhengjie.service.impl; + +import lombok.RequiredArgsConstructor; +import me.zhengjie.config.FileProperties; +import me.zhengjie.domain.BillDetail; +import me.zhengjie.excel.KsyunBillExcel; +import me.zhengjie.repository.BillDetailRepository; +import me.zhengjie.service.BillDetailService; +import me.zhengjie.utils.FileUtil; +import me.zhengjie.utils.SecurityUtils; +import me.zhengjie.utils.StringUtils; +import me.zhengjie.utils.ValidationUtil; +import org.apache.poi.hssf.usermodel.HSSFRow; +import org.apache.poi.hssf.usermodel.HSSFSheet; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.xssf.usermodel.XSSFRow; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.*; + +/** + * @author Zheng Jie + * @date 2018-12-26 + */ +@Service +@RequiredArgsConstructor +@CacheConfig(cacheNames = "billDetail") +public class BillDetailServiceImpl implements BillDetailService { + + private final BillDetailRepository billDetailRepository; + private final FileProperties properties; + + @Override + public BillDetail config(BillDetail billDetail, BillDetail old) throws Exception { + return null; + } + + @Override + @Cacheable(key = "'id:1'") + public BillDetail find() { + Optional billDetail = billDetailRepository.findById(1L); + return billDetail.orElseGet(BillDetail::new); + } + + + @Override + @Transactional(rollbackFor = Exception.class) + public void create(BillDetail resources) { + billDetailRepository.save(resources); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(BillDetail resources) { + BillDetail billDetail = billDetailRepository.findById(resources.getId()).orElseGet(BillDetail::new); + ValidationUtil.isNull(billDetail.getId(),"BillDetail","id",resources.getId()); + billDetail.copy(resources); + billDetailRepository.save(billDetail); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Set ids) { + for (Long id : ids) { + billDetailRepository.deleteById(id); + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Map uploadBill(MultipartFile multipartFile) throws IOException { + File file = FileUtil.upload(multipartFile, properties.getPath().getPath()); + // excel 文件内容处理 + List data = new ArrayList<>(); + try { + data = KsyunBillExcel.read(file); + }catch (Exception exception) { + String err = "erro"; + } + + return new HashMap(){{put("filePath", "ss");}}; + } +}