Authored by 李奇

added:vip价格管理、调拨单

@@ -2,6 +2,7 @@ import create from './create'; @@ -2,6 +2,7 @@ import create from './create';
2 import edit from './edit'; 2 import edit from './edit';
3 import onsale from './onsale'; 3 import onsale from './onsale';
4 import offsale from './offsale'; 4 import offsale from './offsale';
  5 +import vips from './vips';
5 import output from './output'; 6 import output from './output';
6 7
7 export default { 8 export default {
@@ -9,5 +10,6 @@ export default { @@ -9,5 +10,6 @@ export default {
9 edit, 10 edit,
10 onsale, 11 onsale,
11 offsale, 12 offsale,
  13 + vips,
12 output 14 output
13 }; 15 };
@@ -3,5 +3,8 @@ const page = r => require.ensure([], () => r(require('./vips')), 'product.vips') @@ -3,5 +3,8 @@ const page = r => require.ensure([], () => r(require('./vips')), 'product.vips')
3 export default { 3 export default {
4 path: '/vips.html', 4 path: '/vips.html',
5 name: 'vips', 5 name: 'vips',
6 - component: page 6 + component: page,
  7 + meta: {
  8 + pageName: '在售商品'
  9 + }
7 }; 10 };
  1 +/**
  2 + * vips data
  3 + * @author: qi.li <qi.li@yoho.cn>
  4 + * @date: 2017/05/23
  5 + */
  6 +export default () => {
  7 + return {
  8 + tableCols: [
  9 + {
  10 + type: 'selection',
  11 + width: 60,
  12 + align: 'center'
  13 + },
  14 + {
  15 + title: '商品图片',
  16 + key: 'image',
  17 + width: 120,
  18 + align: 'center',
  19 + render(row) { // eslint-disable-line
  20 + return '<cell-image :image-src="row.picImgUrl" :product-url="row.productUrl"></cell-image>';
  21 + }
  22 + },
  23 + {
  24 + title: '商品信息',
  25 + key: 'info',
  26 + align: 'center',
  27 + render(row) { // eslint-disable-line
  28 + return `<cell-info
  29 + :skn="row.productSkn"
  30 + :product-name="row.productName"
  31 + :brand-name="row.brandName"
  32 + :max-name="row.maxSortName"
  33 + :middle-name="row.middleSortName"
  34 + :small-name="row.smallSortName">
  35 + </cell-info>`;
  36 + }
  37 + },
  38 + {
  39 + title: '价格(元)',
  40 + key: 'price',
  41 + width: '180',
  42 + align: 'center',
  43 + render(row, column, index) {
  44 + row.lineIndex = index;
  45 + return `<cell-price
  46 + :can-change="false"
  47 + :retail-price="row.retailPrice"
  48 + :sales-price="row.salesPrice">
  49 + </cell-price>`;
  50 + }
  51 + },
  52 + {
  53 + title: '可售库存',
  54 + key: 'stock',
  55 + width: 100,
  56 + align: 'center',
  57 + },
  58 + {
  59 + title: 'VIP价格',
  60 + key: 'stock',
  61 + width: 100,
  62 + align: 'center',
  63 + },
  64 + {
  65 + title: '销售状态',
  66 + key: 'stock',
  67 + width: 100,
  68 + align: 'center',
  69 + },
  70 + {
  71 + title: 'VIP价格状态',
  72 + key: 'stock',
  73 + width: 100,
  74 + align: 'center',
  75 + },
  76 + {
  77 + title: '操作',
  78 + key: 'action',
  79 + width: 180,
  80 + align: 'center',
  81 + render: function(row) {
  82 + return `<i-button type="primary" size="large"
  83 + @click="enablePrice">启用</i-button>`;
  84 + },
  85 + className: 'action-column'
  86 + }
  87 + ],
  88 + tableData: [],
  89 + pageData: {
  90 + total: 0,
  91 + current: 1
  92 + },
  93 + filterFields: {
  94 + sknCode: {
  95 + label: 'SKN编码',
  96 + model: '',
  97 + holder: ''
  98 + },
  99 + prodCode: {
  100 + label: '商家编码',
  101 + model: '',
  102 + holder: ''
  103 + },
  104 + prodBarCode: {
  105 + label: '商品条码',
  106 + model: '',
  107 + holder: ''
  108 + },
  109 + priceStatus: {
  110 + label: '价格状态',
  111 + model: -1,
  112 + options: [
  113 + {
  114 + value: -1,
  115 + label: '全部'
  116 + },
  117 + {
  118 + value: 1,
  119 + label: '启用'
  120 + },
  121 + {
  122 + value: 2,
  123 + label: '禁用'
  124 + }
  125 + ]
  126 + },
  127 + saleStatus: {
  128 + label: '销售状态',
  129 + model: -1,
  130 + options: [
  131 + {
  132 + value: -1,
  133 + label: '全部'
  134 + },
  135 + {
  136 + value: 1,
  137 + label: '新品未上架'
  138 + },
  139 + {
  140 + value: 2,
  141 + label: '已上架'
  142 + },
  143 + {
  144 + value: 2,
  145 + label: '已下架'
  146 + }
  147 + ]
  148 + },
  149 + stockStatus: {
  150 + label: '库存状态',
  151 + model: -1,
  152 + options: [
  153 + {
  154 + value: -1,
  155 + label: '全部'
  156 + },
  157 + {
  158 + value: 1,
  159 + label: '有库存'
  160 + },
  161 + {
  162 + value: 2,
  163 + label: '无库存'
  164 + }
  165 + ]
  166 + },
  167 + sort: {
  168 + first: {
  169 + label: '选择类目',
  170 + holder: '选择一级类目',
  171 + labelSpan: 6,
  172 + fieldSpan: 18,
  173 + model: ''
  174 + },
  175 + second: {
  176 + label: '二级类目',
  177 + holder: '选择二级类目',
  178 + labelSpan: 6,
  179 + fieldSpan: 18,
  180 + model: ''
  181 + },
  182 + third: {
  183 + label: '三级类目',
  184 + holder: '选择三级类目',
  185 + labelSpan: 6,
  186 + fieldSpan: 18,
  187 + model: ''
  188 + }
  189 + },
  190 + }
  191 + };
  192 +};
1 <template> 1 <template>
2 - <div class="onsale-list">  
3 - </div> 2 + <LayoutBody>
  3 + <LayoutFilter>
  4 + <FilterItem :label="filters.sknCode.label">
  5 + <Input v-model.trim="filters.sknCode.model"
  6 + :placeholder="filters.sknCode.holder"></Input>
  7 + </FilterItem>
  8 + <FilterItem :label="filters.prodCode.label">
  9 + <Input v-model.trim="filters.prodCode.model"
  10 + :placeholder="filters.prodCode.holder"></Input>
  11 + </FilterItem>
  12 + <FilterItem :label="filters.prodBarCode.label">
  13 + <Input v-model.trim="filters.prodBarCode.model"
  14 + :placeholder="filters.prodBarCode.holder"></Input>
  15 + </FilterItem>
  16 + <FilterItem :label="filters.priceStatus.label">
  17 + <Select v-model.trim="filters.priceStatus.model">
  18 + <Option v-for="option in filters.priceStatus.options"
  19 + :value="option.value"
  20 + :key="option.value">{{option.label}}</Option>
  21 + </Select>
  22 + </FilterItem>
  23 + <FilterItem :label="filters.saleStatus.label">
  24 + <Select v-model.trim="filters.saleStatus.model">
  25 + <Option v-for="option in filters.saleStatus.options"
  26 + :value="option.value"
  27 + :key="option.value">{{option.label}}</Option>
  28 + </Select>
  29 + </FilterItem>
  30 + <FilterItem :label="filters.stockStatus.label">
  31 + <Select v-model.trim="filters.stockStatus.model">
  32 + <Option v-for="option in filters.stockStatus.options"
  33 + :value="option.value"
  34 + :key="option.value">{{option.label}}</Option>
  35 + </Select>
  36 + </FilterItem>
  37 + <FilterItem label="选择类目">
  38 + <SelectCategory :value="categoryValue"
  39 + @select-change="sortChange"></SelectCategory>
  40 + </FilterItem>
  41 + <FilterItem>
  42 + <Button type="primary" @click="filterSearch">筛选</Button>
  43 + <Button @click="clearFilter">清空条件</Button>
  44 + </FilterItem>
  45 + </LayoutFilter>
  46 +
  47 + <LayoutAction>
  48 + <Button type="primary" @click="batchEnable">启用</Button>
  49 + <Button type="error" @click="batchDisable">禁用</Button>
  50 + </LayoutAction>
  51 +
  52 + <LayoutList>
  53 + <Table border :context="self" :columns="tableCols"
  54 + :data="tableData" @on-selection-change="selectChange"></Table>
  55 + <Page :total="pageData.total" :current="pageData.current"
  56 + @on-change="pageChange" :page-size="20" show-total></Page>
  57 + </LayoutList>
  58 + </LayoutBody>
4 </template> 59 </template>
5 60
6 <script> 61 <script>
  62 + import _ from 'lodash';
  63 + import service from 'product-service';
  64 + import {ModalSizeEdit} from 'components/modal';
  65 + import {SelectBrand, SelectCategory} from 'components/select';
  66 + import {CellImage, CellInfo, CellPrice} from 'components/cell';
  67 + import onSaleStore from './store';
  68 +
7 export default { 69 export default {
8 data() { 70 data() {
9 return { 71 return {
  72 + self: this,
  73 + showSizeEdit: false,
  74 + tableCols: [],
  75 + tableData: {},
  76 + pageData: {},
  77 + filters: {},
  78 + batchOffSale: [],
  79 + useFilterSign: false,
  80 + categoryValue: []
10 }; 81 };
11 }, 82 },
12 created() { 83 created() {
  84 + const store = onSaleStore();
  85 +
  86 + this.productList();
  87 + this.filters = store.filterFields;
  88 + this.tableCols = store.tableCols;
  89 + this.tableData = store.tableData;
  90 + this.pageData = store.pageData;
  91 +
13 }, 92 },
14 methods: { 93 methods: {
  94 + filterParams() {
  95 + const fts = this.filters;
  96 + const data = {};
  97 +
  98 + return data;
  99 + },
  100 + filterSearch() {
  101 + const params = this.filterParams();
  102 +
  103 + this.useFilterSign = true;
  104 + this.productList(params);
  105 + this.pageData.current = 1;
  106 +
  107 + },
  108 + clearFilter() {
  109 + const store = onSaleStore();
  110 +
  111 + this.filters = store.filterFields;
  112 + this.productList();
  113 + this.useFilterSign = false;
  114 + this.pageData.current = 1;
  115 + this.categoryValue = [];
  116 + },
  117 + enablePrice(){
  118 +
  119 + },
  120 + disablePrice(){
  121 +
  122 + },
  123 + batchEnable(){
  124 + },
  125 + batchDisable(){
  126 + },
  127 + productList(params) {
  128 +
  129 +// if (_.isObject(params) &&
  130 +// typeof params.productSkn !== 'undefined' &&
  131 +// !_.isFinite(+params.productSkn)) {
  132 +// this.$Message.error('SKN编码只能是数字', 3);
  133 +// return;
  134 +// }
  135 +
  136 + this.$Loading.start();
  137 + service.vipProductList({size: 20, page: 1})
  138 + .then(res => {
  139 + this.$Loading.finish();
  140 + if (res.code === 200) {
  141 + this.updateStore(res.data);
  142 + }
  143 + });
  144 + },
  145 + reloadList() {
  146 + let params = {};
  147 +
  148 + if (this.useFilterSign) {
  149 + params = this.filterParams();
  150 + }
  151 +
  152 + _.merge(params, {
  153 + page: 1,
  154 + size: 20,
  155 + productStatusStr: 1
  156 + });
  157 +
  158 + this.productList(params);
  159 + this.pageData.current = 1;
  160 + },
  161 + updateStore(data) {
  162 + _.each(data.list, item => {
  163 + item.changePrice = false;
  164 + item.stock = item.stock || 0;
  165 + item._disabled = item.auditStatus === 1;
  166 + item.shelveTime = item.shelveTime || '-';
  167 + });
  168 +
  169 + this.tableData = data.list;
  170 + this.pageData.total = data.total;
  171 + },
  172 + sortChange(sort) {
  173 + this.filters.sort.first.model = sort.max;
  174 + this.filters.sort.second.model = sort.mid;
  175 + this.filters.sort.third.model = sort.min;
  176 + },
  177 + brandChange(val) {
  178 + _.set(this.filters, 'brand.model', val);
  179 + },
  180 + pageChange(page) {
  181 + this.pageData.current = page;
  182 +
  183 + let params = {};
  184 +
  185 + if (this.useFilterSign) {
  186 + params = this.filterParams();
  187 + }
  188 +
  189 + _.merge(params, {
  190 + page,
  191 + size: 20,
  192 + productStatusStr: 1
  193 + });
  194 +
  195 + this.productList(params);
  196 + },
  197 + selectChange(selection) {
  198 + this.batchOffSale = selection;
  199 + }
15 }, 200 },
16 components: { 201 components: {
  202 + SelectBrand,
  203 + SelectCategory,
  204 + CellImage,
  205 + CellInfo,
  206 + CellPrice
17 } 207 }
18 }; 208 };
19 </script> 209 </script>
20 210
21 <style lang="scss"> 211 <style lang="scss">
  212 +
22 </style> 213 </style>
  1 +<template>
  2 + <LayoutBody>
  3 + <LayoutFilter>
  4 + <FilterItem :label="filters.orderNo.label">
  5 + <Input v-model.trim="filters.orderNo.model"
  6 + :placeholder="filters.orderNo.holder"></Input>
  7 + </FilterItem>
  8 + <FilterItem :label="filters.orderTime.label">
  9 + <Date-picker type="daterange"
  10 + placeholder="选择日期"
  11 + @on-change="dateChange"
  12 + v-model="filters.orderTime.model">
  13 + </Date-picker>
  14 + </FilterItem>
  15 + <FilterItem :label="filters.receiveStatus.label">
  16 + <Select v-model.trim="filters.receiveStatus.model">
  17 + <Option v-for="option in filters.receiveStatus.options"
  18 + :value="option.value"
  19 + :key="option.value">{{option.label}}</Option>
  20 + </Select>
  21 + </FilterItem>
  22 + <FilterItem>
  23 + <Button type="primary" @click="filterSearch">筛选</Button>
  24 + <Button @click="clearFilter">清空条件</Button>
  25 + </FilterItem>
  26 + </LayoutFilter>
  27 + <LayoutList>
  28 + <Table border :context="self" :columns="tableCols" :data="tableData"></Table>
  29 + <Page :total="page.total" :current="page.current"
  30 + @on-change="pageChange" :page-size="20" show-total></Page>
  31 + </LayoutList>
  32 + </LayoutBody>
  33 +</template>
  34 +<script>
  35 + import _ from 'lodash';
  36 + import service from 'trade-service';
  37 + import onSaleStore from './store';
  38 +
  39 + export default {
  40 + data() {
  41 + return {
  42 + self: this,
  43 + tableCols: [],
  44 + tableData: {},
  45 + page: {},
  46 + filters: {},
  47 + withFilter: false
  48 + };
  49 + },
  50 + created() {
  51 + const store = onSaleStore();
  52 +
  53 + this.allotList();
  54 + this.filters = store.filterFields;
  55 + this.tableCols = store.tableCols;
  56 + this.tableData = store.tableData;
  57 + this.page = store.page;
  58 + },
  59 + methods: {
  60 + filterValues() {
  61 + const values = {};
  62 + const keyMap = {
  63 + endTime: 'endTime',
  64 + orderNo: 'orderNo',
  65 + startTime: 'startTime',
  66 + status: 'receiveStatus'
  67 + };
  68 + const filters = this.filters;
  69 +
  70 + _.each(keyMap, (val, key) => {
  71 + values[key] = filters[val];
  72 + });
  73 +
  74 + return values;
  75 + },
  76 + filterSearch() {
  77 + this.page.current = 1;
  78 + this.withFilter = true;
  79 + this.allotList(this.filterValues());
  80 + },
  81 + clearFilter() {
  82 + const store = onSaleStore();
  83 +
  84 + this.filters = store.filterFields;
  85 + this.allotList();
  86 + this.withFilter = false;
  87 + this.page.current = 1;
  88 + this.categoryValue = [];
  89 + },
  90 + allotList() {
  91 + service.allotList()
  92 + .then(res => {
  93 +
  94 + });
  95 +
  96 + },
  97 + reloadList() {
  98 + let params = {};
  99 +
  100 + if (this.withFilter) {
  101 + params = this.filterValues();
  102 + }
  103 +
  104 + _.merge(params, {
  105 + page: 1,
  106 + size: 20
  107 + });
  108 +
  109 + this.allotList(params);
  110 + this.page.current = 1;
  111 + },
  112 + resolveData(data) {
  113 + this.tableData = data.list;
  114 + this.page.total = data.total;
  115 + },
  116 + pageChange(page) {
  117 + this.page.current = page;
  118 +
  119 + let params = {};
  120 +
  121 + if (this.withFilter) {
  122 + params = this.filterValues();
  123 + }
  124 +
  125 + _.merge(params, {
  126 + page,
  127 + size: 20,
  128 + productStatusStr: 1
  129 + });
  130 +
  131 + this.allotList(params);
  132 + },
  133 + dateChange(date) {
  134 + this.filters.startTime = date[0];
  135 + this.filters.endTime = date[1];
  136 + }
  137 + },
  138 + components: {}
  139 + };
  140 +</script>
  141 +
  142 +<style lang="scss">
  143 +</style>
  1 +const allotList = r => require.ensure([], () => r(require('./allot-list')), 'trade.allotList');
  2 +
  3 +export default {
  4 + path: '/allotList.html',
  5 + name: 'allotList',
  6 + component: allotList,
  7 + meta: {
  8 + pageName: '调拨单'
  9 + }
  10 +};
  1 +/**
  2 + * on sale page store
  3 + * @author: qi.li <qi.li@yoho.cn>
  4 + * @date: 2017/04/13
  5 + */
  6 +
  7 +const auditStatus = {
  8 + 0: '无状态',
  9 + 1: '下架待审核',
  10 + 2: '下架驳回',
  11 + 3: '已上架'
  12 +};
  13 +
  14 +export default () => {
  15 + return {
  16 + tableCols: [
  17 + {
  18 + title: '调拨单号',
  19 + key: 'stock',
  20 + align: 'center',
  21 + },
  22 + {
  23 + title: '下单时间',
  24 + key: 'shelveTime',
  25 + align: 'center'
  26 + },
  27 + {
  28 + title: '发货进度(已发总数/实际需发总数)',
  29 + key: 'shelveTime',
  30 + align: 'center'
  31 + },
  32 + {
  33 + title: '收货进度(收货总数/已发总数)',
  34 + key: 'shelveTime',
  35 + align: 'center'
  36 + },
  37 + {
  38 + title: '调拨总数',
  39 + key: 'shelveTime',
  40 + align: 'center'
  41 + },
  42 + {
  43 + title: '缺货数',
  44 + key: 'shelveTime',
  45 + align: 'center'
  46 + },
  47 + {
  48 + title: '状态',
  49 + key: 'shelveTime',
  50 + align: 'center'
  51 + }
  52 + ],
  53 + tableData: [],
  54 + pageData: {
  55 + total: 0,
  56 + current: 1
  57 + },
  58 + filterFields: {
  59 + orderNo: {
  60 + label: '入库单号',
  61 + model: ''
  62 + },
  63 + orderTime: {
  64 + label: '下单时间',
  65 + model: ''
  66 + },
  67 + startTime: {
  68 + model: '',
  69 + },
  70 + endTime: {
  71 + model: '',
  72 + },
  73 + receiveStatus: {
  74 + label: '状态',
  75 + model: -1,
  76 + options: [
  77 + {
  78 + value: -1,
  79 + label: '全部'
  80 + },
  81 + {
  82 + value: 1,
  83 + label: '未收货'
  84 + },
  85 + {
  86 + value: 2,
  87 + label: '收货未完成'
  88 + },
  89 + {
  90 + value: 3,
  91 + label: '发货未完成'
  92 + },
  93 + {
  94 + value: 4,
  95 + label: '收货已完成'
  96 + }
  97 + ]
  98 + }
  99 + }
  100 + };
  101 +};
1 import allot from './allot'; 1 import allot from './allot';
2 import expdetail from './express-detail'; 2 import expdetail from './express-detail';
3 import printdetail from './print-detail'; 3 import printdetail from './print-detail';
  4 +import allotlist from './allot-list';
4 5
5 export default { 6 export default {
6 allot, 7 allot,
7 expdetail, 8 expdetail,
8 - printdetail 9 + printdetail,
  10 + allotlist
9 }; 11 };
@@ -9,6 +9,7 @@ import axios from 'axios'; @@ -9,6 +9,7 @@ import axios from 'axios';
9 const apiUrl = { 9 const apiUrl = {
10 brand: '/platform/getSellerBrandInfo', 10 brand: '/platform/getSellerBrandInfo',
11 productList: '/platform/querySellerProductList', 11 productList: '/platform/querySellerProductList',
  12 + vipProductList: '/platform/queryVipProductList',
12 productOutSale: '/platform/productOutSale', 13 productOutSale: '/platform/productOutSale',
13 productOnSale: '/platform/productOnSale', 14 productOnSale: '/platform/productOnSale',
14 updateSellerPrice: '/platform/updateSellerPrice', 15 updateSellerPrice: '/platform/updateSellerPrice',
@@ -47,6 +48,18 @@ const productService = { @@ -47,6 +48,18 @@ const productService = {
47 }); 48 });
48 }, 49 },
49 50
  51 + vipProductList(params) {
  52 + return axios.post(apiUrl.vipProductList, {
  53 + params
  54 + })
  55 + .then(res => {
  56 + if (res.status === 200) {
  57 + return res.data;
  58 + }
  59 + return {};
  60 + });
  61 + },
  62 +
50 setOffSale(params) { 63 setOffSale(params) {
51 return axios.post(apiUrl.productOutSale, params); 64 return axios.post(apiUrl.productOutSale, params);
52 }, 65 },
@@ -14,6 +14,7 @@ const apiUrl = { @@ -14,6 +14,7 @@ const apiUrl = {
14 allotStockOut: '/erp/allotStockOut', 14 allotStockOut: '/erp/allotStockOut',
15 allotExpressNumList: '/erp/allotExpressNumList', 15 allotExpressNumList: '/erp/allotExpressNumList',
16 allotExpressCompList: '/erp/allotExpressCompList', 16 allotExpressCompList: '/erp/allotExpressCompList',
  17 + allotList: '/erp/allotExpressCompList', // todo
17 allotPrintExpressDetail: '/erp/allotPrintExpressDetail' 18 allotPrintExpressDetail: '/erp/allotPrintExpressDetail'
18 }; 19 };
19 20
@@ -99,6 +100,16 @@ const tradeService = { @@ -99,6 +100,16 @@ const tradeService = {
99 return {}; 100 return {};
100 }); 101 });
101 }, 102 },
  103 + allotList() {
  104 + return axios.get(apiUrl.allotList)
  105 + .then(res => {
  106 + if (res.status === 200) {
  107 + return res.data;
  108 + }
  109 +
  110 + return {};
  111 + });
  112 + },
102 allotPrintExpressDetail(no) { 113 allotPrintExpressDetail(no) {
103 return axios.post(apiUrl.allotPrintExpressDetail, { 114 return axios.post(apiUrl.allotPrintExpressDetail, {
104 expressNumber: no 115 expressNumber: no
@@ -31,6 +31,7 @@ let domainApis = { @@ -31,6 +31,7 @@ let domainApis = {
31 querySellerProductMaterial: '/SellerProductController/querySellerProductMaterial', 31 querySellerProductMaterial: '/SellerProductController/querySellerProductMaterial',
32 updateSellerProductNetSaleInfo: '/SellerProductController/updateSellerProductNetSaleInfo', 32 updateSellerProductNetSaleInfo: '/SellerProductController/updateSellerProductNetSaleInfo',
33 querySellerProductList: '/SellerProductController/querySellerProductList', 33 querySellerProductList: '/SellerProductController/querySellerProductList',
  34 + queryVipProductList: '/sellerVip/queryProductVipList',
34 productOutSale: '/SellerSknStatusController/productOutSale', 35 productOutSale: '/SellerSknStatusController/productOutSale',
35 productOnSale: '/SellerSknStatusController/productOnSale', 36 productOnSale: '/SellerSknStatusController/productOnSale',
36 queryProdSizeList: '/SellerProductSize/queryProdSizeList', 37 queryProdSizeList: '/SellerProductSize/queryProdSizeList',