xiongzhu 5 лет назад
Родитель
Сommit
d470d5da96

+ 1 - 1
src/main/resources/application.yaml

@@ -12,7 +12,7 @@ spring:
 #        url: jdbc:mysql://rdsave1o67m1ido6gwp6public.mysql.rds.aliyuncs.com/zhu_meng_ju_test?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false&serverTimezone=GMT%2b8
 #        username: microball
 #        password: 2wsx@WSX#EDC
-        url: jdbc:mysql://192.168.50.97/zmj_test?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false&serverTimezone=GMT%2b8
+        url: jdbc:mysql://121.40.132.44/zmj_test?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false&serverTimezone=GMT%2b8
         username: root
         password: 3edc#EDC
         hikari:

+ 149 - 154
src/main/vue/src/views/ContractViolationList.vue

@@ -1,55 +1,41 @@
 <template>
-    <div  class="list-view">
+    <div class="list-view">
         <div class="filters-container">
-            <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-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" v-if="canEdit" type="primary" icon="el-icon-plus" class="filter-item"
+                >添加
             </el-button>
-            <el-button @click="addRow" v-if="canEdit" type="primary" icon="el-icon-plus"
-                       class="filter-item">添加
-            </el-button>
-            <el-button @click="download" type="primary" icon="el-icon-download"
-                       :loading="downloading" class="filter-item">导出EXCEL
+            <el-button
+                @click="download"
+                type="primary"
+                icon="el-icon-download"
+                :loading="downloading"
+                class="filter-item"
+                >导出EXCEL
             </el-button>
         </div>
-        <el-table :data="tableData" row-key="id" ref="table"
-                  header-row-class-name="table-header-row"
-                  header-cell-class-name="table-header-cell"
-                  row-class-name="table-row" cell-class-name="table-cell"
-                  :height="tableHeight">
-            <el-table-column v-if="multipleMode" align="center" type="selection"
-                             width="50">
-            </el-table-column>
-            <el-table-column prop="id" label="ID" width="100">
+        <el-table
+            :data="tableData"
+            row-key="id"
+            ref="table"
+            header-row-class-name="table-header-row"
+            header-cell-class-name="table-header-cell"
+            row-class-name="table-row"
+            cell-class-name="table-cell"
+            :height="tableHeight"
+        >
+            <el-table-column v-if="multipleMode" align="center" type="selection" width="50"> </el-table-column>
+            <el-table-column prop="id" label="ID" width="100"> </el-table-column>
+            <el-table-column prop="contractId" label="合同ID"> </el-table-column>
+            <el-table-column prop="contractNumber" label="合同编号"> </el-table-column>
+            <el-table-column prop="violationType" label="违约类型" :formatter="violationTypeFormatter">
             </el-table-column>
-                                <el-table-column prop="contractId" label="合同ID"
->
-                    </el-table-column>
-                    <el-table-column prop="contractNumber" label="合同编号"
->
-                    </el-table-column>
-                    <el-table-column prop="violationType" label="违约类型"
-                            :formatter="violationTypeFormatter"
-                        >
-                    </el-table-column>
-                    <el-table-column prop="restRent" label="剩余房费"
->
-                    </el-table-column>
-                    <el-table-column prop="penalty" label="违约金"
->
-                    </el-table-column>
-                    <el-table-column prop="penaltyType" label="违约金方式"
-                            :formatter="penaltyTypeFormatter"
-                        >
-                    </el-table-column>
-            <el-table-column
-                    label="操作"
-                    v-if="canEdit"
-                    align="center"
-                    fixed="right"
-                    min-width="150">
-                <template slot-scope="{row}">
+            <el-table-column prop="restRent" label="剩余房费"> </el-table-column>
+            <el-table-column prop="penalty" label="违约金"> </el-table-column>
+            <el-table-column prop="penaltyType" label="违约金方式" :formatter="penaltyTypeFormatter"> </el-table-column>
+            <el-table-column label="操作" v-if="canEdit" align="center" fixed="right" min-width="150">
+                <template slot-scope="{ row }">
                     <el-button @click="editRow(row)" type="primary" size="mini" plain>编辑</el-button>
                     <el-button @click="deleteRow(row)" type="danger" size="mini" plain>删除</el-button>
                 </template>
@@ -64,135 +50,144 @@
                     <el-button @click="toggleMultipleMode(false)">取消</el-button>
                 </el-button-group>
             </div> -->
-            <el-pagination background @size-change="onSizeChange"
-                           @current-change="onCurrentChange" :current-page="page"
-                           :page-sizes="[10, 20, 30, 40, 50]" :page-size="pageSize"
-                           layout="total, sizes, prev, pager, next, jumper"
-                           :total="totalElements">
+            <el-pagination
+                background
+                @size-change="onSizeChange"
+                @current-change="onCurrentChange"
+                :current-page="page"
+                :page-sizes="[10, 20, 30, 40, 50]"
+                :page-size="pageSize"
+                layout="total, sizes, prev, pager, next, jumper"
+                :total="totalElements"
+            >
             </el-pagination>
         </div>
-
     </div>
 </template>
 <script>
-    import { mapState } from "vuex";
-    import pageableTable from "@/mixins/pageableTable";
+import { mapState } from 'vuex';
+import pageableTable from '@/mixins/pageableTable';
 
-    export default {
-        name: 'ContractViolationList',
-        mixins: [pageableTable],
-        created() {
-            this.getData();
+export default {
+    name: 'ContractViolationList',
+    mixins: [pageableTable],
+    created() {
+        this.getData();
+    },
+    data() {
+        return {
+            multipleMode: false,
+            search: '',
+            url: '/contractViolation/all',
+            downloading: false,
+            violationTypeOptions: [
+                { label: '部分', value: 'PART' },
+                { label: '全部', value: 'TOTAL' }
+            ],
+            penaltyTypeOptions: [
+                { label: '房费', value: 'RENT' },
+                { label: '押金', value: 'DEPOSIT' }
+            ]
+        };
+    },
+    computed: {
+        selection() {
+            return this.$refs.table.selection.map(i => i.id);
+        }
+    },
+    methods: {
+        violationTypeFormatter(row, column, cellValue, index) {
+            let selectedOption = this.violationTypeOptions.find(i => i.value === cellValue);
+            if (selectedOption) {
+                return selectedOption.label;
+            }
+            return '';
         },
-        data() {
-            return {
-                multipleMode: false,
-                search: "",
-                url: "/contractViolation/all",
-                downloading: false,
-                        violationTypeOptions:[{"label":"部分","value":"PART"},{"label":"全部","value":"TOTAL"}],
-                        penaltyTypeOptions:[{"label":"房费","value":"RENT"},{"label":"押金","value":"DEPOSIT"}],
+        penaltyTypeFormatter(row, column, cellValue, index) {
+            let selectedOption = this.penaltyTypeOptions.find(i => i.value === cellValue);
+            if (selectedOption) {
+                return selectedOption.label;
             }
+            return '';
         },
-        computed: {
-            selection() {
-                return this.$refs.table.selection.map(i => i.id);
+        beforeGetData() {
+            if (this.search) {
+                return { search: this.search };
             }
         },
-        methods: {
-                    violationTypeFormatter(row, column, cellValue, index) {
-                        let selectedOption = this.violationTypeOptions.find(i => i.value === cellValue);
-                        if (selectedOption) {
-                            return selectedOption.label;
-                        }
-                        return '';
-                    },
-                    penaltyTypeFormatter(row, column, cellValue, index) {
-                        let selectedOption = this.penaltyTypeOptions.find(i => i.value === cellValue);
-                        if (selectedOption) {
-                            return selectedOption.label;
-                        }
-                        return '';
-                    },
-            beforeGetData() {
-                if (this.search) {
-                    return { search: this.search };
-                }
-            },
-            toggleMultipleMode(multipleMode) {
-                this.multipleMode = multipleMode;
-                if (!multipleMode) {
-                    this.$refs.table.clearSelection();
-                }
-            },
-            addRow() {
-                this.$router.push({
-                    path: "/contractViolationEdit",
-                    query: {
+        toggleMultipleMode(multipleMode) {
+            this.multipleMode = multipleMode;
+            if (!multipleMode) {
+                this.$refs.table.clearSelection();
+            }
+        },
+        addRow() {
+            this.$router.push({
+                path: '/contractViolationEdit',
+                query: {
                     ...this.$route.query
-                    }
-                });
-            },
-            editRow(row) {
-                this.$router.push({
-                    path: "/contractViolationEdit",
-                    query: {
+                }
+            });
+        },
+        editRow(row) {
+            this.$router.push({
+                path: '/contractViolationEdit',
+                query: {
                     id: row.id
-                    }
-                });
-            },
-            download() {
-                this.downloading = true;
-                this.$axios
-                    .get("/contractViolation/excel", {
-                        responseType: "blob",
-                        params: { size: 10000 }
-                    })
-                    .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",
-                            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);
-                    });
-            },
-            operation1() {
-                this.$notify({
-                    title: '提示',
-                    message: this.selection
+                }
+            });
+        },
+        download() {
+            this.downloading = true;
+            this.$axios
+                .get('/contractViolation/excel', {
+                    responseType: 'blob',
+                    params: { size: 10000 }
+                })
+                .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', 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);
                 });
-            },
-            operation2() {
-                this.$message('操作2');
-            },
-            deleteRow(row) {
-                this.$alert('删除将无法恢复,确认要删除么?', '警告', {type: 'error'}).then(() => {
-                    return this.$http.post(`/contractViolation/del/${row.id}`)
-                }).then(() => {
+        },
+        operation1() {
+            this.$notify({
+                title: '提示',
+                message: this.selection
+            });
+        },
+        operation2() {
+            this.$message('操作2');
+        },
+        deleteRow(row) {
+            this.$alert('删除将无法恢复,确认要删除么?', '警告', { type: 'error' })
+                .then(() => {
+                    return this.$http.post(`/contractViolation/del/${row.id}`);
+                })
+                .then(() => {
                     this.$message.success('删除成功');
                     this.getData();
-                }).catch(action => {
+                })
+                .catch(action => {
                     if (action === 'cancel') {
                         this.$message.info('删除取消');
                     } else {
                         this.$message.error('删除失败');
                     }
-                })
-            },
+                });
         }
     }
+};
 </script>
-<style lang="less" scoped>
-</style>
+<style lang="less" scoped></style>

+ 154 - 66
src/main/vue/src/views/sale/ContractEdit.vue

@@ -82,35 +82,41 @@
             </el-card>
 
             <el-card shadow="never" class="phases">
-                <el-collapse accordion v-model="activeTab">
-                    <el-collapse-item :name="index" v-for="(item, index) in formData.phases" :key="index">
-                        <template slot="title">
-                            {{ toChinesNum(index + 1) }}期绑定门店
-                            <el-button
-                                v-if="activeTab === index"
-                                @click.stop="addPhaseStore(index)"
-                                type="primary"
-                                plain
-                                size="mini"
-                                style="margin-left:10px"
-                            >
-                                新增门店
-                            </el-button>
-                            <span class="phase-time">{{ item.startTime }} 至 {{ item.endTime }}</span>
-                        </template>
-                        <contract-store-choose
-                            v-for="(item, storeIdx) in item.stores"
-                            v-model="formData.phases[index].stores[storeIdx]"
-                            :index="storeIdx"
-                            :key="storeIdx"
-                            @remove="removePhaseStore(index, $event)"
-                            ref="contractStoreChoose"
-                            :checkInType="formData.checkInType"
-                            :storeOptions="storeOptions"
-                        ></contract-store-choose>
-                    </el-collapse-item>
-                </el-collapse>
-
+                <el-form-item prop="phases" style="width:100%;margin-right:0">
+                    <el-collapse accordion v-model="activeTab" v-if="formData.phases.length">
+                        <el-collapse-item
+                            v-for="(item, index) in formData.phases"
+                            :name="index"
+                            :key="index"
+                            :class="`phase-${index}-stores`"
+                        >
+                            <template slot="title">
+                                <span>{{ toChinesNum(index + 1) }}期绑定门店</span>
+                                <el-button
+                                    v-if="activeTab === index"
+                                    @click.stop="addPhaseStore(index)"
+                                    type="primary"
+                                    plain
+                                    size="mini"
+                                    style="margin-left:10px"
+                                >
+                                    新增门店
+                                </el-button>
+                                <span class="phase-time">{{ item.startTime }} 至 {{ item.endTime }}</span>
+                            </template>
+                            <contract-store-choose
+                                v-for="(item, storeIdx) in item.stores"
+                                v-model="formData.phases[index].stores[storeIdx]"
+                                :index="storeIdx"
+                                :key="storeIdx"
+                                @remove="removePhaseStore(index, $event)"
+                                :ref="`phase-${index}-store-choose`"
+                                :checkInType="formData.checkInType"
+                                :storeOptions="storeOptions"
+                            ></contract-store-choose>
+                        </el-collapse-item>
+                    </el-collapse>
+                </el-form-item>
                 <el-button class="btn-add-phase" @click="onAddPhase">添加合同期</el-button>
             </el-card>
 
@@ -615,7 +621,61 @@ export default {
                 isInvoice: false,
                 brandId: null,
                 status: 'STAY_IN',
-                phases: []
+                phases: [
+                    {
+                        startTime: '2020-04-14 00:00:00',
+                        months: 12,
+                        endTime: '2021-04-13 23:59:59',
+                        stores: [
+                            {
+                                storeId: 433,
+                                freeFeeTypes: [],
+                                roomTypeInfo: [],
+                                fixedFeeTypes: [],
+                                roomTypes: [],
+                                roomTypeDesc: '',
+                                storeName: '托乐嘉门店'
+                            },
+                            {
+                                storeId: 2418,
+                                freeFeeTypes: [],
+                                roomTypeInfo: [],
+                                fixedFeeTypes: [],
+                                roomTypes: [],
+                                roomTypeDesc: '',
+                                storeName: '筑梦居公寓闵行吴中路店'
+                            },
+                            { storeId: '', freeFeeTypes: [], roomTypeInfo: [], fixedFeeTypes: [], roomTypes: [] }
+                        ]
+                    },
+                    {
+                        startTime: '2021-04-14 00:00:00',
+                        disableStart: true,
+                        months: 12,
+                        endTime: '2022-04-13 23:59:59',
+                        stores: [
+                            {
+                                storeId: 3123,
+                                freeFeeTypes: [],
+                                roomTypeInfo: [],
+                                fixedFeeTypes: [],
+                                roomTypes: [],
+                                roomTypeDesc: '',
+                                storeName: '筑梦居公寓浦东张江店'
+                            },
+                            {
+                                storeId: 4232,
+                                freeFeeTypes: [],
+                                roomTypeInfo: [],
+                                fixedFeeTypes: [],
+                                roomTypes: [],
+                                roomTypeDesc: '',
+                                storeName: '筑梦居公寓闵行万象城店'
+                            },
+                            { storeId: '', freeFeeTypes: [], roomTypeInfo: [], fixedFeeTypes: [], roomTypes: [] }
+                        ]
+                    }
+                ]
             },
             lastFlowBet: 0,
             rules: {
@@ -629,7 +689,7 @@ export default {
                     {
                         validator: (rule, value, callback) => {
                             if (!value || value.length === 0) {
-                                callback(new Error('请添加门店信息'));
+                                callback(new Error('请添加门店信息'));
                             } else {
                                 Promise.all([
                                     ...this.$refs.contractStoreChoose.map(ref => ref.valid()),
@@ -705,6 +765,27 @@ export default {
                             callback();
                         }
                     }
+                ],
+                phases: [
+                    {
+                        validator: (rule, value, callback) => {
+                            if (!value || value.length === 0) {
+                                callback(new Error('请添加合同期'));
+                            } else {
+                                Promise.all(
+                                    this.formData.phases.map((value, index) => {
+                                        return this.validPhaseStores(index);
+                                    })
+                                )
+                                    .then(() => {
+                                        callback();
+                                    })
+                                    .catch(err => {
+                                        callback(new Error(err || '门店信息有误'));
+                                    });
+                            }
+                        }
+                    }
                 ]
             },
             storeOptions: [],
@@ -1080,11 +1161,7 @@ export default {
                 });
         },
         addPhaseStore(index) {
-            Promise.all([
-                ...(this.$refs.contractStoreChoose || []).map(ref => {
-                    return ref.valid();
-                })
-            ])
+            this.validPhaseStores(index)
                 .then(res => {
                     this.formData.phases[index].stores.push({
                         storeId: '',
@@ -1094,21 +1171,31 @@ export default {
                         roomTypes: []
                     });
                     this.$nextTick(() => {
-                        document
-                            .querySelector('.phases .el-collapse-item__wrap')
-                            .scrollTo({ left: 100000, behavior: 'smooth' });
+                        let el = document.querySelector(`.phase-${index}-stores .el-collapse-item__wrap`);
+                        el && el.scrollTo({ left: 100000, behavior: 'smooth' });
                     });
                 })
-                .catch(e => {
-                    console.log(11111, e);
-                    for (let vm of this.$refs.contractStoreChoose || []) {
-                        if (vm.hasError) {
-                            document
-                                .querySelector('.phases .el-collapse-item__wrap')
-                                .scrollTo({ left: 100000, behavior: 'smooth' });
+                .catch(e => {});
+        },
+        validPhaseStores(i) {
+            return new Promise((resolve, reject) => {
+                Promise.all(this.$refs[`phase-${i}-store-choose`].map(i => i.valid()))
+                    .then(() => {
+                        resolve();
+                    })
+                    .catch(() => {
+                        this.activeTab = i;
+                        for (let vm of this.$refs[`phase-${i}-store-choose`]) {
+                            if (vm.hasError) {
+                                this.$nextTick(() => {
+                                    let el = document.querySelector(`.phase-${i}-stores .el-collapse-item__wrap`);
+                                    el && el.scrollTo({ left: vm.$el.offsetLeft, behavior: 'smooth' });
+                                });
+                            }
                         }
-                    }
-                });
+                        reject(i);
+                    });
+            });
         },
         removeContractStore(index) {
             this.formData.contractStoreList.splice(index, 1);
@@ -1180,13 +1267,6 @@ export default {
                     };
                     this.showSaveDialog = true;
                 } else {
-                    for (let vm of this.$refs.contractStoreChoose) {
-                        if (vm.hasError) {
-                            document
-                                .querySelector('.form-item-choose-contract>.el-form-item__content')
-                                .scrollTo({ left: vm.$el.offsetLeft, behavior: 'smooth' });
-                        }
-                    }
                     this.$message.error('表单有误,请修改后重新提交');
                     return false;
                 }
@@ -1273,17 +1353,25 @@ export default {
             return typeof d !== 'number' ? Number(resultVal) : Number(resultVal.toFixed(parseInt(d)));
         },
         onAddPhase() {
-            if (this.formData.phases.length === 0) {
-                this.phaseForm = {};
-            } else {
-                this.phaseForm = {
-                    startTime: formatDate(
-                        addSeconds(parseDate(this.formData.phases[this.formData.phases.length - 1].endTime), 1)
-                    ),
-                    disableStart: true
-                };
-            }
-            this.showPhaseDialog = true;
+            Promise.all(
+                this.formData.phases.map((value, index) => {
+                    return this.validPhaseStores(index);
+                })
+            )
+                .then(() => {
+                    if (this.formData.phases.length === 0) {
+                        this.phaseForm = {};
+                    } else {
+                        this.phaseForm = {
+                            startTime: formatDate(
+                                addSeconds(parseDate(this.formData.phases[this.formData.phases.length - 1].endTime), 1)
+                            ),
+                            disableStart: true
+                        };
+                    }
+                    this.showPhaseDialog = true;
+                })
+                .catch(i => {});
         },
         addPhase() {
             this.$refs.phaseForm.validate(valid => {