offsale.vue 11.9 KB
<template>
    <layout-body>
        <layout-filter>
            <filter-item :label="filters.sknCode.label">
                <Input v-model.trim="filters.sknCode.model"
                       :placeholder="filters.sknCode.holder" :maxlength="9"></Input>
            </filter-item>
            <filter-item :label="filters.prodCode.label">
                <Input v-model.trim="filters.prodCode.model"
                       :placeholder="filters.prodCode.holder"></Input>
            </filter-item>
            <filter-item :label="filters.prodName.label">
                <Input v-model.trim="filters.prodName.model"
                       :placeholder="filters.prodName.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="选择品牌">
                <select-brand v-model="filters.brand.model"></select-brand>
            </filter-item>
            <filter-item label="选择类目">
                <select-category :value="categoryValue" @select-change="sortChange"></select-category>
            </filter-item>
            <filter-item :label="filters.verifyStatus.label">
                <Select v-model.trim="filters.verifyStatus.model" clearable>
                    <Option v-for="option in filters.verifyStatus.options"
                            :value="option.value"
                            :key="option.value">{{option.label}}</Option>
                </Select>
            </filter-item>
            <filter-item :label="filters.stockStatus.label">
                <Select v-model.trim="filters.stockStatus.model" clearable>
                    <Option v-for="option in filters.stockStatus.options"
                            :value="option.value"
                            :key="option.value">{{option.label}}</Option>
                </Select>
            </filter-item>
            <filter-item :label="filters.publishStatus.label">
                <Select v-model.trim="filters.publishStatus.model" clearable>
                    <Option v-for="option in filters.publishStatus.options"
                            :value="option.value"
                            :key="option.value">{{option.label}}</Option>
                </Select>
            </filter-item>
            <filter-item>
                <Button type="primary" @click="filterSearch">筛选</Button>
                <Button @click="clearFilter">清空条件</Button>
            </filter-item>

        </layout-filter>

        <layout-action>
            <Button type="success" @click="batchSetOnSale">上架</Button>
        </layout-action>

        <layout-list>
            <Table border :columns="tableCols" :data="tableData" @on-selection-change="selectChange"></Table>
            <Page :total="pageData.total" :current="pageData.current"
                  @on-change="pageChange" :page-size="20" show-total></Page>
        </layout-list>

        <modal-size-edit ref="showSizeEdit" :show="showSizeEdit"></modal-size-edit>
    </layout-body>
</template>

<script>
    import _ from 'lodash';
    import ProductService from 'services/product/product-service';
    import {ModalSizeEdit} from 'components/modal';
    import {SelectBrand, SelectCategory} from 'components/select';
    import offSaleStore from './store';

    export default {
        data() {
            return {
                tableCols: [],
                tableData: {},
                pageData: {},
                filters: [],
                batchOnSale: [],
                useFilterSign: false,
                showSizeEdit: false,
                categoryValue: []
            };
        },
        created() {
            this.productService = new ProductService();
            const store = offSaleStore.apply(this);
    
            this.filters = store.filterFields;
            this.tableCols = store.tableCols;
            this.tableData = store.tableData;
            this.pageData = store.pageData;
            this.productList();
        },
        methods: {
            editSize(skn) {
                this.$refs.showSizeEdit.show(skn);
            },
            filterParams() {
                const fts = this.filters;
                const data = {
                    productSkn: fts.sknCode.model,
                    factoryCode: fts.prodCode.model,
                    productName: fts.prodName.model,
                    skuFactoryCode: fts.prodBarCode.model,
                    maxSortId: fts.sort.first.model,
                    middleSortId: fts.sort.second.model,
                    smallSortId: fts.sort.third.model,
                    isPublished: fts.publishStatus.model === '' || fts.publishStatus.model === null ?
                         null : fts.publishStatus.model,
                    brandId: fts.brand.model ? fts.brand.model : null,
                    auditStatus: fts.verifyStatus.model ? fts.verifyStatus.model : null,
                    stock: fts.stockStatus.model === '' || fts.stockStatus.model === null ?
                        null : fts.stockStatus.model
                };

                return data;
            },
            filterSearch() {
                const params = this.filterParams();

                this.useFilterSign = true;
                this.productList(params);
                this.pageData.current = 1;
            },
            clearFilter() {
                const store = offSaleStore.apply(this);
    
                this.filters = store.filterFields;
                this.productList();
                this.useFilterSign = false;
                this.pageData.current = 1;
                this.categoryValue = [];
            },
            productList(params) {
                if (_.isObject(params) &&
                    typeof params.productSkn !== 'undefined' &&
                    !_.isFinite(+params.productSkn)) {
                    this.$Message.error('SKN编码只能是数字', 3);
                    return;
                }

                this.$Loading.start();
                this.productService.productList(
                    _.merge(params || {}, {
                        shelfStatus: 0,
                        size: 20
                    }))
                    .then(res => {
                        this.$Loading.finish();
                        if (res.code === 200) {
                            this.updateStore(res.data);
                        }
                    });
            },
            reloadList() {
                let params = {};

                if (this.useFilterSign) {
                    params = this.filterParams();
                }

                _.merge(params, {
                    page: 1,
                    size: 20,
                    productStatusStr: 1
                });

                this.productList(params);
                this.pageData.current = 1;
            },
            updateStore(data) {
                _.each(data.list, item => {
                    item.changePrice = false;
                    item.stock = item.stock || 0;
                    item._disabled = item.auditStatus === 1;
                    item.offshelveTime = item.offshelveTime || '-';
                });

                this.tableData = data.list;
                this.pageData.total = data.total;
            },
            sortChange(sort) {
                this.filters.sort.first.model = sort.max;
                this.filters.sort.second.model = sort.mid;
                this.filters.sort.third.model = sort.min;
            },
            brandChange(val) {
                _.set(this.filters, 'brand.model', val);
            },
            pageChange(page) {
                this.pageData.current = page;

                let params = {};

                if (this.useFilterSign) {
                    params = this.filterParams();
                }

                _.merge(params, {
                    page,
                    size: 20,
                    productStatusStr: 1
                });

                this.productList(params);
            },
            setOnSale(rows) {
                const params = {
                    targetStatus: 1
                };

                let inValid = [];
                let sknArray = [];

                if (_.isArray(rows)) {
                    _.each(rows, item => {
                        if (item.stock < 1) {
                            inValid.push(item.productSkn);
                        }
                        sknArray.push(item.productSkn);
                    });

                    if (inValid.length) {
                        const error = inValid.join(':库存为0不能上架;');

                        this.$Message.error(`${error}:库存为0不能上架;`, 5);
                        return;
                    }

                    params.productSkns = `[${sknArray.join(',')}]`;
                } else {
                    if (rows.stock < 1) {
                        this.$Message.error('库存为0的商品不能上架');
                        return;
                    }

                    params.productSkns = `[${rows.productSkn}]`;
                }

                this.productService.setOnSale(params)
                    .then(res => {
                        this.$Message.success(res.message);
                        this.reloadList();
                    });
            },

            batchSetOnSale() {
                if (!this.batchOnSale.length) {
                    this.$Message.error('请选择要上架的商品');
                    return;
                }

                this.setOnSale(this.batchOnSale);
            },
            editPrice(row) {
                row.changePrice = true;
            },
            updatePrice(row, newSalesPrice) {
                const index = row.lineIndex;
                const salesPrice = newSalesPrice;
                const productSkn = row.productSkn;
                const fmt = /^\d{1,5}$/;

                if (!fmt.test(newSalesPrice) || newSalesPrice <= 0) {
                    this.$Message.error('销售价必须是大于0,不包含小数点且最多五位的数字', 5);
                    return;
                }

                if (newSalesPrice > row.retailPrice) {
                    this.$Message.error('销售价不能大于吊牌价');
                    return;
                }

                if (newSalesPrice === row.salesPrice) {
                    row.changePrice = false;
                    return;
                }

                const params = {
                    salesPrice,
                    productSkn
                };

                this.productService.updateSalesPrice(params)
                    .then(res => {
                        if (res.code === 200) {
                            this.tableData[index].salesPrice = salesPrice;
                            row.changePrice = false;
                            this.$Message.success(res.message);
                        } else {
                            row.changePrice = false;
                            this.$Message.error(res.message);
                        }
                    });
            },
            editProduct(skn) {
                this.$router.push({
                    name: 'product.edit',
                    params: {
                        id: skn,
                    },
                    query: {
                        from: 'product.offsale'
                    }
                });
            },
            selectChange(selection) {
                this.batchOnSale = selection;
            }
        },
        components: {
            SelectBrand,
            SelectCategory,
            ModalSizeEdit
        }
    };
</script>

<style lang="scss">
.action-column {
    .cell-action-row {
        margin-top: 10px;

        &:last-child {
            margin-bottom: 10px;
        }
    }
}

.status-column {
    .high-light {
        color: #f00;
    }
}
</style>