ソースを参照

添加团购后台管理

Menethil 7 年 前
コミット
eec5e2227c

+ 176 - 0
litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminGrouponController.java

@@ -0,0 +1,176 @@
+package org.linlinjava.litemall.admin.web;
+
+import org.linlinjava.litemall.admin.annotation.LoginAdmin;
+import org.linlinjava.litemall.core.util.JacksonUtil;
+import org.linlinjava.litemall.core.util.ResponseUtil;
+import org.linlinjava.litemall.core.validator.Order;
+import org.linlinjava.litemall.core.validator.Sort;
+import org.linlinjava.litemall.db.domain.LitemallGoods;
+import org.linlinjava.litemall.db.domain.LitemallGroupon;
+import org.linlinjava.litemall.db.domain.LitemallGrouponRules;
+import org.linlinjava.litemall.db.service.LitemallGoodsService;
+import org.linlinjava.litemall.db.service.LitemallGrouponRulesService;
+import org.linlinjava.litemall.db.service.LitemallGrouponService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/admin/groupon")
+@Validated
+public class AdminGrouponController {
+    @Autowired
+    private LitemallGrouponRulesService rulesService;
+    @Autowired
+    private LitemallGoodsService goodsService;
+    @Autowired
+    private LitemallGrouponService grouponService;
+
+    @GetMapping("/listRecord")
+    public Object listRecord(@LoginAdmin Integer adminId,
+                             String grouponId,
+                             @RequestParam(defaultValue = "1") Integer page,
+                             @RequestParam(defaultValue = "10") Integer limit,
+                             @Sort @RequestParam(defaultValue = "add_time") String sort,
+                             @Order @RequestParam(defaultValue = "desc") String order) {
+        if (adminId == null) {
+            return ResponseUtil.unlogin();
+        }
+
+        List<LitemallGroupon> grouponList = grouponService.querySelective(grouponId, page, limit, sort, order);
+        int total = grouponService.countSelective(grouponId, page, limit, sort, order);
+
+        List<Map<String, Object>> records = new ArrayList<>();
+        for (LitemallGroupon groupon : grouponList) {
+            Map<String, Object> RecordData = new HashMap<>();
+            List<LitemallGroupon> subGrouponList = grouponService.queryJoiners(groupon.getId());
+            LitemallGrouponRules rules = rulesService.queryById(groupon.getRulesId());
+            LitemallGoods goods = goodsService.findById(rules.getGoodsId());
+
+            RecordData.put("groupon", groupon);
+            RecordData.put("subGroupons", subGrouponList);
+            RecordData.put("rules", rules);
+            RecordData.put("goods", goods);
+
+            records.add(RecordData);
+        }
+
+        Map<String, Object> data = new HashMap<>();
+        data.put("total", total);
+        data.put("items", records);
+
+        return ResponseUtil.ok(data);
+    }
+
+    @GetMapping("/list")
+    public Object list(@LoginAdmin Integer adminId,
+                       String goodsId,
+                       @RequestParam(defaultValue = "1") Integer page,
+                       @RequestParam(defaultValue = "10") Integer limit,
+                       @Sort @RequestParam(defaultValue = "add_time") String sort,
+                       @Order @RequestParam(defaultValue = "desc") String order) {
+        if (adminId == null) {
+            return ResponseUtil.unlogin();
+        }
+
+        List<LitemallGrouponRules> rulesList = rulesService.querySelective(goodsId, page, limit, sort, order);
+        int total = rulesService.countSelective(goodsId, page, limit, sort, order);
+        Map<String, Object> data = new HashMap<>();
+        data.put("total", total);
+        data.put("items", rulesList);
+
+        return ResponseUtil.ok(data);
+    }
+
+    @PostMapping("/update")
+    public Object update(@LoginAdmin Integer adminId, @RequestBody String grouponRulesBody) {
+        if (adminId == null) {
+            return ResponseUtil.unlogin();
+        }
+
+        Integer id = JacksonUtil.parseInteger(grouponRulesBody, "id");
+        Integer goodsId = JacksonUtil.parseInteger(grouponRulesBody, "goodsId");
+        String discount = JacksonUtil.parseString(grouponRulesBody, "discount");
+        Integer discountMember = JacksonUtil.parseInteger(grouponRulesBody, "discountMember");
+        String expireTimeString = JacksonUtil.parseString(grouponRulesBody, "expireTime");
+
+        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        LocalDateTime expireTime = LocalDateTime.parse(expireTimeString, df);
+
+        LitemallGoods goods = goodsService.findById(goodsId);
+        if (goods == null) {
+            return ResponseUtil.badArgumentValue();
+        }
+
+        LitemallGrouponRules grouponRules = rulesService.queryById(id);
+        if (grouponRules == null) {
+            return ResponseUtil.badArgumentValue();
+        }
+
+        grouponRules.setGoodsId(goodsId);
+        grouponRules.setDiscount(new BigDecimal(discount));
+        grouponRules.setDiscountMember(discountMember);
+        grouponRules.setGoodsName(goods.getName());
+        grouponRules.setExpireTime(expireTime);
+        grouponRules.setPicUrl(goods.getPicUrl());
+
+        rulesService.update(grouponRules);
+
+        return ResponseUtil.ok();
+    }
+
+
+    @PostMapping("/create")
+    public Object create(@LoginAdmin Integer adminId, @RequestBody String grouponRulesBody) {
+        if (adminId == null) {
+            return ResponseUtil.unlogin();
+        }
+
+        Integer goodsId = JacksonUtil.parseInteger(grouponRulesBody, "goodsId");
+        String discount = JacksonUtil.parseString(grouponRulesBody, "discount");
+        Integer discountMember = JacksonUtil.parseInteger(grouponRulesBody, "discountMember");
+        String expireTimeString = JacksonUtil.parseString(grouponRulesBody, "expireTime");
+
+        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        LocalDateTime expireTime = LocalDateTime.parse(expireTimeString, df);
+
+        LitemallGoods goods = goodsService.findById(goodsId);
+        if (goods == null) {
+            return ResponseUtil.badArgumentValue();
+        }
+
+        LitemallGrouponRules grouponRules = new LitemallGrouponRules();
+        grouponRules.setGoodsId(goodsId);
+        grouponRules.setDiscount(new BigDecimal(discount));
+        grouponRules.setDiscountMember(discountMember);
+        grouponRules.setAddTime(LocalDateTime.now());
+        grouponRules.setGoodsName(goods.getName());
+        grouponRules.setExpireTime(expireTime);
+        grouponRules.setPicUrl(goods.getPicUrl());
+
+        rulesService.createRules(grouponRules);
+
+        return ResponseUtil.ok();
+    }
+
+
+    @PostMapping("/delete")
+    public Object delete(@LoginAdmin Integer adminId, @RequestBody String body) {
+        if (adminId == null) {
+            return ResponseUtil.unlogin();
+        }
+
+        Integer id = JacksonUtil.parseInteger(body, "id");
+
+        rulesService.delete(id);
+        return ResponseUtil.ok();
+    }
+}

+ 41 - 0
litemall-admin/src/api/groupon.js

@@ -0,0 +1,41 @@
+import request from '@/utils/request'
+
+export function listRecord(query) {
+  return request({
+    url: '/groupon/listRecord',
+    method: 'get',
+    params: query
+  })
+}
+
+export function listGroupon(query) {
+  return request({
+    url: '/groupon/list',
+    method: 'get',
+    params: query
+  })
+}
+
+export function deleteGroupon(data) {
+  return request({
+    url: '/groupon/delete',
+    method: 'post',
+    data
+  })
+}
+
+export function publishGroupon(data) {
+  return request({
+    url: '/groupon/create',
+    method: 'post',
+    data
+  })
+}
+
+export function editGroupon(data) {
+  return request({
+    url: '/groupon/update',
+    method: 'post',
+    data
+  })
+}

+ 15 - 0
litemall-admin/src/router/index.js

@@ -106,6 +106,21 @@ export const asyncRouterMap = [
   },
 
   {
+    path: '/groupon',
+    component: Layout,
+    redirect: 'noredirect',
+    name: 'grouponManage',
+    meta: {
+      title: '团购管理',
+      icon: 'chart'
+    },
+    children: [
+      { path: 'list', component: _import('groupon/list'), name: 'list', meta: { title: '团购规则', noCache: true }},
+      { path: 'record', component: _import('groupon/record'), name: 'record', meta: { title: '团购活动', noCache: true }}
+    ]
+  },
+
+  {
     path: '/promotion',
     component: Layout,
     redirect: 'noredirect',

+ 290 - 0
litemall-admin/src/views/groupon/list.vue

@@ -0,0 +1,290 @@
+<template>
+  <div class="app-container calendar-list-container">
+
+    <!-- 查询和其他操作 -->
+    <div class="filter-container">
+      <el-input clearable class="filter-item" style="width: 200px;" placeholder="请输入商品编号" v-model="listQuery.goodsId">
+      </el-input>
+      <el-button class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">查找</el-button>
+      <el-button class="filter-item" type="primary" @click="handleCreate" icon="el-icon-edit">添加</el-button>
+      <el-button class="filter-item" type="primary" :loading="downloadLoading" icon="el-icon-download"
+                 @click="handleDownload">导出
+      </el-button>
+    </div>
+
+    <!-- 查询结果 -->
+    <el-table size="small" :data="list" v-loading="listLoading" element-loading-text="正在查询中。。。" border fit
+              highlight-current-row>
+
+      <el-table-column type="expand">
+        <template slot-scope="props">
+          <el-form label-position="left" class="table-expand">
+            <el-form-item label="宣传画廊">
+              <img class="gallery" v-for="pic in props.row.gallery" :key="pic" :src="pic"/>
+            </el-form-item>
+            <el-form-item label="商品介绍">
+              <span>{{ props.row.brief }}</span>
+            </el-form-item>
+            <el-form-item label="商品单位">
+              <span>{{ props.row.unit }}</span>
+            </el-form-item>
+            <el-form-item label="关键字">
+              <span>{{ props.row.keyword }}</span>
+            </el-form-item>
+            <el-form-item label="类目ID">
+              <span>{{ props.row.categoryId }}</span>
+            </el-form-item>
+            <el-form-item label="品牌商ID">
+              <span>{{ props.row.brandId }}</span>
+            </el-form-item>
+          </el-form>
+        </template>
+      </el-table-column>
+
+      <el-table-column align="center" label="商品ID" prop="goodsId">
+      </el-table-column>
+
+      <el-table-column align="center" min-width="100" label="名称" prop="goodsName">
+      </el-table-column>
+
+      <el-table-column align="center" property="iconUrl" label="图片">
+        <template slot-scope="scope">
+          <img :src="scope.row.picUrl" width="40"/>
+        </template>
+      </el-table-column>
+
+      <el-table-column align="center" label="团购优惠" prop="discount">
+      </el-table-column>
+
+      <el-table-column align="center" label="团购要求" prop="discountMember">
+      </el-table-column>
+
+      <el-table-column align="center" label="开始时间" prop="addTime">
+      </el-table-column>
+
+      <el-table-column align="center" label="结束时间" prop="expireTime">
+      </el-table-column>
+
+      <el-table-column align="center" label="操作" width="200" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button type="primary" size="mini" @click="handleUpdate(scope.row)">编辑</el-button>
+          <el-button type="danger" size="mini" @click="handleDelete(scope.row)">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <!-- 添加或修改对话框 -->
+    <el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
+      <el-form :rules="rules" ref="dataForm" :model="dataForm" status-icon label-position="left" label-width="100px"
+               style='width: 400px; margin-left:50px;'>
+        <el-form-item label="商品ID" prop="goodsId">
+          <el-input v-model="dataForm.goodsId"></el-input>
+        </el-form-item>
+        <el-form-item label="团购折扣" prop="discount">
+          <el-input v-model="dataForm.discount"></el-input>
+        </el-form-item>
+        <el-form-item label="团购人数要求" prop="discountMember">
+          <el-input v-model="dataForm.discountMember"></el-input>
+        </el-form-item>
+        <el-form-item label="过期时间" prop="expireTime">
+          <el-date-picker v-model="dataForm.expireTime" type="datetime" placeholder="选择日期"
+                          value-format="yyyy-MM-dd HH:mm:ss">
+          </el-date-picker>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="dialogFormVisible = false">取消</el-button>
+        <el-button v-if="dialogStatus=='create'" type="primary" @click="createData">确定</el-button>
+        <el-button v-else type="primary" @click="updateData">确定</el-button>
+      </div>
+    </el-dialog>
+
+    <!-- 分页 -->
+    <div class="pagination-container">
+      <el-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange"
+                     :current-page="listQuery.page"
+                     :page-sizes="[10,20,30,50]" :page-size="listQuery.limit"
+                     layout="total, sizes, prev, pager, next, jumper" :total="total">
+      </el-pagination>
+    </div>
+
+    <el-tooltip placement="top" content="返回顶部">
+      <back-to-top :visibilityHeight="100"></back-to-top>
+    </el-tooltip>
+
+  </div>
+</template>
+
+<style>
+  .table-expand {
+    font-size: 0;
+  }
+
+  .table-expand label {
+    width: 100px;
+    color: #99a9bf;
+  }
+
+  .table-expand .el-form-item {
+    margin-right: 0;
+    margin-bottom: 0;
+  }
+
+  .gallery {
+    width: 80px;
+    margin-right: 10px;
+  }
+</style>
+
+<script>
+  import {listGroupon, publishGroupon, deleteGroupon, editGroupon} from '@/api/groupon'
+  import BackToTop from '@/components/BackToTop'
+
+  export default {
+    name: 'GoodsList',
+    components: {BackToTop},
+    data() {
+      return {
+        list: [],
+        total: 0,
+        listLoading: true,
+        listQuery: {
+          page: 1,
+          limit: 20,
+          goodsId: undefined,
+          sort: 'add_time',
+          order: 'desc'
+        },
+        goodsDetail: '',
+        detailDialogVisible: false,
+        downloadLoading: false,
+        dataForm: {
+          id: undefined,
+          goodsId: '',
+          discount: '',
+          discountMember: '',
+          expireTime: undefined,
+        },
+        dialogFormVisible: false,
+        dialogStatus: '',
+        textMap: {
+          update: '编辑',
+          create: '创建'
+        },
+      }
+    },
+    created() {
+      this.getList()
+    },
+    methods: {
+      getList() {
+        this.listLoading = true
+        listGroupon(this.listQuery).then(response => {
+          this.list = response.data.data.items
+          this.total = response.data.data.total
+          this.listLoading = false
+        }).catch(() => {
+          this.list = []
+          this.total = 0
+          this.listLoading = false
+        })
+      },
+      handleFilter() {
+        this.listQuery.page = 1
+        this.getList()
+      },
+      handleSizeChange(val) {
+        this.listQuery.limit = val
+        this.getList()
+      },
+      handleCurrentChange(val) {
+        this.listQuery.page = val
+        this.getList()
+      },
+      resetForm() {
+        this.dataForm = {
+          id: undefined,
+          goodsId: '',
+          discount: '',
+          discountMember: '',
+          expireTime: undefined,
+        }
+      },
+      handleCreate() {
+        this.resetForm()
+        this.dialogStatus = 'create'
+        this.dialogFormVisible = true
+        this.$nextTick(() => {
+          this.$refs['dataForm'].clearValidate()
+        })
+      },
+      createData() {
+        this.$refs['dataForm'].validate((valid) => {
+          if (valid) {
+            publishGroupon(this.dataForm).then(response => {
+              this.list.unshift(response.data.data)
+              this.dialogFormVisible = false
+              this.$notify({
+                title: '成功',
+                message: '创建成功',
+                type: 'success',
+                duration: 2000
+              })
+            })
+          }
+        })
+      },
+      handleUpdate(row) {
+        this.dataForm = Object.assign({}, row)
+        this.dialogStatus = 'update'
+        this.dialogFormVisible = true
+        this.$nextTick(() => {
+          this.$refs['dataForm'].clearValidate()
+        })
+      },
+      updateData() {
+        this.$refs['dataForm'].validate((valid) => {
+          if (valid) {
+            editGroupon(this.dataForm).then(() => {
+              for (const v of this.list) {
+                if (v.id === this.dataForm.id) {
+                  const index = this.list.indexOf(v)
+                  this.list.splice(index, 1, this.dataForm)
+                  break
+                }
+              }
+              this.dialogFormVisible = false
+              this.$notify({
+                title: '成功',
+                message: '更新成功',
+                type: 'success',
+                duration: 2000
+              })
+            })
+          }
+        })
+      },
+      handleDelete(row) {
+        deleteGroupon(row).then(response => {
+          this.$notify({
+            title: '成功',
+            message: '删除成功',
+            type: 'success',
+            duration: 2000
+          })
+          const index = this.list.indexOf(row)
+          this.list.splice(index, 1)
+        })
+      },
+      handleDownload() {
+        this.downloadLoading = true
+        import('@/vendor/Export2Excel').then(excel => {
+          const tHeader = ['商品ID', '名称', '首页主图', '折扣', '人数要求', '活动开始时间', '活动结束时间']
+          const filterVal = ['id', 'name', 'pic_url', 'discount', 'discountMember', 'addTime', 'expireTime']
+          excel.export_json_to_excel2(tHeader, this.list, filterVal, '商品信息')
+          this.downloadLoading = false
+        })
+      }
+    }
+  }
+</script>

+ 279 - 0
litemall-admin/src/views/groupon/record.vue

@@ -0,0 +1,279 @@
+<template>
+  <div class="app-container calendar-list-container">
+
+    <!-- 查询和其他操作 -->
+    <div class="filter-container">
+      <el-input clearable class="filter-item" style="width: 200px;" placeholder="请输入商品编号" v-model="listQuery.goodsId">
+      </el-input>
+      <el-button class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">查找</el-button>
+      <!--<el-button class="filter-item" type="primary" @click="handleCreate" icon="el-icon-edit">添加</el-button>-->
+      <el-button class="filter-item" type="primary" :loading="downloadLoading" icon="el-icon-download"
+                 @click="handleDownload">导出
+      </el-button>
+    </div>
+
+    <!-- 查询结果 -->
+    <el-table size="small" :data="list" v-loading="listLoading" element-loading-text="正在查询中。。。" border fit
+              highlight-current-row>
+
+      <el-table-column type="expand">
+        <template slot-scope="scope">
+          <el-table :data="scope.row.subGroupons" border style="width: 100%">
+            <el-table-column align="center" label="订单ID" prop="orderId">
+            </el-table-column>
+            <el-table-column align="center" label="用户ID" prop="userId">
+            </el-table-column>
+          </el-table>
+        </template>
+      </el-table-column>
+
+      <el-table-column align="center" label="订单ID" prop="groupon.orderId">
+      </el-table-column>
+
+      <el-table-column align="center" label="用户ID" prop="groupon.userId">
+      </el-table-column>
+
+      <el-table-column align="center" label="参与人数" prop="subGroupons.length">
+      </el-table-column>
+
+      <el-table-column align="center" label="团购折扣" prop="rules.discount">
+      </el-table-column>
+
+      <el-table-column align="center" label="团购要求" prop="rules.discountMember">
+      </el-table-column>
+
+      <el-table-column align="center" property="iconUrl" label="分享图片">
+        <template slot-scope="scope">
+          <img :src="scope.row.groupon.shareUrl" width="40"/>
+        </template>
+      </el-table-column>
+
+      <el-table-column align="center" label="开始时间" prop="rules.addTime">
+      </el-table-column>
+
+      <el-table-column align="center" label="结束时间" prop="rules.expireTime">
+      </el-table-column>
+
+      <!--<el-table-column align="center" label="操作" width="200" class-name="small-padding fixed-width">-->
+      <!--<template slot-scope="scope">-->
+      <!--<el-button type="primary" size="mini" @click="handleUpdate(scope.row)">编辑</el-button>-->
+      <!--<el-button type="danger" size="mini" @click="handleDelete(scope.row)">删除</el-button>-->
+      <!--</template>-->
+      <!--</el-table-column>-->
+    </el-table>
+
+    <!-- 添加或修改对话框 -->
+    <el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
+      <el-form :rules="rules" ref="dataForm" :model="dataForm" status-icon label-position="left" label-width="100px"
+               style='width: 400px; margin-left:50px;'>
+        <el-form-item label="商品ID" prop="goodsId">
+          <el-input v-model="dataForm.goodsId"></el-input>
+        </el-form-item>
+        <el-form-item label="团购折扣" prop="discount">
+          <el-input v-model="dataForm.discount"></el-input>
+        </el-form-item>
+        <el-form-item label="团购人数要求" prop="discountMember">
+          <el-input v-model="dataForm.discountMember"></el-input>
+        </el-form-item>
+        <el-form-item label="过期时间" prop="expireTime">
+          <el-date-picker v-model="dataForm.expireTime" type="datetime" placeholder="选择日期"
+                          value-format="yyyy-MM-dd HH:mm:ss">
+          </el-date-picker>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="dialogFormVisible = false">取消</el-button>
+        <el-button v-if="dialogStatus=='create'" type="primary" @click="createData">确定</el-button>
+        <el-button v-else type="primary" @click="updateData">确定</el-button>
+      </div>
+    </el-dialog>
+
+    <!-- 分页 -->
+    <div class="pagination-container">
+      <el-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange"
+                     :current-page="listQuery.page"
+                     :page-sizes="[10,20,30,50]" :page-size="listQuery.limit"
+                     layout="total, sizes, prev, pager, next, jumper" :total="total">
+      </el-pagination>
+    </div>
+
+    <el-tooltip placement="top" content="返回顶部">
+      <back-to-top :visibilityHeight="100"></back-to-top>
+    </el-tooltip>
+
+  </div>
+</template>
+
+<style>
+  .table-expand {
+    font-size: 0;
+  }
+
+  .table-expand label {
+    width: 100px;
+    color: #99a9bf;
+  }
+
+  .table-expand .el-form-item {
+    margin-right: 0;
+    margin-bottom: 0;
+  }
+
+  .gallery {
+    width: 80px;
+    margin-right: 10px;
+  }
+</style>
+
+<script>
+  import {listRecord} from '@/api/groupon'
+  import BackToTop from '@/components/BackToTop'
+
+  export default {
+    name: 'GoodsList',
+    components: {BackToTop},
+    data() {
+      return {
+        list: [],
+        total: 0,
+        listLoading: true,
+        listQuery: {
+          page: 1,
+          limit: 20,
+          goodsId: undefined,
+          sort: 'add_time',
+          order: 'desc'
+        },
+        goodsDetail: '',
+        detailDialogVisible: false,
+        downloadLoading: false,
+        dataForm: {
+          id: undefined,
+          goodsId: '',
+          discount: '',
+          discountMember: '',
+          expireTime: undefined,
+        },
+        dialogFormVisible: false,
+        dialogStatus: '',
+        textMap: {
+          update: '编辑',
+          create: '创建'
+        },
+      }
+    },
+    created() {
+      this.getList()
+    },
+    methods: {
+      getList() {
+        this.listLoading = true
+        listRecord(this.listQuery).then(response => {
+          this.list = response.data.data.items
+          this.total = response.data.data.total
+          this.listLoading = false
+        }).catch(() => {
+          this.list = []
+          this.total = 0
+          this.listLoading = false
+        })
+      },
+      handleFilter() {
+        this.listQuery.page = 1
+        this.getList()
+      },
+      handleSizeChange(val) {
+        this.listQuery.limit = val
+        this.getList()
+      },
+      handleCurrentChange(val) {
+        this.listQuery.page = val
+        this.getList()
+      },
+      resetForm() {
+        this.dataForm = {
+          id: undefined,
+          goodsId: '',
+          discount: '',
+          discountMember: '',
+          expireTime: undefined,
+        }
+      },
+      handleCreate() {
+        this.resetForm()
+        this.dialogStatus = 'create'
+        this.dialogFormVisible = true
+        this.$nextTick(() => {
+          this.$refs['dataForm'].clearValidate()
+        })
+      },
+      createData() {
+        this.$refs['dataForm'].validate((valid) => {
+          if (valid) {
+            publishGroupon(this.dataForm).then(response => {
+              this.list.unshift(response.data.data)
+              this.dialogFormVisible = false
+              this.$notify({
+                title: '成功',
+                message: '创建成功',
+                type: 'success',
+                duration: 2000
+              })
+            })
+          }
+        })
+      },
+      handleUpdate(row) {
+        this.dataForm = Object.assign({}, row)
+        this.dialogStatus = 'update'
+        this.dialogFormVisible = true
+        this.$nextTick(() => {
+          this.$refs['dataForm'].clearValidate()
+        })
+      },
+      updateData() {
+        this.$refs['dataForm'].validate((valid) => {
+          if (valid) {
+            editGroupon(this.dataForm).then(() => {
+              for (const v of this.list) {
+                if (v.id === this.dataForm.id) {
+                  const index = this.list.indexOf(v)
+                  this.list.splice(index, 1, this.dataForm)
+                  break
+                }
+              }
+              this.dialogFormVisible = false
+              this.$notify({
+                title: '成功',
+                message: '更新成功',
+                type: 'success',
+                duration: 2000
+              })
+            })
+          }
+        })
+      },
+      handleDelete(row) {
+        deleteGroupon(row).then(response => {
+          this.$notify({
+            title: '成功',
+            message: '删除成功',
+            type: 'success',
+            duration: 2000
+          })
+          const index = this.list.indexOf(row)
+          this.list.splice(index, 1)
+        })
+      },
+      handleDownload() {
+        this.downloadLoading = true
+        import('@/vendor/Export2Excel').then(excel => {
+          const tHeader = ['商品ID', '名称', '首页主图', '折扣', '人数要求', '活动开始时间', '活动结束时间']
+          const filterVal = ['id', 'name', 'pic_url', 'discount', 'discountMember', 'addTime', 'expireTime']
+          excel.export_json_to_excel2(tHeader, this.list, filterVal, '商品信息')
+          this.downloadLoading = false
+        })
+      }
+    }
+  }
+</script>

+ 34 - 0
litemall-db/src/main/java/org/linlinjava/litemall/db/service/LitemallGrouponRulesService.java

@@ -1,5 +1,6 @@
 package org.linlinjava.litemall.db.service;
 
+import com.alibaba.druid.util.StringUtils;
 import com.github.pagehelper.PageHelper;
 import org.linlinjava.litemall.db.dao.LitemallGrouponRulesMapper;
 import org.linlinjava.litemall.db.domain.LitemallGrouponRules;
@@ -41,4 +42,37 @@ public class LitemallGrouponRulesService {
         PageHelper.startPage(offset, limit);
         return mapper.selectByExample(example);
     }
+
+    public List<LitemallGrouponRules> querySelective(String goodsId, Integer page, Integer size, String sort, String order) {
+        LitemallGrouponRulesExample example = new LitemallGrouponRulesExample();
+        LitemallGrouponRulesExample.Criteria criteria = example.createCriteria();
+
+        if (!StringUtils.isEmpty(goodsId)) {
+            criteria.andGoodsIdEqualTo(Integer.parseInt(goodsId));
+        }
+        criteria.andDeletedEqualTo(false);
+
+        PageHelper.startPage(page, size);
+        return mapper.selectByExample(example);
+    }
+
+    public int countSelective(String goodsId, Integer page, Integer limit, String sort, String order) {
+        LitemallGrouponRulesExample example = new LitemallGrouponRulesExample();
+        LitemallGrouponRulesExample.Criteria criteria = example.createCriteria();
+
+        if (!StringUtils.isEmpty(goodsId)) {
+            criteria.andGoodsIdEqualTo(Integer.parseInt(goodsId));
+        }
+        criteria.andDeletedEqualTo(false);
+
+        return (int) mapper.countByExample(example);
+    }
+
+    public void delete(Integer id) {
+        mapper.deleteByPrimaryKey(id);
+    }
+
+    public void update(LitemallGrouponRules grouponRules) {
+        mapper.updateByPrimaryKeySelective(grouponRules);
+    }
 }

+ 31 - 0
litemall-db/src/main/java/org/linlinjava/litemall/db/service/LitemallGrouponService.java

@@ -1,5 +1,7 @@
 package org.linlinjava.litemall.db.service;
 
+import com.alibaba.druid.util.StringUtils;
+import com.github.pagehelper.PageHelper;
 import org.linlinjava.litemall.db.dao.LitemallGrouponMapper;
 import org.linlinjava.litemall.db.domain.LitemallGroupon;
 import org.linlinjava.litemall.db.domain.LitemallGrouponExample;
@@ -99,4 +101,33 @@ public class LitemallGrouponService {
     public int createGroupon(LitemallGroupon groupon) {
         return mapper.insertSelective(groupon);
     }
+
+    public List<LitemallGroupon> querySelective(String rulesId, Integer page, Integer size, String sort, String order) {
+        LitemallGrouponExample example = new LitemallGrouponExample();
+        LitemallGrouponExample.Criteria criteria = example.createCriteria();
+
+        if (!StringUtils.isEmpty(rulesId)) {
+            criteria.andRulesIdEqualTo(Integer.parseInt(rulesId));
+        }
+        criteria.andDeletedEqualTo(false);
+        criteria.andPayedEqualTo(true);
+        criteria.andGrouponIdEqualTo(0);
+
+        PageHelper.startPage(page, size);
+        return mapper.selectByExample(example);
+    }
+
+    public int countSelective(String rulesId, Integer page, Integer limit, String sort, String order) {
+        LitemallGrouponExample example = new LitemallGrouponExample();
+        LitemallGrouponExample.Criteria criteria = example.createCriteria();
+
+        if (!StringUtils.isEmpty(rulesId)) {
+            criteria.andRulesIdEqualTo(Integer.parseInt(rulesId));
+        }
+        criteria.andDeletedEqualTo(false);
+        criteria.andPayedEqualTo(true);
+        criteria.andGrouponIdEqualTo(0);
+
+        return (int) mapper.countByExample(example);
+    }
 }

+ 1 - 0
litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/service/HomeCacheManager.java

@@ -14,6 +14,7 @@ public class HomeCacheManager {
      * @param data
      */
     public static void loadData(Map<String, Object> data) {
+        data.put("isCache", "true");
         cacheData = data;
     }