一键获取

master
fanfan 8 months ago
parent 077c2e3e84
commit ddb2ab313f
  1. 11
      src/api/goods/index.js
  2. 369
      src/components/SelectImage/SelectImage.vue
  3. 42
      src/views/goods/Create.vue
  4. 1418
      src/views/goods/modules/Update.vue

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

@ -15,14 +15,14 @@
<a-form-item label="商品类型" :labelCol="labelCol" :wrapperCol="wrapperCol"> <a-form-item label="商品类型" :labelCol="labelCol" :wrapperCol="wrapperCol">
<GoodsType v-decorator="['goods_type', { initialValue: 10}]" @change="onForceUpdate(true)" /> <GoodsType v-decorator="['goods_type', { initialValue: 10}]" @change="onForceUpdate(true)" />
</a-form-item> </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%"> <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个字符' }] }]" /> <a-input style="width:242px" placeholder="输入商品SKU" v-decorator="['goods_no', { rules: [{ required: true, min: 2, message: '请输入至少2个字符' }] }]" />
<div class="action-item"> <div class="action-item">
<a-button type="primary" @click="handInfo">一键获取</a-button> <a-button type="primary" @click="handInfo">一键获取</a-button>
</div> </div>
</div> </div>
</a-form-item> --> </a-form-item>
<a-form-item label="商品名称" :labelCol="labelCol" :wrapperCol="wrapperCol"> <a-form-item label="商品名称" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input placeholder="请输入商品名称" v-decorator="['goods_name', { rules: [{ required: true, min: 2, message: '请输入至少2个字符' }] }]" /> <a-input placeholder="请输入商品名称" v-decorator="['goods_name', { rules: [{ required: true, min: 2, message: '请输入至少2个字符' }] }]" />
</a-form-item> </a-form-item>
@ -38,7 +38,7 @@
</div> </div>
</a-form-item> </a-form-item>
<a-form-item label="商品图片" :labelCol="labelCol" :wrapperCol="wrapperCol" extra="建议尺寸:750*750像素, 最多上传10张, 可拖拽图片调整顺序, 第1张将作为商品首图"> <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 :defaultList="goods_images" :source='1' multiple :maxNum="10" v-decorator="['imagesIds', { rules: [{ required: true, message: '请至少上传1张商品图片' }] }]" />
</a-form-item> </a-form-item>
<a-form-item label="商品来源" :labelCol="labelCol" :wrapperCol="wrapperCol"> <a-form-item label="商品来源" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-radio-group v-decorator="['goods_source', { initialValue: 'JD', rules: [{ required: true }] }]"> <a-radio-group v-decorator="['goods_source', { initialValue: 'JD', rules: [{ required: true }] }]">
@ -86,9 +86,9 @@
</a-radio-group> </a-radio-group>
</a-form-item> </a-form-item>
<a-form-item label="商品编码" :labelCol="labelCol" :wrapperCol="wrapperCol"> <!-- <a-form-item label="商品编码" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input placeholder="请输入商品编码" v-decorator="['goods_no']" /> <a-input placeholder="请输入商品编码" v-decorator="['goods_no']" />
</a-form-item> </a-form-item> -->
<a-form-item label="所属分类排行(0表示不参加排行)" :labelCol="labelCol" :wrapperCol="wrapperCol"> <a-form-item label="所属分类排行(0表示不参加排行)" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input placeholder="所属分类排行" v-decorator="['paihang']" /> <a-input placeholder="所属分类排行" v-decorator="['paihang']" />
@ -407,7 +407,8 @@ export default {
} }
], ],
// //
citysCount: null citysCount: null,
goods_images: []
} }
}, },
// //
@ -420,11 +421,30 @@ export default {
}, },
methods: { methods: {
handInfo() { handInfo() {
let obj = { const { form } = this
goods_name: '测试', const goods_no = form.getFieldValue('goods_no')
goods_price: 123 if(goods_no){
let param = {
sku: goods_no
}
this.isLoading = true
GoodsApi.getCollector(param).then((result) => {
this.goods_images = 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) { onForceUpdate(bool = false) {

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