wangdong 6 months ago
commit 7060452f8f
  1. 11
      src/api/goods/index.js
  2. 369
      src/components/SelectImage/SelectImage.vue
  3. 53
      src/views/goods/Create.vue
  4. 1418
      src/views/goods/modules/Update.vue

@ -14,7 +14,16 @@ const api = {
exportData: '/goods/import',
setStorePrice: 'store/setStorePrice',
getStorePriceInfo: 'store/getStorePriceInfo',
pool: '/goods/pool'
pool: '/goods/pool',
collector:'/goods/collector'
}
export function getCollector (params) {
return axios({
url: api.collector,
method: 'get',
params
})
}
/**
* 更新状态

@ -1,55 +1,28 @@
<template>
<div class="image-list clearfix" :class="{ multiple }">
<!-- 文件列表 -->
<!-- draggable是拖拽组件 -->
<draggable
v-if="selectedItems.length"
v-model="selectedItems"
@start="drag=true"
@end="drag=false"
@update="onUpdate"
>
<transition-group class="draggable-item" type="transition" :name="'flip-list'">
<div
v-for="(item, index) in selectedItems"
:key="item.file_id"
class="file-item"
:style="{ width: `${width}px`, height: `${width}px` }"
>
<!-- 预览图 -->
<a :href="item.preview_url" target="_blank">
<div class="img-cover" :style="{ backgroundImage: `url('${item.preview_url}')` }"></div>
</a>
<!-- 删除文件 -->
<a-icon
class="icon-close"
theme="filled"
type="close-circle"
@click="handleDeleteFileItem(index)"
/>
</div>
</transition-group>
</draggable>
<!-- 图片选择器 -->
<!-- 如果单选, selectedItems无内容时 显示 -->
<!-- 如果多选, selectedItems数量小于 maxNum 显示 -->
<div
v-show="(!multiple && selectedItems.length <= 0) || (multiple && selectedItems.length < maxNum)"
class="selector"
:style="{ width: `${width}px`, height: `${width}px` }"
@click="handleSelectImage"
>
<a-icon class="icon-plus" :style="{ fontSize: `${width * 0.4}px` }" type="plus" />
</div>
<!-- 文件选择器 -->
<FilesModal
ref="FilesModal"
:multiple="multiple"
:maxNum="maxNum"
:selectedNum="selectedItems.length"
@handleSubmit="handleSelectImageSubmit"
/>
</div>
<div class="image-list clearfix" :class="{ multiple }">
<!-- 文件列表 -->
<!-- draggable是拖拽组件 -->
<draggable v-if="selectedItems.length" v-model="selectedItems" @start="drag=true" @end="drag=false" @update="onUpdate">
<transition-group class="draggable-item" type="transition" :name="'flip-list'">
<div v-for="(item, index) in selectedItems" :key="item.file_id>0?item.file_id:item.id" class="file-item" :style="{ width: `${width}px`, height: `${width}px` }">
<!-- 预览图 -->
<a :href="item.preview_url" target="_blank">
<div class="img-cover" :style="{ backgroundImage: `url('${item.preview_url}')` }"></div>
</a>
<!-- 删除文件 -->
<a-icon class="icon-close" theme="filled" type="close-circle" @click="handleDeleteFileItem(index)" />
</div>
</transition-group>
</draggable>
<!-- 图片选择器 -->
<!-- 如果单选, selectedItems无内容时 显示 -->
<!-- 如果多选, selectedItems数量小于 maxNum 显示 -->
<div v-show="(!multiple && selectedItems.length <= 0) || (multiple && selectedItems.length < maxNum)" class="selector" :style="{ width: `${width}px`, height: `${width}px` }" @click="handleSelectImage">
<a-icon class="icon-plus" :style="{ fontSize: `${width * 0.4}px` }" type="plus" />
</div>
<!-- 文件选择器 -->
<FilesModal ref="FilesModal" :multiple="multiple" :maxNum="maxNum" :selectedNum="selectedItems.length" @handleSubmit="handleSelectImageSubmit" />
</div>
</template>
<script>
@ -60,171 +33,181 @@ import { FilesModal } from '@/components/Modal'
//
export default {
name: 'SelectImage',
components: {
FilesModal,
draggable
},
model: {
prop: 'value',
event: 'change'
},
props: {
// , false
multiple: PropTypes.bool.def(false),
// , multiple
maxNum: PropTypes.integer.def(100),
//
defaultList: PropTypes.array.def([]),
// ()
width: PropTypes.integer.def(80)
},
data () {
return {
//
selectedItems: [],
// (selectedItemsdefaultList)
allowProps: true
}
},
watch: {
//
defaultList: {
//
immediate: true,
handler (val) {
const { selectedItems, allowProps } = this
if (val.length && !selectedItems.length && allowProps) {
this.selectedItems = cloneDeep(val)
this.onChange()
}
}
}
},
created () {
},
methods: {
name: 'SelectImage',
components: {
FilesModal,
draggable
},
model: {
prop: 'value',
event: 'change'
},
props: {
// , false
multiple: PropTypes.bool.def(false),
// , multiple
maxNum: PropTypes.integer.def(100),
//
defaultList: PropTypes.array.def([]),
// ()
width: PropTypes.integer.def(80),
source: PropTypes.any.def(0)
},
data() {
return {
//
selectedItems: [],
// (selectedItemsdefaultList)
allowProps: true
}
},
watch: {
//
defaultList: {
//
immediate: true,
handler(val) {
const { selectedItems, allowProps } = this
if (val.length && !selectedItems.length && allowProps) {
this.selectedItems = cloneDeep(val)
this.onChange()
}
}
}
},
created() {
},
methods: {
//
onUpdate () {
this.onChange()
},
//
onUpdate() {
this.onChange()
},
//
handleSelectImage () {
this.$refs.FilesModal.show()
},
//
handleSelectImage() {
this.$refs.FilesModal.show()
},
// modal
handleSelectImageSubmit (result) {
if (result.length > 0) {
//
const { multiple, selectedItems } = this
this.selectedItems = multiple ? selectedItems.concat(result) : result
this.onChange()
}
},
// modal
handleSelectImageSubmit(result) {
if (result.length > 0) {
//
const { multiple, selectedItems } = this
this.selectedItems = multiple ? selectedItems.concat(result) : result
this.onChange()
}
},
//
handleDeleteFileItem (index) {
this.selectedItems.splice(index, 1)
if (this.selectedItems.length === 0) {
this.allowProps = false
}
this.onChange()
},
//
handleDeleteFileItem(index) {
this.selectedItems.splice(index, 1)
if (this.selectedItems.length === 0) {
this.allowProps = false
}
this.onChange()
},
// change
onChange () {
const { multiple, selectedItems } = this
if (selectedItems.length <= 0) {
return this.$emit('change', multiple ? [] : 0)
}
// fileId
const fileId = multiple ? selectedItems.map(item => item.file_id) : selectedItems[0].file_id
// change
return this.$emit('change', fileId, selectedItems)
}
// change
onChange() {
const { multiple, selectedItems } = this
if (selectedItems.length <= 0) {
return this.$emit('change', multiple ? [] : 0)
}
// fileId
if (this.source == 1) {
let fileId = []
const list = multiple ? selectedItems.map(item => item) : selectedItems[0].file_id
list.forEach(function (item) {
fileId.push({ file_id: item.file_id, image: item.preview_url })
})
return this.$emit('change', fileId, selectedItems)
} else {
const fileId = multiple ? selectedItems.map(item => item.file_id) : selectedItems[0].file_id
return this.$emit('change', fileId, selectedItems)
}
}
}
}
}
</script>
<style lang="less" scoped>
/deep/.flip-list-move {
transition: transform 0.3s !important;
transition: transform 0.3s !important;
}
/deep/.no-move {
transition: transform 0s;
transition: transform 0s;
}
.image-list {
// margin
&.multiple {
.file-item,
.selector {
margin-right: 10px;
margin-bottom: 10px;
}
}
// margin
&.multiple {
.file-item,
.selector {
margin-right: 10px;
margin-bottom: 10px;
}
}
}
//
.file-item {
position: relative;
float: left;
width: 80px;
height: 80px;
position: relative;
padding: 2px;
border: 1px solid #ddd;
background: #fff;
.img-cover {
display: block;
width: 100%;
height: 100%;
background: no-repeat center center / 100%;
}
&:hover {
.icon-close {
display: block;
}
}
.icon-close {
display: none;
position: absolute;
top: -8px;
right: -8px;
cursor: pointer;
font-size: 16px;
color: #c5c5c5;
&:hover {
color: #7d7d7d;
}
}
&:hover {
border: 1px solid #a7c3de;
}
position: relative;
float: left;
width: 80px;
height: 80px;
position: relative;
padding: 2px;
border: 1px solid #ddd;
background: #fff;
.img-cover {
display: block;
width: 100%;
height: 100%;
background: no-repeat center center / 100%;
}
&:hover {
.icon-close {
display: block;
}
}
.icon-close {
display: none;
position: absolute;
top: -8px;
right: -8px;
cursor: pointer;
font-size: 16px;
color: #c5c5c5;
&:hover {
color: #7d7d7d;
}
}
&:hover {
border: 1px solid #a7c3de;
}
}
//
.selector {
width: 80px;
height: 80px;
float: left;
border: 1px dashed #e2e2e2;
text-align: center;
color: #dad9d9;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
&:hover {
border: 1px dashed #40a9ff;
color: #40a9ff;
}
.icon-plus {
font-size: 32px;
}
width: 80px;
height: 80px;
float: left;
border: 1px dashed #e2e2e2;
text-align: center;
color: #dad9d9;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
&:hover {
border: 1px dashed #40a9ff;
color: #40a9ff;
}
.icon-plus {
font-size: 32px;
}
}
</style>

@ -15,14 +15,14 @@
<a-form-item label="商品类型" :labelCol="labelCol" :wrapperCol="wrapperCol">
<GoodsType v-decorator="['goods_type', { initialValue: 10}]" @change="onForceUpdate(true)" />
</a-form-item>
<!-- <a-form-item label="商品SKU" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-form-item label="商品SKU" :labelCol="labelCol" :wrapperCol="wrapperCol">
<div style=" display: flex;align-items: center;width:100%">
<a-input style="width:242px" placeholder="输入商品SKU" v-decorator="['goods_no', { rules: [{ required: true, min: 2, message: '请输入至少2个字符' }] }]" />
<div class="action-item">
<a-button type="primary" @click="handInfo">一键获取</a-button>
</div>
</div>
</a-form-item> -->
</a-form-item>
<a-form-item label="商品名称" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input placeholder="请输入商品名称" v-decorator="['goods_name', { rules: [{ required: true, min: 2, message: '请输入至少2个字符' }] }]" />
</a-form-item>
@ -38,7 +38,7 @@
</div>
</a-form-item>
<a-form-item label="商品图片" :labelCol="labelCol" :wrapperCol="wrapperCol" extra="建议尺寸:750*750像素, 最多上传10张, 可拖拽图片调整顺序, 第1张将作为商品首图">
<SelectImage multiple :maxNum="10" v-decorator="['imagesIds', { rules: [{ required: true, message: '请至少上传1张商品图片' }] }]" />
<SelectImage ref="childComponent" :source='1' multiple :maxNum="10" v-decorator="['imagesIds', { rules: [{ required: true, message: '请至少上传1张商品图片' }] }]" />
</a-form-item>
<a-form-item label="商品来源" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-radio-group v-decorator="['goods_source', { initialValue: 'JD', rules: [{ required: true }] }]">
@ -86,9 +86,9 @@
</a-radio-group>
</a-form-item>
<a-form-item label="商品编码" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input placeholder="请输入商品编码" v-decorator="['goods_no']" />
</a-form-item>
<!-- <a-form-item label="商品编码" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input placeholder="请输入商品编码" v-decorator="['goods_no']" />
</a-form-item> -->
<a-form-item label="所属分类排行(0表示不参加排行)" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input placeholder="所属分类排行" v-decorator="['paihang']" />
@ -407,7 +407,7 @@ export default {
}
],
//
citysCount: null
citysCount: null,
}
},
//
@ -419,12 +419,43 @@ export default {
})
},
methods: {
generateRandomDigits(length) {
let result = '';
for (let i = 0; i < length; i++) {
result += Math.floor(Math.random() * 10); // 0-9
}
return result;
},
handInfo() {
let obj = {
goods_name: '测试',
goods_price: 123
const { form } = this
const goods_no = form.getFieldValue('goods_no')
if (goods_no) {
let param = {
sku: goods_no
}
this.isLoading = true
GoodsApi.getCollector(param).then((result) => {
if (result.data.goods_images.length > 0) {
result.data.goods_images.forEach(item => {
item.id = Number(this.generateRandomDigits(7))
});
}
this.$refs.childComponent.selectedItems= result.data.goods_images
let obj = {
goods_name: result.data.name,
content: result.data.content,
goods_price: result.data.proxyPrice,
}
this.form.setFieldsValue(obj)
this.isLoading = false
})
.catch(() => {
this.isLoading = false
})
.finally(() => (this.isLoading = false))
} else {
this.$message.warning('请输入商品SKU', 1.5)
}
this.form.setFieldsValue(obj)
},
//
onForceUpdate(bool = false) {

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save