提交 91859b33 authored 作者: 王鹏飞's avatar 王鹏飞

update

上级 379ed892
......@@ -17,5 +17,13 @@ export function getToken() {
// 获取oss signature
export function getSignature() {
return httpRequest.get('/api/usercenter//aliyun/get-signature')
return httpRequest.get('/api/usercenter/aliyun/get-signature')
}
// 图片上传
export function uploadFile(data) {
return httpRequest.post('https://webapp-pub.ezijing.com', data, {
withCredentials: false,
headers: { 'Content-Type': 'multipart/form-data' }
})
}
<template>
<div class="container">
<header class="container-header">
<div class="app-card">
<div class="app-card-hd">
<slot name="header">
<app-breadCrumb></app-breadCrumb>
<h2 class="app-card-hd__title" v-if="title">{{ title }}</h2>
<slot name="header-aside"></slot>
</slot>
</header>
<main class="container-main">
</div>
<div class="app-card-bd">
<slot></slot>
</main>
<footer class="container-footer">
<slot name="footer"></slot>
</footer>
</div>
</div>
</template>
<script>
import AppBreadCrumb from './breadCrumb'
export default {
components: { AppBreadCrumb },
props: { title: { type: String } },
data() {
return {}
}
name: 'AppCard',
props: { title: String }
}
</script>
<style>
.container::after {
content: '';
display: table;
clear: both;
}
.container {
padding: 0 24px;
}
.container-main {
.app-card {
background: #ffffff;
box-shadow: 0 1px 6px 0 rgb(228 232 235 / 20%);
border-radius: 8px;
margin-bottom: 64px;
margin-bottom: 20px;
padding: 32px;
}
.app-card-hd {
display: flex;
}
.app-card-hd__title {
flex: 1;
font-size: 18px;
font-weight: 700;
margin-bottom: 16px;
}
</style>
......@@ -57,6 +57,7 @@
:page-sizes="[10, 20, 30, 50, 100]"
:page-size="page.size"
:total="page.total"
:current-page.sync="page.currentPage"
@size-change="pageSizeChange"
@current-change="fetchList"
v-if="hasPagination"
......@@ -120,7 +121,7 @@ export default {
let params = this.params
// 翻页参数设置
if (this.hasPagination) {
params.page = this.page.currentPage.toString()
params.page = (this.page.currentPage - 1).toString()
params.page_size = this.page.size.toString()
}
// 接口请求之前
......
......@@ -20,7 +20,7 @@
import { getSignature } from '@/api/base'
import md5 from 'blueimp-md5'
export default {
name: 'UploadImage',
name: 'AppUpload',
props: {
value: { type: String },
prefix: { type: String, default: 'upload/shop-admin/' }
......
<!--日期组件-->
<template>
<el-date-picker v-model="defaultValue" :type="type" :placeholder="placeholder" suffix-icon="el-icon-date" v-bind="$attrs">
</el-date-picker>
</template>
<script>
export default {
name: 'DateTimePicker',
data: () => ({
defaultValue: null
}),
props: {
value: null,
type: {
type: String,
default: 'datetime'
},
placeholder: {
type: String,
default: '请选择日期'
}
},
watch: {
value: {
handler(value) {
this.defaultValue = value ? new Date(value) : null
},
immediate: true
},
defaultValue(value) {
const result = value ? +new Date(value) : null
this.$emit('input', result)
}
}
}
</script>
<template>
<el-button type="primary" class="phone-code-btn" :disabled="disabled">{{text}}</el-button>
</template>
<script>
export default {
name: 'TimerButton',
props: {
seconds: { type: Number, default: 60 }
},
data: function() {
return {
disabled: false,
time: 0,
timer: null // 倒计时定时器
}
},
computed: {
text() {
return this.time > 0 ? this.time + 's' : '发送验证码'
}
},
methods: {
startTimer() {
clearInterval(this.timer)
this.timer = setInterval(() => {
if (this.time <= 0) {
this.disabled = false
clearInterval(this.timer)
} else {
this.disabled = true
}
this.time--
}, 1000)
},
start() {
this.time = this.seconds
this.startTimer()
},
stop() {
clearInterval(this.timer)
this.disabled = false
this.time = 0
}
},
beforeDestroy() {
clearInterval(this.timer)
}
}
</script>
<!--用户自动提示组件-->
<template>
<el-autocomplete v-model="nickName" valueKey="nickName" popper-class="user-autocomplete" :disabled="disabled" :fetch-suggestions="querySearchAsync" :placeholder="placeholder" @select="handleSelect" suffix-icon="el-icon-search" style="width:100%;">
<template slot-scope="props">
<div class="pic"><img :src="props.item.avatar | setImageUrl" /></div>
<div class="content">
<div class="zcode">{{ props.item.zcode }}</div>
<div class="name">{{ props.item.nickName }}</div>
</div>
</template>
</el-autocomplete>
</template>
<script>
import { fetchUser } from '@/api/base' // 按照昵称查询用户接口
export default {
name: 'UserAutoComplete',
props: {
value: null,
showValue: {
type: String,
default: ''
},
placeholder: {
type: String,
default: '请输入'
},
disabled: {
type: Boolean,
default: false
}
},
data: () => ({
nickName: '',
dataList: []
}),
watch: {
showValue: function(value) {
this.nickName = value
},
nickName: function(value) {
if (!value) {
this.$emit('input', null)
}
}
},
filters: {
setImageUrl: value => {
let url = ''
if (!value) {
url = '//www.zai-art.com/appwrapper_dist/appDefaultImage/user.png'
} else {
url = /(http)|(https)|(\/\/)/gi.test(value)
? value.replace(/(^http:)|(^https:)/gi, '')
: `//img.zai-art.com/${value}`
}
return `${url}?imageView2/1/w/80/h/80`
}
},
created() {
this.nickName = this.showValue
},
methods: {
// 用户自动匹配
querySearchAsync(query, callback) {
fetchUser({ nickName: query }).then(response => {
this.dataList = (response.data.data && response.data.data.list) || []
callback(this.dataList)
})
},
// 处理用户自动匹配点击
handleSelect(item) {
this.$emit('input', item.id)
this.$emit('change', item)
}
}
}
</script>
<style>
.user-autocomplete li {
padding: 10px;
}
.user-autocomplete .pic {
float: left;
width: 40px;
height: 40px;
}
.user-autocomplete .pic img {
width: 100%;
height: 100%;
}
.user-autocomplete .content {
margin-left: 50px;
line-height: 20px;
}
.user-autocomplete .content .name {
font-size: 14px;
}
.user-autocomplete .content .zcode {
font-size: 12px;
color: #b4b4b4;
}
</style>
......@@ -20,6 +20,7 @@ import skuGroup from './skuGroup'
import { getSkuNameList } from '@/api/goods'
export default {
name: 'sku',
components: { skuGroup },
props: {
value: { type: Array, default: () => [] }
......@@ -30,7 +31,7 @@ export default {
{
spec_id: '1',
spec_name: '颜色',
value: [
spec_values: [
{ spec_value_id: '1', spec_value: '红' },
{ spec_value_id: '2', spec_value: '黄' },
{ spec_value_id: '3', spec_value: '蓝' }
......@@ -39,7 +40,7 @@ export default {
{
spec_id: '2',
spec_name: '大小',
value: [
spec_values: [
{ spec_value_id: '1', spec_value: 'L' },
{ spec_value_id: '2', spec_value: 'M' }
]
......@@ -64,18 +65,15 @@ export default {
},
// 添加规格
addSku() {
this.skuList.push({ key: '', value: [] })
this.skuList.push({ key: '', spec_values: [] })
},
// 删除规格
groupRemove(index) {
this.skuList.splice(index, 1)
},
groupChange(index, arg) {
this.skuList.splice(index, 1, arg[0])
}
},
beforeMount() {
// this.getSkuNameList()
this.getSkuNameList()
}
}
</script>
......
......@@ -20,7 +20,7 @@
</div>
</div>
<!-- 规格值 -->
<div class="sku-item-row" v-for="(data, index) in skuItem.value" :key="index">
<div class="sku-item-row" v-for="(data, index) in skuItem.spec_values" :key="index">
<div class="sku-item-row-left">
<el-select
v-model="data.spec_value_id"
......@@ -41,7 +41,7 @@
<div class="sku-item-row-right">
<div class="tools">
<i class="el-icon-circle-plus-outline" @click="addSkuValue(index)"></i>
<i class="el-icon-delete" @click="removeSkuValue(index)" v-if="skuItem.value.length > 1"></i>
<i class="el-icon-delete" @click="removeSkuValue(index)" v-if="skuItem.spec_values.length > 1"></i>
</div>
</div>
</div>
......@@ -49,8 +49,8 @@
</template>
<script>
import { getSkuValueList } from '@/api/goods'
export default {
name: 'skuGroup',
props: {
index: { type: Number, default: 0 }, // 索引
skuList: { type: Array, default: () => [] }, // 规格列表
......@@ -74,12 +74,12 @@ export default {
// 规格值列表
skuValueList() {
const found = this.skuNameList.find(item => item.spec_id === this.skuItem.spec_id)
return found ? found.value || [] : []
return found ? found.spec_values || [] : []
},
// 规格值数据处理后的列表
currentSkuValueList() {
return this.skuValueList.map(item => {
item.selected = !!this.skuItem.value.find(data => data.spec_value_id === item.spec_value_id)
item.selected = !!this.skuItem.spec_values.find(data => data.spec_value_id === item.spec_value_id)
return item
})
}
......@@ -90,26 +90,23 @@ export default {
const found = this.skuNameList.find(item => item.spec_id === id)
// const value = { spec_id: id, spec_name: found.spec_name, value: [] }
this.skuItem.spec_name = found.spec_name
this.skuItem.value = [{}]
this.skuItem.spec_values = [{}]
},
// 规格值改变
skuValueChange(id, index) {
const found = this.skuValueList.find(item => item.spec_value_id === id)
this.skuItem.value[index].spec_value = found.spec_value
this.skuItem.spec_values[index].spec_value = found.spec_value
},
removeSku(index) {
this.skuList.splice(index, 1)
},
// 添加
addSkuValue(index) {
this.skuItem.value.splice(index + 1, 0, {})
this.skuItem.spec_values.splice(index + 1, 0, {})
},
// 删除
removeSkuValue(index) {
this.skuItem.value.splice(index, 1)
},
getSkuValueList(item) {
getSkuValueList({ shop_id: this.shopId, spec_id: item.spec_id }).then(res => {})
this.skuItem.spec_values.splice(index, 1)
}
}
}
......
......@@ -41,7 +41,8 @@
<div class="batch-buttons" v-if="!showBatchInput">
<el-button type="text" @click="batchUpdate('price')">价格</el-button>
<el-button type="text" @click="batchUpdate('stock')">库存</el-button>
<el-button type="text" @click="batchUpdate('mark_price')">成本价</el-button>
<el-button type="text" @click="batchUpdate('mark_price')">划线价</el-button>
<el-button type="text" @click="batchUpdate('prime_price')">成本价</el-button>
</div>
<div class="batch-input" v-else>
<el-input type="number" size="small" v-model="batchInputValue" ref="batchInput"></el-input>
......@@ -53,8 +54,8 @@
</template>
<script>
import DateTimePicker from './dateTimePicker'
export default {
name: 'skuView',
props: {
sku: {
type: Array,
......@@ -69,13 +70,13 @@ export default {
}
}
},
components: { DateTimePicker },
data() {
return {
header: [
{ formType: 'input', key: 'price', value: '价格(元)' },
{ formType: 'input', key: 'mark_price', value: '划线价(元)' },
{ formType: 'input', key: 'stock', value: '库存' },
{ formType: 'input', key: 'mark_price', value: '成本价' }
{ formType: 'input', key: 'prime_price', value: '成本价' }
],
showBatchInput: false,
batchKey: '', // 当前批量修改的字段
......@@ -92,27 +93,34 @@ export default {
skuValueList: {
handler: function (newValue) {
newValue.forEach((item, index) => {
console.log(item)
// 规格
const values = item.reduce(
(result, item) => {
result.ids.push(item.spec_value_id)
result.names.push(item.spec_value)
result.ids.push(item.spec_id)
result.names.push(item.spec_name)
result.valueIds.push(item.spec_value_id)
result.valueNames.push(item.spec_value)
return result
},
{ ids: [], names: [] }
{ ids: [], names: [], valueIds: [], valueNames: [] }
)
const valueIdsText = values.ids.join(',')
const valueNamesText = values.names.join(',')
const valueIdsText = values.valueIds.join(',')
// 设置默认数据
const defaultStock = Object.assign(
{ spec_id: valueIdsText, spec_name: valueNamesText },
{
spec_id: valueIdsText,
spec_name: values.names.join(','),
spec_value_id: values.valueIds.join(','),
spec_value: values.valueNames.join(',')
},
this.defaultStockParams
)
// 查找原始数据
const foundStock = this.stockList.find(item => item.spec_id === valueIdsText)
const foundStock = this.stockList.find(item => item.spec_value_id === valueIdsText)
const stock = this.stockList[index]
// 重新排列数据
if (!stock || (stock && stock.spec_id) !== valueIdsText) {
if (!stock || (stock && stock.spec_value_id) !== valueIdsText) {
this.stockList.splice(index, 0, foundStock || defaultStock)
}
})
......@@ -131,7 +139,7 @@ export default {
skuList() {
const skuList = []
this.sku.forEach(item => {
item.value && item.value.length && skuList.push(item)
item.spec_values && item.spec_values.length && skuList.push(item)
})
return skuList
},
......@@ -139,16 +147,17 @@ export default {
// tr总列数
let trLength = 1
this.skuList.map(item => {
trLength *= item.value.length
trLength *= item.spec_values.length
})
let rowspanDivide = 1
const list = this.skuList.map(item => {
rowspanDivide *= item.value.length
return item.value.map(value => {
return Object.assign({ rowspan: trLength / rowspanDivide }, value)
rowspanDivide *= item.spec_values.length
return item.spec_values.map(value => {
return Object.assign({ rowspan: trLength / rowspanDivide }, item, value)
})
})
console.log(list)
// 笛卡尔积
return list.length ? this.cartesianProduct(list) : list
},
......
<template>
<div class="app-breadcrumb">
<el-breadcrumb>
<el-breadcrumb-item v-for="route in routes" :key="route.path">
<router-link :to="route.path">{{ route.meta.title }}</router-link>
</el-breadcrumb-item>
</el-breadcrumb>
</div>
</template>
<script>
export default {
name: 'Breadcrumb',
computed: {
routes() {
return this.$route.matched.filter(route => route.meta.title)
}
}
}
</script>
<style lang="scss">
.app-breadcrumb {
padding: 40px 0 32px;
.el-breadcrumb {
font-size: 24px;
font-weight: 400;
line-height: 1;
}
.el-breadcrumb__inner a {
font-weight: normal;
color: #5b91fd;
}
.router-link-active {
color: #1a1b1c;
}
}
</style>
......@@ -20,6 +20,7 @@
<script>
export default {
name: 'AppHeader',
computed: {
user() {
return this.$store.state.user
......
<template>
<div class="app-wrapper">
<div class="app-layout">
<app-sidebar></app-sidebar>
<app-header></app-header>
<app-main></app-main>
<app-main v-bind="$attrs"></app-main>
</div>
</template>
......@@ -12,6 +12,7 @@ import AppHeader from './header'
import AppMain from './main'
export default {
name: 'AppLayout',
components: { AppSidebar, AppHeader, AppMain },
beforeMount() {
// 获取店铺信息
......@@ -20,7 +21,7 @@ export default {
}
</script>
<style>
.app-wrapper {
.app-layout {
min-height: 100vh;
background-color: #ededed;
}
......
<template>
<section class="app-main">
<router-view></router-view>
<div class="app-main-header">
<app-breadcrumb v-if="hasBreadcrumb"></app-breadcrumb>
</div>
<div class="app-main-container">
<router-view></router-view>
</div>
</section>
</template>
<script>
import AppBreadcrumb from './breadcrumb'
export default {
name: 'AppMain',
props: { hasBreadcrumb: { type: Boolean, default: true } },
components: { AppBreadcrumb },
watch: {
$route: {
immediate: true,
handler() {
// 没有shopId
if (!this.$store.state.shopId) {
this.$router.push({ path: '/shop' })
}
},
immediate: true
}
}
}
}
......@@ -24,5 +33,11 @@ export default {
.app-main {
position: relative;
margin-left: 200px;
padding: 0 24px;
}
.app-main-container::after {
content: '';
display: table;
clear: both;
}
</style>
......@@ -23,6 +23,7 @@
<script>
export default {
name: 'AppSidebar',
data() {
return {
menuList: [
......
<template>
<page-container v-loading="loading" element-loading-text="拼命加载中">
<div class="main-form" style="max-width: none">
<el-form :model="ruleForm" :rules="rules" label-width="120px" ref="ruleForm" @submit.native.prevent>
<div class="module-item">
<div class="module-item-title">商品类型</div>
<div class="module-item-content">
<el-radio-group v-model="ruleForm.category_id">
<el-radio :label="item.id" border v-for="item in goodsType" :key="item.id">{{ item.name }}</el-radio>
</el-radio-group>
</div>
</div>
<div class="module-item">
<div class="module-item-title">基本信息</div>
<div class="module-item-content">
<el-form-item label="商品名" prop="name">
<el-input placeholder="请输入店铺、品牌、机构的全称" v-model="ruleForm.name"></el-input>
</el-form-item>
<el-form-item label="分享描述" prop="describe">
<el-input v-model="ruleForm.describe"></el-input>
<p class="form-tips">微信分享给好友时会显示,建议36个字以内</p>
</el-form-item>
<el-form-item label="商品卖点" prop="charact">
<el-input v-model="ruleForm.charact"></el-input>
<p class="form-tips">在商品详情页标题下面展示卖点信息,建议60字以内</p>
</el-form-item>
<el-form-item label="商品图" prop="chart_oss">
<app-upload v-model="ruleForm.chart_oss"></app-upload>
<p class="form-tips">建议尺寸:800*800像素,你可以拖拽图片调整顺序,最多上传15张</p>
</el-form-item>
<el-form-item label="主图视频" prop="main_chart_oss">
<app-upload v-model="ruleForm.main_chart_oss"></app-upload>
<p class="form-tips">
添加主图视频可提升成交转化,有利于获取更多新流量;建议视频突出商品核心卖点,时长 9-30 秒,宽高比 16:9
</p>
</el-form-item>
<el-form-item label="商品分组" prop="group_id">
<el-select v-model="ruleForm.group_id" placeholder="选择商品分组">
<el-option
v-for="item in groupList"
:label="item.group_name"
:value="item.group_id"
:key="item.group_id"
/>
</el-select>
</el-form-item>
</div>
</div>
<div class="module-item">
<div class="module-item-title">价格库存</div>
<div class="module-item-content">
<el-form-item label="商品规格" prop="skuKeyValueList">
<sku v-model="ruleForm.skuKeyValueList"></sku>
</el-form-item>
<el-form-item
label="规格明细"
prop="goodStockList"
v-show="ruleForm.skuKeyValueList && ruleForm.skuKeyValueList.length"
>
<sku-view :sku="ruleForm.skuKeyValueList" v-model="ruleForm.goodStockList"></sku-view>
</el-form-item>
<el-form-item label="价格" prop="sellPrice">
<div v-loading="loading" element-loading-text="拼命加载中">
<el-form :model="ruleForm" :rules="rules" label-width="120px" ref="ruleForm" @submit.native.prevent>
<app-card title="商品类型">
<el-radio-group v-model="ruleForm.category_id">
<el-radio :label="item.id" border v-for="item in goodsType" :key="item.id">{{ item.name }}</el-radio>
</el-radio-group>
</app-card>
<app-card title="基本信息">
<el-form-item label="商品名" prop="spu_name">
<el-input placeholder="请输入店铺、品牌、机构的全称" v-model="ruleForm.spu_name"></el-input>
</el-form-item>
<el-form-item label="分享描述" prop="describe">
<el-input v-model="ruleForm.describe"></el-input>
<p class="form-tips">微信分享给好友时会显示,建议36个字以内</p>
</el-form-item>
<el-form-item label="商品卖点" prop="charact">
<el-input v-model="ruleForm.charact"></el-input>
<p class="form-tips">在商品详情页标题下面展示卖点信息,建议60字以内</p>
</el-form-item>
<el-form-item label="商品图" prop="chart_oss">
<app-upload v-model="ruleForm.chart_oss"></app-upload>
<p class="form-tips">建议尺寸:800*800像素,你可以拖拽图片调整顺序,最多上传15张</p>
</el-form-item>
<el-form-item label="主图视频" prop="main_chart_oss">
<app-upload v-model="ruleForm.main_chart_oss"></app-upload>
<p class="form-tips">
添加主图视频可提升成交转化,有利于获取更多新流量;建议视频突出商品核心卖点,时长 9-30 秒,宽高比 16:9
</p>
</el-form-item>
<el-form-item label="商品分组" prop="group_id">
<el-select v-model="ruleForm.group_id" placeholder="选择商品分组">
<el-option v-for="item in groupList" :label="item.group_name" :value="item.group_id" :key="item.group_id" />
</el-select>
</el-form-item>
</app-card>
<app-card title="价格库存">
<el-form-item label="商品规格" prop="skuKeyValueList">
<sku v-model="ruleForm.skuKeyValueList"></sku>
</el-form-item>
<el-form-item
label="规格明细"
prop="goodStockList"
v-show="ruleForm.skuKeyValueList && ruleForm.skuKeyValueList.length"
>
<sku-view :sku="ruleForm.skuKeyValueList" v-model="ruleForm.goodStockList"></sku-view>
</el-form-item>
<!-- <el-form-item label="价格" prop="sellPrice">
<el-input v-model="ruleForm.sellPrice" :disabled="disabledInput">
<template slot="prepend">¥</template>
</el-input>
......@@ -74,67 +60,58 @@
<el-input v-model="ruleForm.code">
<template slot="prepend">¥</template>
</el-input>
</el-form-item>
</div>
</div>
<div class="module-item">
<div class="module-item-title">其他信息</div>
<div class="module-item-content">
<el-form-item label="开售方式" prop="sales_type">
<el-radio-group v-model="ruleForm.sales_type">
<el-radio label="1">立即开售</el-radio>
<div>
<el-radio label="2">定时开售</el-radio>
<el-input v-model="ruleForm.sales_time" v-if="ruleForm.sales_type === '2'" />
</div>
<el-radio label="3">放入仓库</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="立即购买按钮" prop="buy_button_text">
<el-radio-group v-model="ruleForm.buy_button_text">
<el-radio label="1">默认名称</el-radio>
<el-radio label="2">自定义名称</el-radio>
<el-input v-model="ruleForm.buy_button_text" />
</el-radio-group>
</el-form-item>
<el-form-item label="售后服务" prop="endTime">
<el-radio-group v-model="ruleForm.after_sales_mode">
<el-radio label="1" disabled>支持买家申请退款</el-radio>
<el-radio label="2">不支持买家申请退款</el-radio>
</el-radio-group>
</el-form-item>
</div>
</div>
</el-form>
</div>
<template slot="footer">
</el-form-item> -->
</app-card>
<app-card title="其他信息">
<el-form-item label="开售方式" prop="sales_type">
<el-radio-group v-model="ruleForm.sales_type">
<el-radio label="1">立即开售</el-radio>
<div>
<el-radio label="2">定时开售</el-radio>
<el-input v-model="ruleForm.sales_time" v-if="ruleForm.sales_type === '2'" />
</div>
<el-radio label="3">放入仓库</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="立即购买按钮" prop="buy_button_text">
<el-radio-group v-model="ruleForm.buy_button_text">
<el-radio label="1">默认名称</el-radio>
<el-radio label="2">自定义名称</el-radio>
<el-input v-model="ruleForm.buy_button_text" />
</el-radio-group>
</el-form-item>
<el-form-item label="售后服务" prop="after_sales_mode">
<el-radio-group v-model="ruleForm.after_sales_mode">
<el-radio label="1" disabled>支持买家申请退款</el-radio>
<el-radio label="2">不支持买家申请退款</el-radio>
</el-radio-group>
</el-form-item>
</app-card>
<div class="form-action">
<div class="inner">
<el-button size="small" type="primary" @click="onSubmit">保存并查看</el-button>
<el-button size="small" @click="onCancel">下一步</el-button>
</div>
</div>
</template>
</page-container>
</el-form>
</div>
</template>
<script>
// 组件
import PageContainer from '@/components/common/pageContainer'
import AppUpload from '@/components/Upload'
import sku from '@/components/common/sku'
import skuView from '@/components/common/skuView'
// import Editor from '@/components/common/editor'
import AppCard from '@/components/base/card'
import AppUpload from '@/components/base/upload'
import sku from '@/components/goods/sku'
import skuView from '@/components/goods/skuView'
// 接口
import { addGoods, updateGoods, getGoodsList } from '@/api/goods'
export default {
components: {
PageContainer,
AppCard,
AppUpload,
sku,
skuView
// Editor
},
data() {
return {
......@@ -146,46 +123,85 @@ export default {
goodsGroupValue: [], // 商品分组value
disabledInput: false,
ruleForm: {
category_id: '1', // 商品类型
spu_name: '', // 商品名
describe: '', // 分享描述
charact: '', // 商品亮点
chart_oss: '', // 商品图
main_chart_oss: '', // 商品主图
group_id: '', // 商品分组
balanceCount: '', // 库存
category_id: '1',
spu_name: '标题',
describe: '分享描述',
charact: '商品卖点',
chart_oss: 'https://webapp-pub.ezijing.com/upload/shop-admin/aafa464602ae315e56534e81b687522b.jpg',
main_chart_oss: 'https://webapp-pub.ezijing.com/upload/shop-admin/95500a48092218bb7805eb31701ce209.jpg',
group_id: '6800703015822032896',
startTime: null,
sales_type: '1',
buy_button_text: '1',
goodStockList: [], // 规格明细
originPrice: '', // 原价
sellPrice: '', // 现价
spu_context: '',
skuKeyValueList: [
{
spec_id: '1',
spec_name: '颜色',
value: [{ spec_value_id: '1', spec_value: '红' }]
},
{
spec_id: '2',
spec_name: '大小',
value: [
{ spec_value_id: '1', spec_value: 'L' },
{ spec_value_id: '2', spec_value: 'M' }
]
}
], // 商品规格
startTime: null // 售卖开始时间
// {
// spec_id: '1',
// spec_name: '颜色',
// value: [{ spec_value_id: '1', spec_value: '红' }]
// },
// {
// spec_id: '2',
// spec_name: '大小',
// value: [
// { spec_value_id: '1', spec_value: 'L' },
// { spec_value_id: '2', spec_value: 'M' }
// ]
// }
],
stock_sub_method: '2',
after_sales_mode: '2',
app_button_text: '',
sales_time: '',
buy_limit: '1'
},
// ruleForm: {
// category_id: '1', // 商品类型
// spu_name: '', // 商品名
// describe: '', // 分享描述
// charact: '', // 商品亮点
// chart_oss: '', // 商品图
// main_chart_oss: '', // 商品主图
// group_id: '', // 商品分组
// balanceCount: '', // 库存
// goodStockList: [], // 规格明细
// originPrice: '', // 原价
// sellPrice: '', // 现价
// skuKeyValueList: [
// {
// spec_id: '1',
// spec_name: '颜色',
// value: [{ spec_value_id: '1', spec_value: '红' }]
// },
// {
// spec_id: '2',
// spec_name: '大小',
// value: [
// { spec_value_id: '1', spec_value: 'L' },
// { spec_value_id: '2', spec_value: 'M' }
// ]
// }
// ], // 商品规格
// spu_context: '',
// after_sales_mode:'2',
// startTime: null // 售卖开始时间
// },
rules: {
spu_name: [{ required: true, message: '商品名称不可为空', trigger: 'blur' }],
goodPhotoList: [{ required: true, message: '最少需要添加一张商品图', trigger: 'blur' }],
sellPrice: [{ required: true, message: '请输入价格', trigger: 'blur' }],
balanceCount: [{ required: true, message: '请输入库存', trigger: 'blur' }],
freight: [{ required: true, message: '请输入运费', trigger: 'blur' }],
startTime: [{ required: true, message: '请选择售卖开始时间', trigger: 'blur' }],
endTime: [{ required: true, message: '请选择售卖结束时间', trigger: 'blur' }]
spu_name: [{ required: true, message: '商品名称不可为空', trigger: 'blur' }]
// goodPhotoList: [{ required: true, message: '最少需要添加一张商品图', trigger: 'blur' }],
// sellPrice: [{ required: true, message: '请输入价格', trigger: 'blur' }],
// balanceCount: [{ required: true, message: '请输入库存', trigger: 'blur' }],
// startTime: [{ required: true, message: '请选择售卖开始时间', trigger: 'blur' }],
// endTime: [{ required: true, message: '请选择售卖结束时间', trigger: 'blur' }]
}
}
},
computed: {
shopId() {
return this.$store.state.shopId
},
groupList() {
return this.$store.state.groups
}
......@@ -270,9 +286,6 @@ export default {
// 确定
onSubmit() {
let isPass = true
const [firstImage = {}] = this.ruleForm.goodPhotoList
const { imageUrl = '', imageWidth = null, imageHeight = null } = firstImage
Object.assign(this.ruleForm, { imageUrl, imageWidth, imageHeight })
// 基本信息表单校验
this.$refs.ruleForm.validate(valid => {
if (!valid) {
......@@ -282,27 +295,31 @@ export default {
})
// 规格明细校验
if (
isPass &&
this.ruleForm.skuKeyValueList &&
this.ruleForm.skuKeyValueList.length &&
this.ruleForm.goodStockList &&
this.ruleForm.goodStockList.length
) {
this.$lodash.forEach(this.ruleForm.goodStockList, item => {
if (isNaN(parseFloat(item.sellPrice)) || isNaN(parseFloat(item.balanceCount))) {
this.$message({ message: '请完善规格明细表单', type: 'error' })
isPass = false
return false
}
})
if (!isPass) {
return false
}
}
// if (
// isPass &&
// this.ruleForm.skuKeyValueList &&
// this.ruleForm.skuKeyValueList.length &&
// this.ruleForm.goodStockList &&
// this.ruleForm.goodStockList.length
// ) {
// this.$lodash.forEach(this.ruleForm.goodStockList, item => {
// if (isNaN(parseFloat(item.sellPrice)) || isNaN(parseFloat(item.balanceCount))) {
// this.$message({ message: '请完善规格明细表单', type: 'error' })
// isPass = false
// return false
// }
// })
// if (!isPass) {
// return false
// }
// }
const params = Object.assign({ shop_id: this.shopId }, this.ruleForm)
params.spec = JSON.stringify(params.goodStockList)
console.log(params)
// delete params.goodStockList
// delete params.skuKeyValueList
if (isPass) {
this.isEdit ? this.onEdit() : this.onAdd()
this.isEdit ? this.onEdit(params) : this.onAdd(params)
} else {
this.$message({ message: '请完善表单信息', type: 'error' })
}
......@@ -326,23 +343,17 @@ export default {
}
},
// 确定添加商品
onAdd() {
addGoods(this.ruleForm).then(response => {
this.$message({
message: '保存商品成功',
type: 'success'
})
onAdd(params) {
addGoods(params).then(response => {
this.$message({ message: '保存商品成功', type: 'success' })
// 成功回调
this.onSuccess(response.data)
})
},
// 确定修改商品
onEdit() {
updateGoods(this.ruleForm).then(response => {
this.$message({
message: '保存商品成功',
type: 'success'
})
onEdit(params) {
updateGoods(params).then(response => {
this.$message({ message: '保存商品成功', type: 'success' })
// 成功回调
this.onSuccess(response.data)
})
......
<template>
<page-container>
<app-card>
<!--列表-->
<table-list v-bind="tableOptions" ref="list">
<el-tabs v-model="activeName" type="card" @tab-click="handleClick">
......@@ -16,18 +16,18 @@
<el-button type="text" @click="handleCopy(row)">复制</el-button>
</template>
</table-list>
</page-container>
</app-card>
</template>
<script>
// 组件
import TableList from '@/components/TableList'
import PageContainer from '@/components/common/pageContainer'
import TableList from '@/components/base/tableList'
import AppCard from '@/components/base/card'
// 接口
import { getGoodsList } from '@/api/goods'
export default {
components: { PageContainer, TableList },
components: { AppCard, TableList },
data() {
return {
activeName: '1',
......@@ -51,7 +51,7 @@ export default {
return {
remote: {
httpRequest: getGoodsList,
params: { shop_id: this.shopId, spu_name: '贵州空气', group_id: '' }
params: { shop_id: this.shopId, spu_id: '', spu_name: '', group_id: '' }
},
filters: [
{
......
<template>
<page-container v-loading="loading" element-loading-text="拼命加载中">
<!-- 基本信息 -->
<info-list :options="options" :data="detail"></info-list>
</page-container>
</template>
<script>
// 组件
import PageContainer from '@/components/common/pageContainer'
import InfoList from '@/components/common/infoList'
// 接口
import { viewGoodsGroup } from '@/api/goods'
export default {
components: { PageContainer, InfoList },
data() {
return {
pid: '', // ID
loading: true, // 加载中
options: [{ label: '分组名称', code: 'name' }],
detail: {} // 详情页数据
}
},
created() {
this.init()
},
methods: {
// 初始化
init() {
this.pid = this.$route.params.id
this.getDetail()
},
// 获取详情数据
getDetail() {
viewGoodsGroup({ id: this.pid }).then(response => {
this.detail = response.data
this.loading = false
})
}
}
}
</script>
<template>
<page-container>
<app-card>
<table-list v-bind="tableOptions" :hasPagination="false" ref="list">
<template #header-aside>
<el-button type="primary" @click="handleAdd">新建商品分组</el-button>
......@@ -21,19 +21,19 @@
v-if="dialogVisible"
/>
</el-dialog>
</page-container>
</app-card>
</template>
<script>
// 组件
import PageContainer from '@/components/common/pageContainer'
import TableList from '@/components/TableList'
import AppCard from '@/components/base/card'
import TableList from '@/components/base/tableList'
import GroupEdit from './edit'
// 接口
import { getGroupList, deleteGroup } from '@/api/goods'
export default {
components: { PageContainer, TableList, GroupEdit },
components: { AppCard, TableList, GroupEdit },
data() {
return {
dialogVisible: false,
......
<template>
<page-container v-loading="loading" element-loading-text="拼命加载中">
<app-card v-loading="loading" element-loading-text="拼命加载中">
<el-container>
<el-aside width="300px">
<div style="text-align: left; margin-left: 20px">
......@@ -99,15 +99,15 @@
订单共{{ tableData.length }}件商品,总计: <a style="color: red">¥{{ dataDetail.goodAmount }}</a
>(含运费 ¥0.00)
</div>
</page-container>
</app-card>
</template>
<script>
import PageContainer from '@/components/common/pageContainer'
import AppCard from '@/components/base/card'
import { getOrderDetail, closeOrder, refundOrder, Shipment } from '@/api/order'
import * as utils from '@/utils/index'
export default {
components: { PageContainer },
components: { AppCard },
data() {
return {
loading: false,
......
<template>
<page-container>
<app-card>
<!--列表-->
<table-list v-bind="tableOptions" ref="list">
<el-tabs v-model="activeName" type="card" @tab-click="handleClick">
......@@ -16,18 +16,18 @@
<el-button type="text" @click="handleCopy(row)">复制</el-button>
</template>
</table-list>
</page-container>
</app-card>
</template>
<script>
// 组件
import TableList from '@/components/TableList'
import PageContainer from '@/components/common/pageContainer'
import TableList from '@/components/base/tableList'
import AppCard from '@/components/base/card'
// 接口
import { getGoodsList } from '@/api/goods'
export default {
components: { PageContainer, TableList },
components: { AppCard, TableList },
data() {
return {
activeName: '1',
......
<template>
<div>
<div class="order-list-header" id="searchBar">
<div class="inner" :class="{fixed: isFixed}">
<div class="item goods-cell">商品</div>
<div class="item price-cell">单价/数量</div>
<div class="item aftermarket-cell">售后</div>
<div class="item customer-cell">买家</div>
<div class="item time-cell">下单时间</div>
<div class="item state-cell">订单状态</div>
<div class="item check-cell">核销状态</div>
<div class="item pay-price-cell">实付金额</div>
</div>
</div>
<div v-for="(item,index) in dataList" :key="index" class="order-list-item">
<div class="order-list-item-header">
<div class="order-list-item-header-row">
<div class="order-no">订单号:{{item.id}}</div>
<div class="order-tools">
<el-button @click="ClickDetail(item)" type="text" size="small">查看详情</el-button>
<el-button v-if="item.tradeState===3" @click="Clickshipment(item)" type="text" size="small">发货</el-button>
<el-button v-if="item.payState===60&&item.goodAmount>0" @click="Clickrefund(item)" type="text" size="small">退款</el-button>
<el-button v-if="item.payState===1||item.payState===110" @click="Clickclose(item)" type="text" size="small">关闭订单</el-button>
</div>
</div>
</div>
<table class="order-list-item-table">
<tbody class="order-list-item-body">
<tr class="trlis">
<td class="goods-item-cell-td">
<div class="goods-item-cell">
<div class="pic"><img :src="item.tradeItemList[0].itemImageUrl" /></div>
<div class="content">
<h3>
<router-link :to="`/goods/edit/${item.tradeItemList[0].itemId}`" target="_blank">{{item.tradeItemList[0].itemName}}</router-link>
</h3>
</div>
<div class="tools">
<p>{{item.tradeItemList[0].itemPrice}}</p>
<p>({{item.tradeItemList[0].itemCount}}件)</p>
</div>
</div>
</td>
<td class="aftermarket-cell" :rowspan="item.tradeItemList.length">
<div class="order-td-cell">{{item.shouhou}}</div>
</td>
<td class="customer-cell" :rowspan="item.tradeItemList.length">
<div class="order-td-cell">{{item.buyer.id}}<br />{{item.buyer.nickName}}<br />{{item.buyer.phone}}</div>
</td>
<td class="time-cell" :rowspan="item.tradeItemList.length">
<div class="order-td-cell">{{item.createTime | formatDateTime}}</div>
</td>
<td class="state-cell" :rowspan="item.tradeItemList.length">
<div class="order-td-cell">{{updateTradeState(item.tradeState)}}</div>
</td>
<td class="check-cell" :rowspan="item.tradeItemList.length">
<div class="order-td-cell">{{(item.tradeTicket && item.tradeTicket.ticketState || '') | formatTicketState}}</div>
</td>
<td class="pay-price-cell" :rowspan="item.tradeItemList.length">
<div class="order-td-cell">{{item.goodAmount}}</div>
</td>
</tr>
<tr v-for="(goods, index) in item.tradeItemList" :key="goods.id" v-if="index !== 0">
<td class="goods-item-cell-td">
<div class="goods-item-cell">
<div class="pic"><img :src="goods.itemImageUrl" /></div>
<div class="content">
<h3>
<router-link :to="`/goods/edit/${goods.itemId}`" target="_blank">{{goods.itemName}}</router-link>
</h3>
</div>
<div class="tools">
<p>{{goods.itemPrice}}</p>
<p>({{goods.itemCount}}件)</p>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div class="main-page" v-if="pageTotal">
<el-pagination @size-change="handleSizeChange " @current-change="handleCurrentChange " :current-page="currentPage " :page-sizes="[10] " :page-size='pagesize' layout="total, sizes, prev, pager, next, jumper " :total='pageTotal'>
</el-pagination>
</div>
<!-- 发货 modal -->
<el-dialog title="发货" :visible.sync="dialogFormVisible">
<el-form :model="form">
<el-form-item label="订单编号" :label-width="formLabelWidth">
<el-input v-model="form.id" auto-complete="off" :disabled="true"></el-input>
</el-form-item>
<el-form-item label="快递公司" :label-width="formLabelWidth">
<el-select v-model="form.logisticsCompanyName">
<el-option v-for="(company, index) in expressList" :key="`express_${index}`" :label="company.name" :value="company.name"></el-option>
</el-select>
</el-form-item>
<el-form-item label="快递单号" :label-width="formLabelWidth">
<el-input v-model="form.logisticsNo" auto-complete="off"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="Btnshipment">确 定</el-button>
</div>
</el-dialog>
</div>
</template>
<script type="text/ecmascript-6">
import { getOrderList, closeOrder, refundOrder, Shipment } from '@/api/order'
import * as utils from '@/utils/index'
import { Loading } from 'element-ui'
export default {
components: {},
data() {
return {
dataList: [],
dataList0: [],
currentPage: 1,
pagesize: 10,
pageTotal: 0,
param: {
id: null,
tradeState: null,
startTime: null,
endTime: null,
goodName: null,
logisticsNo: null,
tradeAddressName: null,
tradeAddressPhone: null,
logisticsCompanyName: null,
page: {
index: 1,
size: 10
}
},
dialogFormVisible: false,
form: {
id: null,
logisticsCompanyName: null,
logisticsNo: null
},
formLabelWidth: '120px',
expressList: [
{ name: '圆通快递' },
{ name: '中通快递' },
{ name: '顺丰快递' },
{ name: '韵达快递' },
{ name: '申通快递' },
{ name: '天天快递' },
{ name: '百世快递' },
{ name: '邮政' },
{ name: '德邦物流' }
],
isFixed: false,
loadingInstance: null
}
},
filters: {
// 日期
formatDateTime: utils.formatDateTime,
// 核销状态
formatTicketState(value) {
let options = { 0: '未使用', 1: '已使用' }
return options[value] || ''
}
},
methods: {
objectSpanMethod({ row, column, rowIndex, columnIndex }) {},
// 更改一页显示个数
handleSizeChange(pagesize) {
this.pagesize = pagesize
this.freshPage()
},
// 跳转页面
handleCurrentChange(currentPage) {
this.currentPage = currentPage
this.dataList = []
this.param.page.index = currentPage
this.getListData()
},
// 获取列表数据
getListData() {
this.btnloading()
getOrderList(this.param).then(response => {
this.currentPage = this.param.page.index
this.dataList = response.data.list
this.pageTotal = parseInt(response.data.totalCount + '') || 0
this.closeloading()
})
},
// 转换订单状态
updateTradeState(val) {
switch (val) {
case 0:
return '待付款'
case 3:
return '待发货'
case 6:
return '待收货'
case 10:
return '取消'
case 20:
return '完成'
case 40:
return '已退款'
}
},
// 刷新页面
getfresh(remote) {
this.param = JSON.parse(
JSON.stringify(this.$lodash.defaults(remote, this.param))
)
if (remote.tradeState === '-1') {
this.param.tradeState = null
}
this.toRegion(remote.region, remote.ding)
this.getListData()
},
toRegion(val, val1) {
switch (val) {
case 'id':
return (this.param.id = val1)
case 'logisticsNo':
return (this.param.logisticsNo = val1)
case 'logisticsCompanyName':
return (this.param.logisticsCompanyName = val1)
case 'tradeAddressName':
return (this.param.tradeAddressName = val1)
case 'tradeAddressPhone':
return (this.param.tradeAddressPhone = val1)
}
},
// 跳转详情页
ClickDetail(val) {
this.$router.push('/order/detail/' + val.id)
},
// 关闭订单
Clickclose(data) {
this.$confirm('确定要关闭订单?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(() => {
this.closeOrder0(data.id)
})
.catch(() => {
this.$message({
type: 'info',
message: '已取消关闭'
})
})
},
// 关闭
closeOrder0(ArticleId) {
closeOrder({ id: ArticleId }).then(response => {
this.$message({
message: response.message,
type: 'success'
})
// 刷新列表
this.dataList = []
this.getListData()
})
},
// 确定退款
Clickrefund(data) {
this.$confirm('确定要退款?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(() => {
this.Clickrefund0(data.id)
})
.catch(() => {
this.$message({
type: 'info',
message: '已取消退款'
})
})
},
// 退款
Clickrefund0(ArticleId) {
refundOrder({ id: ArticleId }).then(response => {
this.$message({
message: response.message,
type: 'success'
})
// 刷新列表
this.dataList = []
this.getListData()
})
},
// 发货表单
Clickshipment(data) {
this.form = Object.assign({}, this.form, data)
this.dialogFormVisible = true
},
// 确定发货
Btnshipment() {
this.dialogFormVisible = false
Shipment(this.form).then(response => {
this.$message({
message: response.message,
type: 'success'
})
// 刷新列表
this.dataList = []
this.getListData()
})
},
handleScroll() {
// 改变元素#searchBar的top值
let scrollTop =
window.pageYOffset ||
document.documentElement.scrollTop ||
document.body.scrollTop
let offsetTop = document.querySelector('#searchBar').offsetTop
if (scrollTop >= offsetTop) {
this.isFixed = true
} else {
this.isFixed = false
}
},
btnloading() {
this.loadingInstance = Loading.service({
class: 'order-list-item-table',
body: false
})
},
closeloading() {
this.$nextTick(() => {
// 以服务的方式调用的 Loading 需要异步关闭
this.loadingInstance.close()
})
}
},
created() {
this.dataList = []
this.getListData()
},
mounted() {
// 给window添加一个滚动滚动监听事件
window.addEventListener('scroll', this.handleScroll)
},
destroyed() {
// 离开该页面需要移除这个监听的事件
window.removeEventListener('scroll', this.handleScroll)
}
}
</script>
<style>
/* 表头 */
.order-list-header {
position: relative;
height: 40px;
margin-bottom: 10px;
}
.order-list-header .inner {
display: flex;
position: sticky;
top: 0;
background-color: #f8f8f8;
align-items: center;
height: 40px;
z-index: 1;
}
.order-list-header .inner.fixed {
position: fixed;
left: 200px;
right: 40px;
}
.order-list-header .item {
text-align: center;
padding: 10px;
}
.order-list-header .goods-cell {
flex: 1;
text-align: left;
}
.order-list-header .price-cell {
width: 10%;
text-align: right;
}
.order-list-header .aftermarket-cell {
width: 10%;
}
.order-list-header .customer-cell {
width: 10%;
word-break: break-all;
}
.order-list-header .time-cell {
width: 10%;
}
.order-list-header .state-cell {
width: 15%;
}
.order-list-header .check-cell {
width: 15%;
}
.order-list-header .pay-price-cell {
width: 10%;
}
/* table */
.order-list-item {
font-size: 12px;
margin: 10px 0;
}
.order-list-item-header {
background-color: #f8f8f8;
border: 1px solid #e5e5e5;
border-bottom: none;
padding: 10px;
}
.order-list-item-header .order-list-item-header-row {
display: flex;
justify-content: space-between;
}
.order-list-item-header .order-no {
line-height: 32px;
}
.order-list-item-table {
width: 100%;
}
.order-list-item-table td {
border: 1px solid #e5e5e5;
}
.order-td-cell {
padding: 10px;
text-align: center;
}
.goods-item-cell {
display: flex;
padding: 10px;
}
.goods-item-cell .pic {
width: 60px;
height: 60px;
}
.goods-item-cell .pic img {
width: 100%;
height: 100%;
}
.goods-item-cell .content {
flex: 1;
padding: 0 10px;
}
.goods-item-cell .content h3 {
font-weight: normal;
color: #0000ff;
}
.order-list-item-body .aftermarket-cell {
width: 10%;
}
.order-list-item-body .customer-cell {
width: 10%;
word-break: break-all;
}
.order-list-item-body .time-cell {
width: 10%;
}
.order-list-item-body .state-cell {
width: 15%;
}
.order-list-item-body .check-cell {
width: 15%;
}
.order-list-item-body .pay-price-cell {
width: 10%;
}
</style>
<template>
<page-container>
<app-card>
<el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" style="width: 400px">
<el-form-item label="客户电话" prop="tel">
<el-input v-model="ruleForm.tel"></el-input>
......@@ -12,14 +12,14 @@
</el-input>
</el-form-item>
</el-form>
</page-container>
</app-card>
</template>
<script>
import PageContainer from '@/components/common/pageContainer'
import AppCard from '@/components/base/card'
export default {
components: { PageContainer },
components: { AppCard },
data() {
return {
ruleForm: { tel: '', address: '' },
......
<template>
<page-container>
<div class="module-item">
<div class="module-item-hd">
<h2 class="module-item-hd__title">商品规格</h2>
<app-card title="商品规格">
<div class="sku-item" v-for="(item, index) in skuList" :key="index">
<div class="sku-item-row">
<div class="sku-item-row-left">
<label class="label">规格{{ index + 1 }}</label>
<el-input
v-model="item.spec_name"
placeholder="规格名"
:readonly="!!item.spec_id"
@blur="onNameBlur(item)"
@keyup.enter.native="onNameBlur(item)"
/>
</div>
<div class="sku-item-row-right is-right">
<el-button type="text" @click="removeSku(item, index)">删除规格</el-button>
</div>
</div>
<div class="module-item-bd">
<div class="sku-item" v-for="(item, index) in skuList" :key="index">
<div class="sku-item-row">
<div class="sku-item-row-left">
<label class="label">规格{{ index + 1 }}</label>
<el-input v-model="item.spec_name" placeholder="规格名" />
</div>
<div class="sku-item-row-right is-right">
<el-button type="text" @click="removeSku(item, index)">删除规格</el-button>
</div>
</div>
<div class="sku-item-row">
<div class="sku-item-row-left">
<el-input placeholder="规格值" />
</div>
<div class="sku-item-row-right">
<div class="tools">
<i class="el-icon-circle-plus-outline" @click="addSkuValue(item, index)"></i>
<i class="el-icon-delete" @click="removeSkuValue(item, index)"></i>
</div>
</div>
<div class="sku-item-row" v-for="item in item.spec_values" :key="item.spec_value_id">
<div class="sku-item-row-left">
<el-input
placeholder="规格值"
v-model="item.spec_value"
:readonly="!!item.spec_value_id"
@blur="onNameBlur(item)"
/>
</div>
<div class="sku-item-row-right">
<div class="tools">
<!-- <i class="el-icon-circle-plus-outline" @click="addSkuValue(item, index)"></i> -->
<i class="el-icon-delete" @click="removeSkuValue(item, index)"></i>
</div>
</div>
<el-button type="text" @click="addSku">
<i class="el-icon-circle-plus-outline"></i>&nbsp;&nbsp;创建新规格
</el-button>
</div>
<div class="sku-item-row">
<div class="sku-item-row-left">
<el-button type="text" @click="addSkuValue(item)">
<i class="el-icon-circle-plus-outline"></i>&nbsp;&nbsp;添加规格值
</el-button>
</div>
</div>
</div>
</page-container>
<el-button type="text" @click="addSku">
<i class="el-icon-circle-plus-outline"></i>&nbsp;&nbsp;创建新规格
</el-button>
</app-card>
</template>
<script>
import PageContainer from '@/components/common/pageContainer'
import { getSkuNameList } from '@/api/goods'
import AppCard from '@/components/base/card'
import { getSkuNameList, addSku, addSkuValue } from '@/api/goods'
export default {
components: { PageContainer },
components: { AppCard },
data() {
return {
ruleForm: { shop_name: '', shop_logo: '', shop_desc: '', shop_tel: '', shop_type: '1' },
......@@ -63,6 +74,25 @@ export default {
this.skuList = res.data
})
},
onNameBlur(item) {
if (item.spec_id) {
return
}
if (!item.spec_name) {
return
}
addSku({ shop_id: this.shopId, spec_name: item.spec_name }).then(res => {
this.getSkuNameList()
})
},
onValueBlur(item) {
if (item.spec_value_id) {
return
}
addSkuValue({ shop_id: this.shopId, spec_value: item.spec_value }).then(res => {
this.getSkuNameList()
})
},
// 添加规格
addSku() {
this.skuList.push({ spec_name: '' })
......@@ -80,19 +110,8 @@ export default {
</script>
<style lang="scss" scoped>
.module-item {
max-width: 800px;
}
.module-item-hd {
display: flex;
}
.module-item-hd__title {
flex: 1;
font-size: 18px;
font-weight: 700;
margin-bottom: 16px;
}
.sku-item {
max-width: 800px;
background-color: #f9f9f9;
border-radius: 8px;
padding: 24px;
......
<template>
<page-container>
<div class="module-item">
<div class="module-item-hd">
<h2 class="module-item-hd__title">基础信息</h2>
<el-button type="text" @click="handleUpdate">编辑</el-button>
</div>
<div class="module-item-bd shop-info">
<img :src="shop.shop_logo" class="shop-logo" />
<div class="shop-info-content">
<h3 class="title">{{ shop.shop_name }}</h3>
<div class="item">
<label class="label">店铺编号:</label><span class="content">{{ shop.shop_id }}</span>
</div>
<div class="item">
<label class="label">创建时间:</label><span class="content">{{ shop.create_time }}</span>
</div>
<div class="item">
<label class="label">联系电话:</label><span class="content">{{ shop.tel }}</span>
</div>
<app-card title="基础信息">
<template #header-aside><el-button type="text" @click="handleUpdate">编辑</el-button></template>
<div class="shop-info">
<img :src="shop.shop_logo" class="shop-logo" />
<div class="shop-info-content">
<h3 class="title">{{ shop.shop_name }}</h3>
<div class="item">
<label class="label">店铺编号:</label><span class="content">{{ shop.shop_id }}</span>
</div>
<div class="item">
<label class="label">创建时间:</label><span class="content">{{ shop.create_time }}</span>
</div>
<div class="item">
<label class="label">联系电话:</label><span class="content">{{ shop.tel }}</span>
</div>
</div>
</div>
......@@ -51,15 +46,15 @@
</el-form-item>
</el-form>
</el-dialog>
</page-container>
</app-card>
</template>
<script>
import PageContainer from '@/components/common/pageContainer'
import AppUpload from '@/components/Upload'
import AppCard from '@/components/base/card'
import AppUpload from '@/components/base/upload'
export default {
components: { PageContainer, AppUpload },
components: { AppCard, AppUpload },
data() {
return {
ruleForm: { shop_name: '', shop_logo: '', shop_desc: '', shop_tel: '', shop_type: '1' },
......@@ -91,17 +86,6 @@ export default {
</script>
<style lang="scss" scoped>
.module-item {
}
.module-item-hd {
display: flex;
}
.module-item-hd__title {
flex: 1;
font-size: 18px;
font-weight: 700;
margin-bottom: 16px;
}
.shop-info {
display: flex;
}
......
......@@ -36,7 +36,7 @@
<script>
// 组件
import PageMain from '@/components/common/pageMain'
import AppUpload from '@/components/Upload'
import AppUpload from '@/components/base/upload'
// 接口
import { addShop } from '@/api/shop'
......
<template>
<page-container v-loading="loading" element-loading-text="拼命加载中">
<!-- 基本信息 -->
<info-list :options="options" :data="detailData"></info-list>
</page-container>
<page-main title="选择店铺">
<el-card class="box-card shop-card">
<template #header>
<div class="header">
<el-button type="primary" size="mini" @click="addShop">创建店铺</el-button>
</div>
</template>
<div class="shop-list" v-if="list.length">
<div class="item" v-for="item in list" :key="item.shop_id" @click="entryShop(item)">
<h2 class="title">{{ item.shop_name }}</h2>
<p>主体信息:{{ item.business_entity }}</p>
<p>有效期至:{{ item.end_time }}</p>
<span class="type">{{ typeName(item.shop_type) }}</span>
</div>
</div>
<div class="shop-tips" v-else>
<p><router-link to="/shop/add">创建</router-link>你的专属店铺</p>
</div>
</el-card>
</page-main>
</template>
<script>
// 组件
import PageContainer from '@/components/common/pageContainer'
import InfoList from '@/components/common/infoList'
import { getShopDetail } from '@/api/shop'
import PageMain from '@/components/common/pageMain'
// 接口
import { getShopList } from '@/api/shop'
export default {
components: { PageContainer, InfoList },
components: { PageMain },
data() {
return {
pid: '', // ID
loading: true, // 加载中
options: [
{ label: '编号', code: 'id' },
{ label: '店铺名称', code: 'name' }
],
detailData: {} // 详情页数据
list: []
}
},
created() {
this.pid = this.$route.params.id
this.getDetail()
computed: {
user() {
return this.$store.state.user
}
},
methods: {
// 获取详情数据
getDetail() {
this.loading = true
// 请求接口
getShopDetail({ id: this.pid }).then(response => {
this.detailData = response.data
this.loading = false
typeName(value) {
const map = { 1: '微商城' }
return map[value]
},
// 获取店铺
getShop() {
getShopList().then(res => {
this.list = res.data || []
})
},
entryShop(item) {
this.$store.dispatch('setShopId', item.shop_id)
// 进入店铺概括
this.$router.push({ path: '/dashboard' })
},
// 创建店铺
addShop() {
this.$router.push('/shop/add')
}
},
beforeMount() {
this.getShop()
}
}
</script>
<style lang="scss">
.shop-card {
border: 0;
border-radius: 0;
}
.shop-card .el-card__header {
padding: 0 40px;
background: #f8f8f8;
border-bottom: 0;
}
.shop-card .header {
height: 70px;
display: flex;
align-items: center;
justify-content: flex-end;
}
.shop-list {
overflow: hidden;
display: flex;
flex-wrap: wrap;
margin-left: -22px;
.item {
width: 300px;
height: 130px;
padding: 0 20px;
margin-left: 25px;
margin-bottom: 25px;
border-radius: 2px;
border: 1px solid #e5e5e5;
border-top: 3px solid #d5d7db;
background: #fff;
cursor: pointer;
color: #999;
box-sizing: border-box;
p {
padding-bottom: 5px;
}
}
.title {
margin-top: 18px;
line-height: 20px;
padding-bottom: 5px;
font-size: 14px;
color: #111;
font-weight: 400;
}
.type {
display: inline-block;
padding: 0 3px;
font-size: 12px;
line-height: 1.5;
color: var(--main-color);
border: 1px solid var(--main-color);
border-radius: 2px;
}
}
.shop-tips {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
</style>
<template>
<page-main title="选择店铺">
<el-card class="box-card shop-card">
<template #header>
<div class="header">
<el-button type="primary" size="mini" @click="addShop">创建店铺</el-button>
</div>
</template>
<div class="shop-list" v-if="list.length">
<div class="item" v-for="item in list" :key="item.shop_id" @click="entryShop(item)">
<h2 class="title">{{ item.shop_name }}</h2>
<p>主体信息:{{ item.business_entity }}</p>
<p>有效期至:{{ item.end_time }}</p>
<span class="type">{{ typeName(item.shop_type) }}</span>
</div>
</div>
<div class="shop-tips" v-else>
<p><router-link to="/shop/add">创建</router-link>你的专属店铺</p>
</div>
</el-card>
</page-main>
</template>
<script>
// 组件
import PageMain from '@/components/common/pageMain'
// 接口
import { getShopList } from '@/api/shop'
export default {
components: { PageMain },
data() {
return {
list: []
}
},
computed: {
user() {
return this.$store.state.user
}
},
methods: {
typeName(value) {
const map = { 1: '微商城' }
return map[value]
},
// 获取店铺
getShop() {
getShopList().then(res => {
this.list = res.data || []
})
},
entryShop(item) {
this.$store.dispatch('setShopId', item.shop_id)
// 进入店铺概括
this.$router.push({ path: '/dashboard' })
},
// 创建店铺
addShop() {
this.$router.push('/shop/add')
}
},
beforeMount() {
this.getShop()
}
}
</script>
<style lang="scss">
.shop-card {
border: 0;
border-radius: 0;
}
.shop-card .el-card__header {
padding: 0 40px;
background: #f8f8f8;
border-bottom: 0;
}
.shop-card .header {
height: 70px;
display: flex;
align-items: center;
justify-content: flex-end;
}
.shop-list {
overflow: hidden;
display: flex;
flex-wrap: wrap;
margin-left: -22px;
.item {
width: 300px;
height: 130px;
padding: 0 20px;
margin-left: 25px;
margin-bottom: 25px;
border-radius: 2px;
border: 1px solid #e5e5e5;
border-top: 3px solid #d5d7db;
background: #fff;
cursor: pointer;
color: #999;
box-sizing: border-box;
p {
padding-bottom: 5px;
}
}
.title {
margin-top: 18px;
line-height: 20px;
padding-bottom: 5px;
font-size: 14px;
color: #111;
font-weight: 400;
}
.type {
display: inline-block;
padding: 0 3px;
font-size: 12px;
line-height: 1.5;
color: var(--main-color);
border: 1px solid var(--main-color);
border-radius: 2px;
}
}
.shop-tips {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
</style>
/* layout */
import Layout from '@/components/layout/layout'
// /* 商品 */
// const GoodsEdit = () => import(/* webpackChunkName: "goods" */ '@/pages/goods/edit')
// /* 商品分组 */
// const GoodsGroup = () => import(/* webpackChunkName: "goods" */ '@/pages/goods/group/index')
// const GoodsGroupEdit = () => import(/* webpackChunkName: "goods" */ '@/pages/goods/group/edit')
// const GoodsGroupDetail = () => import(/* webpackChunkName: "goods" */ '@/pages/goods/group/detail')
// /* 订单 */
const orderList = () => import(/* webpackChunkName: "order" */ '@/pages/order/orderList')
// const orderDetail = () => import(/* webpackChunkName: "order" */ '@/pages/order/orderDetail')
export default [
{ path: '*', redirect: '/dashboard' },
{
path: '/dashboard',
component: Layout,
props: { hasBreadcrumb: false },
children: [
{
path: '',
component: () => import(/* webpackChunkName: "shop" */ '@/pages/dashboard/index'),
component: () => import(/* webpackChunkName: "dashboard" */ '@/pages/dashboard/index'),
meta: { title: '首页' }
}
]
},
// 店铺
{
path: '/shop',
component: () => import(/* webpackChunkName: "shop" */ '@/pages/shop/list'),
component: () => import(/* webpackChunkName: "shop" */ '@/pages/shop/index'),
meta: { title: '选择店铺' }
},
{
......@@ -44,47 +34,24 @@ export default [
children: [
{
path: '',
component: () => import(/* webpackChunkName: "goods" */ '@/pages/goods/index'),
component: () => import(/* webpackChunkName: "goods" */ '@/pages/goods/goods/index'),
meta: { title: '商品列表' }
},
{
path: 'add',
component: () => import(/* webpackChunkName: "goods" */ '@/pages/goods/edit'),
component: () => import(/* webpackChunkName: "goods" */ '@/pages/goods/goods/edit'),
meta: { title: '发布商品' }
},
{
path: 'edit/:id',
component: () => import(/* webpackChunkName: "goods" */ '@/pages/goods/edit'),
component: () => import(/* webpackChunkName: "goods" */ '@/pages/goods/goods/edit'),
meta: { title: '编辑商品' }
}
]
},
// 商品分组
{
path: '/goods/group',
component: Layout,
meta: { title: '商品' },
children: [
},
{
path: '',
path: 'group',
component: () => import(/* webpackChunkName: "goods-group" */ '@/pages/goods/group/index'),
meta: { title: '商品分组' }
}
// {
// path: 'add',
// component: GoodsGroupEdit,
// meta: { title: '新建商品分组' }
// },
// {
// path: 'edit/:id',
// component: GoodsGroupEdit,
// meta: { title: '编辑商品分组' }
// },
// {
// path: 'detail/:id',
// component: GoodsGroupDetail,
// meta: { title: '查看商品分组' }
// }
]
},
// 订单管理
......@@ -93,7 +60,11 @@ export default [
component: Layout,
meta: { title: '订单' },
children: [
{ path: '', component: orderList, meta: { title: '订单列表' } }
{
path: '',
component: () => import(/* webpackChunkName: "order" */ '@/pages/order/index'),
meta: { title: '订单列表' }
}
// {
// path: 'detail/:id',
// component: orderDetail,
......
......@@ -16,6 +16,13 @@ httpRequest.interceptors.request.use(
if (config.headers['Content-Type'] === 'application/x-www-form-urlencoded') {
config.data = qs.stringify(config.data)
}
if (config.headers['Content-Type'] === 'multipart/form-data') {
const formData = new window.FormData()
for (const key in config.data) {
formData.append(key, config.data[key])
}
config.data = formData
}
return config
},
function(error) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论