新增商品模板,图片导入

This commit is contained in:
weipengfei 2023-11-24 14:32:14 +08:00
parent 8915f0256b
commit f529194aa1
2 changed files with 540 additions and 223 deletions

View File

@ -566,3 +566,11 @@ export function productBathExtApi(data) {
export function productBathSvipApi (data) { export function productBathSvipApi (data) {
return request.post(`store/product/batch_svip`, data) return request.post(`store/product/batch_svip`, data)
} }
/** 商品导入 -- 导入模板 */
export function importProduct (data) {
return request.post(`store/import/product`, data)
}
/** 商品导入 -- 导入图片 */
export function importImages (data) {
return request.post(`store/import/import_images`, data)
}

View File

@ -2,7 +2,10 @@
<div class="divBox"> <div class="divBox">
<el-card class="box-card"> <el-card class="box-card">
<div slot="header" class="clearfix"> <div slot="header" class="clearfix">
<el-tabs v-model="tableFrom.type" @tab-click="getList(1),getLstFilterApi()"> <el-tabs
v-model="tableFrom.type"
@tab-click="getList(1), getLstFilterApi()"
>
<el-tab-pane <el-tab-pane
v-for="(item, index) in headeNum" v-for="(item, index) in headeNum"
:key="index" :key="index"
@ -133,23 +136,33 @@
<router-link :to="{ path: `${roterPre}` + '/product/list/addProduct' }"> <router-link :to="{ path: `${roterPre}` + '/product/list/addProduct' }">
<el-button size="small" type="primary">添加商品</el-button> <el-button size="small" type="primary">添加商品</el-button>
</router-link> </router-link>
<el-button size="small" type="success" @click="onCopy">商品采集</el-button> <!-- <el-button size="small" type="success" @click="onCopy"
>商品采集</el-button
> -->
<el-button <el-button
size="mini" size="mini"
:disabled="tableFrom.type != 1 || multipleSelection.length == 0" :disabled="tableFrom.type != 1 || multipleSelection.length == 0"
@click="batchOff" @click="batchOff"
>批量下架</el-button> >批量下架</el-button
>
<el-button <el-button
size="mini" size="mini"
:disabled="tableFrom.type != 2 || multipleSelection.length == 0" :disabled="tableFrom.type != 2 || multipleSelection.length == 0"
@click="batchShelf" @click="batchShelf"
>批量上架</el-button> >批量上架</el-button
<el-button size="mini" :disabled="multipleSelection.length == 0" @click="batchLabel">批量设置标签</el-button> >
<el-button
size="mini"
:disabled="multipleSelection.length == 0"
@click="batchLabel"
>批量设置标签</el-button
>
<el-button <el-button
size="mini" size="mini"
:disabled="multipleSelection.length == 0" :disabled="multipleSelection.length == 0"
@click="batchFreight" @click="batchFreight"
>批量设置运费</el-button> >批量设置运费</el-button
>
<!-- <el-button <!-- <el-button
size="mini" size="mini"
:disabled="multipleSelection.length == 0" :disabled="multipleSelection.length == 0"
@ -160,7 +173,14 @@
size="mini" size="mini"
:disabled="multipleSelection.length == 0" :disabled="multipleSelection.length == 0"
@click="batchSvip" @click="batchSvip"
>批量设置会员价</el-button> >批量设置会员价</el-button
>
<el-button size="mini" @click="importShort" type="success"
>商品模板导入</el-button
>
<el-button size="mini" @click="importShortImg" type="success"
>商品图片导入</el-button
>
</div> </div>
<el-table <el-table
v-loading="listLoading" v-loading="listLoading"
@ -168,16 +188,32 @@
style="width: 100%" style="width: 100%"
size="mini" size="mini"
:row-class-name="tableRowClassName" :row-class-name="tableRowClassName"
:row-key="(row) => { return row.product_id }" :row-key="
(row) => {
return row.product_id;
}
"
@selection-change="handleSelectionChange" @selection-change="handleSelectionChange"
@rowclick.stop="closeEdit" @rowclick.stop="closeEdit"
> >
<el-table-column type="selection" :reserve-selection="true" width="55" /> <el-table-column
type="selection"
:reserve-selection="true"
width="55"
/>
<el-table-column type="expand"> <el-table-column type="expand">
<template slot-scope="props"> <template slot-scope="props">
<el-form label-position="left" inline class="demo-table-expand demo-table-expand1"> <el-form
label-position="left"
inline
class="demo-table-expand demo-table-expand1"
>
<el-form-item label="平台分类:"> <el-form-item label="平台分类:">
<span>{{ props.row.storeCategory?props.row.storeCategory.cate_name:'-' }}</span> <span>{{
props.row.storeCategory
? props.row.storeCategory.cate_name
: "-"
}}</span>
</el-form-item> </el-form-item>
<el-form-item label="商品分类:"> <el-form-item label="商品分类:">
<template v-if="props.row.merCateId.length"> <template v-if="props.row.merCateId.length">
@ -185,12 +221,15 @@
v-for="(item, index) in props.row.merCateId" v-for="(item, index) in props.row.merCateId"
:key="index" :key="index"
class="mr10" class="mr10"
>{{ item.category.cate_name }}</span> >{{ item.category.cate_name }}</span
>
</template> </template>
<span v-else>-</span> <span v-else>-</span>
</el-form-item> </el-form-item>
<el-form-item label="品牌:"> <el-form-item label="品牌:">
<span class="mr10">{{ props.row.brand?props.row.brand.brand_name:'-' }}</span> <span class="mr10">{{
props.row.brand ? props.row.brand.brand_name : "-"
}}</span>
</el-form-item> </el-form-item>
<el-form-item label="市场价格:"> <el-form-item label="市场价格:">
<span>{{ props.row.ot_price | filterEmpty }}</span> <span>{{ props.row.ot_price | filterEmpty }}</span>
@ -201,7 +240,11 @@
<el-form-item label="收藏:"> <el-form-item label="收藏:">
<span>{{ props.row.care_count | filterEmpty }}</span> <span>{{ props.row.care_count | filterEmpty }}</span>
</el-form-item> </el-form-item>
<el-form-item v-if="tableFrom.type === '7'" key="1" label="未通过原因:"> <el-form-item
v-if="tableFrom.type === '7'"
key="1"
label="未通过原因:"
>
<span>{{ props.row.refusal }}</span> <span>{{ props.row.refusal }}</span>
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -211,7 +254,10 @@
<el-table-column label="商品图" min-width="80"> <el-table-column label="商品图" min-width="80">
<template slot-scope="scope"> <template slot-scope="scope">
<div class="demo-image__preview"> <div class="demo-image__preview">
<el-image :src="scope.row.image" :preview-src-list="[scope.row.image]" /> <el-image
:src="scope.row.image"
:preview-src-list="[scope.row.image]"
/>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
@ -219,7 +265,7 @@
<el-table-column prop="price" label="商品售价" min-width="90" /> <el-table-column prop="price" label="商品售价" min-width="90" />
<el-table-column prop="svip_price" label="会员价" min-width="90"> <el-table-column prop="svip_price" label="会员价" min-width="90">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ scope.row.svip_price || '-' }}</span> <span>{{ scope.row.svip_price || "-" }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="sales" label="销量" min-width="90" /> <el-table-column prop="sales" label="销量" min-width="90" />
@ -238,7 +284,9 @@
@blur="inputBlur(scope)" @blur="inputBlur(scope)"
/> />
</span> </span>
<span v-else @dblclick.stop="tabClick(scope.row)">{{ scope.row['sort'] }}</span> <span v-else @dblclick.stop="tabClick(scope.row)">{{
scope.row["sort"]
}}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
@ -270,7 +318,9 @@
v-for="(item, index) in scope.row.mer_labels" v-for="(item, index) in scope.row.mer_labels"
:key="index" :key="index"
class="label-list" class="label-list"
>{{ item.name }}</div> >
{{ item.name }}
</div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="create_time" label="创建时间" min-width="150" /> <el-table-column prop="create_time" label="创建时间" min-width="150" />
@ -278,13 +328,22 @@
<template slot-scope="scope"> <template slot-scope="scope">
<router-link <router-link
v-if="tableFrom.type != 5" v-if="tableFrom.type != 5"
:to="{path: roterPre + '/product/list/addProduct/' + scope.row.product_id}" :to="{
path:
roterPre + '/product/list/addProduct/' + scope.row.product_id,
}"
> >
<el-button type="text" size="small" class="mr10">编辑</el-button> <el-button type="text" size="small" class="mr10">编辑</el-button>
</router-link> </router-link>
<router-link <router-link
v-if="tableFrom.type != 5" v-if="tableFrom.type != 5"
:to="{path: roterPre + '/product/list/addProduct/' + scope.row.product_id+'?type=copy'}" :to="{
path:
roterPre +
'/product/list/addProduct/' +
scope.row.product_id +
'?type=copy',
}"
> >
<el-button type="text" size="small" class="mr10">复制</el-button> <el-button type="text" size="small" class="mr10">复制</el-button>
</router-link> </router-link>
@ -293,37 +352,53 @@
type="text" type="text"
size="small" size="small"
@click="handlePreview(scope.row.product_id)" @click="handlePreview(scope.row.product_id)"
>预览</el-button> >预览</el-button
>
<router-link <router-link
v-if="tableFrom.type != 5" v-if="tableFrom.type != 5"
:to="{path: roterPre + '/product/reviews/?product_id=' + scope.row.product_id}" :to="{
path:
roterPre +
'/product/reviews/?product_id=' +
scope.row.product_id,
}"
>
<el-button type="text" size="small" class="mr10"
>查看评价</el-button
> >
<el-button type="text" size="small" class="mr10">查看评价</el-button>
</router-link> </router-link>
<el-button <el-button
v-if="tableFrom.type !== '5' && is_audit == '1'" v-if="tableFrom.type !== '5' && is_audit == '1'"
type="text" type="text"
size="small" size="small"
@click="onAuditFree(scope.row)" @click="onAuditFree(scope.row)"
>免审编辑</el-button> >免审编辑</el-button
>
<el-button <el-button
v-if="tableFrom.type !== '5'" v-if="tableFrom.type !== '5'"
type="text" type="text"
size="small" size="small"
@click="onEditLabel(scope.row)" @click="onEditLabel(scope.row)"
>编辑标签</el-button> >编辑标签</el-button
>
<el-button <el-button
v-if="tableFrom.type === '5'" v-if="tableFrom.type === '5'"
type="text" type="text"
size="small" size="small"
@click="handleRestore(scope.row.product_id)" @click="handleRestore(scope.row.product_id)"
>恢复商品</el-button> >恢复商品</el-button
>
<el-button <el-button
v-if="tableFrom.type !== '1' && tableFrom.type!== '3' && tableFrom.type !=='4' " v-if="
tableFrom.type !== '1' &&
tableFrom.type !== '3' &&
tableFrom.type !== '4'
"
type="text" type="text"
size="small" size="small"
@click="handleDelete(scope.row.product_id, scope.$index)" @click="handleDelete(scope.row.product_id, scope.$index)"
>{{ tableFrom.type === '5' ? '删除' : '加入回收站' }}</el-button> >{{ tableFrom.type === "5" ? "删除" : "加入回收站" }}</el-button
>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -384,7 +459,9 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
<span slot="footer" class="dialog-footer"> <span slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm('labelForm')">提交</el-button> <el-button type="primary" @click="submitForm('labelForm')"
>提交</el-button
>
</span> </span>
</el-dialog> </el-dialog>
<!-- 免审核弹窗--> <!-- 免审核弹窗-->
@ -397,9 +474,19 @@
width="800px" width="800px"
:before-close="handleFreightClose" :before-close="handleFreightClose"
> >
<el-form ref="tempForm" :model="tempForm" :rules="tempRule" @submit.native.prevent> <el-form
ref="tempForm"
:model="tempForm"
:rules="tempRule"
@submit.native.prevent
>
<el-form-item prop="temp_id"> <el-form-item prop="temp_id">
<el-select v-model="tempForm.temp_id" clearable placeholder="请选择" class="selWidth"> <el-select
v-model="tempForm.temp_id"
clearable
placeholder="请选择"
class="selWidth"
>
<el-option <el-option
v-for="item in tempList" v-for="item in tempList"
:key="item.shipping_template_id" :key="item.shipping_template_id"
@ -410,11 +497,18 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
<span slot="footer" class="dialog-footer"> <span slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitTempForm('tempForm')">提交</el-button> <el-button type="primary" @click="submitTempForm('tempForm')"
>提交</el-button
>
</span> </span>
</el-dialog> </el-dialog>
<!--批量设置佣金弹窗--> <!--批量设置佣金弹窗-->
<el-dialog v-if="dialogCommision" title="设置佣金" :visible.sync="dialogCommision" width="600px"> <el-dialog
v-if="dialogCommision"
title="设置佣金"
:visible.sync="dialogCommision"
width="600px"
>
<el-form <el-form
ref="commisionForm" ref="commisionForm"
:model="commisionForm" :model="commisionForm"
@ -444,16 +538,31 @@
/> />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<span>备注订单交易成功后给上级返佣的比例:0.5 = 返订单金额的50%</span> <span
>备注订单交易成功后给上级返佣的比例:0.5 =
返订单金额的50%</span
>
</el-form-item> </el-form-item>
</el-form> </el-form>
<span slot="footer" class="dialog-footer"> <span slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitCommisionForm('commisionForm')">提交</el-button> <el-button type="primary" @click="submitCommisionForm('commisionForm')"
>提交</el-button
>
</span> </span>
</el-dialog> </el-dialog>
<!--批量设置付费会员价--> <!--批量设置付费会员价-->
<el-dialog v-if="dialogSvip" title="批量设置付费会员价" :visible.sync="dialogSvip" width="700px"> <el-dialog
<el-form ref="svipForm" :model="svipForm" @submit.native.prevent label-width="80px"> v-if="dialogSvip"
title="批量设置付费会员价"
:visible.sync="dialogSvip"
width="700px"
>
<el-form
ref="svipForm"
:model="svipForm"
@submit.native.prevent
label-width="80px"
>
<el-form-item label="参与方式:"> <el-form-item label="参与方式:">
<el-radio-group v-model="svipForm.svip_price_type"> <el-radio-group v-model="svipForm.svip_price_type">
<el-radio :label="0" class="radio">不设置会员价</el-radio> <el-radio :label="0" class="radio">不设置会员价</el-radio>
@ -464,14 +573,134 @@
备注默认设置会员价是指商户在 备注默认设置会员价是指商户在
<router-link <router-link
:to="{ path: roterPre + '/systemForm/Basics/svip' }" :to="{ path: roterPre + '/systemForm/Basics/svip' }"
style="color: #1890ff;" style="color: #1890ff"
>[设置-付费会员设置]</router-link>中设置的会员折扣价选择后每个商品默认展示此处设置的会员折扣价 >[设置-付费会员设置]</router-link
>中设置的会员折扣价选择后每个商品默认展示此处设置的会员折扣价
</el-form-item> </el-form-item>
</el-form> </el-form>
<span slot="footer" class="dialog-footer"> <span slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitSvipForm('svipForm')">提交</el-button> <el-button type="primary" @click="submitSvipForm('svipForm')"
>提交</el-button
>
</span> </span>
</el-dialog> </el-dialog>
<!--商品模板导入-->
<el-dialog
v-if="dialogImport"
title="商品模板导入"
:visible.sync="dialogImport"
width="800px"
:before-close="importClose"
>
<el-form :model="importInfo">
<el-form-item label="商品模板" label-width="100px">
<div style="display: flex">
<el-upload
class="upload-demo"
drag
action="store/import/product"
:multiple="false"
:http-request="importXlsUpload"
accept="application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
:limit="1"
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">
将文件拖到此处<em>点击上传</em>
</div>
<div class="el-upload__tip" slot="tip">
只能上传xls*类型的文件
</div>
</el-upload>
<div
class="el-upload__text"
style="padding-left: 20px; line-height: 20px"
>
<div>温馨提示:</div>
<div>
第一次导入请下载模板查看, 按照模板填写商品信息,
点击左边按钮进行上传, 上传完成后请耐心等待商品导入完成,
<span style="color: coral"
>商品全部导入成功后再上传商品图片,
如果未导入请检查格式是否正确</span
>
</div>
<div style="color: #1890ff; padding-top: 10px">
<a
v-if="merchantType.type_code == 'TypeSupplyChain'"
href="https://lihai001.oss-cn-chengdu.aliyuncs.com/app/%E5%B8%82%E7%BA%A7%E4%BE%9B%E5%BA%94%E9%93%BE%E5%95%86%E6%88%B7%E5%95%86%E5%93%81%E8%B5%84%E6%96%99%E5%AF%BC%E5%85%A5%E6%A8%A1%E6%9D%BF.xls"
><em>下载示例模板</em></a
>
<a
v-else
href="https://lihai001.oss-cn-chengdu.aliyuncs.com/app/%E9%95%87%E5%95%86%E6%88%B7%E5%95%86%E5%93%81%E8%B5%84%E6%96%99%E5%AF%BC%E5%85%A5%E6%A8%A1%E6%9D%BF.xls"
><em>下载示例模板</em></a
>
</div>
</div>
</div>
</el-form-item>
</el-form>
</el-dialog>
<!--商品图片导入-->
<el-dialog
v-if="dialogImportImg"
title="商品图片导入"
:visible.sync="dialogImportImg"
width="800px"
:before-close="importCloseImg"
>
<el-form :model="importInfo">
<el-form-item label="商品图片" label-width="100px">
<div style="display: flex">
<el-upload
class="upload-demo"
drag
action="store/import/import_images"
:multiple="false"
:http-request="importZipUpload"
accept=".zip,.rar,application/x-rar-compressed"
:limit="1"
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">
将文件拖到此处<em>点击上传</em>
</div>
<div class="el-upload__tip" slot="tip">
只能上传zip, rar, rar4压缩包文件
</div>
</el-upload>
<div
class="el-upload__text"
style="padding-left: 20px; line-height: 20px"
>
<div>温馨提示:</div>
<div>
请先将商品模板导入成功后再导入商品图片, 否则导入的商品图片无效,
<span style="color: coral"
>请等待商品完全导入后再上传图片压缩包,
如果未导入请检查格式是否正确</span
>
</div>
<div style="color: #1890ff; padding-top: 10px">
<a
href="https://lihai001.oss-cn-chengdu.aliyuncs.com/app/%E5%AF%BC%E5%85%A5%E5%95%86%E5%93%81%E5%9B%BE%E7%89%87%E6%93%8D%E4%BD%9C%E6%8C%87%E5%BC%95.pdf"
target="_blank"
>
<em>查看详细操作步骤</em>
</a>
</div>
<div style="color: #1890ff; padding-top: 10px">
<a
href="https://lihai001.oss-cn-chengdu.aliyuncs.com/app/XXX%E5%95%86%E6%88%B7%E5%95%86%E5%93%81%E5%9B%BE%E7%89%87.zip"
><em>下载示例模板</em></a
>
</div>
</div>
</div>
</el-form-item>
</el-form>
</el-dialog>
</div> </div>
</template> </template>
<script> <script>
@ -502,13 +731,17 @@ import {
shippingListApi, shippingListApi,
batchesTempApi, batchesTempApi,
productBathExtApi, productBathExtApi,
productBathSvipApi productBathSvipApi,
importProduct,
importImages
} from "@/api/product"; } from "@/api/product";
import { getBaseInfo } from "@/api/user"; import { getBaseInfo } from "@/api/user";
import { roterPre } from "@/settings"; import { roterPre } from "@/settings";
import taoBao from "./taoBao"; import taoBao from "./taoBao";
import editAttr from "./editAttr"; import editAttr from "./editAttr";
import previewBox from "@/components/previewBox/index"; import previewBox from "@/components/previewBox/index";
import SettingMer from "@/libs/settingMer"
import { Message } from 'element-ui';
export default { export default {
name: "ProductList", name: "ProductList",
components: { taoBao, previewBox, editAttr }, components: { taoBao, previewBox, editAttr },
@ -518,6 +751,7 @@ export default {
emitPath: false emitPath: false
}, },
roterPre: roterPre, roterPre: roterPre,
BASE_URL: SettingMer.https,
headeNum: [], headeNum: [],
labelList: [], labelList: [],
tempList: [], tempList: [],
@ -564,6 +798,7 @@ export default {
{ required: true, message: "请输入二级佣金", trigger: "change" } { required: true, message: "请输入二级佣金", trigger: "change" }
] ]
}, },
importInfo: {}, //
commisionForm: { extension_one: 0, extension_two: 0 }, commisionForm: { extension_one: 0, extension_two: 0 },
svipForm: { svip_price_type: 0 }, svipForm: { svip_price_type: 0 },
goodsId: "", goodsId: "",
@ -574,6 +809,8 @@ export default {
dialogFreight: false, dialogFreight: false,
dialogCommision: false, dialogCommision: false,
dialogSvip: false, dialogSvip: false,
dialogImport: false,
dialogImportImg: false,
is_audit: false, is_audit: false,
deliveryType: [], deliveryType: [],
deliveryList: [], deliveryList: [],
@ -581,7 +818,10 @@ export default {
tempForm: {}, tempForm: {},
isBatch: false, isBatch: false,
open_svip: false, open_svip: false,
product:'' product: '',
merchantType: {
type_code: ''
}
}; };
}, },
mounted () { mounted () {
@ -592,6 +832,7 @@ export default {
this.getLabelLst(); this.getLabelLst();
this.getTempLst(); this.getTempLst();
this.productCon(); this.productCon();
this.merchantType = this.$store.state.user.merchantType;
}, },
updated () { updated () {
getBaseInfo().then(res => { getBaseInfo().then(res => {
@ -948,6 +1189,74 @@ export default {
.catch(({ message }) => { .catch(({ message }) => {
this.$message.error(message); this.$message.error(message);
}); });
},
//
importShort () {
this.dialogImport = true;
},
importClose () {
this.dialogImport = false;
},
//
importShortImg () {
this.dialogImportImg = true;
},
importCloseImg () {
this.dialogImportImg = false;
},
//
async importXlsUpload (options) {
console.log('上传', options);
const file = options.file;
const formData = new FormData();
formData.append('file', file);
importProduct(formData).then((res) => {
Message.success(res.message);
}).catch(e => {
Message.error(e);
})
// const chunkSize = 2 * 1024 * 1024; // 2MB
// //
// const totalChunks = Math.ceil(file.size / chunkSize);
// try {
// //
// for (let i = 0; i < totalChunks; i++) {
// const start = i * chunkSize;
// const end = Math.min((i + 1) * chunkSize, file.size);
// const chunk = file.slice(start, end);
// // FormData
// const formData = new FormData();
// formData.append('file', chunk);
// formData.append('chunkIndex', i);
// formData.append('totalChunks', totalChunks);
// formData.append('filename', file.name);
// // 使axios
// await axios.post('store/import/product', formData);
// }
// //
// // ...
// Message.success('');
// } catch (error) {
// Message.error('');
// }
},
//
async importZipUpload (options) {
console.log('上传', options);
const file = options.file;
const formData = new FormData();
formData.append('file', file);
importImages(formData).then((res) => {
Message.success(res.message);
}).catch(e => {
Message.error(e);
})
} }
} }
}; };