style:修复样式被全局污染
This commit is contained in:
parent
2bd37864a4
commit
8abba6f541
@ -1,24 +1,25 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-drawer
|
||||
:title="mode === 'add' ? '批量新增商品配置' : '编辑商品配置'"
|
||||
:visible.sync="drawerVisible"
|
||||
:before-close="handleClose"
|
||||
direction="rtl"
|
||||
size="50%"
|
||||
:before-close="handleClose"
|
||||
:title="mode === 'add' ? '批量新增商品配置' : '编辑商品配置'"
|
||||
:visible.sync="drawerVisible"
|
||||
>
|
||||
<div class="fixed-header">
|
||||
<div class="goodst_fixed_header">
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="el-icon-plus"
|
||||
v-if="mode === 'add'"
|
||||
icon="el-icon-plus"
|
||||
type="primary"
|
||||
@click="addNewItem"
|
||||
>添加组</el-button
|
||||
>
|
||||
添加组
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<div class="scrollable-content">
|
||||
<el-form :model="batchForm" label-width="80px" ref="batchFormRef">
|
||||
<el-form ref="batchFormRef" label-width="80px" :model="batchForm">
|
||||
<div
|
||||
v-for="(item, index) in batchForm.items"
|
||||
:key="index"
|
||||
@ -27,385 +28,388 @@
|
||||
<div class="card-header">
|
||||
<span>组{{ index + 1 }}</span>
|
||||
<el-button
|
||||
type="danger"
|
||||
size="small"
|
||||
v-if="mode === 'add' || batchForm.items.length > 1"
|
||||
size="small"
|
||||
type="danger"
|
||||
@click="removeItem(index)"
|
||||
>删除</el-button
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<el-form-item
|
||||
<el-form-item
|
||||
label="店铺"
|
||||
:prop="'items.' + index + '.storeId'"
|
||||
:rules="rules.storeId"
|
||||
label="店铺"
|
||||
>
|
||||
<el-select
|
||||
style="width: 100%"
|
||||
v-model="item.storeId"
|
||||
placeholder="选择店铺"
|
||||
filterable
|
||||
clearable
|
||||
filterable
|
||||
placeholder="选择店铺"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in shopListData"
|
||||
:key="item.store_id"
|
||||
:label="item.store_name"
|
||||
:value="item.store_id"
|
||||
>
|
||||
</el-option>
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item
|
||||
label="商品名称"
|
||||
:prop="'items.' + index + '.productName'"
|
||||
:rules="rules.productName"
|
||||
label="商品名称"
|
||||
>
|
||||
<el-input
|
||||
v-model="item.productName"
|
||||
placeholder="请输入商品名称"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<el-form-item
|
||||
:prop="'items.' + index + '.specValue'"
|
||||
:rules="rules.specValue"
|
||||
label="规格值"
|
||||
>
|
||||
<el-input
|
||||
v-model.number="item.specValue"
|
||||
type="number"
|
||||
placeholder="请输入规格值"
|
||||
></el-input>
|
||||
/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<el-form-item
|
||||
label="规格值"
|
||||
:prop="'items.' + index + '.specValue'"
|
||||
:rules="rules.specValue"
|
||||
>
|
||||
<el-input
|
||||
v-model.number="item.specValue"
|
||||
placeholder="请输入规格值"
|
||||
type="number"
|
||||
/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<el-form-item
|
||||
label="规格单位"
|
||||
:prop="'items.' + index + '.specUnit'"
|
||||
:rules="rules.specUnit"
|
||||
label="规格单位"
|
||||
>
|
||||
<el-input
|
||||
v-model="item.specUnit"
|
||||
placeholder="请输入规格单位"
|
||||
></el-input>
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item
|
||||
label="排序"
|
||||
:prop="'items.' + index + '.sortOrder'"
|
||||
:rules="rules.sortOrder"
|
||||
label="排序"
|
||||
>
|
||||
<el-input
|
||||
v-model.number="item.sortOrder"
|
||||
type="number"
|
||||
placeholder="请输入排序"
|
||||
></el-input>
|
||||
type="number"
|
||||
/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<el-form-item
|
||||
<el-form-item
|
||||
label="描述"
|
||||
:prop="'items.' + index + '.description'"
|
||||
:rules="rules.description"
|
||||
label="描述"
|
||||
>
|
||||
<el-input
|
||||
style="display: block"
|
||||
v-model="item.description"
|
||||
type="textarea"
|
||||
:rows="1"
|
||||
placeholder="请输入描述"
|
||||
></el-input>
|
||||
:rows="1"
|
||||
style="display: block"
|
||||
type="textarea"
|
||||
/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</div>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<div class="fixed-footer">
|
||||
<div class="goodst_fixed_footer">
|
||||
<el-button @click="drawerVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="loading" @click="submitForm">{{
|
||||
mode === "add" ? "提交" : "保存"
|
||||
}}</el-button>
|
||||
<el-button :loading="loading" type="primary" @click="submitForm">
|
||||
{{ mode === 'add' ? '提交' : '保存' }}
|
||||
</el-button>
|
||||
</div>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import GoodsToolApi from "@/api/goodsTool";
|
||||
import GoodsToolApi from '@/api/goodsTool'
|
||||
|
||||
export default {
|
||||
name: "BatchProductForm",
|
||||
props: {
|
||||
mode: {
|
||||
type: String,
|
||||
default: "add",
|
||||
validator: (value) => ["add", "edit"].includes(value),
|
||||
},
|
||||
initialData: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
shopListData: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
drawerVisible: false,
|
||||
loading: false,
|
||||
batchForm: {
|
||||
items: [],
|
||||
export default {
|
||||
name: 'BatchProductForm',
|
||||
props: {
|
||||
mode: {
|
||||
type: String,
|
||||
default: 'add',
|
||||
validator: (value) => ['add', 'edit'].includes(value),
|
||||
},
|
||||
rules: {
|
||||
productName: [
|
||||
{ required: true, message: "请输入商品名称", trigger: "blur" },
|
||||
],
|
||||
storeId: [{ required: true, message: "请选择店铺", trigger: "change" }],
|
||||
specValue: [
|
||||
{ required: true, message: "请输入规格值", trigger: "blur" },
|
||||
{ type: "number", message: "规格值必须为数字", trigger: "blur" },
|
||||
],
|
||||
specUnit: [
|
||||
{ required: true, message: "请输入规格单位", trigger: "blur" },
|
||||
],
|
||||
sortOrder: [
|
||||
{ required: true, message: "请输入排序", trigger: "blur" },
|
||||
],
|
||||
description: [
|
||||
{ required: true, message: "请输入描述", trigger: "blur" },
|
||||
],
|
||||
initialData: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
// 监听props变化,更新表单数据
|
||||
initialData: {
|
||||
handler(newVal) {
|
||||
if (this.mode === "edit" && newVal && newVal.length > 0) {
|
||||
// 深拷贝初始数据,避免修改原始数据
|
||||
this.batchForm.items = JSON.parse(JSON.stringify(newVal));
|
||||
}
|
||||
shopListData: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
// 打开抽屉
|
||||
open() {
|
||||
this.drawerVisible = true;
|
||||
|
||||
// 如果是新增模式,确保有一个空项
|
||||
if (this.mode === "add" && this.batchForm.items.length === 0) {
|
||||
this.addNewItem();
|
||||
data() {
|
||||
return {
|
||||
drawerVisible: false,
|
||||
loading: false,
|
||||
batchForm: {
|
||||
items: [],
|
||||
},
|
||||
rules: {
|
||||
productName: [
|
||||
{ required: true, message: '请输入商品名称', trigger: 'blur' },
|
||||
],
|
||||
storeId: [
|
||||
{ required: true, message: '请选择店铺', trigger: 'change' },
|
||||
],
|
||||
specValue: [
|
||||
{ required: true, message: '请输入规格值', trigger: 'blur' },
|
||||
{ type: 'number', message: '规格值必须为数字', trigger: 'blur' },
|
||||
],
|
||||
specUnit: [
|
||||
{ required: true, message: '请输入规格单位', trigger: 'blur' },
|
||||
],
|
||||
sortOrder: [
|
||||
{ required: true, message: '请输入排序', trigger: 'blur' },
|
||||
],
|
||||
description: [
|
||||
{ required: true, message: '请输入描述', trigger: 'blur' },
|
||||
],
|
||||
},
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
// 监听props变化,更新表单数据
|
||||
initialData: {
|
||||
handler(newVal) {
|
||||
if (this.mode === 'edit' && newVal && newVal.length > 0) {
|
||||
// 深拷贝初始数据,避免修改原始数据
|
||||
this.batchForm.items = JSON.parse(JSON.stringify(newVal))
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
// 打开抽屉
|
||||
open() {
|
||||
this.drawerVisible = true
|
||||
|
||||
// 关闭抽屉前的确认
|
||||
handleClose(done) {
|
||||
if (this.hasUnsavedChanges()) {
|
||||
this.$confirm("确定要关闭吗?未保存的数据将会丢失。", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(() => {
|
||||
done();
|
||||
// 如果是新增模式,确保有一个空项
|
||||
if (this.mode === 'add' && this.batchForm.items.length === 0) {
|
||||
this.addNewItem()
|
||||
}
|
||||
},
|
||||
|
||||
// 关闭抽屉前的确认
|
||||
handleClose(done) {
|
||||
if (this.hasUnsavedChanges()) {
|
||||
this.$confirm('确定要关闭吗?未保存的数据将会丢失。', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
})
|
||||
.catch(() => {
|
||||
// 取消关闭
|
||||
});
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
},
|
||||
|
||||
// 检查是否有未保存的更改
|
||||
hasUnsavedChanges() {
|
||||
if (this.mode === "add") {
|
||||
return this.batchForm.items.some(
|
||||
(item) =>
|
||||
item.productName || item.storeId || item.specValue || item.specUnit
|
||||
);
|
||||
}
|
||||
|
||||
// 编辑模式下的比较逻辑
|
||||
if (this.initialData && this.initialData.length > 0) {
|
||||
return (
|
||||
JSON.stringify(this.batchForm.items) !==
|
||||
JSON.stringify(this.initialData)
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
// 添加新项目
|
||||
addNewItem() {
|
||||
this.batchForm.items.push({
|
||||
productName: "",
|
||||
storeId: "",
|
||||
specValue: "",
|
||||
specUnit: "",
|
||||
description: "",
|
||||
sortOrder: "",
|
||||
});
|
||||
|
||||
// 滚动到底部
|
||||
this.$nextTick(() => {
|
||||
const container = document.querySelector(".scrollable-content");
|
||||
if (container) {
|
||||
container.scrollTop = container.scrollHeight;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 删除项目
|
||||
removeItem(index) {
|
||||
if (this.mode === "add" && this.batchForm.items.length > 1) {
|
||||
console.log(111);
|
||||
this.batchForm.items.splice(index, 1);
|
||||
} else {
|
||||
this.$message.warning("至少保留一个商品组配置");
|
||||
}
|
||||
},
|
||||
|
||||
// 提交表单
|
||||
submitForm() {
|
||||
this.$refs.batchFormRef.validate(async(valid) => {
|
||||
if (valid) {
|
||||
this.loading = true;
|
||||
|
||||
// 准备提交数据
|
||||
const submitData = this.batchForm.items.map((item) => ({
|
||||
productName: item.productName,
|
||||
storeId: item.storeId,
|
||||
specValue: item.specValue,
|
||||
specUnit: item.specUnit,
|
||||
description: item.description,
|
||||
sortOrder: item.sortOrder,
|
||||
}));
|
||||
|
||||
// 过滤掉空项(新增模式下)
|
||||
const filteredData =
|
||||
this.mode === "add"
|
||||
? submitData.filter(
|
||||
(item) =>
|
||||
item.productName ||
|
||||
item.storeId ||
|
||||
item.specValue ||
|
||||
item.specUnit
|
||||
)
|
||||
: submitData;
|
||||
|
||||
if (filteredData.length === 0) {
|
||||
this.$message.warning("请添加商品配置组数据");
|
||||
this.loading = false;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
let res = null;
|
||||
if(this.mode=='add'){
|
||||
res = await GoodsToolApi.batchCreateGoods(submitData)
|
||||
}else{
|
||||
res = await GoodsToolApi.updateGoods({
|
||||
...submitData?.[0],
|
||||
id: this.batchForm.items?.[0].id
|
||||
.then(() => {
|
||||
done()
|
||||
})
|
||||
.catch(() => {
|
||||
// 取消关闭
|
||||
})
|
||||
}
|
||||
|
||||
if(res.status==200){
|
||||
this.$message.success("操作成功");
|
||||
} else {
|
||||
this.loading = false;
|
||||
}
|
||||
|
||||
} else {
|
||||
this.$message.error("请完善表单信息");
|
||||
return false;
|
||||
done()
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 检查是否有未保存的更改
|
||||
hasUnsavedChanges() {
|
||||
if (this.mode === 'add') {
|
||||
return this.batchForm.items.some(
|
||||
(item) =>
|
||||
item.productName ||
|
||||
item.storeId ||
|
||||
item.specValue ||
|
||||
item.specUnit
|
||||
)
|
||||
}
|
||||
|
||||
// 编辑模式下的比较逻辑
|
||||
if (this.initialData && this.initialData.length > 0) {
|
||||
return (
|
||||
JSON.stringify(this.batchForm.items) !==
|
||||
JSON.stringify(this.initialData)
|
||||
)
|
||||
}
|
||||
|
||||
return false
|
||||
},
|
||||
|
||||
// 添加新项目
|
||||
addNewItem() {
|
||||
this.batchForm.items.push({
|
||||
productName: '',
|
||||
storeId: '',
|
||||
specValue: '',
|
||||
specUnit: '',
|
||||
description: '',
|
||||
sortOrder: '',
|
||||
})
|
||||
|
||||
// 滚动到底部
|
||||
this.$nextTick(() => {
|
||||
const container = document.querySelector('.scrollable-content')
|
||||
if (container) {
|
||||
container.scrollTop = container.scrollHeight
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 删除项目
|
||||
removeItem(index) {
|
||||
if (this.mode === 'add' && this.batchForm.items.length > 1) {
|
||||
console.log(111)
|
||||
this.batchForm.items.splice(index, 1)
|
||||
} else {
|
||||
this.$message.warning('至少保留一个商品组配置')
|
||||
}
|
||||
},
|
||||
|
||||
// 提交表单
|
||||
submitForm() {
|
||||
this.$refs.batchFormRef.validate(async (valid) => {
|
||||
if (valid) {
|
||||
this.loading = true
|
||||
|
||||
// 准备提交数据
|
||||
const submitData = this.batchForm.items.map((item) => ({
|
||||
productName: item.productName,
|
||||
storeId: item.storeId,
|
||||
specValue: item.specValue,
|
||||
specUnit: item.specUnit,
|
||||
description: item.description,
|
||||
sortOrder: item.sortOrder,
|
||||
}))
|
||||
|
||||
// 过滤掉空项(新增模式下)
|
||||
const filteredData =
|
||||
this.mode === 'add'
|
||||
? submitData.filter(
|
||||
(item) =>
|
||||
item.productName ||
|
||||
item.storeId ||
|
||||
item.specValue ||
|
||||
item.specUnit
|
||||
)
|
||||
: submitData
|
||||
|
||||
if (filteredData.length === 0) {
|
||||
this.$message.warning('请添加商品配置组数据')
|
||||
this.loading = false
|
||||
return
|
||||
}
|
||||
|
||||
let res = null
|
||||
if (this.mode == 'add') {
|
||||
res = await GoodsToolApi.batchCreateGoods(submitData)
|
||||
} else {
|
||||
res = await GoodsToolApi.updateGoods({
|
||||
...submitData?.[0],
|
||||
id: this.batchForm.items?.[0].id,
|
||||
})
|
||||
}
|
||||
|
||||
if (res.status == 200) {
|
||||
this.$message.success('操作成功')
|
||||
} else {
|
||||
this.loading = false
|
||||
}
|
||||
} else {
|
||||
this.$message.error('请完善表单信息')
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.fixed-header {
|
||||
padding: 0 12px 12px;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.goodst_fixed_header {
|
||||
padding: 0 12px 12px;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.scrollable-content {
|
||||
padding: 12px;
|
||||
height: calc(100vh - 195px);
|
||||
overflow-y: auto;
|
||||
}
|
||||
.scrollable-content {
|
||||
padding: 12px;
|
||||
height: calc(100vh - 195px);
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.fixed-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 12px;
|
||||
border-top: 1px solid #ebeef5;
|
||||
background-color: #fff;
|
||||
}
|
||||
.goodst_fixed_footer {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
padding: 12px;
|
||||
border-top: 1px solid #ebeef5;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.product-card {
|
||||
width: 100%;
|
||||
margin-bottom: 12px;
|
||||
padding: 12px 12px 0;
|
||||
border: 1px solid #dcdfe6;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
||||
background-color: #fff;
|
||||
}
|
||||
.product-card {
|
||||
width: 100%;
|
||||
margin-bottom: 12px;
|
||||
padding: 12px 12px 0;
|
||||
border: 1px solid #dcdfe6;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 12px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
}
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 12px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
}
|
||||
|
||||
.form-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.form-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.form-row .el-form-item {
|
||||
flex: 1 1 calc(33.33% - 12px);
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.form-row .el-form-item {
|
||||
flex: 1 1 calc(33.33% - 12px);
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.form-row .el-form-item:last-child {
|
||||
flex: 1 1 calc(33.34% - 12px);
|
||||
}
|
||||
.form-row .el-form-item:last-child {
|
||||
flex: 1 1 calc(33.34% - 12px);
|
||||
}
|
||||
|
||||
.form-row .el-form-item:nth-child(3n) {
|
||||
flex: 1 1 100%;
|
||||
}
|
||||
.form-row .el-form-item:nth-child(3n) {
|
||||
flex: 1 1 100%;
|
||||
}
|
||||
|
||||
.form-row .el-input__inner {
|
||||
height: 32px;
|
||||
}
|
||||
.form-row .el-input__inner {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.form-row .el-input--textarea .el-input__inner {
|
||||
height: auto;
|
||||
}
|
||||
.form-row .el-input--textarea .el-input__inner {
|
||||
height: auto;
|
||||
}
|
||||
</style>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user