|
|
@@ -1,6 +1,16 @@
|
|
|
<template>
|
|
|
<div class="ele-body">
|
|
|
<el-card shadow="never">
|
|
|
+ <!-- 状态 Tab 切换 -->
|
|
|
+ <el-tabs v-model="activeStatus" @tab-click="handleTabClick" class="goods-status-tabs">
|
|
|
+ <el-tab-pane v-for="tab in statusTabs" :key="tab.value" :name="String(tab.value)">
|
|
|
+ <span slot="label" class="goods-tab-label">
|
|
|
+ <i :class="tab.icon" style="margin-right: 5px;"></i>
|
|
|
+ <span class="goods-tab-text">{{ tab.label }}</span>
|
|
|
+ </span>
|
|
|
+ </el-tab-pane>
|
|
|
+ </el-tabs>
|
|
|
+
|
|
|
<!-- 搜索表单 -->
|
|
|
<el-form :model="where" label-width="90px" class="ele-form-search" @keyup.enter.native="query"
|
|
|
@submit.native.prevent>
|
|
|
@@ -22,19 +32,9 @@
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
<el-col :md="6" :sm="12">
|
|
|
- <el-form-item label="审核状态:">
|
|
|
- <el-select v-model="where.status" placeholder="请选择审核状态" clearable>
|
|
|
- <el-option label="全部" :value="0" />
|
|
|
- <el-option label="已发布" :value="1" />
|
|
|
- <el-option label="待发布" :value="2" />
|
|
|
- <el-option label="待审核" :value="3" />
|
|
|
- <el-option label="审核失败" :value="4" />
|
|
|
- </el-select>
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- <el-col :md="24" :sm="24">
|
|
|
<div class="ele-form-actions">
|
|
|
<el-button type="primary" @click="query" icon="el-icon-search" class="ele-btn-icon">查询</el-button>
|
|
|
+ <el-button @click="handleReset">重置</el-button>
|
|
|
<el-button @click="add()" type="primary" icon="el-icon-plus" class="ele-btn-icon"
|
|
|
v-if="permission.includes('sys:goods:add')">添加</el-button>
|
|
|
</div>
|
|
|
@@ -70,10 +70,9 @@
|
|
|
<el-table-column label="上传时间" show-overflow-tooltip min-width="160" align="center">
|
|
|
<template slot-scope="{row}">{{ row.create_time || '-' }}</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column label="操作" width="250px" align="center" :resizable="false" fixed="right">
|
|
|
+ <el-table-column label="操作" width="280px" align="center" :resizable="false" fixed="right">
|
|
|
<template slot-scope="{row}">
|
|
|
- <el-link @click="view(row)" icon="el-icon-view" type="primary" :underline="false"
|
|
|
- v-if="permission.includes('goods:goods:view')">查看</el-link>
|
|
|
+ <el-link @click="viewDetail(row)" icon="el-icon-view" type="primary" :underline="false">查看</el-link>
|
|
|
<el-link @click="edit(row)" icon="el-icon-edit" type="primary" :underline="false"
|
|
|
v-if="permission.includes('sys:goods:edit') && row.status != 1">修改</el-link>
|
|
|
<el-link @click="confirm(row, 1)" icon="el-icon-check" type="success" :underline="false"
|
|
|
@@ -88,6 +87,200 @@
|
|
|
</el-table-column>
|
|
|
</ele-data-table>
|
|
|
</el-card>
|
|
|
+ <!-- 商品编辑/查看弹窗 -->
|
|
|
+ <el-dialog :title="editMode === 'view' ? '查看商品' : (editForm.id ? '编辑商品' : '添加商品')" :visible.sync="showEdit"
|
|
|
+ min-width="1200px" @closed="resetEditForm" :destroy-on-close="true" :lock-scroll="false"
|
|
|
+ :close-on-click-modal="false" custom-class="goods-edit-dialog" top="5vh">
|
|
|
+ <el-form :model="editForm" :rules="editRules" ref="editForm" label-width="100px"
|
|
|
+ :class="['goods-edit-form', { 'is-disabled': editMode === 'view' }]" :disabled="editMode === 'view'">
|
|
|
+
|
|
|
+ <!-- 所属店铺 -->
|
|
|
+ <el-form-item label="所属店铺" prop="store_id">
|
|
|
+ <el-select v-model="editForm.store_id" placeholder="请选择店铺(不选则为平台商品)" clearable filterable
|
|
|
+ style="width: 100%;">
|
|
|
+ <el-option :value="0" label="平台商品">
|
|
|
+ <span style="float: left">平台商品</span>
|
|
|
+ <span style="float: right; color: #8492a6; font-size: 13px">ID: 0</span>
|
|
|
+ </el-option>
|
|
|
+ <el-option v-for="store in storeList" :key="store.id" :value="store.id" :label="store.name">
|
|
|
+ <span style="float: left">{{ store.name }}</span>
|
|
|
+ <span style="float: right; color: #8492a6; font-size: 13px">ID: {{ store.id }}</span>
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 商品名称 -->
|
|
|
+ <el-form-item label="商品名称" prop="goods_name">
|
|
|
+ <el-input v-model="editForm.goods_name" placeholder="请输入商品名称" clearable prefix-icon="el-icon-goods"
|
|
|
+ maxlength="100" show-word-limit />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 商品分类 -->
|
|
|
+ <el-form-item label="商品分类" prop="category_id">
|
|
|
+ <el-cascader v-model="editForm.category_id" :options="categoryTree" :props="cascaderProps"
|
|
|
+ placeholder="请选择商品分类" clearable style="width: 100%;" :show-all-levels="false" />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 封面图 -->
|
|
|
+ <el-form-item label="封面图" prop="thumb">
|
|
|
+ <upload-image v-model="editForm.thumb" :limit="1" :disabled="editMode === 'view'" />
|
|
|
+ <div class="el-form-item__tip">建议尺寸:800x800像素,支持jpg、png格式</div>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 商品相册 -->
|
|
|
+ <el-form-item label="商品相册">
|
|
|
+ <upload-image v-model="albumsArray" :limit="9" :disabled="editMode === 'view'" />
|
|
|
+ <div class="el-form-item__tip">最多上传9张图片,建议尺寸:800x800像素</div>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 商品单位 -->
|
|
|
+ <el-form-item label="商品单位" prop="unit">
|
|
|
+ <el-input v-model="editForm.unit" placeholder="如:件、个、斤、盒等" clearable maxlength="10">
|
|
|
+ <template slot="prepend">单位</template>
|
|
|
+ </el-input>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 商品重量 -->
|
|
|
+ <el-form-item label="商品重量" prop="weight">
|
|
|
+ <el-input-number v-model="editForm.weight" :precision="2" :step="0.1" :min="0" placeholder="请输入重量"
|
|
|
+ style="width: 100%;" controls-position="right">
|
|
|
+ <template slot="append">kg</template>
|
|
|
+ </el-input-number>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 规格类型 -->
|
|
|
+ <el-form-item label="规格类型">
|
|
|
+ <el-radio-group v-model="editForm.sku_type" @change="handleSkuTypeChange" size="medium">
|
|
|
+ <el-radio-button :label="1">
|
|
|
+ <i class="el-icon-document"></i> 单规格
|
|
|
+ </el-radio-button>
|
|
|
+ <el-radio-button :label="2">
|
|
|
+ <i class="el-icon-s-grid"></i> 多规格
|
|
|
+ </el-radio-button>
|
|
|
+ </el-radio-group>
|
|
|
+ <el-alert v-if="editForm.sku_type == 2 && editMode !== 'view'" title="多规格模式:可为商品设置不同的规格选项,如颜色、尺寸等" type="info"
|
|
|
+ :closable="false" style="margin-top: 10px;" />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 单规格 -->
|
|
|
+ <template v-if="editForm.sku_type == 1">
|
|
|
+ <el-form-item label="商品价格" prop="price">
|
|
|
+ <el-input-number v-model="editForm.price" :precision="2" :step="0.1" :min="0" placeholder="请输入售价"
|
|
|
+ style="width: 100%;" controls-position="right">
|
|
|
+ <template slot="prepend">¥</template>
|
|
|
+ </el-input-number>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item label="商品库存" prop="stock">
|
|
|
+ <el-input-number v-model="editForm.stock" :step="1" :min="0" placeholder="请输入库存" style="width: 100%;"
|
|
|
+ controls-position="right">
|
|
|
+ <template slot="append">{{ editForm.unit || '件' }}</template>
|
|
|
+ </el-input-number>
|
|
|
+ </el-form-item>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <!-- 多规格 -->
|
|
|
+ <el-form-item label="商品规格" v-if="editForm.sku_type == 2">
|
|
|
+ <div class="sku-actions" v-if="editMode !== 'view'">
|
|
|
+ <el-button type="primary" size="small" icon="el-icon-plus" @click="addSku" plain>
|
|
|
+ 添加规格
|
|
|
+ </el-button>
|
|
|
+ <span class="sku-tip">已添加 {{ editForm.skus.length }} 个规格</span>
|
|
|
+ </div>
|
|
|
+ <el-table :data="editForm.skus" border stripe style="margin-top: 10px;" max-height="300" class="sku-table">
|
|
|
+ <el-table-column type="index" label="#" width="50" align="center" />
|
|
|
+ <el-table-column label="规格名称" min-width="120">
|
|
|
+ <template slot-scope="{row}">
|
|
|
+ <el-input v-model="row.sku_name" placeholder="如:红色、L码" size="small" :disabled="editMode === 'view'" />
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="价格" width="120">
|
|
|
+ <template slot-scope="{row}">
|
|
|
+ <el-input-number v-model="row.price" :precision="2" :step="0.1" :min="0" size="small"
|
|
|
+ style="width: 100%;" controls-position="right" :disabled="editMode === 'view'" />
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="库存" width="120">
|
|
|
+ <template slot-scope="{row}">
|
|
|
+ <el-input-number v-model="row.stock" :step="1" :min="0" size="small" style="width: 100%;"
|
|
|
+ controls-position="right" :disabled="editMode === 'view'" />
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="排序" width="120">
|
|
|
+ <template slot-scope="{row}">
|
|
|
+ <el-input-number v-model="row.sort" :step="1" :min="0" size="small" style="width: 100%;"
|
|
|
+ controls-position="right" :disabled="editMode === 'view'" />
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="状态" width="70" align="center">
|
|
|
+ <template slot-scope="{row}">
|
|
|
+ <el-switch v-model="row.status" :active-value="1" :inactive-value="2" active-color="#13ce66"
|
|
|
+ inactive-color="#ff4949" :disabled="editMode === 'view'" />
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="操作" width="70" align="center" fixed="right" v-if="editMode !== 'view'">
|
|
|
+ <template slot-scope="{$index}">
|
|
|
+ <el-button type="text" size="small" icon="el-icon-delete" style="color: #F56C6C;"
|
|
|
+ @click="deleteSku($index)">删除</el-button>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ <el-empty v-if="editForm.skus.length === 0" description="暂无规格" :image-size="80" />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 排序号 -->
|
|
|
+ <el-form-item label="排序号">
|
|
|
+ <el-input-number v-model="editForm.sort" :step="1" :min="0" placeholder="数字越大越靠前" style="width: 100%;"
|
|
|
+ controls-position="right" />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 商品详情 -->
|
|
|
+ <el-form-item label="商品详情">
|
|
|
+ <tinymce-editor v-model="editForm.content" :disabled="editMode === 'view'" :height="400" />
|
|
|
+ <div class="el-form-item__tip">详细描述商品的特点、规格、使用说明等信息</div>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 商品状态 -->
|
|
|
+ <el-form-item label="商品状态">
|
|
|
+ <el-radio-group v-model="editForm.status" size="medium">
|
|
|
+ <el-radio-button :label="1">
|
|
|
+ <i class="el-icon-circle-check"></i> 已发布
|
|
|
+ </el-radio-button>
|
|
|
+ <el-radio-button :label="2">
|
|
|
+ <i class="el-icon-remove-outline"></i> 待发布
|
|
|
+ </el-radio-button>
|
|
|
+ <el-radio-button :label="3">
|
|
|
+ <i class="el-icon-time"></i> 待审核
|
|
|
+ </el-radio-button>
|
|
|
+ </el-radio-group>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 状态说明 -->
|
|
|
+ <el-form-item label=" " class="status-tips-wrapper" v-if="editMode !== 'view'">
|
|
|
+ <div class="status-tips">
|
|
|
+ <el-tag type="success" size="small">已发布</el-tag>
|
|
|
+ <span>商品将在前台展示,用户可以购买</span>
|
|
|
+ </div>
|
|
|
+ <div class="status-tips">
|
|
|
+ <el-tag type="info" size="small">待发布</el-tag>
|
|
|
+ <span>商品暂不展示,可随时发布</span>
|
|
|
+ </div>
|
|
|
+ <div class="status-tips">
|
|
|
+ <el-tag type="warning" size="small">待审核</el-tag>
|
|
|
+ <span>商品需要管理员审核后才能发布</span>
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <div slot="footer" class="dialog-footer">
|
|
|
+ <el-button @click="showEdit = false" size="medium">
|
|
|
+ <i class="el-icon-close"></i> {{ editMode === 'view' ? '关闭' : '取消' }}
|
|
|
+ </el-button>
|
|
|
+ <el-button v-if="editMode !== 'view'" type="primary" @click="saveEdit" :loading="editLoading" size="medium">
|
|
|
+ <i class="el-icon-check"></i> {{ editLoading ? '保存中...' : '保存' }}
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
+
|
|
|
<!-- 审核弹窗 -->
|
|
|
<el-dialog :title="confirmForm.status == 1 ? '审核通过' : '审核驳回'" :visible.sync="showConfirm" width="500px"
|
|
|
@closed="confirmForm = {}" :destroy-on-close="true" custom-class="ele-dialog-form" :lock-scroll="false"
|
|
|
@@ -108,17 +301,60 @@
|
|
|
|
|
|
<script>
|
|
|
import { mapGetters } from "vuex";
|
|
|
+import UploadImage from "@/components/uploadImage";
|
|
|
+import TinymceEditor from "@/components/TinymceEditor";
|
|
|
|
|
|
export default {
|
|
|
name: "Goods",
|
|
|
+ components: {
|
|
|
+ UploadImage,
|
|
|
+ TinymceEditor
|
|
|
+ },
|
|
|
data() {
|
|
|
return {
|
|
|
+ // 当前选中的状态 tab
|
|
|
+ activeStatus: '0',
|
|
|
+ // Tab 配置
|
|
|
+ statusTabs: [
|
|
|
+ {
|
|
|
+ value: 0,
|
|
|
+ label: '全部商品',
|
|
|
+ icon: 'el-icon-goods'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: 1,
|
|
|
+ label: '已发布',
|
|
|
+ icon: 'el-icon-circle-check'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: 2,
|
|
|
+ label: '待发布',
|
|
|
+ icon: 'el-icon-remove-outline'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: 3,
|
|
|
+ label: '待审核',
|
|
|
+ icon: 'el-icon-time'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: 4,
|
|
|
+ label: '审核失败',
|
|
|
+ icon: 'el-icon-circle-close'
|
|
|
+ }
|
|
|
+ ],
|
|
|
table: {
|
|
|
url: '/goods/index',
|
|
|
- where: {}
|
|
|
+ where: {
|
|
|
+ status: 0
|
|
|
+ }
|
|
|
+ },
|
|
|
+ where: {
|
|
|
+ goods_name: '',
|
|
|
+ store_name: '',
|
|
|
+ category_id: null
|
|
|
},
|
|
|
- where: {},
|
|
|
choose: [],
|
|
|
+ storeList: [],
|
|
|
categoryTree: [],
|
|
|
cascaderProps: {
|
|
|
value: 'id',
|
|
|
@@ -129,18 +365,118 @@ export default {
|
|
|
},
|
|
|
showConfirm: false,
|
|
|
confirmForm: {},
|
|
|
+ showEdit: false,
|
|
|
+ editMode: 'add', // add, edit, view
|
|
|
+ editLoading: false,
|
|
|
+ editForm: {
|
|
|
+ id: 0,
|
|
|
+ store_id: 0,
|
|
|
+ goods_name: '',
|
|
|
+ category_id: null,
|
|
|
+ thumb: '',
|
|
|
+ albums: '',
|
|
|
+ content: '',
|
|
|
+ price: 0,
|
|
|
+ stock: 0,
|
|
|
+ unit: '件',
|
|
|
+ weight: 0,
|
|
|
+ sku_type: 1,
|
|
|
+ status: 3,
|
|
|
+ sort: 0,
|
|
|
+ skus: []
|
|
|
+ },
|
|
|
+ editRules: {
|
|
|
+ goods_name: [
|
|
|
+ { required: true, message: '请输入商品名称', trigger: 'blur' }
|
|
|
+ ],
|
|
|
+ category_id: [
|
|
|
+ { required: true, message: '请选择商品分类', trigger: 'change' }
|
|
|
+ ],
|
|
|
+ thumb: [
|
|
|
+ { required: true, message: '请上传商品封面图', trigger: 'change' }
|
|
|
+ ],
|
|
|
+ unit: [
|
|
|
+ { required: true, message: '请输入商品单位', trigger: 'blur' }
|
|
|
+ ],
|
|
|
+ price: [
|
|
|
+ { required: true, message: '请输入商品价格', trigger: 'blur' }
|
|
|
+ ],
|
|
|
+ stock: [
|
|
|
+ { required: true, message: '请输入商品库存', trigger: 'blur' }
|
|
|
+ ]
|
|
|
+ }
|
|
|
}
|
|
|
},
|
|
|
computed: {
|
|
|
...mapGetters(["permission"]),
|
|
|
+ // 相册数组:用于组件显示
|
|
|
+ albumsArray: {
|
|
|
+ get() {
|
|
|
+ if (!this.editForm.albums) return [];
|
|
|
+ // 如果是字符串,按逗号分割转为数组
|
|
|
+ if (typeof this.editForm.albums === 'string') {
|
|
|
+ return this.editForm.albums ? this.editForm.albums.split(',').map(url => ({ url })) : [];
|
|
|
+ }
|
|
|
+ // 如果已经是数组,直接返回
|
|
|
+ return this.editForm.albums;
|
|
|
+ },
|
|
|
+ set(val) {
|
|
|
+ // 组件返回的是数组,转为逗号分割的字符串
|
|
|
+ if (Array.isArray(val)) {
|
|
|
+ this.editForm.albums = val.map(item => item.url).join(',');
|
|
|
+ } else {
|
|
|
+ this.editForm.albums = val || '';
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
},
|
|
|
mounted() {
|
|
|
+ // 初始化时,根据 URL 参数或默认值设置状态
|
|
|
+ const status = this.$route.query.status;
|
|
|
+ if (status !== undefined) {
|
|
|
+ this.activeStatus = String(status);
|
|
|
+ this.table.where.status = parseInt(status);
|
|
|
+ } else {
|
|
|
+ this.activeStatus = '0';
|
|
|
+ this.table.where.status = 0;
|
|
|
+ }
|
|
|
this.getCategoryTree();
|
|
|
+ this.getStoreList();
|
|
|
},
|
|
|
methods: {
|
|
|
+ /* Tab 切换事件 */
|
|
|
+ handleTabClick(tab) {
|
|
|
+ const status = parseInt(tab.name);
|
|
|
+ this.table.where.status = status;
|
|
|
+ // 更新 URL 参数(可选,用于刷新页面时保持状态)
|
|
|
+ if (this.$route.query.status !== String(status)) {
|
|
|
+ this.$router.replace({
|
|
|
+ query: { ...this.$route.query, status: status }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ // 重新加载表格数据
|
|
|
+ this.$refs.table.reload();
|
|
|
+ },
|
|
|
+ /* 重置搜索条件 */
|
|
|
+ handleReset() {
|
|
|
+ this.activeStatus = '0';
|
|
|
+ this.where = {
|
|
|
+ goods_name: '',
|
|
|
+ store_name: '',
|
|
|
+ category_id: null
|
|
|
+ };
|
|
|
+ this.table.where = {
|
|
|
+ status: 0
|
|
|
+ };
|
|
|
+ this.$refs.table.reload();
|
|
|
+ },
|
|
|
/* 查询 */
|
|
|
query() {
|
|
|
- this.table.where = this.where;
|
|
|
+ // 合并状态和搜索条件
|
|
|
+ this.table.where = {
|
|
|
+ ...this.where,
|
|
|
+ status: parseInt(this.activeStatus)
|
|
|
+ };
|
|
|
this.$refs.table.reload();
|
|
|
},
|
|
|
/* 获取分类树 */
|
|
|
@@ -153,17 +489,149 @@ export default {
|
|
|
console.error(e);
|
|
|
});
|
|
|
},
|
|
|
+ /* 获取店铺列表 */
|
|
|
+ getStoreList() {
|
|
|
+ this.$http.get('/store/options').then(res => {
|
|
|
+ if (res.data.code === 0) {
|
|
|
+ this.storeList = res.data.data || [];
|
|
|
+ }
|
|
|
+ }).catch(e => {
|
|
|
+ console.error(e);
|
|
|
+ });
|
|
|
+ },
|
|
|
/* 显示添加 */
|
|
|
add() {
|
|
|
- this.$router.push('/goods/edit');
|
|
|
+ this.resetEditForm();
|
|
|
+ this.editMode = 'add';
|
|
|
+ this.showEdit = true;
|
|
|
},
|
|
|
/* 显示修改 */
|
|
|
edit(row) {
|
|
|
- this.$router.push('/goods/edit?id=' + row.id);
|
|
|
+ this.editMode = 'edit';
|
|
|
+ this.getGoodsInfo(row.id);
|
|
|
},
|
|
|
/* 查看详情 */
|
|
|
- view(row) {
|
|
|
- this.$router.push('/goods/detail?id=' + row.id);
|
|
|
+ viewDetail(row) {
|
|
|
+ this.editMode = 'view';
|
|
|
+ this.getGoodsInfo(row.id);
|
|
|
+ },
|
|
|
+ /* 获取商品信息 */
|
|
|
+ getGoodsInfo(id) {
|
|
|
+ const loading = this.$loading({ lock: true });
|
|
|
+ this.$http.get('/goods/info', { params: { id: id } }).then(res => {
|
|
|
+ loading.close();
|
|
|
+ if (res.data.code === 0) {
|
|
|
+ const data = res.data.data;
|
|
|
+ this.editForm = {
|
|
|
+ id: data.id,
|
|
|
+ store_id: data.store_id || 0,
|
|
|
+ goods_name: data.goods_name || '',
|
|
|
+ category_id: data.category_id || null,
|
|
|
+ thumb: data.thumb || '',
|
|
|
+ albums: data.albums || '',
|
|
|
+ content: data.content || '',
|
|
|
+ price: data.price || 0,
|
|
|
+ stock: data.stock || 0,
|
|
|
+ unit: data.unit || '件',
|
|
|
+ weight: data.weight || 0,
|
|
|
+ sku_type: data.sku_type || 1,
|
|
|
+ status: data.status || 3,
|
|
|
+ sort: data.sort || 0,
|
|
|
+ skus: data.skus || []
|
|
|
+ };
|
|
|
+ this.showEdit = true;
|
|
|
+ } else {
|
|
|
+ this.$message.error(res.data.msg);
|
|
|
+ }
|
|
|
+ }).catch(e => {
|
|
|
+ loading.close();
|
|
|
+ this.$message.error(e.message);
|
|
|
+ });
|
|
|
+ },
|
|
|
+ /* 规格类型改变 */
|
|
|
+ handleSkuTypeChange(val) {
|
|
|
+ if (val == 2 && this.editForm.skus.length === 0) {
|
|
|
+ this.addSku();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ /* 添加规格 */
|
|
|
+ addSku() {
|
|
|
+ this.editForm.skus.push({
|
|
|
+ id: 0,
|
|
|
+ sku_name: '',
|
|
|
+ price: this.editForm.price || 0,
|
|
|
+ stock: this.editForm.stock || 0,
|
|
|
+ sort: this.editForm.skus.length,
|
|
|
+ status: 1
|
|
|
+ });
|
|
|
+ },
|
|
|
+ /* 删除规格 */
|
|
|
+ deleteSku(index) {
|
|
|
+ this.editForm.skus.splice(index, 1);
|
|
|
+ },
|
|
|
+ /* 保存编辑 */
|
|
|
+ saveEdit() {
|
|
|
+ this.$refs.editForm.validate((valid) => {
|
|
|
+ if (valid) {
|
|
|
+ // 验证多规格
|
|
|
+ if (this.editForm.sku_type == 2) {
|
|
|
+ if (this.editForm.skus.length === 0) {
|
|
|
+ this.$message.error('请至少添加一个商品规格');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ for (let i = 0; i < this.editForm.skus.length; i++) {
|
|
|
+ const sku = this.editForm.skus[i];
|
|
|
+ if (!sku.sku_name) {
|
|
|
+ this.$message.error(`请填写第${i + 1}个规格的名称`);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (!sku.price || sku.price <= 0) {
|
|
|
+ this.$message.error(`请填写第${i + 1}个规格的价格`);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ this.editLoading = true;
|
|
|
+ this.$http.post('/goods/edit', this.editForm).then(res => {
|
|
|
+ this.editLoading = false;
|
|
|
+ if (res.data.code === 0) {
|
|
|
+ this.showEdit = false;
|
|
|
+ this.$message.success(res.data.msg || '保存成功');
|
|
|
+ this.$refs.table.reload();
|
|
|
+ } else {
|
|
|
+ this.$message.error(res.data.msg);
|
|
|
+ }
|
|
|
+ }).catch(e => {
|
|
|
+ this.editLoading = false;
|
|
|
+ this.$message.error(e.message);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ /* 重置编辑表单 */
|
|
|
+ resetEditForm() {
|
|
|
+ this.editForm = {
|
|
|
+ id: 0,
|
|
|
+ store_id: 0,
|
|
|
+ goods_name: '',
|
|
|
+ category_id: null,
|
|
|
+ thumb: '',
|
|
|
+ albums: '',
|
|
|
+ content: '',
|
|
|
+ price: 0,
|
|
|
+ stock: 0,
|
|
|
+ unit: '件',
|
|
|
+ weight: 0,
|
|
|
+ sku_type: 1,
|
|
|
+ status: 3,
|
|
|
+ sort: 0,
|
|
|
+ skus: []
|
|
|
+ };
|
|
|
+ this.editMode = 'add';
|
|
|
+ if (this.$refs.editForm) {
|
|
|
+ this.$refs.editForm.clearValidate();
|
|
|
+ }
|
|
|
},
|
|
|
/* 审核 */
|
|
|
confirm(row, status) {
|
|
|
@@ -215,4 +683,217 @@ export default {
|
|
|
}
|
|
|
</script>
|
|
|
|
|
|
-<style lang="scss" scoped></style>
|
|
|
+<style lang="scss" scoped>
|
|
|
+.goods-status-tabs {
|
|
|
+ margin-bottom: 20px;
|
|
|
+
|
|
|
+ ::v-deep .el-tabs__header {
|
|
|
+ margin-bottom: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ ::v-deep .el-tabs__nav-wrap::after {
|
|
|
+ height: 1px;
|
|
|
+ }
|
|
|
+
|
|
|
+ ::v-deep .el-tabs__item {
|
|
|
+ padding: 0 30px;
|
|
|
+ height: 50px;
|
|
|
+ line-height: 50px;
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .goods-tab-label {
|
|
|
+ display: inline-flex;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ .goods-tab-text {
|
|
|
+ font-weight: 500;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ ::v-deep .el-tabs__item.is-active {
|
|
|
+ color: #409EFF;
|
|
|
+ font-weight: 600;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 商品编辑弹窗样式
|
|
|
+::v-deep .goods-edit-dialog {
|
|
|
+ .el-dialog__header {
|
|
|
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
|
+ padding: 20px;
|
|
|
+
|
|
|
+ .el-dialog__title {
|
|
|
+ color: #fff;
|
|
|
+ font-size: 18px;
|
|
|
+ font-weight: 600;
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-dialog__headerbtn .el-dialog__close {
|
|
|
+ color: #fff;
|
|
|
+ font-size: 20px;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ color: #f0f0f0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-dialog__body {
|
|
|
+ padding: 25px 30px;
|
|
|
+ max-height: 70vh;
|
|
|
+ overflow-y: auto;
|
|
|
+
|
|
|
+ // 美化滚动条
|
|
|
+ &::-webkit-scrollbar {
|
|
|
+ width: 6px;
|
|
|
+ }
|
|
|
+
|
|
|
+ &::-webkit-scrollbar-thumb {
|
|
|
+ background-color: #dcdfe6;
|
|
|
+ border-radius: 3px;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background-color: #c0c4cc;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-dialog__footer {
|
|
|
+ border-top: 1px solid #EBEEF5;
|
|
|
+ padding: 15px 30px;
|
|
|
+ background-color: #fafafa;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.goods-edit-form {
|
|
|
+ ::v-deep .el-form-item {
|
|
|
+ margin-bottom: 22px;
|
|
|
+
|
|
|
+ .el-form-item__label {
|
|
|
+ font-weight: 500;
|
|
|
+ color: #606266;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查看模式样式
|
|
|
+ &.is-disabled {
|
|
|
+
|
|
|
+ ::v-deep .el-input.is-disabled .el-input__inner,
|
|
|
+ ::v-deep .el-textarea.is-disabled .el-textarea__inner,
|
|
|
+ ::v-deep .el-input-number.is-disabled .el-input__inner {
|
|
|
+ background-color: #f5f7fa;
|
|
|
+ border-color: #e4e7ed;
|
|
|
+ color: #606266;
|
|
|
+ cursor: not-allowed;
|
|
|
+ }
|
|
|
+
|
|
|
+ ::v-deep .el-radio-button__inner {
|
|
|
+ cursor: not-allowed;
|
|
|
+ }
|
|
|
+
|
|
|
+ ::v-deep .el-cascader.is-disabled .el-input__inner {
|
|
|
+ background-color: #f5f7fa;
|
|
|
+ border-color: #e4e7ed;
|
|
|
+ color: #606266;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ ::v-deep .el-input-number {
|
|
|
+ .el-input__inner {
|
|
|
+ text-align: left;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-form-item__tip {
|
|
|
+ color: #909399;
|
|
|
+ font-size: 12px;
|
|
|
+ line-height: 1.5;
|
|
|
+ margin-top: 5px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .sku-actions {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ margin-bottom: 10px;
|
|
|
+
|
|
|
+ .sku-tip {
|
|
|
+ color: #909399;
|
|
|
+ font-size: 13px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .sku-table {
|
|
|
+ ::v-deep .el-table__header {
|
|
|
+ th {
|
|
|
+ background-color: #F5F7FA;
|
|
|
+ color: #606266;
|
|
|
+ font-weight: 600;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ ::v-deep .el-table__body {
|
|
|
+
|
|
|
+ .el-input__inner,
|
|
|
+ .el-input-number__decrease,
|
|
|
+ .el-input-number__increase {
|
|
|
+ border-radius: 4px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .status-tips-wrapper {
|
|
|
+ ::v-deep .el-form-item__content {
|
|
|
+ line-height: normal;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .status-tips {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 10px;
|
|
|
+ padding: 8px 0;
|
|
|
+ color: #606266;
|
|
|
+ font-size: 13px;
|
|
|
+
|
|
|
+ .el-tag {
|
|
|
+ width: 70px;
|
|
|
+ text-align: center;
|
|
|
+ flex-shrink: 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ ::v-deep .el-alert {
|
|
|
+ padding: 10px 15px;
|
|
|
+
|
|
|
+ .el-alert__title {
|
|
|
+ font-size: 13px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ ::v-deep .el-radio-group {
|
|
|
+ .el-radio-button__inner {
|
|
|
+ padding: 10px 20px;
|
|
|
+
|
|
|
+ i {
|
|
|
+ margin-right: 5px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.dialog-footer {
|
|
|
+ display: flex;
|
|
|
+ justify-content: flex-end;
|
|
|
+ gap: 10px;
|
|
|
+
|
|
|
+ .el-button {
|
|
|
+ min-width: 100px;
|
|
|
+
|
|
|
+ i {
|
|
|
+ margin-right: 5px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|