Compare commits

..

No commits in common. "d7b40ebf3ce3a2e1de31a8f13341110cdf1b3bfd" and "00f7d33b1ac369791b4472b746eb2453d94a53c7" have entirely different histories.

2 changed files with 291 additions and 294 deletions

View File

@ -1,25 +1,24 @@
<template> <template>
<div> <div>
<el-drawer <el-drawer
:before-close="handleClose"
direction="rtl"
size="50%"
:title="mode === 'add' ? '批量新增商品配置' : '编辑商品配置'" :title="mode === 'add' ? '批量新增商品配置' : '编辑商品配置'"
:visible.sync="drawerVisible" :visible.sync="drawerVisible"
direction="rtl"
size="50%"
:before-close="handleClose"
> >
<div class="goodst_fixed_header"> <div class="fixed-header">
<el-button <el-button
v-if="mode === 'add'"
icon="el-icon-plus"
type="primary" type="primary"
icon="el-icon-plus"
v-if="mode === 'add'"
@click="addNewItem" @click="addNewItem"
>添加组</el-button
> >
添加组
</el-button>
</div> </div>
<div class="scrollable-content"> <div class="scrollable-content">
<el-form ref="batchFormRef" label-width="80px" :model="batchForm"> <el-form :model="batchForm" label-width="80px" ref="batchFormRef">
<div <div
v-for="(item, index) in batchForm.items" v-for="(item, index) in batchForm.items"
:key="index" :key="index"
@ -28,127 +27,127 @@
<div class="card-header"> <div class="card-header">
<span>{{ index + 1 }}</span> <span>{{ index + 1 }}</span>
<el-button <el-button
v-if="mode === 'add' || batchForm.items.length > 1"
size="small"
type="danger" type="danger"
size="small"
v-if="mode === 'add' || batchForm.items.length > 1"
@click="removeItem(index)" @click="removeItem(index)"
>删除</el-button
> >
删除
</el-button>
</div> </div>
<div class="form-row"> <div class="form-row">
<el-form-item <el-form-item
label="店铺"
:prop="'items.' + index + '.storeId'" :prop="'items.' + index + '.storeId'"
:rules="rules.storeId" :rules="rules.storeId"
label="店铺"
> >
<el-select <el-select
v-model="item.storeId"
clearable
filterable
placeholder="选择店铺"
style="width: 100%" style="width: 100%"
v-model="item.storeId"
placeholder="选择店铺"
filterable
clearable
> >
<el-option <el-option
v-for="item in shopListData" v-for="item in shopListData"
:key="item.store_id" :key="item.store_id"
:label="item.store_name" :label="item.store_name"
:value="item.store_id" :value="item.store_id"
/> >
</el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item <el-form-item
label="商品名称"
:prop="'items.' + index + '.productName'" :prop="'items.' + index + '.productName'"
:rules="rules.productName" :rules="rules.productName"
label="商品名称"
> >
<el-input <el-input
v-model="item.productName" v-model="item.productName"
placeholder="请输入商品名称" placeholder="请输入商品名称"
/> ></el-input>
</el-form-item> </el-form-item>
</div> </div>
<div class="form-row"> <div class="form-row">
<el-form-item <el-form-item
label="规格值"
:prop="'items.' + index + '.specValue'" :prop="'items.' + index + '.specValue'"
:rules="rules.specValue" :rules="rules.specValue"
label="规格值"
> >
<el-input <el-input
v-model.number="item.specValue" v-model.number="item.specValue"
placeholder="请输入规格值"
type="number" type="number"
/> placeholder="请输入规格值"
></el-input>
</el-form-item> </el-form-item>
</div> </div>
<div class="form-row"> <div class="form-row">
<el-form-item <el-form-item
label="规格单位"
:prop="'items.' + index + '.specUnit'" :prop="'items.' + index + '.specUnit'"
:rules="rules.specUnit" :rules="rules.specUnit"
label="规格单位"
> >
<el-input <el-input
v-model="item.specUnit" v-model="item.specUnit"
placeholder="请输入规格单位" placeholder="请输入规格单位"
/> ></el-input>
</el-form-item> </el-form-item>
<el-form-item <el-form-item
label="排序"
:prop="'items.' + index + '.sortOrder'" :prop="'items.' + index + '.sortOrder'"
:rules="rules.sortOrder" :rules="rules.sortOrder"
label="排序"
> >
<el-input <el-input
v-model.number="item.sortOrder" v-model.number="item.sortOrder"
placeholder="请输入排序"
type="number" type="number"
/> placeholder="请输入排序"
></el-input>
</el-form-item> </el-form-item>
</div> </div>
<div class="form-row"> <div class="form-row">
<el-form-item <el-form-item
label="描述"
:prop="'items.' + index + '.description'" :prop="'items.' + index + '.description'"
:rules="rules.description" :rules="rules.description"
label="描述"
> >
<el-input <el-input
v-model="item.description"
placeholder="请输入描述"
:rows="1"
style="display: block" style="display: block"
v-model="item.description"
type="textarea" type="textarea"
/> :rows="1"
placeholder="请输入描述"
></el-input>
</el-form-item> </el-form-item>
</div> </div>
</div> </div>
</el-form> </el-form>
</div> </div>
<div class="goodst_fixed_footer"> <div class="fixed-footer">
<el-button @click="drawerVisible = false">取消</el-button> <el-button @click="drawerVisible = false">取消</el-button>
<el-button :loading="loading" type="primary" @click="submitForm"> <el-button type="primary" :loading="loading" @click="submitForm">{{
{{ mode === 'add' ? '提交' : '保存' }} mode === "add" ? "提交" : "保存"
</el-button> }}</el-button>
</div> </div>
</el-drawer> </el-drawer>
</div> </div>
</template> </template>
<script> <script>
import GoodsToolApi from '@/api/goodsTool' import GoodsToolApi from "@/api/goodsTool";
export default { export default {
name: 'BatchProductForm', name: "BatchProductForm",
props: { props: {
mode: { mode: {
type: String, type: String,
default: 'add', default: "add",
validator: (value) => ['add', 'edit'].includes(value), validator: (value) => ["add", "edit"].includes(value),
}, },
initialData: { initialData: {
type: Array, type: Array,
@ -168,34 +167,32 @@
}, },
rules: { rules: {
productName: [ productName: [
{ required: true, message: '请输入商品名称', trigger: 'blur' }, { required: true, message: "请输入商品名称", trigger: "blur" },
],
storeId: [
{ required: true, message: '请选择店铺', trigger: 'change' },
], ],
storeId: [{ required: true, message: "请选择店铺", trigger: "change" }],
specValue: [ specValue: [
{ required: true, message: '请输入规格值', trigger: 'blur' }, { required: true, message: "请输入规格值", trigger: "blur" },
{ type: 'number', message: '规格值必须为数字', trigger: 'blur' }, { type: "number", message: "规格值必须为数字", trigger: "blur" },
], ],
specUnit: [ specUnit: [
{ required: true, message: '请输入规格单位', trigger: 'blur' }, { required: true, message: "请输入规格单位", trigger: "blur" },
], ],
sortOrder: [ sortOrder: [
{ required: true, message: '请输入排序', trigger: 'blur' }, { required: true, message: "请输入排序", trigger: "blur" },
], ],
description: [ description: [
{ required: true, message: '请输入描述', trigger: 'blur' }, { required: true, message: "请输入描述", trigger: "blur" },
], ],
}, },
} };
}, },
watch: { watch: {
// props // props
initialData: { initialData: {
handler(newVal) { handler(newVal) {
if (this.mode === 'edit' && newVal && newVal.length > 0) { if (this.mode === "edit" && newVal && newVal.length > 0) {
// //
this.batchForm.items = JSON.parse(JSON.stringify(newVal)) this.batchForm.items = JSON.parse(JSON.stringify(newVal));
} }
}, },
immediate: true, immediate: true,
@ -205,43 +202,40 @@
methods: { methods: {
// //
open() { open() {
this.drawerVisible = true this.drawerVisible = true;
// //
if (this.mode === 'add' && this.batchForm.items.length === 0) { if (this.mode === "add" && this.batchForm.items.length === 0) {
this.addNewItem() this.addNewItem();
} }
}, },
// //
handleClose(done) { handleClose(done) {
if (this.hasUnsavedChanges()) { if (this.hasUnsavedChanges()) {
this.$confirm('确定要关闭吗?未保存的数据将会丢失。', '提示', { this.$confirm("确定要关闭吗?未保存的数据将会丢失。", "提示", {
confirmButtonText: '确定', confirmButtonText: "确定",
cancelButtonText: '取消', cancelButtonText: "取消",
type: 'warning', type: "warning",
}) })
.then(() => { .then(() => {
done() done();
}) })
.catch(() => { .catch(() => {
// //
}) });
} else { } else {
done() done();
} }
}, },
// //
hasUnsavedChanges() { hasUnsavedChanges() {
if (this.mode === 'add') { if (this.mode === "add") {
return this.batchForm.items.some( return this.batchForm.items.some(
(item) => (item) =>
item.productName || item.productName || item.storeId || item.specValue || item.specUnit
item.storeId || );
item.specValue ||
item.specUnit
)
} }
// //
@ -249,39 +243,39 @@
return ( return (
JSON.stringify(this.batchForm.items) !== JSON.stringify(this.batchForm.items) !==
JSON.stringify(this.initialData) JSON.stringify(this.initialData)
) );
} }
return false return false;
}, },
// //
addNewItem() { addNewItem() {
this.batchForm.items.push({ this.batchForm.items.push({
productName: '', productName: "",
storeId: '', storeId: "",
specValue: '', specValue: "",
specUnit: '', specUnit: "",
description: '', description: "",
sortOrder: '', sortOrder: "",
}) });
// //
this.$nextTick(() => { this.$nextTick(() => {
const container = document.querySelector('.scrollable-content') const container = document.querySelector(".scrollable-content");
if (container) { if (container) {
container.scrollTop = container.scrollHeight container.scrollTop = container.scrollHeight;
} }
}) });
}, },
// //
removeItem(index) { removeItem(index) {
if (this.mode === 'add' && this.batchForm.items.length > 1) { if (this.mode === "add" && this.batchForm.items.length > 1) {
console.log(111) console.log(111);
this.batchForm.items.splice(index, 1) this.batchForm.items.splice(index, 1);
} else { } else {
this.$message.warning('至少保留一个商品组配置') this.$message.warning("至少保留一个商品组配置");
} }
}, },
@ -289,7 +283,7 @@
submitForm() { submitForm() {
this.$refs.batchFormRef.validate(async(valid) => { this.$refs.batchFormRef.validate(async(valid) => {
if (valid) { if (valid) {
this.loading = true this.loading = true;
// //
const submitData = this.batchForm.items.map((item) => ({ const submitData = this.batchForm.items.map((item) => ({
@ -299,11 +293,11 @@
specUnit: item.specUnit, specUnit: item.specUnit,
description: item.description, description: item.description,
sortOrder: item.sortOrder, sortOrder: item.sortOrder,
})) }));
// //
const filteredData = const filteredData =
this.mode === 'add' this.mode === "add"
? submitData.filter( ? submitData.filter(
(item) => (item) =>
item.productName || item.productName ||
@ -311,41 +305,43 @@
item.specValue || item.specValue ||
item.specUnit item.specUnit
) )
: submitData : submitData;
if (filteredData.length === 0) { if (filteredData.length === 0) {
this.$message.warning('请添加商品配置组数据') this.$message.warning("请添加商品配置组数据");
this.loading = false this.loading = false;
return return;
} }
let res = null
let res = null;
if(this.mode=='add'){ if(this.mode=='add'){
res = await GoodsToolApi.batchCreateGoods(submitData) res = await GoodsToolApi.batchCreateGoods(submitData)
}else{ }else{
res = await GoodsToolApi.updateGoods({ res = await GoodsToolApi.updateGoods({
...submitData?.[0], ...submitData?.[0],
id: this.batchForm.items?.[0].id, id: this.batchForm.items?.[0].id
}) })
} }
if(res.status==200){ if(res.status==200){
this.$message.success('操作成功') this.$message.success("操作成功");
} else { } else {
this.loading = false this.loading = false;
} }
} else { } else {
this.$message.error('请完善表单信息') this.$message.error("请完善表单信息");
return false return false;
} }
}) });
}, },
}, },
} };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.goodst_fixed_header { .fixed-header {
padding: 0 12px 12px; padding: 0 12px 12px;
border-bottom: 1px solid #ebeef5; border-bottom: 1px solid #ebeef5;
display: flex; display: flex;
@ -358,9 +354,9 @@
overflow-y: auto; overflow-y: auto;
} }
.goodst_fixed_footer { .fixed-footer {
display: flex; display: flex;
justify-content: flex-start; justify-content: flex-end;
padding: 12px; padding: 12px;
border-top: 1px solid #ebeef5; border-top: 1px solid #ebeef5;
background-color: #fff; background-color: #fff;

View File

@ -1914,7 +1914,7 @@
display: flex; display: flex;
align-items: center; align-items: center;
padding: 20px; padding: 20px;
margin-bottom: 15px; margin: 20px;
gap: 10px; gap: 10px;
border-radius: 5px; border-radius: 5px;
box-shadow: 1px 1px 6px rgba(0, 0, 0, 0.1); box-shadow: 1px 1px 6px rgba(0, 0, 0, 0.1);
@ -1927,6 +1927,7 @@
.list { .list {
background: #fff; background: #fff;
padding: 20px; padding: 20px;
margin: 20px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 10px; gap: 10px;