merchant-web/src/views/modules/operation-management/commodity/popup/add-or-update.vue

987 lines
31 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div>
<obj-modal
class="obj-modal"
ref="modal"
labelWidth="120px"
:modalCols="modalCols"
:modalConfig="modalConfig"
:modalData="modalData"
:modalHandles="modalHandles"
>
<template slot="dialog__before">
<el-tabs :before-leave="beforeTabLeave" v-model="currentPanel">
<el-tab-pane label="基础信息" name="基础信息"></el-tab-pane>
<el-tab-pane label="销售信息" name="销售信息"></el-tab-pane>
<el-tab-pane label="其他信息" name="其他信息"></el-tab-pane>
</el-tabs>
</template>
</obj-modal>
<!-- 添加规格 -->
<addSpecifications
@getSpecs="getSpecs"
ref="addSpecifications"
></addSpecifications>
<!-- 属性 -->
<addAttribute
@getAttribute="getAttribute"
ref="addAttribute"
></addAttribute>
</div>
</template>
<script>
import addAttribute from "./add-attribute.vue";
import addSpecifications from "./add-specifications.vue";
import { debounce, cloneDeep } from "lodash";
export default {
components: { addSpecifications, addAttribute },
data() {
return {
currentPanel: "基础信息",
modalData: {
merchantId: null,
shopId: null,
id: null,
name: "",
productCategoryId: "",
productPhotoList: [
// {
// "url": "https://dmjs.obs.cn-east-3.myhuaweicloud.com/hhsh/20240807/914faade6f82459388d084c14c91f866.png",
// "isMain": 1
// }
],
description: "",
productUnit: "",
productPlace: "",
//保质期
shelfLife: "",
//产品介绍图
productIntroducePhoto: "",
//产品介绍视频
productVideo: "",
//单价
singlePrice: "",
//单库存
singleStock: "",
//其他属性
otherAttribute: [], //[{"name":"颜色","value":"黄色;屎黄色"}]
//折扣情况
discountActivity: {
// "endTime": "2024-08-31 00:00:00",
// "id": "1821213180710957056",
// "merchantId": "1818337963053297664",
// "ruleObject": {
// "discount": 5,
// "limitCount": 99
// },
// "shopId": "1818337963523059712",
// "startTime": "2024-08-01 00:00:00",
// "type": 0
},
//是否折扣
isDiscount: 1,
marketId: null,
//最大消费
maxCostPrice: 15,
//市场最大消费
maxMarketPrice: 35,
//最大售价
maxSalePrice: 17.5,
//最低售价
minCostPrice: 10,
//市场最低售价
minMarketPrice: 20,
minSalePrice: 10,
salePrice: 20,
sort: 999,
status: "DOWN", //up 上架 //DOWN 放入仓库
stockNum: 200,
specType: 1,
productAttributeList: [
// {
// "id": "1821213026050191360",
// "attributeName": "重量",
// "attributeValue": "1斤,2斤"
// }
],
productSpecificationList: [
// {
// "attributeValue": "重量1斤",
// "costPrice": 10,
// "id": "1821213026083745792",
// "isDiscount": 1,
// "limitCount": 99,
// "marketPrice": 20,
// "productId": "1821207097380515840",
// "saleNum": 0,
// "salePrice": 10,
// "stockNum": 100,
// "virtualSaleNum": 0,
// "warnStockNum": 0,
// "_id": "重量1斤",
// "value": "售价¥10 成本¥10 库存100"
// },
// {
// "attributeValue": "重量2斤",
// "costPrice": 15,
// "id": "1821213026083745793",
// "isDiscount": 1,
// "limitCount": 99,
// "marketPrice": 35,
// "productId": "1821207097380515840",
// "saleNum": 0,
// "salePrice": 17.5,
// "stockNum": 100,
// "virtualSaleNum": 0,
// "warnStockNum": 0,
// "_id": "重量2斤",
// "value": "售价¥17.5 成本¥15 库存100"
// }
]
},
modalConfig: {
title: "编辑商品",
show: false,
width: "1300px",
fullscreen: true
},
fileList: [], //回显图片
fileListOne: [], //介绍图
fileListTwo: [], //视频
place: "", //场地
passCheck: [], //通行证
shopId: "",
getProductCategory: [],
getSaleUnit: []
};
},
mounted() {},
watch: {
"modalConfig.show"(newVal) {
if (!newVal) {
this.currentPanel = "基础信息";
this.fileList = [];
(this.fileListOne = []), (this.fileListTwo = []);
}
}
},
methods: {
toggle(e) {
if (this.modalConfig.show == false) {
this.modalConfig.show = true;
} else {
this.modalConfig.show = false;
}
if (e) {
console.log(e);
this.init(cloneDeep(e));
}
return {
add: shopId => {
this.shopId = shopId;
this.getData();
console.log(this.shopId);
this.$nextTick(() => {
this.modalConfig.title = "添加商品";
this.modalData = {
description: "",
merchantId: "",
name: "",
otherAttribute: [],
productAttributeList: [],
productCategoryId: "",
productIntroducePhoto: "",
productPhotoList: [],
productPlace: "",
productSpecificationList: [],
productUnit: "",
productVideo: "",
shelfLife: "",
shopId: "",
singleStock: "",
specType: 0,
minCostPrice: "",
status: "UP",
isAdvanceSell: "0"
};
this.modalData.merchantId = JSON.parse(
sessionStorage.getItem("userInfo")
).merchantId;
this.modalData.shopId = shopId;
this.passCheck = [];
this.place = [];
});
this.isAdd = true;
console.log("112233");
},
update: () => {
this.modalConfig.title = "编辑商品";
this.isAdd = false;
}
};
},
init(row) {
console.log(row);
this.shopId = row.shopId;
this.getData();
this.fileList = row.productPhotoList.map(item => {
return {
name: "",
url: item.url
};
});
if (row.productIntroducePhoto) {
// 处理多张介绍图(逗号分隔的URL)
const urls = row.productIntroducePhoto.split(",");
this.fileListOne = urls.map(url => ({
name: "",
url: url.trim()
}));
} else {
this.fileListOne = [];
}
if (row.productVideo) {
this.fileListTwo = [
{
name: "",
url: row.productVideo
}
];
} else {
this.fileListTwo = [];
}
this.place = row.productPlace.split("-");
this.modalData = row;
if (row.minCostPrice == row.maxCostPrice) {
this.$set(this.modalData, "costPrice", row.minCostPrice);
} else {
this.$set(
this.modalData,
"costPrice",
row.minCostPrice + "~" + row.maxCostPrice
);
}
if (row.minMarketPrice == row.maxMarketPrice) {
this.$set(this.modalData, "marketPrice", row.minMarketPrice);
} else {
this.$set(
this.modalData,
"marketPrice",
row.minMarketPrice + "~" + row.maxMarketPrice
);
}
if (!row.productAttributeList) {
this.$set(this.modalData, "productAttributeList", []);
}
if (row.otherAttribute) {
this.modalData.otherAttribute = JSON.parse(row.otherAttribute);
} else {
this.modalData.otherAttribute = [];
}
console.log(this.modalData);
},
addSpecs() {
console.log("123");
if (this.isAdd) {
this.$refs.addSpecifications
.toggle()
.add(
this.modalData.productAttributeList,
this.modalData.productSpecificationList
);
} else {
if (this.modalData.specType == 0) {
this.$refs.addSpecifications.toggle().update([], []);
} else {
this.$refs.addSpecifications
.toggle()
.update(
this.modalData.productAttributeList,
this.modalData.productSpecificationList
);
}
}
},
//获取属性
getSpecs(tableData, AttributeData) {
console.log(tableData);
this.modalData.specType = 1;
let AttributeList = AttributeData.map(item => {
return {
attributeName: item.attributeName,
attributeValue: item.attributeValue.join(",")
};
});
this.$set(this.modalData, "productSpecificationList", tableData);
this.$set(this.modalData, "productAttributeList", AttributeList);
},
addAttribute() {
if (this.isAdd) {
this.$refs.addAttribute.toggle().add(this.modalData.otherAttribute);
} else {
this.$refs.addAttribute.toggle().update(this.modalData.otherAttribute);
}
},
getAttribute(data) {
console.log(data);
this.modalData.otherAttribute = [
{
name: data.name,
value: data.value.join(",")
}
];
console.log(this.modalData);
},
beforeTabLeave(activeName, oldActiveName) {
if (this.passCheck.includes(activeName)) {
return true;
}
let state = "";
this.$refs.modal.validate(valid => {
if (valid) {
if (!this.passCheck.includes(oldActiveName)) {
this.passCheck.push(oldActiveName);
}
}
state = valid;
});
return state;
},
getData() {
this.$api.mer_admin
.getProductCategory({ shopId: this.shopId })
.then(res => {
this.getProductCategory = res.data.data;
console.log(res);
});
this.$api.mer_admin.getSaleUnit({ shopId: this.shopId }).then(res => {
this.getSaleUnit = res.data.data;
console.log(res);
});
}
},
computed: {
modalCols() {
switch (this.currentPanel) {
case "基础信息":
return [
{
label: "商品图片",
prop: "productPhotoList",
required: true,
rules: {
required: true,
message: "请上传商品图片",
trigger: "blur"
},
type: "jsx",
render: () => {
const handleChange = (file, fileList) => {
// console.log(fileList);
};
const handleAvatarSuccess = (res, file, fileList) => {
console.log(res, fileList);
this.modalData.productPhotoList = fileList.map(
(item, index) => {
if (index == 0) {
return {
isMain: 1,
url: item.response ? item.response.data : item.url
};
} else {
return {
isMain: 0,
url: item.response ? item.response.data : item.url
};
}
}
);
console.log(this.modalData.productPhotoList);
this.fileList = fileList.map(item => {
return {
name: item.name,
url: item.response ? item.response.data : item.url
};
});
};
const handleRemove = (file, fileList) => {
console.log(file, fileList);
this.modalData.productPhotoList = fileList.map(
(item, index) => {
if (index == 0) {
return {
isMain: 1,
url: item.url
};
} else {
return {
isMain: 0,
url: item.url
};
}
}
);
console.log(this.modalData.productPhotoList);
this.fileList = fileList.map(item => {
return {
name: item.name,
url: item.url
};
});
};
return (
<el-upload
class="upload-demo"
drag
action={this.$api.mer_admin.uploadFile()}
{...{
props: {
"on-change": handleChange,
"on-success": handleAvatarSuccess,
"on-remove": handleRemove
}
}}
headers={{
token: "Bearer " + this.$cookie.get("token")
}}
multiple={true}
file-list={this.fileList}
list-type="picture"
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">
将文件拖到此处<em>点击上传</em>
</div>
<div class="el-upload__tip" slot="tip">
只能上传jpg/png文件且不超过500kb
</div>
</el-upload>
);
}
},
{
label: "商品类目",
prop: "productCategoryId",
type: "jsx",
required: true,
rules: {
required: true,
message: "请选择商品类目",
trigger: "blur"
},
render: () => {
return (
<el-select
placeholder="请选择商品类目"
v-model={this.modalData.productCategoryId}
>
{this.getProductCategory.map(item => {
return (
<el-option
label={item.name}
value={item.id}
></el-option>
);
})}
</el-select>
);
}
},
{
label: "商品名称",
prop: "name",
type: "Input",
required: true,
maxlength: "30",
rules: {
required: true,
message: "请输入商品名称",
trigger: "blur"
},
placeholder: "请输入商品名称"
},
{
label: "商品描述",
prop: "description",
required: true,
rules: {
required: true,
message: "请填写商品描述",
trigger: "blur"
},
type: "jsx",
render: () => {
return (
<el-input
type="textarea"
maxlength={100}
v-model={this.modalData.description}
placeholder="请简单描述,如别称、口感、用途等"
/>
);
}
}
// {
// label: "是否为预售产品",
// prop: "isAdvanceSell",
// required: true,
// rules: {
// required: true,
// message: "是否为预售产品",
// trigger: "blur",
// },
// type: "jsx",
// render: () => {
// return (
// <el-select
// v-model={this.modalData.isAdvanceSell}
// placeholder="请选择销售单位"
// >
// {[
// { label: "是", value: "1" },
// { label: "否", value: "0" },
// ].map((item) => {
// return (
// <el-option
// label={item.label}
// value={item.value}
// ></el-option>
// );
// })}
// </el-select>
// );
// },
// },
];
break;
case "销售信息":
return [
{
label: "销售单位",
prop: "productUnit",
required: true,
rules: {
required: true,
message: "请选择销售单位",
trigger: "blur"
},
type: "jsx",
render: () => {
return (
<el-select
v-model={this.modalData.productUnit}
placeholder="请选择销售单位"
>
{this.getSaleUnit.map(item => {
return (
<el-option
label={item.name}
value={item.name}
></el-option>
);
})}
</el-select>
);
}
},
{
label: "规格",
prop: "productSpecificationList",
type: "jsx",
render: () => {
return (
<el-button onClick={this.addSpecs}>
若有多规格请在此配置
</el-button>
);
}
},
{
label: "成本",
prop: "costPrice",
type: "jsx",
required: true,
rules: {
required: true,
message: "请输入成本价格",
trigger: "blur"
},
render: () => {
return (
<el-input
readonly={this.modalData.specType != 0}
placeholder="请输入价格"
v-model={this.modalData.costPrice}
>
<template slot="append">单位</template>
</el-input>
);
}
},
{
label: "市场价",
prop: "marketPrice",
type: "jsx",
required: true,
rules: {
required: true,
message: "请输入市场价",
trigger: "blur"
},
render: () => {
return (
<el-input
readonly={this.modalData.specType != 0}
placeholder="请输入市场价"
v-model={this.modalData.marketPrice}
>
<template slot="append">单位</template>
</el-input>
);
}
},
{
label: "库存",
prop: "stockNum",
type: "jsx",
required: true,
rules: {
required: true,
message: "请输入库存",
trigger: "blur"
},
render: () => {
return (
<el-input
readonly={this.modalData.specType != 0}
placeholder="请输入库存"
v-model={this.modalData.stockNum}
></el-input>
);
}
},
{
label: "重量",
prop: "weight",
type: "jsx",
required: true,
rules: {
required: true,
message: "请输入重量",
trigger: "blur"
},
render: () => {
return (
<el-input
readonly={this.modalData.specType != 0}
placeholder="请输入重量"
v-model={this.modalData.weight}
>
<template slot="append">KG</template>
</el-input>
);
}
},
{
label: "体积",
prop: "volume",
type: "jsx",
required: true,
rules: {
required: true,
message: "请输入体积",
trigger: "blur"
},
render: () => {
return (
<el-input
readonly={this.modalData.specType != 0}
placeholder="请输入体积"
v-model={this.modalData.volume}
>
<template slot="append">立方米</template>
</el-input>
);
}
},
{
label: "其他属性",
prop: "productAttributeList",
type: "jsx",
render: () => {
return (
<el-button onClick={this.addAttribute}>
添加其他属性
</el-button>
);
}
}
];
break;
case "其他信息":
return [
{
label: "产地",
prop: "productPlace",
type: "jsx",
render: () => {
const change = e => {
console.log(e);
this.modalData.productPlace = e.join("-");
};
return (
<el-cascader
v-model={this.place}
onChange={change}
options={this.$api.mer_admin.getCityOptions()}
props={{
props: {
label: "name",
value: "name"
}
}}
clearable
></el-cascader>
);
}
},
{
label: "保质期",
prop: "shelfLife",
type: "jsx",
render: () => {
return (
<el-input
style="width:150px;"
placeholder="请填写保质期"
v-model={this.modalData.shelfLife}
>
<div slot="suffix"></div>
</el-input>
);
}
},
{
label: "商品介绍图",
prop: "productIntroducePhoto",
type: "Input",
// required: true,
// rules: { required: true, message: "商品介绍图", trigger: "blur" },
placeholder: "商品介绍图",
type: "jsx",
render: () => {
const handleChange = (file, fileList) => {
// console.log(fileList);
};
const handleAvatarSuccess = (res, file, fileList) => {
// 拼接所有已上传图片URL使用逗号分隔
const urls = fileList
.map(item => {
return item.response ? item.response.data : item.url;
})
.filter(Boolean);
this.modalData.productIntroducePhoto = urls.join(",");
console.log(this.modalData.productIntroducePhoto);
};
const handleRemove = (file, fileList) => {
// 从已上传列表中移除一张图片后重新拼接剩余的图片URL
const urls = fileList
.map(item => {
return item.response ? item.response.data : item.url;
})
.filter(Boolean);
this.modalData.productIntroducePhoto = urls.join(",");
console.log(this.modalData.productIntroducePhoto);
};
return (
<el-upload
class="upload-demo"
drag
action={this.$api.mer_admin.uploadFile()}
file-list={this.fileListOne}
list-type="picture"
{...{
props: {
"on-change": handleChange,
"on-success": handleAvatarSuccess,
"on-remove": handleRemove
}
}}
headers={{
token: "Bearer " + this.$cookie.get("token")
}}
multiple
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">
将文件拖到此处<em>点击上传</em>
</div>
<div class="el-upload__tip" slot="tip">
只能上传jpg/png文件且不超过500kb
</div>
</el-upload>
);
}
},
{
label: "商品视频",
prop: "productVideo",
// required: true,
// rules: {
// required: true,
// message: "请填写商品描述",
// trigger: "blur",
// },
type: "jsx",
render: () => {
const handleChange = (file, fileList) => {
console.log(fileList);
};
const handleAvatarSuccess = res => {
this.modalData.productVideo = res.data;
};
const handleRemove = () => {
this.modalData.productVideo = "";
};
return (
<el-upload
class="upload-demo"
drag
action={this.$api.mer_admin.uploadFile()}
limit={1}
file-list={this.fileListTwo}
accept=".mp4,.avi,.mov,.wmv,.flv"
{...{
props: {
"on-change": handleChange,
"on-success": handleAvatarSuccess,
"on-remove": handleRemove
}
}}
headers={{
token: "Bearer " + this.$cookie.get("token")
}}
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">
将视频文件拖到此处<em>点击上传</em>
</div>
<div class="el-upload__tip" slot="tip">
支持mp4avimov等视频格式建议不超过50MB
</div>
</el-upload>
);
}
}
];
break;
default:
break;
}
},
modalHandles() {
return [
{
label: this.currentPanel === "其他信息" ? "保存并上架" : "下一步",
type: "primary",
loading: this.isLoading,
submit: true,
handle: debounce(() => {
if (this.currentPanel === "基础信息") {
this.currentPanel = "销售信息";
} else if (this.currentPanel == "销售信息") {
this.currentPanel = "其他信息";
} else {
console.log("请求接口", this.modalData);
if (this.modalData.specType == 0) {
this.modalData.productAttributeList = [
{
id: "1821213026050191360",
attributeName: "重量",
attributeValue: "1斤"
}
];
this.modalData.productSpecificationList = [
{
attributeValue: "默认",
costPrice: this.modalData.costPrice,
marketPrice: this.modalData.marketPrice,
stockNum: this.modalData.stockNum,
weight: this.modalData.weight,
volume: this.modalData.volume
}
];
}
// 明确设置状态为上架
this.modalData.status = "UP";
this.$api.mer_admin.saveProduct(this.modalData).then(res => {
console.log(res);
this.$emit("queryList");
this.toggle();
});
}
}, 300)
},
{
disabled: () => this.currentPanel != "其他信息",
label: "保存并放入仓库",
type: "info",
loading: this.isLoading,
submit: true,
handle: debounce(() => {
if (this.modalData.specType == 0) {
this.modalData.productAttributeList = [
{
id: "1821213026050191360",
attributeName: "重量",
attributeValue: "1斤"
}
];
this.modalData.productSpecificationList = [
{
attributeValue: "默认",
costPrice: this.modalData.costPrice,
marketPrice: this.modalData.marketPrice,
stockNum: this.modalData.stockNum,
weight: this.modalData.weight,
volume: this.modalData.volume
}
];
}
// 明确设置状态为下架/放入仓库
this.modalData.status = "DOWN";
this.$api.mer_admin.saveProduct(this.modalData).then(res => {
console.log(res);
this.$emit("queryList");
this.toggle();
});
}, 300)
}
];
}
},
asyncComputed: {
// async getProductCategory() {
// let res = await this.$api.mer_admin.getProductCategory();
// return res.data.data;
// },
// async getSaleUnit() {
// let res = await this.$api.mer_admin.getSaleUnit({
// shopId: JSON.parse(sessionStorage.getItem("userInfo")).shopId,
// });
// console.log(res);
// return res.data.data;
// },
}
};
</script>
<style lang="scss" scoped>
.obj-modal ::v-deep {
.el-dialog__body {
padding: 0 30px;
}
}
</style>