Sfoglia il codice sorgente

交班导出、维修信息

drew 5 anni fa
parent
commit
efcb7c1961

+ 1 - 1
pom.xml

@@ -304,7 +304,7 @@
         <dependency>
             <groupId>com.alibaba</groupId>
             <artifactId>fastjson</artifactId>
-            <version>1.2.37</version>
+            <version>1.2.68</version>
         </dependency>
 
         <dependency>

+ 3 - 9
src/main/java/com/izouma/zhumj/domain/RepairInfo.java

@@ -35,21 +35,15 @@ public class RepairInfo extends BaseEntity {
     private Long bedId;
 
     @ManyToOne(fetch = FetchType.LAZY)
-    @JoinColumn(name = "storeId", insertable = false, updatable = false, foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
-    @NotFound(action = NotFoundAction.IGNORE)
-    @JsonIgnore
+    @JoinColumn(name = "storeId", insertable = false, updatable = false)
     private StoreInfo storeInfo;
 
     @ManyToOne(fetch = FetchType.LAZY)
-    @JoinColumn(name = "roomId", insertable = false, updatable = false, foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
-    @NotFound(action = NotFoundAction.IGNORE)
-    @JsonIgnore
+    @JoinColumn(name = "roomId", insertable = false, updatable = false)
     private RoomInfo roomInfo;
 
     @ManyToOne(fetch = FetchType.LAZY)
-    @JoinColumn(name = "bedId", insertable = false, updatable = false, foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
-    @NotFound(action = NotFoundAction.IGNORE)
-    @JsonIgnore
+    @JoinColumn(name = "bedId", insertable = false, updatable = false)
     private BedInfo bedInfo;
 
     @ApiModelProperty(value = "维修时间", name = "repairTime")

+ 3 - 1
src/main/java/com/izouma/zhumj/dto/client/ClientRoomInfoDTO.java

@@ -19,7 +19,9 @@ import java.time.LocalDateTime;
 @ApiModel(value = "客户端信息", description = "客户端信息")
 public class ClientRoomInfoDTO {
     @ApiModelProperty(value = "房间ID", name = "roomId")
-    private Long          roomId;
+    private Long roomId;
+    @ApiModelProperty(value = "床位ID", name = "bedId")
+    private Long bedId;
     @ApiModelProperty(value = "入住ID", name = "checkInfoId")
     private Long          checkinInfoId;
     @ApiModelProperty(value = "入住时间", name = "checkinTime")

+ 69 - 0
src/main/java/com/izouma/zhumj/dto/report/ShiftReport.java

@@ -1,5 +1,10 @@
 package com.izouma.zhumj.dto.report;
 
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.annotation.write.style.ColumnWidth;
+import com.alibaba.excel.annotation.write.style.ContentLoopMerge;
+import com.alibaba.excel.annotation.write.style.OnceAbsoluteMerge;
 import com.izouma.zhumj.enums.DepositRefundType;
 import com.izouma.zhumj.enums.PayMethod;
 import lombok.AllArgsConstructor;
@@ -37,6 +42,7 @@ public class ShiftReport {
     @NoArgsConstructor
     @AllArgsConstructor
     @Builder
+    @ExcelIgnoreUnannotated
     public static class Fee {
         private Long          feeId;
         private String        feeName;
@@ -72,4 +78,67 @@ public class ShiftReport {
         private String     name;
         private BigDecimal money;
     }
+
+
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @Builder
+    @ExcelIgnoreUnannotated
+    public static class FeeExcel {
+        @ExcelProperty({"本班账务发生合计", "费用名称"})
+        private String     feeName;
+        @ExcelProperty({"本班账务发生合计", "发生金额"})
+        private BigDecimal amount;
+        @ExcelProperty({"本班账务发生合计", "调整金额"})
+        private BigDecimal adjust;
+        @ExcelProperty({"本班账务发生合计", "总计"})
+        private BigDecimal total;
+    }
+
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @Builder
+    @ExcelIgnoreUnannotated
+    public static class DepositExcel {
+        @ExcelProperty({"本班押金发生合计", "收取"})
+        private BigDecimal amount;
+        @ExcelProperty({"本班押金发生合计", "退还"})
+        private BigDecimal refund;
+        @ExcelProperty({"本班押金发生合计", "总计"})
+        private BigDecimal total;
+    }
+
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @Builder
+    @ExcelIgnoreUnannotated
+    public static class FeeDetailExcel {
+        @ExcelProperty({"本班收退款明细", "费用名称"})
+        private String        feeName;
+        @ExcelProperty({"本班收退款明细", "发生金额"})
+        private BigDecimal    amount;
+        @ExcelProperty({"本班收退款明细", "时间"})
+        private LocalDateTime time;
+    }
+
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @Builder
+    @ExcelIgnoreUnannotated
+    public static class DepositDetailExcel {
+        @ExcelProperty({"本班押金收退明细", "类型"})
+        private String        type;
+        @ExcelProperty({"本班押金收退明细", "姓名"})
+        private String        name;
+        @ExcelProperty({"本班押金收退明细", "房间"})
+        private String        room;
+        @ExcelProperty({"本班押金收退明细", "金额"})
+        private BigDecimal    amount;
+        @ExcelProperty({"本班押金收退明细", "时间"})
+        private LocalDateTime time;
+    }
 }

+ 1 - 1
src/main/java/com/izouma/zhumj/service/ShiftHandoverService.java

@@ -133,7 +133,7 @@ public class ShiftHandoverService {
 //                .build());
         for (RechargeRecord rechargeRecord : rechargeRecordList) {
             feeDetailList.add(ShiftReport.Fee.builder()
-                    .feeName("微信实付-" + rechargeRecord.getRemark())
+                    .feeName("微信实付")
                     .name(userRepo.findFirstByIdNo(rechargeRecord.getIdNo()).getRealName())
                     .amount(rechargeRecord.getAmount())
                     .isPersonalFee(true)

+ 1 - 0
src/main/java/com/izouma/zhumj/service/client/ClientRoomInfoService.java

@@ -70,6 +70,7 @@ public class ClientRoomInfoService {
                 .orElseThrow(new BusinessException("无记录"));
         ClientRoomInfoDTO clientRoomInfoDTO = ClientRoomInfoDTO.builder()
                 .roomId(checkinInfo.getRoomId())
+                .bedId(checkinInfo.getBedId())
                 .checkinInfoId(checkinInfo.getId())
                 .checkInType(checkinInfo.getCheckInType())
                 .storeName(checkinInfo.getStoreInfo().getStoreName())

+ 4 - 4
src/main/java/com/izouma/zhumj/utils/excel/ExcelUtils.java

@@ -163,10 +163,10 @@ public class ExcelUtils<T> {
         cellStyle.setAlignment(HorizontalAlignment.CENTER); // 居中设置
         cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
         cellStyle.setWrapText(true);
-        cellStyle.setBorderRight(BorderStyle.NONE);
-        cellStyle.setBorderLeft(BorderStyle.NONE);
-        cellStyle.setBorderTop(BorderStyle.NONE);
-        cellStyle.setBorderBottom(BorderStyle.NONE);
+        cellStyle.setBorderRight(BorderStyle.THIN);
+        cellStyle.setBorderLeft(BorderStyle.THIN);
+        cellStyle.setBorderTop(BorderStyle.THIN);
+        cellStyle.setBorderBottom(BorderStyle.THIN);
         cellStyle.setFont(cellStyleFont);
         return cellStyle;
     }

+ 92 - 27
src/main/java/com/izouma/zhumj/web/ShiftHandoverController.java

@@ -1,7 +1,16 @@
 package com.izouma.zhumj.web;
 
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.ExcelWriter;
+import com.alibaba.excel.write.metadata.WriteSheet;
+import com.alibaba.excel.write.metadata.WriteTable;
+import com.alibaba.excel.write.style.column.SimpleColumnWidthStyleStrategy;
+import com.alibaba.excel.write.style.row.SimpleRowHeightStyleStrategy;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
 import com.izouma.zhumj.domain.ShiftHandover;
 import com.izouma.zhumj.domain.User;
+import com.izouma.zhumj.domain.sale.BillDetail;
 import com.izouma.zhumj.dto.PageQuery;
 import com.izouma.zhumj.dto.report.ShiftReport;
 import com.izouma.zhumj.excel.CellModel;
@@ -13,17 +22,23 @@ import com.izouma.zhumj.service.ShiftHandoverService;
 import com.izouma.zhumj.utils.DateTimeUtils;
 import com.izouma.zhumj.utils.ObjUtils;
 import com.izouma.zhumj.utils.SecurityUtils;
+import com.izouma.zhumj.utils.excel.BooleanConverter;
 import com.izouma.zhumj.utils.excel.ExcelUtils;
+import com.izouma.zhumj.utils.excel.LocalDateConverter;
+import com.izouma.zhumj.utils.excel.LocalDateTimeConverter;
+import lombok.AllArgsConstructor;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
+import java.io.UnsupportedEncodingException;
 import java.math.BigDecimal;
 import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
 import java.time.LocalDateTime;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.function.BiConsumer;
@@ -31,17 +46,11 @@ import java.util.stream.Collectors;
 
 @RestController
 @RequestMapping("/shiftHandover")
+@AllArgsConstructor
 public class ShiftHandoverController extends BaseController {
-    /*generatedStart*/
-    @Autowired
     private ShiftHandoverService shiftHandoverService;
+    private ShiftHandoverRepo    shiftHandoverRepo;
 
-    @Autowired
-    private ShiftHandoverRepo shiftHandoverRepo;
-    /*generatedEnd*/
-
-    /*generatedStart*/
-    //@PreAuthorize("hasRole('ADMIN')")
     @PostMapping("/save")
     public ShiftHandover save(@RequestBody ShiftHandover record) {
         if (record.getId() != null) {
@@ -52,8 +61,6 @@ public class ShiftHandoverController extends BaseController {
         return shiftHandoverRepo.save(record);
     }
 
-
-    //@PreAuthorize("hasRole('ADMIN')")
     @GetMapping("/all")
     public Page<ShiftHandover> all(PageQuery pageQuery) {
         return shiftHandoverRepo.findAll(toSpecification(pageQuery, ShiftHandover.class), toPageRequest(pageQuery));
@@ -75,7 +82,6 @@ public class ShiftHandoverController extends BaseController {
         List<ShiftHandover> data = all(pageQuery).getContent();
         ExcelUtils.export(response, data);
     }
-    /*generatedEnd*/
 
     @GetMapping("/shiftStartTime")
     public LocalDateTime shiftStartTime(@RequestParam Long storeId) {
@@ -237,22 +243,81 @@ public class ShiftHandoverController extends BaseController {
                 .to(response.getOutputStream());
     }
 
-    private int min(int a, int b) {
-        if (a < b) {
-            int t = a;
-            a = b;
-            b = t;
-        }
-        while (b != 0) {
-            if (a == b) {
-                return a;
-            } else {
-                int k = a % b;
-                a = b;
-                b = k;
-            }
-        }
-        return a;
+    @GetMapping("/excel/{id}")
+    @ResponseBody
+    public void excel(@PathVariable Long id, HttpServletResponse response) throws IOException {
+        ShiftHandover shiftHandover = shiftHandoverRepo.findById(id).orElseThrow(new BusinessException("无记录"));
+        JSONObject jsonObject = JSON.parseObject(shiftHandover.getFeeReport());
+        export(jsonObject, response);
+    }
+
+    @PostMapping("/excelData")
+    @ResponseBody
+    public void excelData(@RequestBody JSONObject data, HttpServletResponse response) throws IOException {
+        export(data, response);
     }
+
+    private void export(JSONObject jsonObject, HttpServletResponse response) throws IOException {
+        List<ShiftReport.FeeExcel> feeExcelList = jsonObject.getJSONArray("feeList")
+                .toJavaList(ShiftReport.Fee.class)
+                .stream()
+                .map(fee -> ShiftReport.FeeExcel.builder()
+                        .feeName(fee.getFeeName())
+                        .amount(fee.getAmount())
+                        .adjust(fee.getAdjust())
+                        .total(fee.getAmount().add(fee.getAdjust()))
+                        .build())
+                .collect(Collectors.toList());
+        List<ShiftReport.DepositDetail> depositDetailList = jsonObject.getJSONArray("depositDetailList")
+                .toJavaList(ShiftReport.DepositDetail.class);
+        List<ShiftReport.DepositDetailExcel> depositDetailExcelList = depositDetailList.stream()
+                .map(depositDetail -> ShiftReport.DepositDetailExcel.builder()
+                        .type(depositDetail.isRefund() ? "退还" : "收取")
+                        .amount(depositDetail.getAmount())
+                        .name(depositDetail.getName())
+                        .room(depositDetail.getRoomName())
+                        .time(depositDetail.getTime())
+                        .build())
+                .collect(Collectors.toList());
+        ShiftReport.DepositExcel depositExcel = jsonObject.getObject("deposit", ShiftReport.DepositExcel.class);
+        List<ShiftReport.FeeDetailExcel> feeDetailExcelList = jsonObject.getJSONArray("feeDetailList")
+                .toJavaList(ShiftReport.Fee.class)
+                .stream()
+                .map(fee -> ShiftReport.FeeDetailExcel.builder()
+                        .feeName(fee.getFeeName())
+                        .amount(fee.getAmount())
+                        .time(fee.getTime())
+                        .build()).collect(Collectors.toList());
+
+        String fileName = "交班报表.xlsx";
+        response.setContentType("application/vnd.ms-excel");
+        response.setCharacterEncoding("utf-8");
+        response.setHeader("Content-Disposition",
+                "attachment;filename=" + URLEncoder.encode(fileName, StandardCharsets.UTF_8.name()));
+        response.setHeader("File-Name", URLEncoder.encode(fileName, StandardCharsets.UTF_8.name()));
+        ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream())
+                .registerConverter(new LocalDateConverter())
+                .registerConverter(new LocalDateTimeConverter())
+                .registerConverter(new BooleanConverter())
+                .registerWriteHandler(ExcelUtils.customStyle())
+                .registerWriteHandler(new SimpleRowHeightStyleStrategy((short) 20, (short) 20))
+                .registerWriteHandler(new SimpleColumnWidthStyleStrategy(25))
+                .build();
+
+        WriteSheet writeSheet = EasyExcel.writerSheet("交班报表").needHead(Boolean.TRUE).build();
+        WriteTable writeTable0 = EasyExcel.writerTable(0).head(ShiftReport.FeeExcel.class).needHead(true).build();
+        WriteTable writeTable1 = EasyExcel.writerTable(1).head(ShiftReport.DepositExcel.class).needHead(true).build();
+        WriteTable writeTable2 = EasyExcel.writerTable(2).head(ShiftReport.FeeDetailExcel.class).needHead(true).build();
+        WriteTable writeTable3 = EasyExcel.writerTable(3)
+                .head(ShiftReport.DepositDetailExcel.class)
+                .needHead(true)
+                .build();
+        excelWriter.write(feeExcelList, writeSheet, writeTable0);
+        excelWriter.write(Collections.singletonList(depositExcel), writeSheet, writeTable1);
+        excelWriter.write(feeDetailExcelList, writeSheet, writeTable2);
+        excelWriter.write(depositDetailExcelList, writeSheet, writeTable3);
+        excelWriter.finish();
+    }
+
 }
 

+ 5 - 20
src/main/vue/src/views/RepairInfoList.vue

@@ -10,9 +10,6 @@
 
             <el-input placeholder="输入关键字" v-model="search" clearable class="filter-item"></el-input>
             <el-button @click="getData" type="primary" icon="el-icon-search" class="filter-item">搜索 </el-button>
-            <el-button @click="addRow" type="primary" icon="el-icon-plus" v-if="canEdit" class="filter-item"
-                >添加
-            </el-button>
             <el-button
                 @click="download"
                 type="primary"
@@ -39,8 +36,8 @@
                 </template>
             </el-table-column>
             <el-table-column prop="storeId" label="门店ID"> </el-table-column>
-            <el-table-column prop="roomId" label="房间ID"> </el-table-column>
-            <el-table-column prop="bedId" label="床位ID"> </el-table-column>
+            <el-table-column prop="roomInfo.roomName" label="房间"> </el-table-column>
+            <el-table-column prop="bedInfo.bedName" label="床位"> </el-table-column>
             <el-table-column prop="images" label="图片" width="60">
                 <template v-slot="{ row }">
                     <el-image
@@ -52,21 +49,9 @@
                     ></el-image>
                 </template>
             </el-table-column>
-            <el-table-column prop="repairTime" label="维修时间">
-                <template slot="header" slot-scope="{ column }">
-                    <sortable-header :column="column" :current-sort="sort" @changeSort="changeSort"> </sortable-header>
-                </template>
-            </el-table-column>
-            <el-table-column prop="finishTime" label="完成时间">
-                <template slot="header" slot-scope="{ column }">
-                    <sortable-header :column="column" :current-sort="sort" @changeSort="changeSort"> </sortable-header>
-                </template>
-            </el-table-column>
-            <el-table-column prop="operator" label="维修人">
-                <template slot="header" slot-scope="{ column }">
-                    <sortable-header :column="column" :current-sort="sort" @changeSort="changeSort"> </sortable-header>
-                </template>
-            </el-table-column>
+            <el-table-column prop="repairTime" label="维修时间" width="150"> </el-table-column>
+            <el-table-column prop="finishTime" label="完成时间" width="150"> </el-table-column>
+            <el-table-column prop="operator" label="维修人"> </el-table-column>
             <el-table-column prop="remark" label="备注"> </el-table-column>
             <el-table-column prop="repairType" label="维修类型" :formatter="repairTypeFormatter">
                 <template slot="header" slot-scope="{ column }">

+ 55 - 11
src/main/vue/src/views/ShiftHandoverEdit.vue

@@ -105,10 +105,11 @@
             <el-form-item prop="remark" label="备注" style="width:100%">
                 <el-input type="textarea" v-model="formData.remark" autosize :disabled="!!id"> </el-input>
             </el-form-item>
-            <el-form-item label=" " v-if="!id">
-                <el-button @click="onSave" :loading="saving" type="primary">保存 </el-button>
-                <el-button @click="onDelete" :loading="saving" type="danger" v-if="formData.id">删除 </el-button>
-                <el-button @click="$emit('dismiss')">取消</el-button>
+            <el-form-item label=" ">
+                <el-button @click="onSave" :loading="saving" type="primary" v-if="!id">保存 </el-button>
+                <el-button @click="onDelete" :loading="saving" type="danger" v-if="formData.id && !id">删除 </el-button>
+                <el-button @click="$emit('dismiss')" v-if="!id">取消</el-button>
+                <el-button :loading="downloading" @click="download">导出EXCEL</el-button>
             </el-form-item>
         </el-form>
     </div>
@@ -117,10 +118,11 @@
 import { mapState } from 'vuex';
 import format from 'date-fns/format';
 import eventBus from '../eventBus';
+import NP from 'number-precision';
 export default {
     name: 'ShiftHandoverEdit',
     props: ['id'],
-    created() {
+    mounted() {
         if (this.id) {
             this.$http.get(`/shiftHandover/get/${this.id}`).then(res => {
                 this.formData = res;
@@ -142,6 +144,7 @@ export default {
     },
     data() {
         return {
+            downloading: false,
             saving: false,
             formData: {},
             rules: {
@@ -194,14 +197,14 @@ export default {
                         amount: res.depositDetailList
                             .filter(i => !i.refund)
                             .map(i => i.amount)
-                            .reduce((a, b) => a + b, 0),
+                            .reduce((a, b) => NP.plus(a, b), 0),
                         refund: res.depositDetailList
                             .filter(i => i.refund)
                             .map(i => i.amount)
-                            .reduce((a, b) => a + b, 0),
+                            .reduce((a, b) => NP.plus(a, b), 0),
                         total: res.depositDetailList
                             .map(i => (i.refund ? -i.amount : i.amount))
-                            .reduce((a, b) => a + b, 0)
+                            .reduce((a, b) => NP.plus(a, b), 0)
                     };
                     this.stat = res;
                 })
@@ -266,17 +269,58 @@ export default {
             this.$router.push({
                 name: 'IndependentDeposit'
             });
+        },
+        download() {
+            this.downloading = true;
+            (this.id
+                ? this.$axios.get(`/shiftHandover/excel/${this.id}`, { responseType: 'blob' })
+                : this.$axios.post(`/shiftHandover/excelData`, this.stat, { responseType: 'blob' })
+            )
+                .then(res => {
+                    console.log(res);
+                    this.downloading = false;
+                    const downloadUrl = window.URL.createObjectURL(new Blob([res.data]));
+                    const link = document.createElement('a');
+                    link.href = downloadUrl;
+                    link.setAttribute(
+                        'download',
+                        decodeURIComponent(res.headers['content-disposition'].split('filename=')[1])
+                    );
+                    document.body.appendChild(link);
+                    link.click();
+                    link.remove();
+                })
+                .catch(e => {
+                    console.log(e);
+                    this.downloading = false;
+                    this.$message.error(e.error);
+                });
         }
     },
     watch: {
         selectedStoreId() {
-            this.getData();
+            if (!this.id) {
+                this.getData();
+            }
         },
         'formData.beginTime'() {
-            this.getData();
+            if (!this.id) {
+                this.getData();
+            }
         },
         'formData.endTime'() {
-            this.getData();
+            if (!this.id) {
+                this.getData();
+            }
+        },
+        id(id) {
+            if (id) {
+                this.$http.get(`/shiftHandover/get/${id}`).then(res => {
+                    this.formData = res;
+                    this.stat = JSON.parse(res.feeReport || '{}');
+                });
+                return;
+            }
         }
     }
 };

+ 8 - 2
src/main/vue/src/views/ShiftHandoverList.vue

@@ -80,7 +80,7 @@
             >
             </el-pagination>
         </div>
-        <el-dialog :visible.sync="showDialog" width="80%" destroy-on-close>
+        <el-dialog :visible.sync="showDialog" width="80%" custom-class="shift-handover-dialog" title="交班报表">
             <shift-handover-edit :id="rowId"></shift-handover-edit>
         </el-dialog>
     </div>
@@ -211,4 +211,10 @@ export default {
     }
 };
 </script>
-<style lang="less" scoped></style>
+<style lang="less"  >
+.shift-handover-dialog {
+    .el-dialog__body {
+        padding: 0;
+    }
+}
+</style>

+ 2 - 2
src/main/zmj_mp/src/views/RepairReport.vue

@@ -76,8 +76,8 @@ export default {
             this.$loading('加载中');
             this.$http
                 .post('/repairInfo/create', {
-                    targetId: this.roomInfo.roomId,
-                    repairType: 'ROOM',
+                    targetId: this.roomInfo.bedId,
+                    repairType: 'BED',
                     images: this.files.join()
                 })
                 .then(res => {