大大的豆芽 1 неделя назад
Родитель
Сommit
de86d65d83

+ 191 - 77
README.md

@@ -27,113 +27,227 @@
 
 
 单选多选设置
-
 <template>
-  <div>
-    <!-- 显示已选中的数据 -->
-    <div v-if="selectedFactory" class="selected-item">
-      已选择: {{ selectedFactory.name }}
-      <el-button type="text" icon="el-icon-close" @click="clearSelected"></el-button>
-    </div>
-    
-    <!-- 多选模式下显示已选中的数据列表 -->
-    <div v-if="selectedFactories.length" class="selected-list">
-      <el-tag 
-        v-for="item in selectedFactories" 
-        :key="item.id" 
-        closable 
-        @close="removeFactory(item)"
-      >
-        {{ item.name }}
-      </el-tag>
-    </div>
-
-    <el-button @click="openSelector">选择工厂</el-button>
-    
-    <!-- 单选模式 -->
-    <data-selector
-      ref="singleSelector"
-      title="选择工厂"
+  <div class="app-container">
+    <el-card class="box-card">
+      <div slot="header" class="clearfix">
+        <span>选择器组件示例</span>
+      </div>
+
+      <!-- 单选示例 -->
+      <div class="demo-block">
+        <h3>单选示例</h3>
+        <div class="selected-info">
+          <el-descriptions v-if="selectedUser" :column="1" border>
+            <el-descriptions-item label="用户名">{{ selectedUser.userName }}</el-descriptions-item>
+            <el-descriptions-item label="昵称">{{ selectedUser.nickName }}</el-descriptions-item>
+            <el-descriptions-item label="手机号">{{ selectedUser.phonenumber }}</el-descriptions-item>
+          </el-descriptions>
+          <el-empty v-else description="暂未选择用户"></el-empty>
+        </div>
+        <div class="button-group">
+          <el-button type="primary" @click="handleSelectUser">选择用户</el-button>
+          <el-button v-if="selectedUser" @click="selectedUser = null">清除选择</el-button>
+        </div>
+      </div>
+
+      <!-- 多选示例 -->
+      <div class="demo-block">
+        <h3>多选示例</h3>
+        <div class="selected-info">
+          <template v-if="selectedDepts.length">
+            <el-tag
+              v-for="dept in selectedDepts"
+              :key="dept.deptId"
+              closable
+              class="tag-item"
+              @close="removeDept(dept)"
+            >
+              {{ dept.deptName }}
+            </el-tag>
+          </template>
+          <el-empty v-else description="暂未选择部门"></el-empty>
+        </div>
+        <div class="button-group">
+          <el-button type="primary" @click="handleSelectDept">选择部门</el-button>
+          <el-button v-if="selectedDepts.length" @click="selectedDepts = []">清除全部</el-button>
+        </div>
+      </div>
+    </el-card>
+
+    <!-- 用户选择器 -->
+    <DataSelector
+      ref="userSelector"
+      title="选择用户"
       :multiple="false"
-      :selected="selectedFactory"
-      :data-columns="dataColumns"
-      :fetch-data="fetchFactoryData"
-      @confirm="handleSingleSelect"
+      :data-columns="userColumns"
+      :fetch-data="fetchUserData"
+      @confirm="handleUserSelect"
     />
-    
-    <!-- 多选模式 -->
-    <data-selector
-      ref="multiSelector"
-      title="选择工厂"
+
+    <!-- 部门选择器 -->
+    <DataSelector
+      ref="deptSelector"
+      title="选择部门"
       :multiple="true"
-      :selected="selectedFactories"
-      :data-columns="dataColumns"
-      :fetch-data="fetchFactoryData"
-      @confirm="handleMultiSelect"
+      :data-columns="deptColumns"
+      :fetch-data="fetchDeptData"
+      @confirm="handleDeptSelect"
     />
   </div>
 </template>
 
 <script>
+import DataSelector from '@/components/DataSelector'
+import { listUser } from '@/api/system/user'
+import { listDept } from '@/api/system/dept'
+
 export default {
+  name: 'SelectorDemo',
+  components: {
+    DataSelector
+  },
   data() {
     return {
       // 单选数据
-      selectedFactory: null,
+      selectedUser: null,
       // 多选数据
-      selectedFactories: [],
-      dataColumns: [
-        { field: 'name', label: '工厂名称' },
-        { field: 'address', label: '地址' },
-        { field: 'contact', label: '联系人' }
+      selectedDepts: [],
+
+      // 用户选择器列配置
+      userColumns: [
+        { field: 'userName', label: '用户名称', width: '120' },
+        { field: 'nickName', label: '用户昵称', width: '120' },
+        { field: 'deptName', label: '所属部门' },
+        { field: 'phonenumber', label: '手机号码', width: '120' },
+        { field: 'email', label: '邮箱', width: '180' }
+      ],
+
+      // 部门选择器列配置
+      deptColumns: [
+        { field: 'deptName', label: '部门名称', width: '180' },
+        { field: 'leader', label: '负责人', width: '120' },
+        { field: 'phone', label: '联系电话', width: '120' },
+        { field: 'email', label: '邮箱', width: '180' },
+        { field: 'status', label: '状态', width: '100', formatter: this.formatStatus }
       ]
     }
   },
   methods: {
-    // 打开选择器
-    openSelector(type = 'single') {
-      if (type === 'single') {
-        this.$refs.singleSelector.show()
-      } else {
-        this.$refs.multiSelector.show()
+    // 打开用户选择器
+    handleSelectUser() {
+      this.$refs.userSelector.show()
+    },
+
+    // 打开部门选择器
+    handleSelectDept() {
+      this.$refs.deptSelector.show()
+    },
+
+    // 获取用户数据
+    async fetchUserData(params) {
+      try {
+        const response = await listUser({
+          pageNum: params.pageNum,
+          pageSize: params.pageSize,
+          userName: params.title
+        })
+        return {
+          data: response.rows,
+          total: response.total
+        }
+      } catch (error) {
+        console.error('获取用户数据失败:', error)
+        return {
+          data: [],
+          total: 0
+        }
+      }
+    },
+
+    // 获取部门数据
+    async fetchDeptData(params) {
+      try {
+        const response = await listDept({
+          pageNum: params.pageNum,
+          pageSize: params.pageSize,
+          deptName: params.title
+        })
+        return {
+          data: response.rows,
+          total: response.total
+        }
+      } catch (error) {
+        console.error('获取部门数据失败:', error)
+        return {
+          data: [],
+          total: 0
+        }
       }
     },
-    // 处理单选
-    handleSingleSelect(data) {
-      this.selectedFactory = data
+
+    // 处理用户选择
+    handleUserSelect(data) {
+      this.selectedUser = data
+      this.$message.success(`已选择用户:${data.userName}`)
     },
-    // 处理多选
-    handleMultiSelect(data) {
-      this.selectedFactories = data
+
+    // 处理部门选择
+    handleDeptSelect(data) {
+      this.selectedDepts = data
+      this.$message.success(`已选择 ${data.length} 个部门`)
     },
-    // 清除选择
-    clearSelected() {
-      this.selectedFactory = null
+
+    // 移除选中部门
+    removeDept(dept) {
+      this.selectedDepts = this.selectedDepts.filter(item => item.deptId !== dept.deptId)
     },
-    // 移除某个选中项
-    removeFactory(item) {
-      this.selectedFactories = this.selectedFactories.filter(f => f.id !== item.id)
+
+    // 格式化状态
+    formatStatus(row) {
+      return row.status === '0' ? '正常' : '停用'
     }
   }
 }
 </script>
 
 <style lang="scss" scoped>
-.selected-item {
-  margin-bottom: 10px;
-  padding: 8px;
-  border: 1px solid #dcdfe6;
-  border-radius: 4px;
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-}
+.app-container {
+  padding: 20px;
+
+  .demo-block {
+    margin-bottom: 20px;
+    padding: 20px;
+    border-bottom: 1px solid #ebeef5;
+
+    h3 {
+      margin: 0 0 15px;
+      font-size: 16px;
+      color: #303133;
+    }
+
+    .selected-info {
+      margin-bottom: 15px;
+      min-height: 100px;
+      padding: 15px;
+      background-color: #f5f7fa;
+      border-radius: 4px;
+
+      .tag-item {
+        margin-right: 8px;
+        margin-bottom: 8px;
+      }
+    }
+
+    .button-group {
+      .el-button {
+        margin-right: 10px;
+      }
+    }
+  }
 
-.selected-list {
-  margin-bottom: 10px;
-  .el-tag {
-    margin-right: 8px;
-    margin-bottom: 8px;
+  .box-card {
+    margin-bottom: 20px;
   }
 }
 </style>

+ 12 - 0
src/api/app/delivery.js

@@ -73,3 +73,15 @@ export function getDeliveryManListByOrg() {
     method: 'get'
   })
 }
+
+/**
+ * 获取配送员绑定的门店列表
+ * @param {Object} query 查询参数
+ */
+export function getDeliveryStoreList(query) {
+  return request({
+    url: '/mapi/app/delivery/store/list',
+    method: 'get',
+    params: query
+  })
+}

+ 102 - 0
src/components/DataList/index.vue

@@ -0,0 +1,102 @@
+<template>
+  <el-dialog :title="title" :visible.sync="visible" width="60%" append-to-body class="data-list-dialog">
+    <el-table
+      v-loading="loading"
+      :data="tableData"
+      fit highlight-current-row border stripe
+      style="width: 100%">
+      <el-table-column
+        v-for="column in columns"
+        :key="column.prop"
+        :prop="column.prop"
+        :label="column.label"
+        :width="column.width"
+        :formatter="column.formatter"
+        align="center">
+      </el-table-column>
+    </el-table>
+    <pagination
+      v-show="total > 0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+  </el-dialog>
+</template>
+
+<script>
+/**
+ * 通用数据列表展示组件
+ * @component DataList
+ */
+export default {
+  name: 'DataList',
+  props: {
+    /**
+     * 对话框标题
+     */
+    title: {
+      type: String,
+      default: '数据列表'
+    },
+    /**
+     * 表格列配置
+     */
+    columns: {
+      type: Array,
+      required: true
+    },
+    /**
+     * 获取数据的方法
+     */
+    fetchData: {
+      type: Function,
+      required: true
+    }
+  },
+  data() {
+    return {
+      visible: false,
+      loading: false,
+      // 表格数据
+      tableData: [],
+      // 总条数
+      total: 0,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10
+      }
+    }
+  },
+  methods: {
+    /** 
+     * 显示对话框
+     */
+    show() {
+      this.visible = true
+      this.getList()
+    },
+    /** 
+     * 获取数据列表
+     */
+    async getList() {
+      this.loading = true
+      try {
+        const res = await this.fetchData(this.queryParams)
+        // 优先使用 data 字段的数据
+        this.tableData = res.data || res.rows || []
+        // 如果返回的 total 为 0,则使用 data 数组的长度作为 total
+        this.total = res.total || (res.data ? res.data.length : 0)
+      } catch (error) {
+        console.error('获取数据失败:', error)
+        this.tableData = []
+        this.total = 0
+      } finally {
+        this.loading = false
+      }
+    }
+  }
+}
+</script>

+ 27 - 12
src/components/DataSelector/index.vue

@@ -16,26 +16,29 @@
             clearable
             @keyup.enter.native="handleQuery"
           >
-            <el-button slot="append" icon="el-icon-search" @click="handleQuery"></el-button>
           </el-input>
         </el-form-item>
+        <el-form-item>
+          <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
+        </el-form-item>
       </el-form>
     </div>
 
     <!-- 数据表格 -->
     <el-table
-      v-loading="loading"
+      v-loading="loading" fit highlight-current-row border stripe
       :data="tableData"
+      row-key="id"
       @selection-change="handleSelectionChange"
       @row-click="handleRowClick"
       ref="table"
     >
       <el-table-column
-        v-if="multiple"
         type="selection"
         :reserve-selection="true"
         width="55"
       />
+
       <el-table-column
         v-for="column in dataColumns"
         :key="column.field"
@@ -129,19 +132,22 @@ export default {
       this.getList()
       // 下一个 tick 等待表格渲染完成后设置选中状态
       this.$nextTick(() => {
-        if (this.multiple && this.selectedData.length > 0) {
+        if (this.selectedData.length > 0) {
           this.selectedData.forEach(row => {
-            this.$refs.table.toggleRowSelection(row, true);
-          });
+            this.$refs.table.toggleRowSelection(row, true)
+          })
         }
-      });
+      })
     },
     // 获取数据列表
     async getList() {
       this.loading = true
       try {
         const { data, total } = await this.fetchData(this.queryParams)
-        this.tableData = data
+        this.tableData = data.map(item => ({
+          ...item,
+          id: item.id || item.userId || item.deptId
+        }))
         this.total = total
       } catch (error) {
         console.error('获取数据失败:', error)
@@ -165,13 +171,21 @@ export default {
     },
     // 多选改变
     handleSelectionChange(selection) {
-      this.selectedData = selection
+      if (!this.multiple && selection.length > 1) {
+        // 单选模式下,只保留最后选中的一项
+        const lastSelected = selection[selection.length - 1]
+        this.$refs.table.clearSelection()
+        this.$refs.table.toggleRowSelection(lastSelected, true)
+        this.selectedData = [lastSelected]
+      } else {
+        this.selectedData = selection
+      }
     },
     // 单击行
     handleRowClick(row) {
       if (!this.multiple) {
-        this.selectedData = [row]
-        this.handleConfirm()
+        this.$refs.table.clearSelection()
+        this.$refs.table.toggleRowSelection(row, true)
       }
     },
     // 确认选择
@@ -184,6 +198,7 @@ export default {
       this.dialogVisible = false
       this.selectedData = []
       this.resetQuery()
+      this.$refs.table.clearSelection()
     }
   }
 }
@@ -191,7 +206,7 @@ export default {
 
 <style lang="scss" scoped>
 .search-box {
-  margin-bottom: 20px;
+  margin-bottom: 5px;
   .el-input {
     width: 300px;
   }

+ 45 - 48
src/views/app/delivery/index.vue

@@ -30,7 +30,9 @@
       <el-table-column label="等级" align="center" prop="level" />
       <el-table-column label="绑定门店数量" align="center">
         <template slot-scope="scope">
-          <span> {{ scope.row.relationStoreNum == null ? '0' : scope.row.relationStoreNum }}</span>
+          <el-button type="text" @click="showStoreList(scope.row)">
+            {{ scope.row.relationStoreNum == null ? '0' : scope.row.relationStoreNum }}
+          </el-button>
         </template>
       </el-table-column>
       <el-table-column label="状态" align="center" prop="status">
@@ -50,28 +52,18 @@
       <el-row :gutter="10" style="margin-right: 20px; margin-left: 20px; width: 95%">
         <el-card class="box-card custom-card" style="height: 800px">
           <div slot="header" class="clearfix">
-            <span>
-              <el-button @click="openSelector">选择数据</el-button>
-            </span>
-            <!-- 使用选择器组件 -->
-            <data-selector ref="dataSelector" title="选择人员" :multiple="false" :selected="selectedFactory" :data-columns="dataColumns"
-              :fetch-data="fetchFactoryData" @confirm="handleDataSelected" />
+            <span>选择客户</span>
           </div>
-
           <el-form :model="phoneNumber" size="small" :inline="true" label-width="68px">
             <el-col :span="24" v-if="isUpdate">
               <el-form-item label="手机号" prop="phoneNumber">
-
+                <el-input label-width="110px" v-model="phoneNumber" placeholder="请输入手机号" clearable maxlength="11" @change="searchUser" />
               </el-form-item>
               <el-form-item>
-                <el-button @click="openSelector">选择人员</el-button>
+                <el-button type="primary" @click="searchUser">查询</el-button>
               </el-form-item>
-              <div v-if="selectedFactory" class="selected-item">
-                已选择: {{ selectedFactory.name }}
-                <el-button type="text" icon="el-icon-close" @click="clearSelected"></el-button>
-              </div>
             </el-col>
-            <el-col :span="24">
+            <el-col :span="24" v-if="appUserInfo">
               <el-descriptions :column="2" style="margin-top: 20px">
                 <el-descriptions-item label="用户名">{{ appUserInfo.realName }}</el-descriptions-item>
                 <el-descriptions-item label="手机号">{{ appUserInfo.phoneNumber }}</el-descriptions-item>
@@ -100,6 +92,14 @@
       </div>
     </el-dialog>
 
+        <!-- 门店列表弹窗 -->
+      <data-list
+      ref="storeList"
+      title="绑定门店列表"
+      :columns="storeColumns"
+      :fetch-data="fetchStoreList"
+    />
+
     <!--   接单记录 -->
     <el-dialog v-loading="loading" :title="recordDetailTitle" :visible.sync="openDetail" size="80%" append-to-body>
       <div class="head-column1" style="margin-top: 5px">
@@ -126,34 +126,32 @@
           @pagination="recordDetail" />
       </div>
     </el-dialog>
+
   </div>
 </template>
 
 <script>
-import { listDelivery, getDelivery, delDelivery, addDelivery, updateDelivery, updateDeliveryStatus, getDeliveryOrderRecordList } from '@/api/app/delivery'
+import { listDelivery, getDelivery, delDelivery, addDelivery, updateDelivery, updateDeliveryStatus, getDeliveryOrderRecordList, getDeliveryStoreList } from '@/api/app/delivery'
 import { findUserByPhoneNumber } from '@/api/app/user'
 import { allOrg } from '@/api/system/store'
-import DataSelector from '@/components/DataSelector'
+import DataList from '@/components/DataList'
+
 export default {
   name: 'Delivery',
   components: {
-    DataSelector
-  },
-  data() {
+    DataList
+  },  data() {
     return {
-      // 表格列配置
-      selectedFactory: null,
-      dataColumns: [
-        { field: 'id', label: 'ID' },
-        { field: 'phoneNumber', label: '地址' },
-        { field: 'realName', label: '联系人' },
-        { field: 'phone', label: '联系电话' },
-        {
-          field: 'status',
-          label: '状态',
-          formatter: (row) => (row.status === 1 ? '正常' : '停用')
-        }
+              // 门店列表列配置
+      storeColumns: [
+      { prop: 'code', label: '门店编号' },
+      { prop: 'name', label: '门店名称' },
+      { prop: 'address', label: '门店地址' },
+      { prop: 'contactName', label: '联系人' },
+      { prop: 'contactPhone', label: '联系电话' }
       ],
+       // 当前选中的配送员ID
+      currentDeliveryId: null,
       // 遮罩层
       loading: true,
       // 选中数组
@@ -216,24 +214,23 @@ export default {
     this.getList()
   },
   methods: {
-    // 打开选择器
-    openSelector() {
-      this.$refs.dataSelector.show()
-    },
-    // 获取工厂数据
-    async fetchFactoryData(params) {
-      // 调用接口获取数据
-      const res = await this.getList()
-      console.log("2222", res)
-      return {
-        data: res.rows,
-        total: res.total
-      }
+        /**
+     * 显示门店列表
+     * @param {Object} row 当前行数据
+     */
+     showStoreList(row) {
+      this.currentDeliveryId = row.appUserId
+      this.$refs.storeList.show()
     },
-    // 处理选中数据
-    handleDataSelected(data) {
-      console.log('选中的数据:', data)
+        // 获取部门数据
+     fetchStoreList(params) {
+       return getDeliveryStoreList({
+          pageNum: params.pageNum,
+          pageSize: params.pageSize,
+          deliveryId: this.currentDeliveryId
+        })
     },
+
     //搜索用户
     searchUser() {
       findUserByPhoneNumber({ phoneNumber: this.phoneNumber }).then((res) => {

+ 1 - 1
src/views/app/user/index.vue

@@ -26,7 +26,7 @@
 
     <Page uri="/mapi/app/user/list" :request-params="queryParams" ref="pagination">
       <!--      <el-table-column type="selection" width="55" align="center" fixed="left"/>-->
-      <!--      <el-table-column label="客户ID" align="center" prop="id" />-->
+           <el-table-column label="ID" align="center" prop="id" />
       <el-table-column label="昵称" align="center" prop="nickName" />
       <el-table-column label="真实姓名" align="center" prop="realName" />
       <el-table-column label="手机号" align="center" prop="phoneNumber" />

+ 320 - 59
src/views/goods/commonGoods/index.vue

@@ -78,66 +78,178 @@
         </Page>
         <!-- 分页 -->
         <!-- 添加或修改商品管理对话框 -->
-        <el-dialog :title="title" :visible.sync="open" width="50%" append-to-body>
-            <el-row :gutter="15">
-                <el-form ref="form" :model="form" :rules="rules" label-width="120px">
-                    <el-col :span="24">
-                        <el-form-item label="商品名称" prop="goodsName">
-                            <el-input v-model="form.goodsName" placeholder="请输入商品名称" />
+        <el-dialog :title="title" :visible.sync="open" width="70%" append-to-body>
+            <el-form ref="form" :model="form" :rules="rules" label-width="120px">
+                <el-tabs v-model="activeTab">
+                    <!-- 基本信息 tab -->
+                    <el-tab-pane label="基本信息" name="basic">
+                        <el-row :gutter="15">
+                            <el-col :span="12">
+                                <el-form-item label="商品名称" prop="goodsName">
+                                    <el-input v-model="form.goodsName" placeholder="请输入商品名称" />
+                                </el-form-item>
+                            </el-col>
+                            <el-col :span="12">
+                                <el-form-item label="商品编码" prop="goodsCode">
+                                    <el-input v-model="form.goodsCode" placeholder="请输入商品编码" />
+                                </el-form-item>
+                            </el-col>
+                        </el-row>
+
+                        <el-row :gutter="15">
+                            <el-col :span="12">
+                                <el-form-item label="品牌" prop="brandId">
+                                    <el-select v-model="form.brandId" placeholder="请选择品牌" clearable>
+                                        <el-option v-for="brand in brandList" :key="brand.id" :label="brand.brandName" :value="brand.id" />
+                                    </el-select>
+                                </el-form-item>
+                            </el-col>
+                            <el-col :span="12">
+                                <el-form-item label="商品分类" prop="goodsCategoryId">
+                                    <el-select v-model="form.goodsCategoryId" placeholder="请选择商品分类" clearable>
+                                        <el-option v-for="category in categoryList" :key="category.id" :label="category.categoryName" :value="category.id" />
+                                    </el-select>
+                                </el-form-item>
+                            </el-col>
+                        </el-row>
+
+                        <el-form-item label="商品图片" prop="goodsImg">
+                            <image-upload v-model="form.goodsImg" />
                         </el-form-item>
-                        <el-form-item label="品牌" prop="brandId">
-                            <el-select v-model="form.brandId" placeholder="请选择商品分类" clearable>
-                                <el-option v-for="brand in brandList" :key="brand.id" :label="brand.brandName" :value="brand.id" />
-                            </el-select>
+
+                        <el-form-item label="商品图片集" prop="goodsImgs">
+                            <image-upload v-model="form.goodsImgs" :limit="limit" />
                         </el-form-item>
-                        <el-form-item label="商品分类" prop="goodsCategoryId">
-                            <el-select v-model="form.goodsCategoryId" placeholder="请选择商品分类" clearable>
-                                <el-option v-for="category in categoryList" :key="category.id" :label="category.categoryName" :value="category.id" />
-                            </el-select>
+
+                        <el-form-item label="商品简介" prop="goodsSynopsis">
+                            <editor v-model="form.goodsSynopsis" :min-height="192" />
                         </el-form-item>
-                        <el-form-item label="商品编码" prop="goodsCode">
-                            <el-input v-model="form.goodsCode" placeholder="请输入商品编码" />
+                    </el-tab-pane>
+
+                    <!-- 规格设置 tab -->
+                    <el-tab-pane label="规格设置" name="sku">
+                        <el-form-item label="规格类型">
+                            <el-radio-group v-model="skuType" @change="handleSkuTypeChange">
+                                <el-radio :label="0">单规格</el-radio>
+                                <el-radio :label="1">多规格</el-radio>
+                            </el-radio-group>
                         </el-form-item>
-                        <template v-if="goodsType === '0'">
-                            <el-form-item label="促销标识" prop="isSell">
-                                <el-radio-group v-model="form.isSell" size="small">
-                                    <el-radio-button v-for="dict in dict.type.sys_yes_no" :label="dict.value" :key="dict.code">{{ dict.label }}</el-radio-button>
-                                </el-radio-group>
+
+                        <!-- 单规格设置 -->
+                        <template v-if="skuType === 0">
+                            <el-form-item label="销售价格" prop="singleSkuPrice">
+                                <el-input-number v-model="form.singleSkuPrice" :precision="2" :step="0.1" :min="0" />
+                            </el-form-item>
+                            <el-form-item label="库存数量" prop="singleSkuStock">
+                                <el-input-number v-model="form.singleSkuStock" :min="0" :step="1" />
                             </el-form-item>
                         </template>
-                        <el-form-item label="是否余额支付" prop="isBalancePay">
-                            <el-radio-group v-model="form.isBalancePay" size="small">
-                                <el-radio-button v-for="dict in dict.type.sys_yes_no" :label="dict.value" :key="dict.code">{{ dict.label }}</el-radio-button>
+
+                        <!-- 多规格设置 -->
+                        <template v-if="skuType === 1">
+                            <!-- 规格项设置 -->
+                            <div class="spec-group" v-for="(spec, index) in form.specList" :key="index">
+                                <el-row :gutter="10">
+                                    <el-col :span="8">
+                                        <el-form-item :label="'规格项' + (index + 1)">
+                                            <el-input v-model="spec.name" placeholder="如: 颜色、尺码" />
+                                        </el-form-item>
+                                    </el-col>
+                                    <el-col :span="14">
+                                        <el-form-item label="规格值">
+                                            <el-tag
+                                                :key="tag"
+                                                v-for="tag in spec.values"
+                                                closable
+                                                :disable-transitions="false"
+                                                @close="handleRemoveSpecValue(spec.values, tag)">
+                                                {{tag}}
+                                            </el-tag>
+                                            <el-input
+                                                class="input-new-tag"
+                                                v-if="spec.inputVisible"
+                                                v-model="spec.inputValue"
+                                                ref="saveTagInput"
+                                                size="small"
+                                                @keyup.enter.native="handleInputConfirm(spec)"
+                                                @blur="handleInputConfirm(spec)">
+                                            </el-input>
+                                            <el-button v-else class="button-new-tag" size="small" @click="showInput(spec)">
+                                                + 添加规格值
+                                            </el-button>
+                                        </el-form-item>
+                                    </el-col>
+                                    <el-col :span="2">
+                                        <el-button type="text" @click="removeSpec(index)" icon="el-icon-delete">删除</el-button>
+                                    </el-col>
+                                </el-row>
+                            </div>
+                            
+                            <el-button type="primary" plain @click="addSpec">添加规格项</el-button>
+
+                            <!-- 规格组合列表 -->
+                            <el-table :data="form.skuList" border style="margin-top: 20px">
+                                <el-table-column 
+                                    v-for="(spec, index) in form.specList" 
+                                    :key="index"
+                                    :label="spec.name"
+                                    align="center">
+                                    <template slot-scope="scope">
+                                        {{scope.row.specs[index]}}
+                                    </template>
+                                </el-table-column>
+                                <el-table-column label="销售价格" align="center" width="150">
+                                    <template slot-scope="scope">
+                                        <el-input-number 
+                                            v-model="scope.row.price" 
+                                            :precision="2" 
+                                            :step="0.1"
+                                            :min="0"
+                                            controls-position="right"
+                                            size="mini" />
+                                    </template>
+                                </el-table-column>
+                                <el-table-column label="库存" align="center" width="150">
+                                    <template slot-scope="scope">
+                                        <el-input-number 
+                                            v-model="scope.row.stock" 
+                                            :min="0"
+                                            :step="1"
+                                            controls-position="right"
+                                            size="mini" />
+                                    </template>
+                                </el-table-column>
+                            </el-table>
+                        </template>
+                    </el-tab-pane>
+
+                    <!-- 其他设置 tab -->
+                    <el-tab-pane label="其他设置" name="other">
+                        <el-form-item label="促销标识" prop="isSell">
+                            <el-radio-group v-model="form.isSell">
+                                <el-radio-button v-for="dict in dict.type.sys_yes_no" :label="dict.value" :key="dict.code">
+                                    {{dict.label}}
+                                </el-radio-button>
                             </el-radio-group>
                         </el-form-item>
-                        <!--                        <el-form-item label="是否现金支付" prop="isCashPay">-->
-                        <!--                            <el-radio-group v-model="form.isCashPay" size="small">-->
-                        <!--                                <el-radio-button v-for="dict in dict.type.sys_yes_no" :label="dict.value" :key="dict.code">{{ dict.label }}</el-radio-button>-->
-                        <!--                            </el-radio-group>-->
-                        <!--                        </el-form-item>-->
-                        <!--                        <template v-if="form.isCashPay === 'Y'">-->
-                        <!--                            <el-form-item label="现金金额" prop="cashMoney">-->
-                        <!--                                <el-input v-model="form.cashMoney" placeholder="请输入金额" />-->
-                        <!--                            </el-form-item>-->
-                        <!--                        </template>-->
-                        <el-form-item label="上传图片" prop="goodsImg">
-                            <image-upload v-model="form.goodsImg" />
-                        </el-form-item>
-                        <el-form-item label="上传图片集" prop="goodsImgs">
-                            <image-upload v-model="form.goodsImgs" :limit="limit" />
+
+                        <el-form-item label="余额支付" prop="isBalancePay">
+                            <el-radio-group v-model="form.isBalancePay">
+                                <el-radio-button v-for="dict in dict.type.sys_yes_no" :label="dict.value" :key="dict.code">
+                                    {{dict.label}}
+                                </el-radio-button>
+                            </el-radio-group>
                         </el-form-item>
+
                         <el-form-item label="显示顺序" prop="sort">
-                            <el-input-number v-model="form.sort" placeholder="请输入显示顺序(升序排列显示)" :min="0" :step-strictly="true" :style="{ width: '100%' }"> </el-input-number>
-                        </el-form-item>
-                        <el-form-item label="商品简介" prop="goodsSynopsis">
-                            <editor v-model="form.goodsSynopsis" :min-height="192" />
+                            <el-input-number v-model="form.sort" :min="0" :step="1" />
                         </el-form-item>
-                    </el-col>
-                </el-form>
-            </el-row>
+                    </el-tab-pane>
+                </el-tabs>
+            </el-form>
 
             <div slot="footer" class="dialog-footer">
-                <el-button type="primary" @click="submitForm" style="margin-left: 5%">提交</el-button>
+                <el-button type="primary" @click="submitForm">确 定</el-button>
                 <el-button @click="cancel">取 消</el-button>
             </div>
         </el-dialog>
@@ -191,7 +303,31 @@ export default {
                 goodsType: null
             },
             // 表单参数
-            form: {},
+            form: {
+                id: null,
+                goodsName: null,
+                goodsCategoryId: null,
+                goodsSynopsis: null,
+                brandId: null,
+                goodsImg: null,
+                goodsImgs: [],
+                goodsCode: null,
+                isSell: 'N',
+                isCashPay: 'Y',
+                cashMoney: null,
+                isBalancePay: 'Y',
+                createBy: null,
+                createById: null,
+                createTime: null,
+                updateBy: null,
+                updateById: null,
+                updateTime: null,
+                remark: null,
+                specList: [],
+                skuList: [],
+                singleSkuPrice: 0,
+                singleSkuStock: 0
+            },
             // 表单校验
             rules: {
                 goodsName: [
@@ -275,7 +411,9 @@ export default {
             categoryList: {},
             brandList: {},
             goodsType: '',
-            limit: 9
+            limit: 9,
+            activeTab: 'basic',
+            skuType: 0
         }
     },
     created() {
@@ -333,7 +471,11 @@ export default {
                 updateBy: null,
                 updateById: null,
                 updateTime: null,
-                remark: null
+                remark: null,
+                specList: [],
+                skuList: [],
+                singleSkuPrice: 0,
+                singleSkuStock: 0
             }
             this.resetForm('form')
         },
@@ -380,22 +522,30 @@ export default {
         },
         /** 提交按钮 */
         submitForm() {
-            this.$refs['form'].validate((valid) => {
+            this.$refs['form'].validate(valid => {
                 if (valid) {
-                    if (this.form.isCashPay != 'Y') {
-                        this.form.cashMoney = '0'
+                    const formData = { ...this.form }
+                    
+                    // 处理SKU数据
+                    if (this.skuType === 0) {
+                        formData.skuList = [{
+                            specs: [],
+                            price: this.form.singleSkuPrice,
+                            stock: this.form.singleSkuStock
+                        }]
+                    } else {
+                        formData.skuList = this.form.skuList
                     }
-                    this.form.goodsType = this.goodsType
-                    if (this.form.id != null) {
-                        updateGoods(this.form).then((response) => {
+                    
+                    // 提交数据
+                    if (formData.id) {
+                        updateGoods(formData).then(response => {
                             this.$modal.msgSuccess('修改成功')
                             this.open = false
                             this.getList()
                         })
                     } else {
-                        this.form.status = '0'
-                        this.form.delFlag = '0'
-                        addGoods(this.form).then((response) => {
+                        addGoods(formData).then(response => {
                             this.$modal.msgSuccess('新增成功')
                             this.open = false
                             this.getList()
@@ -513,7 +663,118 @@ export default {
         },
         gotoComment(row) {
             this.$router.push({ path: `/platform/goodsComment/appGoodsComment?goodsType=${this.goodsType}&goodsId=${row.id}` })
+        },
+        handleSkuTypeChange(val) {
+            if (val === 0) {
+                this.form.specList = []
+                this.form.skuList = []
+            } else {
+                // 如果已有规格数据,重新生成组合
+                if (this.form.specList.length > 0) {
+                    this.generateSkuList()
+                }
+            }
+        },
+        addSpec() {
+            this.form.specList.push({
+                name: '',
+                values: [],
+                inputVisible: false,
+                inputValue: ''
+            })
+        },
+        removeSpec(index) {
+            this.form.specList.splice(index, 1)
+            this.$nextTick(() => {
+                this.generateSkuList()
+            })
+        },
+        handleRemoveSpecValue(values, tag) {
+            values.splice(values.indexOf(tag), 1)
+            this.$nextTick(() => {
+                this.generateSkuList()
+            })
+        },
+        showInput(spec) {
+            spec.inputVisible = true
+            this.$nextTick(_ => {
+                this.$refs.saveTagInput.$refs.input.focus()
+            })
+        },
+        handleInputConfirm(spec) {
+            let inputValue = spec.inputValue
+            if (inputValue && spec.values.indexOf(inputValue) === -1) {
+                spec.values.push(inputValue)
+                this.$nextTick(() => {
+                    this.generateSkuList()
+                })
+            }
+            spec.inputVisible = false
+            spec.inputValue = ''
+        },
+        generateSkuList() {
+            const specs = this.form.specList
+            if (specs.length === 0 || specs.some(spec => spec.values.length === 0)) {
+                this.form.skuList = []
+                return
+            }
+            
+            // 获取所有规格值的组合
+            const values = specs.map(spec => spec.values)
+            const combinations = this.cartesianProduct(values)
+            
+            // 保存现有的价格和库存数据
+            const existingSkus = this.form.skuList || []
+            
+            // 生成新的SKU列表,保留已存在的价格和库存
+            this.form.skuList = combinations.map(specs => {
+                // 查找是否存在相同规格的旧数据
+                const existingSku = existingSkus.find(old => 
+                    JSON.stringify(old.specs) === JSON.stringify(specs)
+                )
+                
+                return {
+                    specs,
+                    price: existingSku ? existingSku.price : 0,
+                    stock: existingSku ? existingSku.stock : 0
+                }
+            })
+        },
+        cartesianProduct(arrays) {
+            return arrays.reduce((a, b) => {
+                return a.map(x => {
+                    return b.map(y => {
+                        return Array.isArray(x) ? [...x, y] : [x, y]
+                    })
+                }).flat()
+            }, [[]])
         }
     }
 }
 </script>
+
+<style lang="scss" scoped>
+.spec-group {
+    padding: 10px;
+    border: 1px solid #EBEEF5;
+    margin-bottom: 10px;
+}
+
+.el-tag + .el-tag {
+    margin-left: 10px;
+}
+
+.button-new-tag {
+    margin-left: 10px;
+    height: 32px;
+    line-height: 30px;
+    padding-top: 0;
+    padding-bottom: 0;
+}
+
+.input-new-tag {
+    width: 90px;
+    margin-left: 10px;
+    vertical-align: bottom;
+}
+</style>