javacodeadmin/ruoyi-ui/src/views/system/IntegralProduct/index.vue

826 lines
26 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 class="app-container">
<el-form
:model="queryParams"
ref="queryForm"
size="small"
:inline="true"
v-show="showSearch"
label-width="68px"
>
<el-form-item label="名称" prop="title">
<el-input
v-model="queryParams.title"
placeholder="请输入名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<!-- 市场价范围 -->
<el-form-item label="市场价">
<el-input
v-model="queryParams.minPrice"
class="number-input"
type="number"
placeholder="最小值"
clearable
style="width: 120px"
/>
-
<el-input
v-model="queryParams.maxPrice"
class="number-input"
type="number"
placeholder="最大值"
clearable
style="width: 120px"
/>
</el-form-item>
<!-- 积分范围 -->
<el-form-item label="积分">
<el-input
v-model="queryParams.minNum"
class="number-input"
type="number"
placeholder="最小值"
clearable
style="width: 120px"
/>
-
<el-input
v-model="queryParams.maxNum"
class="number-input"
type="number"
placeholder="最大值"
clearable
style="width: 120px"
/>
</el-form-item>
<el-form-item label="分类" prop="cateId">
<el-select v-model="queryParams.cateId" placeholder="请选择分类" clearable style="width: 200px">
<el-option
v-for="item in integralCateList"
:key="item.id"
:label="item.title"
:value="item.id"
/>
</el-select>
</el-form-item>
<!-- 新增:状态 -->
<el-form-item label="状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="请选择状态"
clearable
>
<el-option label="启用" :value="1" />
<el-option label="停用" :value="0" />
</el-select>
</el-form-item>
<!-- 新增:创建时间范围 -->
<el-form-item label="创建时间">
<el-date-picker
v-model="queryParams.beginTime"
type="date"
placeholder="开始日期"
value-format="yyyy-MM-dd"
format="yyyy-MM-dd"
></el-date-picker>
-
<el-date-picker
v-model="queryParams.endTime"
type="date"
placeholder="结束日期"
value-format="yyyy-MM-dd"
format="yyyy-MM-dd"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button
type="primary"
icon="el-icon-search"
size="mini"
@click="handleQuery"
>搜索</el-button
>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
>重置</el-button
>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['system:IntegralProduct:add']"
>新增</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['system:IntegralProduct:edit']"
>修改</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['system:IntegralProduct:remove']"
>删除</el-button
>
</el-col>
<right-toolbar
:showSearch.sync="showSearch"
@queryTable="getList"
></right-toolbar>
</el-row>
<el-table
v-loading="loading"
:data="IntegralProductList"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="ID" align="center" width="55" prop="id" />
<el-table-column label="分类" align="center" prop="cateName" />
<el-table-column label="名称" align="center" prop="title" />
<el-table-column label="主图" align="center" prop="image" width="100">
<template slot-scope="scope">
<image-preview :src="scope.row.image" :width="50" :height="50" />
</template>
</el-table-column>
<!-- 市场价范围 -->
<!-- <el-form-item label="市场价">
<el-input
v-model="queryParams.minPrice"
placeholder="最小值"
style="width: 80px"
oninput="value=value.replace(/[^\\d\\.]/g,'')"
/>
-
<el-input
v-model="queryParams.maxPrice"
placeholder="最大值"
style="width: 80px"
oninput="value=value.replace(/[^\\d\\.]/g,'')"
/>
</el-form-item> -->
<!-- 积分范围 -->
<!-- <el-form-item label="积分">
<el-input
v-model="queryParams.minNum"
placeholder="最小值"
style="width: 80px"
oninput="value=value.replace(/[^\\d]/g,'')"
/>
-
<el-input
v-model="queryParams.maxNum"
placeholder="最大值"
style="width: 80px"
oninput="value=value.replace(/[^\\d]/g,'')"
/>
</el-form-item> -->
<el-table-column label="排序" align="center" width="75" prop="sort">
<template slot-scope="scope">
<div style="cursor: pointer; color: #409eff; display: inline-block">
<span @click="openEditDialog(scope.row, 'sort', '排序')">{{
scope.row.sort
}}</span>
<svg
@click="openEditDialog(scope.row, 'sort', '排序')"
width="14"
height="14"
viewBox="0 0 1024 1024"
fill="#bbb"
style="margin-left: 4px; vertical-align: middle; cursor: pointer"
>
<path
d="M880.64 227.84l-84.48-84.48c-25.6-25.6-67.2-25.6-92.8 0l-59.52 59.52 177.28 177.28 59.52-59.52c25.6-25.6 25.6-67.2 0-92.8zM160 736v128h128l376.32-376.32-128-128L160 736z"
/>
</svg>
<div
style="
border-bottom: 1px dashed #bbb;
width: 100%;
margin-top: 2px;
"
></div>
</div>
</template>
</el-table-column>
<el-table-column label="销量" align="center" width="75" prop="sales">
<template slot-scope="scope">
<div style="cursor: pointer; color: #409eff; display: inline-block">
<span @click="openEditDialog(scope.row, 'sales', '销量')">{{
scope.row.sales
}}</span>
<svg
@click="openEditDialog(scope.row, 'sales', '销量')"
width="14"
height="14"
viewBox="0 0 1024 1024"
fill="#bbb"
style="margin-left: 4px; vertical-align: middle; cursor: pointer"
>
<path
d="M880.64 227.84l-84.48-84.48c-25.6-25.6-67.2-25.6-92.8 0l-59.52 59.52 177.28 177.28 59.52-59.52c25.6-25.6 25.6-67.2 0-92.8zM160 736v128h128l376.32-376.32-128-128L160 736z"
/>
</svg>
<div
style="
border-bottom: 1px dashed #bbb;
width: 100%;
margin-top: 2px;
"
></div>
</div>
</template>
</el-table-column>
<el-table-column label="库存" align="center" width="75" prop="stock">
<template slot-scope="scope">
<div style="cursor: pointer; color: #409eff; display: inline-block">
<span @click="openEditDialog(scope.row, 'stock', '库存')">{{
scope.row.stock
}}</span>
<svg
@click="openEditDialog(scope.row, 'stock', '库存')"
width="14"
height="14"
viewBox="0 0 1024 1024"
fill="#bbb"
style="margin-left: 4px; vertical-align: middle; cursor: pointer"
>
<path
d="M880.64 227.84l-84.48-84.48c-25.6-25.6-67.2-25.6-92.8 0l-59.52 59.52 177.28 177.28 59.52-59.52c25.6-25.6 25.6-67.2 0-92.8zM160 736v128h128l376.32-376.32-128-128L160 736z"
/>
</svg>
<div
style="
border-bottom: 1px dashed #bbb;
width: 100%;
margin-top: 2px;
"
></div>
</div>
</template>
</el-table-column>
<el-table-column label="状态" width="85" align="center">
<template slot-scope="scope">
<el-switch
v-model="scope.row.status"
:active-value="1"
:inactive-value="0"
@change="handleStatusChange(scope.row)"
></el-switch>
</template>
</el-table-column>
<el-table-column
label="创建时间"
align="center"
prop="createdAt"
width="150"
>
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createdAt, "{y}-{m}-{d}") }}</span>
</template>
</el-table-column>
<el-table-column
label="更新时间"
align="center"
prop="updatedAt"
width="150"
>
<template slot-scope="scope">
<span>{{ parseTime(scope.row.updatedAt, "{y}-{m}-{d}") }}</span>
</template>
</el-table-column>
<el-table-column
label="操作"
align="center"
width="100"
class-name="small-padding fixed-width"
>
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['system:IntegralProduct:edit']"
>修改</el-button
>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['system:IntegralProduct:remove']"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改积分商品对话框 -->
<el-drawer :title="title" :visible.sync="open" size="60%" append-to-body>
<div style="padding:0 30px;">
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-tabs v-model="activeTab">
<el-tab-pane label="基本信息" name="base">
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-form-item label="分类" prop="cateId">
<el-select v-model="form.cateId" placeholder="请选择分类" style="width: 100%">
<el-option
v-for="item in integralCateList"
:key="item.id"
:label="item.title"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="名称" prop="title">
<el-input v-model="form.title" placeholder="请输入名称" />
</el-form-item>
<el-form-item label="主图" prop="image">
<image-upload v-model="form.image"/>
</el-form-item>
<el-form-item label="轮播图" prop="images">
<image-upload v-model="form.images"/>
</el-form-item>
<el-form-item label="标签" prop="tags">
<el-input v-model="form.tags" placeholder="请输入标签" />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-switch v-model="form.status" :active-value="1" :inactive-value="0" />
</el-form-item>
</el-form>
</el-tab-pane>
<el-tab-pane label="营销配置" name="marketing">
<el-form-item label="市场价" prop="price">
<el-input-number v-model="form.price" :min="0" :step="0.01" :precision="2" placeholder="请输入市场价" style="width: 200px;" />
</el-form-item>
<el-form-item label="积分" prop="num">
<el-input-number v-model="form.num" :min="0" style="width: 200px;" />
</el-form-item>
<el-form-item label="排序" prop="sort">
<el-input-number v-model="form.sort" :min="1" style="width: 200px;" />
</el-form-item>
<el-form-item label="销量" prop="sales">
<el-input-number v-model="form.sales" :min="0" style="width: 200px;" />
</el-form-item>
<el-form-item label="库存" prop="stock">
<el-input-number v-model="form.stock" :min="0" style="width: 200px;" />
</el-form-item>
</el-tab-pane>
<el-tab-pane label="规格配置" name="spec">
<el-form-item label="规格">
<el-radio-group v-model="skuType">
<el-radio-button :label="1">单规格</el-radio-button>
<el-radio-button :label="2">多规格</el-radio-button>
</el-radio-group>
</el-form-item>
<div v-if="skuType === 1">
<!-- <el-form-item label="规格名">
<el-input v-model="form.skuName" placeholder="请输入规格名" />
</el-form-item>
<el-form-item label="规格值">
<el-input v-model="form.skuValue" placeholder="请输入规格值" />
</el-form-item> -->
</div>
<div v-else>
<Sku :info="form.sku" ref="skuRef"></Sku>
</div>
</el-tab-pane>
<!-- <el-tab-pane label="规格配置1" name="sku">
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-form-item label="规格" prop="skuType">
<el-radio-group v-model="form.skuType">
<el-radio :label="1">单规格</el-radio>
<el-radio :label="2">多规格</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="规格名" v-if="form.skuType == 2">
<el-input v-model="form.skuName" placeholder="请输入规格名" />
</el-form-item>
<el-form-item label="规格值" v-if="form.skuType == 2">
<el-input v-model="form.skuValue" placeholder="请输入规格值" />
</el-form-item>
<el-form-item label="规格" prop="sku">
<el-input v-model="form.sku" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
</el-tab-pane> -->
<el-tab-pane label="详情配置" name="detail">
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-form-item label="详情">
<editor v-model="form.contetnt" :min-height="192"/>
</el-form-item>
</el-form>
</el-tab-pane>
</el-tabs>
</el-form>
<div class="dialog-footer" style="text-align:left;margin-top:20px;">
<el-button @click="reset">重置</el-button>
<el-button type="primary" @click="submitForm">提交</el-button>
</div>
</div>
</el-drawer>
<el-dialog :visible.sync="editDialogVisible" title="编辑" width="300px">
<el-form>
<el-form-item :label="editFieldLabel">
<el-input v-model="editFieldValue" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="editDialogVisible = false">取消</el-button>
<el-button type="primary" @click="saveEditField">保存</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {
listIntegralProduct,
getIntegralProduct,
delIntegralProduct,
addIntegralProduct,
updateIntegralProduct,
changetypeStatus,
getIntegralCateList
} from "@/api/system/IntegralProduct";
import Editor from "@/components/Editor";
export default {
name: "IntegralProduct",
components: { Editor },
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 积分商品表格数据
IntegralProductList: [],
// 弹出层标题
title: "",
integralCateList: [],
// 是否显示弹出层
open: false,
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 10,
title: null,
price: null,
status: null,
tags: null,
// 市场价范围
minPrice: null,
maxPrice: null,
beginTime: null,
endTime: null,
// 积分范围
minNum: null,
maxNum: null,
cateId: null,
skuType: null,
},
// 表单参数
form: {},
// 表单校验
rules: {
title: [{ required: true, message: "名称不能为空", trigger: "blur" }],
price: [{ required: true, message: "市场价不能为空", trigger: "blur" }],
num: [{ required: true, message: "积分不能为空", trigger: "blur" }],
sort: [{ required: true, message: "排序不能为空", trigger: "blur" }],
sales: [{ required: true, message: "销量不能为空", trigger: "blur" }],
stock: [{ required: true, message: "库存不能为空", trigger: "blur" }],
status: [
{ required: true, message: "状态不能为空", trigger: "change" },
],
tags: [{ required: true, message: "标签不能为空", trigger: "blur" }],
cateId: [{ required: true, message: "分类不能为空", trigger: "blur" }],
skuType: [
{
required: true,
message: "1单规格 2多规格不能为空",
trigger: "change",
},
],
sku: [{ required: true, message: "规格不能为空", trigger: "blur" }],
},
editDialogVisible: false,
editFieldValue: "",
editField: "",
editFieldLabel: "",
editRow: null,
activeTab: "base",
skuType: 1,
skuList: [{ name: "", value: "" }],
specList: [{ name: "", values: [""] }],
skuTable: [],
};
},
created() {
this.getList();
this.getintegralCateList()
},
methods: {
/** 查询积分商品列表 */
getList() {
this.loading = true;
listIntegralProduct(this.queryParams).then((response) => {
this.IntegralProductList = response.rows;
this.total = response.total;
this.loading = false;
});
},
// 取消按钮
cancel() {
this.open = false;
this.reset();
},
// 表单重置
reset() {
this.form = {
id: null,
title: null,
image: null,
images: null,
price: null,
num: null,
sort: null,
sales: null,
stock: null,
status: null,
tags: null,
cateId: null,
skuType: 1,
sku: "{}",
skuName: null,
skuValue: null,
contetnt: null,
createdAt: null,
updatedAt: null,
};
// 重置skuType为默认值
this.skuType = 1;
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
// 校验最小最大值逻辑(可选)
if (
this.queryParams.minPrice !== null &&
this.queryParams.maxPrice !== null &&
this.queryParams.minPrice > this.queryParams.maxPrice
) {
this.$message.warning("市场价范围不合法");
return;
}
if (
this.queryParams.minNum !== null &&
this.queryParams.maxNum !== null &&
this.queryParams.minNum > this.queryParams.maxNum
) {
this.$message.warning("积分范围不合法");
return;
}
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
getintegralCateList () {
getIntegralCateList().then((response) => {
this.integralCateList = response.data;
});
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map((item) => item.id);
this.single = selection.length !== 1;
this.multiple = !selection.length;
},
// 任务状态修改
handleStatusChange(row) {
let text = row.status === "0" ? "启用" : "停用";
this.$modal
.confirm('确认要"' + text + '""' + row.title + '"状态吗?')
.then(function () {
return changetypeStatus(row.id, row.status);
})
.then(() => {
this.$modal.msgSuccess(text + "成功");
})
.catch(function () {
row.status = row.status === "0" ? "1" : "0";
});
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加积分商品";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids;
getIntegralProduct(id).then((response) => {
this.form = response.data;
// 设置skuType如果没有则默认为1
this.skuType = this.form.skuType || 1;
// 如果是单规格且sku有数据尝试解析
if (this.skuType === 1 && this.form.sku && this.form.sku !== '{}') {
try {
const skuData = JSON.parse(this.form.sku);
if (skuData.name && skuData.value) {
this.form.skuName = skuData.name;
this.form.skuValue = skuData.value;
}
} catch (e) {
console.warn('解析单规格数据失败:', e);
}
}
this.open = true;
this.title = "修改积分商品";
});
},
/** 提交按钮 */
submitForm() {
// 设置规格类型
this.form.skuType = this.skuType;
// 处理规格信息
if (this.skuType === 2) {
// 多规格模式
if (this.$refs.skuRef && this.$refs.skuRef.submit) {
const skuData = this.$refs.skuRef.submit();
if (!skuData) {
this.$modal.msgError("请完善规格信息");
return;
}
this.form.sku = typeof skuData === 'string' ? skuData : JSON.stringify(skuData);
} else {
this.$modal.msgError("规格信息不能为空");
return;
}
} else {
// 单规格模式
if (!this.form.skuName || !this.form.skuValue) {
this.$modal.msgError("请完善单规格信息");
return;
}
const singleSku = {
name: this.form.skuName,
value: this.form.skuValue
};
this.form.sku = JSON.stringify(singleSku);
}
// 验证sku不能为空
if (!this.form.sku || this.form.sku === '{}') {
this.$modal.msgError("规格信息不能为空");
return;
}
this.$refs["form"].validate((valid) => {
if (valid) {
if (this.form.id != null) {
updateIntegralProduct(this.form).then((response) => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addIntegralProduct(this.form).then((response) => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal
.confirm('是否确认删除积分商品编号为"' + ids + '"的数据项?')
.then(function () {
return delIntegralProduct(ids);
})
.then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
})
.catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
this.download(
"system/IntegralProduct/export",
{
...this.queryParams,
},
`IntegralProduct_${new Date().getTime()}.xlsx`
);
},
openEditDialog(row, field, label) {
this.editRow = row;
this.editField = field;
this.editFieldLabel = label;
this.editFieldValue = row[field];
this.editDialogVisible = true;
},
async saveEditField() {
if (!this.editRow) return;
// 需要转为数字的字段
const numberFields = ["price", "num", "sort", "sales", "stock"];
const value = numberFields.includes(this.editField)
? Number(this.editFieldValue)
: this.editFieldValue;
const payload = {
id: this.editRow.id,
[this.editField]: value,
};
try {
await updateIntegralProduct(payload);
this.$message.success("修改成功");
this.editDialogVisible = false;
this.getList();
} catch (e) {
this.$message.error("修改失败");
}
},
},
};
</script>
<style scoped>
.number-input
::v-deep
.el-input__inner[type="number"]::-webkit-inner-spin-button,
.number-input
::v-deep
.el-input__inner[type="number"]::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
</style>