Authored by htoooth

Merge branch 'release/1.0' of http://git.yoho.cn/fe/yoho-shop-manage into release/1.0

import SelectBrand from './select-brand';
import SelectCategory from './select-category';
export {
SelectBrand,
SelectCategory
};
... ...
<template>
<Select v-model="_fieldModel" @on-change="selectChange" clearable>
<Option :value="-1">全部</Option>
<Option v-for="option in optionList" :value="option.brandId" :key="option.brandId">
{{option.brandName}}
</Option>
</Select>
</template>
<script>
import _ from 'lodash';
import service from 'finance-service';
export default {
name: 'SelectBrand',
props: {
fieldLabel: {
type: String
},
fieldModel: {
type: [String, Number]
},
labelSpan: {
type: [String, Number],
default: 6
},
fieldSpan: {
type: [String, Number],
default: 18
}
},
data() {
return {
optionList: []
};
},
computed: {
_fieldModel() {
return this.fieldModel;
}
},
created() {
const err_msg = '获取品牌列表失败。';
service.getBrand().then((res) => {
let code = _.get(res, 'data.code');
if (code === 200) {
this.optionList = res.data.data;
}
return this.$Message.error(err_msg);
}, (error) => {
this.$Message.error(error.message);
});
},
methods: {
selectChange(val) {
this.$emit('on-change', val);
}
}
};
</script>
<style lang="scss" scoped>
.field-label {
line-height: 32px;
}
</style>
... ...
<template>
<div>
<Cascader :value="value" :data="categoryList" change-on-select @on-change="selectChange"></Cascader>
<slot></slot>
</div>
</template>
<script>
import _ from 'lodash';
import service from 'product-service';
export default {
name: 'SelcetCategory',
props: {
value: {
type: Array
}
},
data() {
return {
categoryList: []
};
},
created() {
this.getSortInfo(1);
},
methods: {
getSortInfo(level, sortId) {
const params = {
level,
sortId
};
service.getAllSort(params)
.then((res) => {
if (res.code === 200) {
_.each(res.data, item => {
this.categoryList.push({
value: item.sortId,
label: item.sortName,
children: [{
value: -1,
label: ''
}]
});
});
}
});
},
selectChange(val) {
const len = val.length;
const max = val[0] || '';
const mid = val[1] || '';
const min = val[2] || '';
switch (len) {
case 1:
_.each(this.categoryList, item => {
if (item.value !== max) {
return;
}
this.getChildren(2, max)
.then(res => {
item.children.shift();
_.each(res, i => {
item.children.push({
value: i.value,
label: i.label,
children: [{
value: -1,
label: ''
}]
});
});
});
});
break;
case 2:
_.each(this.categoryList, maxItem => {
if (maxItem.value !== max) {
return;
}
_.each(maxItem.children, midItem => {
if (midItem.value !== mid) {
return;
}
this.getChildren(3, mid)
.then(res => {
midItem.children.shift();
_.each(res, i => {
midItem.children.push({
value: i.value,
label: i.label
});
});
});
});
});
break;
}
this.$emit('select-change', {
max,
mid,
min
});
},
getChildren(level, sortId) {
const params = {
level,
sortId
};
return service.getAllSort(params)
.then((res) => {
let children = [];
if (res.code === 200) {
_.each(res.data, item => {
children.push({
value: item.sortId,
label: item.sortName
});
});
}
return children;
});
}
}
};
</script>
<style lang="scss" scoped>
</style>
... ...
... ... @@ -5,10 +5,29 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>YOHO商铺管理平台</title>
<style>
.check-browers {
display: none;
}
</style>
</head>
<body>
<div id="app">
正在初始化
<div class="loading-init" id="loading-init">正在初始化...</div>
<div class="check-browers" id="check-browers">
检测到您的浏览器版本过低,请下载最新浏览器:
<ul>
<li><a href="http://browser.qq.com/mac/index.html">QQ浏览器</a></li>
<li><a href="http://www.firefox.com.cn/">火狐浏览器</a></li>
<li><a href="http://www.google.cn/intl/zh-CN/chrome/browser/desktop/index.html">Chrome浏览器</a></li>
</ul>
</div>
</div>
<script>
if (!Object.defineProperty) {
document.getElementById('loading-init').style.display = 'none';
document.getElementById('check-browers').style.display = 'block';
}
</script>
</body>
</html>
\ No newline at end of file
... ...
<template>
结算页
<LayoutBody>
<LayoutFilter>
<FilterItem label="对帐单号">
<!--<Input v-model.trim.trim=""-->
<!--:placeholder=""-->
<!--&gt;</Input>-->
</FilterItem>
<FilterItem label="供应商">
<!--<SelectBrand>-->
<!--</SelectBrand>-->
</FilterItem>
<FilterItem label="品牌">
</FilterItem>
</template>
<FilterItem label="日期">
<Date-picker type="date" placeholder="选择日期" style="width: 180px"></Date-picker>
</FilterItem>
<script>
<FilterItem label="">
<Date-picker type="daterange" placement="bottom-end" placeholder="选择日期" style="width: 180px"></Date-picker>
</FilterItem>
<FilterItem>
<Button type="primary" @click="filterSearch">筛选</Button>
<Button @click="">导出</Button>
</FilterItem>
</LayoutFilter>
import service from 'balance-service';
<LayoutList>
<Table border :context="self" :columns="tableCols" :data="tableData"></Table>
<!--<Page :total="" :current=""-->
<!--@on-change="" :page-size="20" show-total></Page>-->
</LayoutList>
const _ = require('lodash');
</LayoutBody>
</template>
<script>
import Vue from 'vue';
import service from 'finance-service';
import {SelectBrand, SelectCategory} from 'finance/filter-select';
import {filterFields, initialFields, tableCols, tableData} from './detail';
export default {
created() {
},
data() {
return {
self: this,
tableCols,
tableData,
filters: '',
};
},
created() {
this.filters = JSON.parse(initialFields);
},
methods: {
filterParams() {
// const fts = this.filters;
const data = {
};
return data;
},
filterSearch() {
const params = this.filterParams();
this.useFilterSign = true;
this.productList(params);
this.pageData.current = 1;
},
productList(params) {
if (_.isObject(params) &&
params.productSkn !== undefined &&
!_.isFinite(+params.productSkn)) {
this.$Message.error('SKN编码只能是数字', 3);
return;
};
service.productList(
_.merge(params || {}, {
shelfStatus: 1,
size: 20
}))
.then(res => {
if (res.code === 200) {
this.updateStore(res.data);
}
});
}
},
components: {
SelectBrand,
SelectCategory,
}
};
</script>
... ...
let filterFields = {
sknCode: {
label: 'SKN编码',
labelSpan: 6,
model: '',
holder: '',
fieldSpan: 18
},
prodCode: {
label: '商家编码',
labelSpan: 6,
model: '',
holder: '',
fieldSpan: 18
},
prodName: {
label: '商品名称',
labelSpan: 6,
model: '',
holder: '',
fieldSpan: 18
},
prodBarCode: {
label: '商品条码',
labelSpan: 6,
model: '',
holder: '',
fieldSpan: 18
},
sort: {
first: {
label: '选择类目',
holder: '选择一级类目',
labelSpan: 6,
fieldSpan: 18,
model: ''
},
second: {
label: '二级类目',
holder: '选择二级类目',
labelSpan: 6,
fieldSpan: 18,
model: ''
},
third: {
label: '三级类目',
holder: '选择三级类目',
labelSpan: 6,
fieldSpan: 18,
model: ''
}
},
brand: {
label: '选择品牌',
labelSpan: 6,
fieldSpan: 18,
model: -1
},
verifyStatus: {
label: '审核状态',
labelSpan: 6,
fieldSpan: 18,
model: -1,
options: [
{
value: -1,
label: '全部'
},
{
value: 1,
label: '下架待审核'
},
{
value: 2,
label: '下架驳回'
}
]
},
stockStatus: {
label: '库存情况',
labelSpan: 6,
fieldSpan: 18,
model: -1,
options: [
{
value: -1,
label: '全部'
},
{
value: 1,
label: '有库存'
},
{
value: 0,
label: '无库存'
}
]
}
};
let initialFields = JSON.stringify(filterFields);
let tableCols = [
{
title: '对账单号',
key: 'image',
width: 120,
align: 'center',
render (row, column, index) {
return '<cell-image :image-src="row.picImgUrl" :product-url="row.productUrl"></cell-image>';
}
},
{
title: '生成日期',
key: 'info',
align: 'center',
render(row, column, index) {
return `<cell-info
:skn="row.productSkn"
:product-name="row.productName"
:brand-name="row.brandName"
:max-name="row.maxSortName"
:middle-name="row.middleSortName"
:small-name="row.smallSortName">
</cell-info>`;
}
},
{
title: '结算周期',
key: 'price',
align: 'center',
render(row, column, index) {
row.lineIndex = index;
return `<cell-price
@click-change="editPrice(row)"
@click-save="updatePrice"
:can-change="true"
:current-row="row"
:show-change="row.changePrice"
:retail-price="row.retailPrice"
:sales-price="row.salesPrice">
</cell-price>`;
}
},
{
title: '品牌',
key: 'stock',
width: 100,
align: 'center',
},
{
title: '供应商',
key: 'shelveTime',
width: 150,
align: 'center'
},
{
title: '结算金额',
key: 'verify',
align: 'center',
render(row, column, index) {
return `${auditStatus[row.auditStatus]}`
}
},
{
title: '操作',
key: 'action',
width: 180,
align: 'center',
render: function(row, column, index) {
return `<div class="action-btn-row">
<i-button type="primary" size="small" @click="editSize(row.productSkn)">尺码维护</i-button>
<i-button v-if="row._disabled" type="primary" size="small"
@click="editProduct(${row.productSkn})" disabled>内容编辑</i-button>
<i-button v-else type="primary" size="small" @click="editProduct(${row.productSkn})">内容编辑</i-button>
</div>
<div class="btn-row-space">
<i-button v-if="row._disabled" type="error" size="small"
@click="setOffSale(${row.productSkn})" disabled>下架</i-button>
<i-button v-else type="error" size="small" @click="setOffSale(${row.productSkn})" >下架</i-button>
</div>`;
}
}
];
let tableData = [];
export {
filterFields,
initialFields,
tableCols,
tableData
};
... ...
import info from './balance';
import balance from './balance';
import store from './store';
let routers = [info];
let routers = [balance, store];
routers.forEach(router => {
router.path = `/balance${router.path}`;
router.name = `balance.${router.name}`;
router.path = `/finance${router.path}`;
router.name = `finance.${router.name}`;
});
export default routers;
\ No newline at end of file
export default routers;
... ...
const page = r => require.ensure([], () => r(require('./store')), 'finance.store');
export default {
path: '/store.html',
name: 'store',
component: page,
meta: {
pageName: '结算单'
}
};
... ...
<template>
<LayoutBody>
<LayoutFilter>
<FilterItem label="公司">
</FilterItem>
<!--<FilterItem label="品牌">-->
<!--<SelectBrand>-->
<!--</SelectBrand>-->
<!--</FilterItem>-->
<FilterItem label="日期">
<Date-picker type="date" placeholder="选择日期" style="width: 180px"></Date-picker>
</FilterItem>
<FilterItem label="">
<Date-picker type="date" placement="bottom-end" placeholder="选择日期" style="width: 180px"></Date-picker>
</FilterItem>
<FilterItem>
<Button type="primary" @click="">筛选</Button>
<Button @click="">打印</Button>
</FilterItem>
</LayoutFilter>
<LayoutList>
<!--<Table :columns="" :data=""></Table>-->
<!--<Page :total="" :current=""-->
<!--@on-change="" :page-size="20" show-total></Page>-->
</LayoutList>
</LayoutBody>
</template>
<script>
import Vue from 'vue';
import service from 'finance-service';
export default {
data() {
return {
};
},
created() {
},
methods: {
}
};
</script>
<style lang="scss" scoped>
</style>
... ...
<template>
<div>
默认页
<div style="">
<Button v-purview="'opration'" @click="">我有权限吗?</Button>
<editor :content="content" @change="updateData"></editor>
<!--<Table ref="table" :data="data" :columns="columns"></Table>
<Button @click="getTable">获得数据</Button>
<Button @click="addRow">增加一列</Button>
{{data}}
<br />
<editor :content="content" @change="updateData"></editor>
{{content}}
<YohoUpload id="123" @on-success="uploadSuccess" @on-error="uploadError"></YohoUpload>-->
</div>
默认页
</div>
</template>
<script>
export default {
created() {
},
data() {
return {
content: '',
columns: [
{title: '列', key: 'name', render(row, col, index) {
return `<input type="text" v-model="row.name" />`;
}}
],
data: [
{name: '1'}
]
};
},
methods: {
getTable() {
console.log(this.$refs.table.rebuildData);
},
addRow() {
this.data = this.$refs.table.rebuildData;
this.data.push({name: '2'})
},
updateData(c) {
this.content = c;
},
uploadSuccess(id, files) {
console.log(id, files)
},
uploadError(id, error) {
console.log(id, error)
}
}
};
</script>
... ...
... ... @@ -4,8 +4,9 @@ import product from './product';
import shop from './shop';
import repository from './repository';
import statistics from './statistics';
import finance from './finance';
let routers = [product, home, shop, repository, statistics];
let routers = [product, home, shop, repository, statistics, finance];
let childrenRoutes = [].concat(...routers);
... ...
... ... @@ -17,10 +17,6 @@
<Input v-model.trim="filters.prodBarCode.model"
:placeholder="filters.prodBarCode.holder"></Input>
</FilterItem>
<FilterItem :label="filters.prodBarCode.label">
<Input v-model.trim="filters.prodBarCode.model"
:placeholder="filters.prodBarCode.holder"></Input>
</FilterItem>
<FilterItem label="选择品牌">
<SelectBrand @on-change="brandChange"
:field-label="filters.brand.label"
... ... @@ -30,6 +26,9 @@
:option-list="filters.brand.options">
</SelectBrand>
</FilterItem>
<FilterItem label="选择类目">
<SelectCategory :value="categoryValue" @select-change="sortChange"></SelectCategory>
</FilterItem>
<FilterItem :label="filters.verifyStatus.label">
<Select v-model.trim="filters.verifyStatus.model">
<Option v-for="option in filters.verifyStatus.options"
... ... @@ -51,9 +50,6 @@
:key="option.value">{{option.label}}</Option>
</Select>
</FilterItem>
<FilterItem label="选择类目">
<SelectCategory :value="categoryValue" @select-change="sortChange"></SelectCategory>
</FilterItem>
<FilterItem>
<Button type="primary" @click="filterSearch">筛选</Button>
<Button @click="clearFilter">清空条件</Button>
... ...
... ... @@ -9,10 +9,6 @@
<Input v-model.trim="filters.prodCode.model"
:placeholder="filters.prodCode.holder"></Input>
</FilterItem>
<FilterItem :label="filters.prodCode.label">
<Input v-model.trim="filters.prodCode.model"
:placeholder="filters.prodCode.holder"></Input>
</FilterItem>
<FilterItem :label="filters.prodName.label">
<Input v-model.trim="filters.prodName.model"
:placeholder="filters.prodName.holder"></Input>
... ... @@ -30,6 +26,9 @@
:option-list="filters.brand.options">
</SelectBrand>
</FilterItem>
<FilterItem label="选择类目">
<SelectCategory :value="categoryValue" @select-change="sortChange"></SelectCategory>
</FilterItem>
<FilterItem :label="filters.verifyStatus.label">
<Select v-model.trim="filters.verifyStatus.model">
<Option v-for="option in filters.verifyStatus.options"
... ... @@ -44,9 +43,6 @@
:key="option.value">{{option.label}}</Option>
</Select>
</FilterItem>
<FilterItem label="选择类目">
<SelectCategory :value="categoryValue" @select-change="sortChange"></SelectCategory>
</FilterItem>
<FilterItem>
<Button type="primary" @click="filterSearch">筛选</Button>
<Button @click="clearFilter">清空条件</Button>
... ...
<template>
<Form :label-width="100">
<Form-item label="店铺名称:">
<span>{{}}</span>
</Form-item>
<Form-item label="店铺类型:">
<span>{{}}</span>
</Form-item>
<Form-item label="店铺域名:">
<span>{{}}</span>
</Form-item>
<Form-item label="店铺LOGO:">
<div class="upload-item">
<div class="upload-item-img">
<drag-file-upload
:id="{goodIndex:1, imageIndex: 1}"
@on-success="uploadImageSuccess"
@on-remove="uploadImageRemove">
</drag-file-upload>
<LayoutBody>
<Form :label-width="100">
<Form-item label="店铺名称:">
<span>{{shopData.shopName}}</span>
</Form-item>
<Form-item label="店铺类型:">
<span>{{SHOPNATURE[shopData.shopNature]}}</span>
</Form-item>
<Form-item label="店铺域名:">
<span>{{shopData.shopDomain}}</span>
</Form-item>
<Form-item label="店铺LOGO:">
<div class="upload-item">
<div class="upload-item-img">
<drag-file-upload
:default-file="shopData.shopLogo"
:id="{goodIndex:1, imageIndex: 1}"
@on-success="uploadImageSuccess"
@on-remove="uploadImageRemove">
</drag-file-upload>
</div>
</div>
</div>
<em class="upload-img-tip">尺寸要求150px*150px&nbsp;&nbsp;不大于500KB</em>
</Form-item>
<Form-item label="店铺简介:">
<editor :content="content" @change="updateData"></editor>
</Form-item>
<Form-item label="品牌-供应商:">
<Table :columns="columns1" :data="data1"></Table>
</Form-item>
<Form-item>
<Button type="primary" @click="submit">提交</Button>
</Form-item>
</Form>
<em class="upload-img-tip">尺寸要求150px*150px&nbsp;&nbsp;不大于500KB</em>
</Form-item>
<Form-item label="店铺简介:">
<editor :content="shopData.shopIntro" @change="updateData"></editor>
</Form-item>
<Form-item label="品牌-供应商:">
<Table :columns="tableCols" :data="tableData"></Table>
</Form-item>
<Form-item>
<Button type="primary" @click="submit">提交</Button>
</Form-item>
</Form>
</LayoutBody>
</template>
<script>
import service from 'shop-service';
import service from 'shop-service';
const _ = require('lodash');
const _ = require('lodash');
const makeSubmitShop = () => {
return {
const SHOPNATURE = {
1: '旗舰店',
2: '专卖店',
3: '初始状态(异常情况)'
};
};
export default {
created() {
},
data() {
return {
//店铺简介
content: '',
//供应商
columns1: [
{
title: '品牌',
key: 'coupon'
},
{
title: '供应商',
key: 'supplier'
}
],
data1: [
{
coupon: 'hahahah',
supplier: 'hhhhhhhh'
}
]
};
},
methods: {
updateData(c) {
this.content = c;
},
//上传图片
uploadImageSuccess: function(attach, file) {
let colorIndex = attach.goodIndex;
let imageIndex = attach.imageIndex;
export default {
created() {
service.getShop().then((res) => {
this.product.goods[colorIndex].goodsImage[imageIndex].imageUrl = file.url;
},
uploadImageRemove: function(attach) {
let colorIndex = attach.goodIndex;
let imageIndex = attach.imageIndex;
this.shopData = res.data;
this.tableData = JSON.parse(res.data.shopRelationList);
this.product.goods[colorIndex].goodsImage[imageIndex].imageUrl = '';
// console.log(res);
console.log(res.data.shopLogo);
}, (error) => {
this.$Message.error(error.message);
});
},
data() {
return {
SHOPNATURE,
shopData: {},
tableCols: [
{
title: '品牌',
key: 'brandName',
align: 'center',
},
{
title: '供应商',
key: 'supplierName',
width: 300,
align: 'center'
}
],
tableData: []
};
},
methods: {
updateData(c) {
this.content = c;
},
//提交
beforeSubmit: function() {
let newShop = makeSubmitShop();
//上传图片
uploadImageSuccess: function (attach, file) {
let colorIndex = attach.goodIndex;
let imageIndex = attach.imageIndex;
this.product.goods[colorIndex].goodsImage[imageIndex].imageUrl = file.url;
},
uploadImageRemove: function (attach) {
let colorIndex = attach.goodIndex;
let imageIndex = attach.imageIndex;
this.product.goods[colorIndex].goodsImage[imageIndex].imageUrl = '';
},
//提交
beforeSubmit: function () {
// newShop.expectSaleTimeStr = this.product.expectSaleTimeStr;
//
// newShop.sellerGoodsInfoStr = JSON.stringify(this.handleColor());
return newShop;
},
submit: function() {
let newShop = this.beforeSubmit();
this.$Loading.start();
service.saveBaseShopInfo(newShop).then((result) => {
this.$Loading.finish();
if (result.code === 200) {
this.$Notice.success({
title: '修改成功',
desc: '该店铺保存成功!'
});
this.$router.push({name: 'shop'});
} else {
this.$Notice.error({
title: '保存错误',
desc: result.message
});
}
});
}
},
submit: function () {
let newShop = this.beforeSubmit();
}
};
this.$Loading.start();
service.saveBaseShopInfo(newShop).then((result) => {
this.$Loading.finish();
if (result.code === 200) {
this.$Notice.success({
title: '修改成功',
desc: '该店铺保存成功!'
});
this.$router.push({name: 'shop'});
} else {
this.$Notice.error({
title: '保存错误',
desc: result.message
});
}
});
}
}
};
</script>
<style lang="scss" scoped>
<style lang="scss">
.upload-item {
float: left;
... ...
... ... @@ -87,5 +87,27 @@ export default [
menu_id: 'statistics',
status: 1,
id: 4
},
{
sub: [
{
menu_name: '查看明细',
menu_url: '/finance/balance.html',
menu_id: 'finance.balance',
status: 1,
id: 51
},
{
menu_name: '库存',
menu_url: '/finance/store.html',
menu_id: 'finance.store',
status: 1,
id: 52
}
],
menu_name: '财务管理',
menu_id: 'finance',
status: 1,
id: 5
}
];
... ...
// import _ from 'lodash';
// import axios from 'axios';
const balanceService = {
};
export default balanceService;
// import _ from 'lodash';
import axios from 'axios';
const apiUrl = {
productList: '/platform/querySellerProductList'
};
const balanceService = {
productList(params) {
return axios.get(apiUrl.productList, {
params
})
.then(res => {
if (res.status === 200) {
return res.data;
}
return {};
});
}
};
export default balanceService;
... ...
import _ from 'lodash';
// import _ from 'lodash';
import axios from 'axios';
const apiUrl = {
shop: 'shop/info/detail',
};
const shopService = {
getShop(params) {
return axios.get('/platform/getShopDetailById', {
params
})
.then(res => {
if (res.status === 200) {
return res.data;
}
return {};
});
},
/**
* 保存店铺基本信息
* @param shop
*/
saveBaseShopInfo(shop) {
return axios.post(apiUrl.shop, shop)
return axios.post('/platform/getShopDetailById', shop)
.then(result => result.data);
}
};
export default shopService;
... ...
... ... @@ -42,12 +42,7 @@ app.use(compression());
app.use(favicon(path.join(__dirname, '/favicon.ico')));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use(cookieParser('', {
decode(val) {
console.log(val)
return val;
}
}));
app.use(cookieParser());
const middleware = require('./middleware');
const controllers = require('./controllers');
... ...
... ... @@ -26,7 +26,8 @@ let domainApis = {
exportSellerProductList: '/SellerProductController/exportSellerProductList',
updateSellerPrice: '/SellerPriceController/updateSellerPrice',
updateProduct: '/SellerProductController/updateProduct',
getProduct: '/SellerProductController/getProduct'
getProduct: '/SellerProductController/getProduct',
getShopDetailById: '/SellerShopController/getShopDetailById'
},
shop: {
login: '/login'
... ...