undone.vue 13.5 KB
<template>
    <div class="un-done">
        <layout-filter>
            <filter-item :label="filters.orderNo.label">
                <Input v-model.trim.number="filters.orderNo.model"
                       :placeholder="filters.orderNo.holder"></Input>
            </filter-item>
            <filter-item :label="filters.prodCode.label">
                <Input v-model.trim.number="filters.prodCode.model"
                       :placeholder="filters.prodCode.holder" :maxlength="9"></Input>
            </filter-item>
            <filter-item :label="filters.skuCode.label">
                <Input v-model.trim.number="filters.skuCode.model"
                       :placeholder="filters.skuCode.holder" :maxlength="9"></Input>
            </filter-item>
            <filter-item :label="filters.merChantCode.label">
                <Input v-model.trim="filters.merChantCode.model"
                       :placeholder="filters.merChantCode.holder"></Input>
            </filter-item>
            <filter-item :label="filters.prodBarCode.label">
                <Input v-model.trim="filters.prodBarCode.model"
                       :placeholder="filters.prodBarCode.holder"></Input>
            </filter-item>
            <filter-item :label="filters.orderTime.label">
                <Date-picker type="daterange"
                             placeholder="选择日期"
                             @on-change="dateChange"
                             v-model="filters.orderTime.model">
                </Date-picker>
            </filter-item>
            <filter-item :label="filters.prodStatus.label">
                <Select v-model.trim="filters.prodStatus.model" clearable>
                    <Option v-for="option in filters.prodStatus.options"
                            :value="option.value"
                            :key="option.value">{{option.label}}</Option>
                </Select>
            </filter-item>
            <filter-item>
                <Button type="primary" @click="filterSearch">筛选</Button>
                <Button type="warning" @click="exportList">导出</Button>
                <Button @click="clearFilter">清空条件</Button>
                <filter-tips type="warning" show-icon closable>请务必认真填写发货情况及物流信息,否则商品无法正常入库</filter-tips>
            </filter-item>
        </layout-filter>

        <layout-action>
            <Button type="primary" @click="showDeliverModal">发货</Button>
        </layout-action>

        <layout-list>
            <Table border :columns="table.cols" :data="table.list"
                   :row-class-name="rowClassName" @on-selection-change="selectChange"></Table>
            <Page :total="page.total" :current="page.current"
                  @on-change="pageChange" :page-size="100" show-total></Page>
        </layout-list>

        <allot-deliver
            ref="deliverModal"
            @deliver="allotDeliver">
        </allot-deliver>
        <modal-stock-out
            ref="stockOutModal"
            @upload-success="uploadSuccess">
        </modal-stock-out>
        <div v-show="showBackTop" class="back-top" @click="backTop">
            <Icon type="chevron-up" class="icon"></Icon>
        </div>
    </div>
</template>

<script>
    import _ from 'lodash';
    import moment from 'moment';
    import {AllotDeliver} from '../components';
    import {undone as undoneStore} from '../store';
    import TradeService from 'services/trade/trade-service';

    export default {
        name: 'TabUndone',
        data() {
            return undoneStore.apply(this);
        },
        created() {
            this.tradeService = new TradeService();
            const no = this.$route.query.no || 0;

            if (no) {
                this.filters.orderNo.model = +no;
                this.useFilter = true;
            }
            this.productList(this.params());

        },
        mounted() {
            const decide = _.throttle(e => {
                const show = e.target.scrollTop > 500;

                if (this.showBackTop !== show) {
                    this.showBackTop = show;
                }
            }, 100);

            document.querySelector('.layout-content').addEventListener('scroll', decide);
        },
        components: {AllotDeliver},
        methods: {
            params() {
                let params = {
                    pageNo: 1,
                    pageSize: 100,
                    statusList: [1]
                };

                if (!this.useFilter) {
                    return params;
                }

                _.assign(params, this.filterValues());
                params = _.pickBy(params, (v) => {
                    return (v + '').length;
                });

                return params;
            },
            filterValues() {
                const keyMap = {
                    proReqFormId: 'orderNo',
                    productSkn: 'prodCode',
                    productSku: 'skuCode',
                    sknFactoryCode: 'merChantCode',
                    skuFactoryCode: 'prodBarCode',
                    startTime: 'startTime',
                    endTime: 'endTime',
                    isOvertime: 'prodStatus'
                };
                let values = {};
                let modelVal;

                _.each(keyMap, (v, k) => {
                    modelVal = this.filters[v].model;
                    if ((modelVal + '').length) {
                        values[k] = this.filters[v].model;
                    }
                });

                if (typeof values.proReqFormId !== 'undefined' &&
                    !_.isFinite(+values.proReqFormId)) {
                    this.$Message.error('调拨单号只能是数字', 3);
                    return;
                }

                if (typeof values.productSkn !== 'undefined' &&
                    !_.isFinite(+values.productSkn)) {
                    this.$Message.error('SKN编码只能是数字', 3);
                    return;
                }

                if (typeof values.productSku !== 'undefined' &&
                    !_.isFinite(+values.productSku)) {
                    this.$Message.error('SKU编码只能是数字', 3);
                    return;
                }

                const ot = values.isOvertime;
                const start = values.startTime;
                const end = values.endTime;

                if (start && moment(start).isValid()) {
                    values.startTime = +moment(start).format('X');
                } else {
                    values.startTime = '';
                }

                if (end && moment(end).isValid()) {
                    values.endTime = +moment(end).add(1, 'days').format('X');
                } else {
                    values.endTime = '';
                }

                values.isOvertime = ot ? (ot === 1 ? 'N' : 'Y') : ''; // eslint-disable-line

                return values;
            },
            productList(params) {
                this.$Loading.start();
                this.tradeService.allotPurchaseList(params)
                    .then(res => {
                        this.$Loading.finish();
                        this.processData(res.data);
                    });
            },
            processData(data) {
                const fmt = 'YYYY-MM-DD HH:mm:ss';
                const list = data.records;

                _.each(list, (v, i) => {
                    v._rowIndex = i; // 当前行index
                    v._colorName = v.factoryGoodsName || '';
                    v.createTime = moment.unix(v.createTime).format(fmt);
                    v._needDeliver = v.buyingNums - v.lackNum - v.shipmentsNums; // 当前需发数
                });

                this.table.list = list;
                this.page.total = data.totalCount;
            },
            filterSearch() {
                this.useFilter = true;
                const params = this.params();

                this.productList(params);
                this.page.current = 1;
            },
            clearFilter() {
                this.useFilter = false;
                this.productList(this.params());
                this.page.current = 1;

                _.each(this.filters, item => {
                    item.model = '';
                });
            },
            pageChange(page) {
                let params = this.params();

                params.pageNo = page;
                this.productList(params);
                this.page.current = page;
            },
            selectChange(rows) {
                this.deliverRows = rows;
            },
            deliverChange(data) {
                const index = data.index;
                const value = data.value;

                this.table.list[index]._inputDeliverNum = +value;

                _.each(this.deliverRows, item => {
                    if (item._rowIndex === index) {
                        item._inputDeliverNum = value;
                    }
                });
            },
            showDeliverModal() {
                if (this.checkDeliver()) {
                    this.$refs.deliverModal.show();
                }
            },
            checkDeliver() {
                const rows = this.deliverRows;
                const len = rows.length;

                if (!len) {
                    this.$Message.error('请勾选要发货的订单');
                    return false;
                }

                let invalidRows = [];

                _.each(rows, (v) => {
                    if (!_.isFinite(+v._inputDeliverNum) ||
                        !(+v._inputDeliverNum) ||
                        v._inputDeliverNum > v._needDeliver) {
                        invalidRows.push(v.productSku);
                    }
                });

                if (invalidRows.length) {
                    this.$Message.error('已选择的条目、请输入大于0且不大于当前需发数的发货数', 5);
                    return false;
                }

                return true;
            },
            allotDeliver({expressId, expressNumber}) {
                let goods = {};
                let keyId;

                _.each(this.deliverRows, i => {
                    keyId = i.proRequisitionFormId;

                    if (!goods[keyId]) {
                        goods[keyId] = [];
                    }

                    goods[keyId].push({
                        sku: i.productSku,
                        num: i._inputDeliverNum || 0,
                        factoryCode: i.skuFactoryCode
                    });
                });
                this.tradeService.allotDelivery({
                    expressId,
                    expressNumber,
                    expressGoodsMap: goods
                }).then((ret) => {
                    if (ret.code === 200) {
                        this.$Message.success('发货成功');
                        this.productList(this.params());
                        this.page.current = 1;
                        this.$refs.deliverModal.hide();
                    } else {
                        this.$Message.error('发货失败');
                    }
                });
            },
            setModel(k, v) {
                this.filters[k].model = v;
            },
            dateChange(date) {
                this.setModel('startTime', date[0]);
                this.setModel('endTime', date[1]);
            },
            rowClassName(row) {
                if (row.isOvertime === 'Y') {
                    return 'over-time';
                }
                return '';
            },
            lackNumChange(data) {
                const i = data.index;
                const v = data.value;

                this.table.list[i].inputLackNum = +v;
            },
            showUploadModal(index) {
                const row = this.table.list[index];
                const inputLackNum = row.inputLackNum;
                const needDeliver = row._needDeliver;

                if (!inputLackNum || inputLackNum > needDeliver) {
                    this.$Message.error('请输入缺货数量,且缺货数量不能大于当前需发数', 3);
                    return;
                }
                this.$refs.stockOutModal.show(row);
            },
            uploadSuccess() {
                this.$Message.success('上传缺货成功');
                this.productList(this.params());
                this.page.current = 1;
            },
            exportList() {
                let params = {
                    statusList: 1
                };

                let filters = this.filterValues();

                _.assign(params, filters);
                params = _.pickBy(params, (v) => {
                    return (v + '').length;
                });

                let temp = [];

                _.each(params, (val, key) => {
                    temp.push(`${key}=${val}`);
                });

                const href = `/Api/erp/allotExportList?${temp.join('&')}`;

                window.open(href, '_blank');
            },
            backTop() {
                document.querySelector('.layout-content').scrollTop = 0;
            }
        }
    };
</script>

<style lang="scss">
.ivu-table .over-time td {
    background-color: #fcecec;
}

.status-cell {
    .is-overtime {
        color: #f00;
        font-weight: bold;
    }
}

.back-top {
    position: fixed;
    z-index: 5;
    padding: 8px 12px;
    right: 30px;
    bottom: 90px;
    border-radius: 2px;
    background-color: rgba(0, 0, 0, 0.6);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
    transition: all 0.2s ease-in-out;

    .icon {
        color: #fff;
        font-size: 24px;
    }
}
</style>