Procházet zdrojové kódy

卓美审核原因优化

yjwang před 2 týdny
rodič
revize
4ab737e2c5

+ 39 - 0
src/api/hisStore/productDiscount.js

@@ -0,0 +1,39 @@
+import request from '@/utils/request'
+
+export function listProductDiscount(query) {
+  return request({
+    url: '/store/store/productDiscount/list',
+    method: 'get',
+    params: query
+  })
+}
+
+export function getProductDiscount(id) {
+  return request({
+    url: '/store/store/productDiscount/' + id,
+    method: 'get'
+  })
+}
+
+export function addProductDiscount(data) {
+  return request({
+    url: '/store/store/productDiscount',
+    method: 'post',
+    data: data
+  })
+}
+
+export function updateProductDiscount(data) {
+  return request({
+    url: '/store/store/productDiscount',
+    method: 'put',
+    data: data
+  })
+}
+
+export function delProductDiscount(id) {
+  return request({
+    url: '/store/store/productDiscount/' + id,
+    method: 'delete'
+  })
+}

+ 39 - 0
src/api/hisStore/productFlashSale.js

@@ -0,0 +1,39 @@
+import request from '@/utils/request'
+
+export function listProductFlashSale(query) {
+  return request({
+    url: '/store/store/productFlashSale/list',
+    method: 'get',
+    params: query
+  })
+}
+
+export function getProductFlashSale(id) {
+  return request({
+    url: '/store/store/productFlashSale/' + id,
+    method: 'get'
+  })
+}
+
+export function addProductFlashSale(data) {
+  return request({
+    url: '/store/store/productFlashSale',
+    method: 'post',
+    data: data
+  })
+}
+
+export function updateProductFlashSale(data) {
+  return request({
+    url: '/store/store/productFlashSale',
+    method: 'put',
+    data: data
+  })
+}
+
+export function delProductFlashSale(id) {
+  return request({
+    url: '/store/store/productFlashSale/' + id,
+    method: 'delete'
+  })
+}

+ 528 - 0
src/views/hisStore/productDiscount/index.vue

@@ -0,0 +1,528 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="90px">
+      <el-form-item label="商品名称" prop="productName">
+        <el-input
+          v-model="queryParams.productName"
+          placeholder="请输入商品名称"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="状态" prop="status">
+        <el-select v-model="queryParams.status" placeholder="请选择状态" clearable size="small">
+          <el-option label="上架" :value="1"/>
+          <el-option label="下架" :value="0"/>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="活动时间" prop="timeRange">
+        <el-date-picker
+          v-model="queryParams.timeRange"
+          type="datetimerange"
+          range-separator="-"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期"
+          value-format="yyyy-MM-dd HH:mm:ss"
+          size="small"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="cyan" 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" icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['store:productDiscount:add']">新增</el-button>
+      </el-col>
+<!--      <el-col :span="1.5">-->
+<!--        <el-button type="warning" icon="el-icon-download" size="mini" @click="handleExport" v-hasPermi="['store:productDiscount:export']">导出</el-button>-->
+<!--      </el-col>-->
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="list" border>
+      <el-table-column label="序号" type="index" width="55" align="center" />
+      <el-table-column label="商品信息" align="center" min-width="200">
+        <template slot-scope="scope">
+          <div style="display:flex;align-items:center;">
+            <el-image v-if="scope.row.productImage" style="width:50px;height:50px;margin-right:10px;" :src="scope.row.productImage" fit="contain" :preview-src-list="[scope.row.productImage]"/>
+            <span>{{ scope.row.productName || '-' }}</span>
+          </div>
+        </template>
+      </el-table-column>
+      <el-table-column label="原价" align="center" prop="originalPrice" width="100">
+        <template slot-scope="scope">
+          <span v-if="scope.row.originalPrice != null">¥{{ scope.row.originalPrice.toFixed(2) }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="折扣" align="center" prop="discount" width="80">
+        <template slot-scope="scope">
+          <span>{{ (scope.row.discount * 10).toFixed(1) }}折</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="折扣价格" align="center" prop="discountPrice" width="110">
+        <template slot-scope="scope">
+          <span style="color:#f56c6c;font-weight:bold;">¥{{ scope.row.discountPrice ? scope.row.discountPrice.toFixed(2) : '0.00' }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="库存" align="center" prop="stock" width="80" />
+      <el-table-column label="开始时间" align="center" prop="startTime" width="160">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.startTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="结束时间" align="center" prop="endTime" width="160">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.endTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="状态" align="center" prop="status" width="80">
+        <template slot-scope="scope">
+          <el-tag v-if="scope.row.status === 1" type="success">上架</el-tag>
+          <el-tag v-else type="info">下架</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="180">
+        <template slot-scope="scope">
+          <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['store:productDiscount:edit']">编辑</el-button>
+          <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['store:productDiscount: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-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
+      <el-alert
+        v-if="!form.id && selectedProducts.length === 0"
+        title="提示:可批量选择多个商品,统一设置折扣信息后一键添加"
+        type="info"
+        :closable="false"
+        show-icon
+        style="margin-bottom:15px;"
+      />
+
+      <el-form ref="form" :model="form" :rules="rules" label-width="100px">
+        <!-- 批量选择商品 -->
+        <el-form-item label="选择商品" prop="productIds" v-if="!form.id">
+          <el-select
+            v-model="selectedProducts"
+            multiple
+            filterable
+            remote
+            reserve-keyword
+            placeholder="请输入商品名称搜索,可多选"
+            :remote-method="searchProduct"
+            :loading="productLoading"
+            style="width:100%"
+            collapse-tags
+            collapse-tags-tooltip
+          >
+            <el-option
+              v-for="item in productOptions"
+              :key="item.productId"
+              :label="item.productName"
+              :value="item.productId"
+              :disabled="isProductSelected(item.productId)"
+            >
+              <div style="display:flex;justify-content:space-between;align-items:center;">
+                <span style="float:left">{{ item.productName }}</span>
+                <span style="float:right;color:#8492a6;font-size:12px;margin-left:15px;">ID:{{ item.productId }} | ¥{{ item.price || item.originalPrice || '-' }}</span>
+              </div>
+            </el-option>
+          </el-select>
+          <div style="color:#909399;font-size:12px;margin-top:5px;" v-if="selectedProducts.length > 0">
+            已选择 {{ selectedProducts.length }} 个商品
+          </div>
+        </el-form-item>
+
+        <!-- 编辑模式显示单个商品 -->
+        <el-form-item label="选择商品" prop="productId" v-if="form.id">
+          <el-select
+            v-model="form.productId"
+            filterable
+            remote
+            reserve-keyword
+            placeholder="请输入商品名称搜索"
+            :remote-method="searchProduct"
+            :loading="productLoading"
+            style="width:100%"
+            disabled
+          >
+            <el-option v-for="item in productOptions" :key="item.productId" :label="item.productName" :value="item.productId"/>
+          </el-select>
+        </el-form-item>
+
+        <!-- 公共设置项 -->
+        <el-divider content-position="left">折扣设置(以下设置将应用于所有选中商品)</el-divider>
+
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="原价" prop="originalPrice">
+              <el-input-number v-model="form.originalPrice" :precision="2" :min="0" placeholder="请输入原价" style="width:100%" @change="handleOriginalPriceChange"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="库存" prop="stock">
+              <el-input-number v-model="form.stock" :min="0" placeholder="请输入库存数量" style="width:100%"/>
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <!-- 折扣滑块:支持小数步长 0.1 -->
+        <el-form-item label="折扣" prop="discount" class="discount-slider-item">
+          <el-slider
+            v-model="form.discountValue"
+            :marks="discountMarks"
+            :min="1"
+            :max="10"
+            :step="0.1"
+            show-input
+            @change="handleDiscountChange"
+          />
+        </el-form-item>
+
+        <el-form-item label="折扣价格" prop="discountPrice">
+          <el-input-number v-model="form.discountPrice" :precision="2" :min="0" placeholder="自动计算或手动输入" style="width:100%" @change="handleDiscountPriceChange"/>
+        </el-form-item>
+
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="开始时间" prop="startTime">
+              <el-date-picker v-model="form.startTime" type="datetime" placeholder="选择开始时间" value-format="yyyy-MM-dd HH:mm:ss" style="width:100%"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="结束时间" prop="endTime">
+              <el-date-picker v-model="form.endTime" type="datetime" placeholder="选择结束时间" value-format="yyyy-MM-dd HH:mm:ss" style="width:100%"/>
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-form-item label="状态" prop="status">
+          <el-radio-group v-model="form.status">
+            <el-radio :label="1">上架</el-radio>
+            <el-radio :label="0">下架</el-radio>
+          </el-radio-group>
+        </el-form-item>
+
+        <el-form-item label="备注" prop="remark">
+          <el-input v-model="form.remark" type="textarea" placeholder="请输入备注" :rows="3"/>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm" :loading="submitLoading">{{ form.id ? '确 定' : `确 定 (${selectedProducts.length}个商品)` }}</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  addProductDiscount,
+  delProductDiscount,
+  getProductDiscount,
+  listProductDiscount,
+  updateProductDiscount
+} from '@/api/hisStore/productDiscount'
+import { getStoreProduct, listStoreProduct } from '@/api/hisStore/storeProduct'
+
+export default {
+  name: 'ProductDiscount',
+  data() {
+    return {
+      loading: true,
+      showSearch: true,
+      list: [],
+      total: 0,
+      title: '',
+      open: false,
+      submitLoading: false,
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        productName: null,
+        status: null,
+        timeRange: null,
+        beginTime: null,
+        endTime: null
+      },
+      form: {},
+      rules: {
+        originalPrice: [{ required: true, message: '请输入原价', trigger: 'blur' }],
+        discount: [{ required: true, message: '请设置折扣', trigger: 'change' }],
+        discountPrice: [{ required: true, message: '请输入折扣价格', trigger: 'blur' }],
+        stock: [{ required: true, message: '请输入库存', trigger: 'blur' }],
+        startTime: [{ required: true, message: '请选择开始时间', trigger: 'change' }],
+        endTime: [{ required: true, message: '请选择结束时间', trigger: 'change' }],
+        status: [{ required: true, message: '请选择状态', trigger: 'change' }]
+      },
+      productLoading: false,
+      productOptions: [],
+      selectedProducts: [],
+      discountMarks: {
+        1: '1折',
+        5: '5折',
+        10: '不打折'
+      }
+    }
+  },
+  watch: {
+    'form.discountValue': {
+      handler(newVal) {
+        if (newVal !== undefined && newVal !== null) {
+          this.form.discount = newVal / 10
+          this.$nextTick(() => {
+            this.calcDiscountPrice()
+          })
+        }
+      },
+      immediate: true
+    }
+  },
+  created() {
+    this.getList()
+  },
+  methods: {
+    getList() {
+      this.loading = true
+      const params = { ...this.queryParams }
+      if (this.queryParams.timeRange && this.queryParams.timeRange.length === 2) {
+        params.beginTime = this.queryParams.timeRange[0]
+        params.endTime = this.queryParams.timeRange[1]
+      }
+      delete params.timeRange
+      listProductDiscount(params).then(response => {
+        this.list = response.rows || []
+        this.total = response.total || 0
+        this.loading = false
+      })
+    },
+
+    searchProduct(query) {
+      if (query !== '') {
+        this.productLoading = true
+        listStoreProduct({ productName: query, isDel: 0, pageSize: 50 }).then(response => {
+          const currentSelected = this.selectedProducts.map(id =>
+            this.productOptions.find(p => p.productId === id)
+          ).filter(Boolean)
+          this.productOptions = [...currentSelected, ...(response.rows || [])]
+          this.productLoading = false
+        })
+      } else {
+        if (this.selectedProducts.length > 0) {
+          this.productOptions = this.selectedProducts.map(id =>
+            this.productOptions.find(p => p.productId === id)
+          ).filter(Boolean)
+        } else {
+          this.productOptions = []
+        }
+      }
+    },
+
+    isProductSelected(productId) {
+      return this.selectedProducts.includes(productId)
+    },
+
+    handleOriginalPriceChange(val) {
+      console.log('原价变化:', val)
+      this.calcDiscountPrice()
+    },
+
+    handleDiscountChange(val) {
+      console.log('折扣滑块变化:', val)
+      this.form.discount = this.form.discountValue / 10
+      this.calcDiscountPrice()
+    },
+
+    handleDiscountPriceChange(val) {
+      console.log('折扣价格变化:', val)
+      if (this.form.originalPrice && this.form.originalPrice > 0 && val >= 0) {
+        const newDiscount = parseFloat((val / this.form.originalPrice).toFixed(4))
+        if (newDiscount >= 0.1 && newDiscount <= 1) {
+          this.form.discountValue = newDiscount * 10
+          this.form.discount = newDiscount
+        }
+      }
+    },
+
+    calcDiscountPrice() {
+      if (this.form.originalPrice && this.form.originalPrice > 0 && this.form.discount !== undefined && this.form.discount !== null) {
+        if (this.form.discount >= 1) {
+          this.form.discountPrice = this.form.originalPrice
+        } else {
+          console.log("折扣价格-------》",parseFloat((this.form.originalPrice * this.form.discount).toFixed(2)))
+          this.form.discountPrice = parseFloat((this.form.originalPrice * this.form.discount).toFixed(2))
+        }
+        console.log('计算结果 - 原价:', this.form.originalPrice, '折扣:', this.form.discount, '价格:', this.form.discountPrice)
+      } else {
+        if (!this.form.originalPrice || this.form.originalPrice <= 0) {
+          this.form.discountPrice = null
+        }
+      }
+    },
+
+    cancel() {
+      this.open = false
+      this.reset()
+    },
+
+    reset() {
+      this.form = {
+        id: null,
+        productId: null,
+        stock: 0,
+        originalPrice: null,
+        discount: 1,
+        discountValue: 10,
+        discountPrice: null,
+        startTime: null,
+        endTime: null,
+        status: 1,
+        remark: null
+      }
+      this.selectedProducts = []
+      this.productOptions = []
+      this.submitLoading = false
+      this.resetForm('form')
+    },
+
+    handleQuery() {
+      this.queryParams.pageNum = 1
+      this.getList()
+    },
+
+    resetQuery() {
+      this.resetForm('queryForm')
+      this.handleQuery()
+    },
+
+    handleAdd() {
+      this.reset()
+      this.open = true
+      this.title = '批量添加限时折扣'
+    },
+
+    handleUpdate(row) {
+      this.reset()
+      getProductDiscount(row.id).then(response => {
+        this.form = response.data
+        if (this.form.discount) {
+          this.form.discountValue = this.form.discount * 10
+        }
+        if (this.form.productId) {
+          getStoreProduct(this.form.productId).then(res => {
+            if (res.data) {
+              this.productOptions = [res.data]
+            }
+          })
+        }
+        this.selectedProducts = [this.form.productId]
+        this.open = true
+        this.title = '编辑限时折扣'
+      })
+    },
+
+    handleDelete(row) {
+      const ids = row.id
+      this.$confirm('是否确认删除限时折扣编号为"' + ids + '"的数据项?', '警告', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        return delProductDiscount(ids)
+      }).then(() => {
+        this.getList()
+        this.msgSuccess('删除成功')
+      }).catch(() => {})
+    },
+
+    handleExport() {
+      this.download('/store/store/productDiscount/export', {
+        ...this.queryParams
+      }, `productDiscount_${new Date().getTime()}.xlsx`)
+    },
+
+    async submitForm() {
+      if (!this.form.id && this.selectedProducts.length === 0) {
+        this.msgError('请至少选择一个商品')
+        return
+      }
+
+      try {
+        await this.$refs['form'].validate()
+
+        this.submitLoading = true
+
+        if (this.form.id) {
+          const submitData = { ...this.form }
+          delete submitData.discountValue
+          delete submitData.productIds
+
+          await updateProductDiscount(submitData)
+          this.msgSuccess('修改成功')
+          this.open = false
+          this.getList()
+        } else {
+          const baseData = { ...this.form }
+          delete baseData.id
+          delete baseData.productId
+          delete baseData.discountValue
+          delete baseData.productIds
+
+          const promises = this.selectedProducts.map(productId => {
+            const productData = {
+              ...baseData,
+              productId: productId
+            }
+            return addProductDiscount(productData)
+          })
+
+          await Promise.all(promises)
+          this.msgSuccess(`成功添加 ${this.selectedProducts.length} 个限时折扣商品`)
+          this.open = false
+          this.getList()
+        }
+
+        this.submitLoading = false
+      } catch (error) {
+        console.error('提交失败:', error)
+        this.submitLoading = false
+        if (error !== 'cancel') {
+          this.msgError(error.message || '操作失败,请重试')
+        }
+      }
+    }
+  }
+}
+</script>
+
+<style scoped>
+.discount-slider-item >>> .el-slider {
+  overflow: visible;
+  margin: 0 10px;
+}
+.discount-slider-item >>> .el-slider__marks-text {
+  white-space: nowrap;
+  font-size: 12px;
+  transform: translateX(-50%) scale(0.95);
+  min-width: 40px;
+  text-align: center;
+}
+.discount-slider-item >>> .el-slider__marks {
+  height: 30px;
+}
+
+/* 多选下拉框优化 */
+>>> .el-select .el-tag {
+  max-width: 150px;
+}
+>>> .el-select .el-tag__close {
+  margin-left: 4px;
+}
+</style>

+ 347 - 0
src/views/hisStore/productFlashSale/index.vue

@@ -0,0 +1,347 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="90px">
+      <el-form-item label="商品名称" prop="productName">
+        <el-input
+          v-model="queryParams.productName"
+          placeholder="请输入商品名称"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="状态" prop="status">
+        <el-select v-model="queryParams.status" placeholder="请选择状态" clearable size="small">
+          <el-option label="上架" :value="1"/>
+          <el-option label="下架" :value="0"/>
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="cyan" 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" icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['store:productFlashSale:add']">新增</el-button>
+      </el-col>
+<!--      <el-col :span="1.5">-->
+<!--        <el-button type="warning" icon="el-icon-download" size="mini" @click="handleExport" v-hasPermi="['store:productFlashSale:export']">导出</el-button>-->
+<!--      </el-col>-->
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="list" border>
+      <el-table-column label="序号" type="index" width="55" align="center" />
+      <el-table-column label="商品信息" align="center" min-width="200">
+        <template slot-scope="scope">
+          <div style="display:flex;align-items:center;">
+            <el-image v-if="scope.row.productImage" style="width:50px;height:50px;margin-right:10px;" :src="scope.row.productImage" fit="contain" :preview-src-list="[scope.row.productImage]"/>
+            <span>{{ scope.row.productName || '-' }}</span>
+          </div>
+        </template>
+      </el-table-column>
+      <el-table-column label="原价" align="center" prop="originalPrice" width="100">
+        <template slot-scope="scope">
+          <span v-if="scope.row.originalPrice != null">¥{{ scope.row.originalPrice.toFixed(2) }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="秒杀价" align="center" prop="flashPrice" width="110">
+        <template slot-scope="scope">
+          <span style="color:#f56c6c;font-weight:bold;">¥{{ scope.row.flashPrice ? scope.row.flashPrice.toFixed(2) : '0.00' }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="库存" align="center" prop="stock" width="80" />
+      <el-table-column label="开始时间" align="center" prop="startTime" width="160">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.startTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="结束时间" align="center" prop="endTime" width="160">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.endTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="状态" align="center" prop="status" width="80">
+        <template slot-scope="scope">
+          <el-tag v-if="scope.row.status === 1" type="success">上架</el-tag>
+          <el-tag v-else type="info">下架</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="180">
+        <template slot-scope="scope">
+          <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['store:productFlashSale:edit']">编辑</el-button>
+          <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['store:productFlashSale: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-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="100px">
+        <el-form-item label="选择商品" prop="productId" v-if="!form.id">
+          <el-select
+            v-model="form.productId"
+            filterable
+            remote
+            reserve-keyword
+            placeholder="请输入商品名称搜索"
+            :remote-method="searchProduct"
+            :loading="productLoading"
+            style="width:100%"
+          >
+            <el-option
+              v-for="item in productOptions"
+              :key="item.productId"
+              :label="item.productName"
+              :value="item.productId"
+            >
+              <div style="display:flex;justify-content:space-between;align-items:center;">
+                <span style="float:left">{{ item.productName }}</span>
+                <span style="float:right;color:#8492a6;font-size:12px;margin-left:15px;">ID:{{ item.productId }} | ¥{{ item.price || item.originalPrice || '-' }}</span>
+              </div>
+            </el-option>
+          </el-select>
+        </el-form-item>
+
+        <el-form-item label="选择商品" v-if="form.id">
+          <el-select
+            v-model="form.productId"
+            filterable
+            remote
+            reserve-keyword
+            placeholder="请输入商品名称搜索"
+            :remote-method="searchProduct"
+            :loading="productLoading"
+            style="width:100%"
+            disabled
+          >
+            <el-option v-for="item in productOptions" :key="item.productId" :label="item.productName" :value="item.productId"/>
+          </el-select>
+        </el-form-item>
+
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="原价" prop="originalPrice">
+              <el-input-number v-model="form.originalPrice" :precision="2" :min="0" placeholder="请输入原价" style="width:100%"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="秒杀价" prop="flashPrice">
+              <el-input-number v-model="form.flashPrice" :precision="2" :min="0" placeholder="请输入秒杀价" style="width:100%"/>
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="库存" prop="stock">
+              <el-input-number v-model="form.stock" :min="0" placeholder="请输入库存数量" style="width:100%"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="状态" prop="status">
+              <el-radio-group v-model="form.status">
+                <el-radio :label="1">上架</el-radio>
+                <el-radio :label="0">下架</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="开始时间" prop="startTime">
+              <el-date-picker v-model="form.startTime" type="datetime" placeholder="选择开始时间" value-format="yyyy-MM-dd HH:mm:ss" style="width:100%"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="结束时间" prop="endTime">
+              <el-date-picker v-model="form.endTime" type="datetime" placeholder="选择结束时间" value-format="yyyy-MM-dd HH:mm:ss" style="width:100%"/>
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-form-item label="备注" prop="remark">
+          <el-input v-model="form.remark" type="textarea" placeholder="请输入备注" :rows="3"/>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm" :loading="submitLoading">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  addProductFlashSale,
+  delProductFlashSale,
+  getProductFlashSale,
+  listProductFlashSale,
+  updateProductFlashSale
+} from '@/api/hisStore/productFlashSale'
+import { getStoreProduct, listStoreProduct } from '@/api/hisStore/storeProduct'
+
+export default {
+  name: 'ProductFlashSale',
+  data() {
+    return {
+      loading: true,
+      showSearch: true,
+      list: [],
+      total: 0,
+      title: '',
+      open: false,
+      submitLoading: false,
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        productName: null,
+        status: null
+      },
+      form: {},
+      rules: {
+        productId: [{ required: true, message: '请选择商品', trigger: 'change' }],
+        originalPrice: [{ required: true, message: '请输入原价', trigger: 'blur' }],
+        flashPrice: [{ required: true, message: '请输入秒杀价', trigger: 'blur' }],
+        stock: [{ required: true, message: '请输入库存', trigger: 'blur' }],
+        startTime: [{ required: true, message: '请选择开始时间', trigger: 'change' }],
+        endTime: [{ required: true, message: '请选择结束时间', trigger: 'change' }],
+        status: [{ required: true, message: '请选择状态', trigger: 'change' }]
+      },
+      productLoading: false,
+      productOptions: []
+    }
+  },
+  created() {
+    this.getList()
+  },
+  methods: {
+    getList() {
+      this.loading = true
+      listProductFlashSale(this.queryParams).then(response => {
+        this.list = response.rows || []
+        this.total = response.total || 0
+        this.loading = false
+      })
+    },
+
+    searchProduct(query) {
+      if (query !== '') {
+        this.productLoading = true
+        listStoreProduct({ productName: query, isDel: 0, pageSize: 50 }).then(response => {
+          this.productOptions = response.rows || []
+          this.productLoading = false
+        })
+      } else {
+        this.productOptions = []
+      }
+    },
+
+    cancel() {
+      this.open = false
+      this.reset()
+    },
+
+    reset() {
+      this.form = {
+        id: null,
+        productId: null,
+        originalPrice: null,
+        flashPrice: null,
+        stock: 0,
+        startTime: null,
+        endTime: null,
+        status: 1,
+        remark: null
+      }
+      this.productOptions = []
+      this.submitLoading = false
+      this.resetForm('form')
+    },
+
+    handleQuery() {
+      this.queryParams.pageNum = 1
+      this.getList()
+    },
+
+    resetQuery() {
+      this.resetForm('queryForm')
+      this.handleQuery()
+    },
+
+    handleAdd() {
+      this.reset()
+      this.open = true
+      this.title = '新增秒杀商品'
+    },
+
+    handleUpdate(row) {
+      this.reset()
+      getProductFlashSale(row.id).then(response => {
+        this.form = response.data
+        if (this.form.productId) {
+          getStoreProduct(this.form.productId).then(res => {
+            if (res.data) {
+              this.productOptions = [res.data]
+            }
+          })
+        }
+        this.open = true
+        this.title = '编辑秒杀商品'
+      })
+    },
+
+    handleDelete(row) {
+      const ids = row.id
+      this.$confirm('是否确认删除秒杀商品编号为"' + ids + '"的数据项?', '警告', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        return delProductFlashSale(ids)
+      }).then(() => {
+        this.getList()
+        this.msgSuccess('删除成功')
+      }).catch(() => {})
+    },
+
+    handleExport() {
+      this.download('/store/store/productFlashSale/export', {
+        ...this.queryParams
+      }, `productFlashSale_${new Date().getTime()}.xlsx`)
+    },
+
+    submitForm() {
+      this.$refs['form'].validate(valid => {
+        if (valid) {
+          this.submitLoading = true
+          if (this.form.id) {
+            updateProductFlashSale(this.form).then(() => {
+              this.msgSuccess('修改成功')
+              this.open = false
+              this.getList()
+              this.submitLoading = false
+            }).catch(() => {
+              this.submitLoading = false
+            })
+          } else {
+            addProductFlashSale(this.form).then(() => {
+              this.msgSuccess('新增成功')
+              this.open = false
+              this.getList()
+              this.submitLoading = false
+            }).catch(() => {
+              this.submitLoading = false
+            })
+          }
+        }
+      })
+    }
+  }
+}
+</script>

+ 2 - 2
src/views/hisStore/storeProduct/index.vue

@@ -47,7 +47,7 @@
           />
         </el-select>
       </el-form-item>
-      <el-form-item label="所属店铺" v-if="this.isStores">
+      <el-form-item label="" v-if="this.isStores">
         <el-select style="width: 240px" v-model="queryParams.storeIds" placeholder="请选择店铺" clearable size="small" >
           <el-option
             v-for="item in storeOptions"
@@ -890,7 +890,7 @@
             />
           </el-select>
         </el-form-item>
-        <el-form-item label="所属店铺" prop="storeId" v-if="this.isStores">
+        <el-form-item label="所属店铺" v-if="this.isStores">
           <el-select style="width: 240px" v-model="form.storeId" placeholder="请选择店铺" clearable size="small" >
             <el-option
               v-for="item in storeOptions"