Browse Source

Merge branch '0601Action' into test

mo 3 năm trước cách đây
mục cha
commit
a893c18d56

+ 5 - 0
src/constant/index.js

@@ -297,3 +297,8 @@ export const courseViewType = {
   1:'AMR收费',
   2:'会员收费'
 }
+
+export const couponType = {
+  FULL_REDUCTION:'满减',
+  DISCOUNT:'折扣'
+}

+ 35 - 31
src/router/index.js

@@ -46,8 +46,7 @@ export const constantRoutes = [
     path: '/instructions', // 侧边栏
     component: Layout,
     hidden: true,
-    children: [
-    {
+    children: [{
       name: '说明文档',
       path: 'instructions',
       component: () => import('@/layout/components/fullPageIns'),
@@ -78,8 +77,7 @@ export const constantRoutes = [
     path: '/setSilder', // 侧边栏
     component: Layout,
     hidden: true,
-    children: [
-    {
+    children: [{
       name: '提交表单',
       path: 'save-form',
       component: () => import('@/views/save-form-test'),
@@ -237,14 +235,14 @@ export const asyncRoutes = {
   // 全局乐团设置
   globalMusicGroup: () => import('@/views/categroyManager/globalMusicGroup'),
   // 全局产品设置
-  productSystem:()=>import('@/views/categroyManager/productSystem'),
+  productSystem: () => import('@/views/categroyManager/productSystem'),
   // 侧边栏管理
   setSilder: () => import('@/views/setSilder/addSilder'),
   // 乐团老师点名记录
   teamTeacherRecord: () => import('@/views/teamDetail/components/teamTeacherRecord'),
   // 乐团筹备中 报名中
   signupList: () => import('@/views/teamBuild/signupList'),
-  remedy:() => import('@/views/teamBuild/signupList'),
+  remedy: () => import('@/views/teamBuild/signupList'),
   // 乐团筹备设置 (班级 老师 小课)
   teamSeting: () => import('@/views/teamBuild/teamSeting/'),
   //乐团详情
@@ -387,7 +385,7 @@ export const asyncRoutes = {
   // 训练管理
   workManager: () => import('@/views/courseListManager'),
   // 老师管理
- teacherManager: () => import('@/views/courseListManager'),
+  teacherManager: () => import('@/views/courseListManager'),
   // 学生管理
   studentManager: () => import('@/views/courseListManager'),
   // 订单管理
@@ -401,53 +399,59 @@ export const asyncRoutes = {
   // 参数设置
   parameter: () => import('@/views/courseListManager'),
   // 抽奖活动
-  luckyDraw:()=>import('@/views/courseListManager'),
+  luckyDraw: () => import('@/views/courseListManager'),
   // 乐团管理
-  teamMananger:()=>import('@/views/courseListManager'),
+  teamMananger: () => import('@/views/courseListManager'),
   // vip管理
-  vipManager:()=>import('@/views/courseListManager'),
+  vipManager: () => import('@/views/courseListManager'),
   // 网管课管理
-  accompanyManager:()=>import('@/views/courseListManager'),
+  accompanyManager: () => import('@/views/courseListManager'),
   // 乐团管理
   // 评论管理
-  commentManagerWrap:()=>import('@/views/courseListManager'),
+  commentManagerWrap: () => import('@/views/courseListManager'),
   // 课外训练
-  afterSchoolManagerWrap:()=>import('@/views/courseListManager'),
+  afterSchoolManagerWrap: () => import('@/views/courseListManager'),
   //
-  serverIndexManager:()=>import('@/views/courseListManager'),
-  reportFormCenter:()=>import('@/views/courseListManager'),
+  serverIndexManager: () => import('@/views/courseListManager'),
+  reportFormCenter: () => import('@/views/courseListManager'),
   // 乐器维护
-  musicalManager:()=>import('@/views/musicalManager'),
+  musicalManager: () => import('@/views/musicalManager'),
   // 服务指标明细
-  branchActiveManager:()=>import('@/views/courseListManager'),
+  branchActiveManager: () => import('@/views/courseListManager'),
   // vip活动管理
-  vipActiveManager:()=>import('@/views/courseListManager'),
+  vipActiveManager: () => import('@/views/courseListManager'),
   // 乐团缴费
-  teamPayInfo:()=>import('@/views/courseListManager'),
-  serverDetail:()=>import('@/views/serverDetail'),
+  teamPayInfo: () => import('@/views/courseListManager'),
+  serverDetail: () => import('@/views/serverDetail'),
   // 未在班级学员
-  notClassStudent:()=>import('@/views/main/notClassStudent'),
+  notClassStudent: () => import('@/views/main/notClassStudent'),
   // 报表中心 下载列表
-  downList:()=>import('@/views/reportForm/downList'),
+  downList: () => import('@/views/reportForm/downList'),
   // 乐器置换
-  reaplceMusicPlayer:()=>import('@/views/reaplceMusicPlayer'),
-  answerList:()=>import('@/views/reaplceMusicPlayer/answerList'),
+  reaplceMusicPlayer: () => import('@/views/reaplceMusicPlayer'),
+  answerList: () => import('@/views/reaplceMusicPlayer/answerList'),
   // 问卷管理
   setQuestions: () => import('@/views/setQuestions'),
   questionOperation: () => import('@/views/setQuestions/operation'),
   // 21暑期考级
-  childrensDay:()=>import('@/views/childrensDay'),
+  childrensDay: () => import('@/views/childrensDay'),
   // 考级详情
-  childrensdayDetail:()=>import('@/views/childrensDay/detail'),
+  childrensdayDetail: () => import('@/views/childrensDay/detail'),
   // 异常数据
-  indexErrDataRecord:()=>import('@/views/indexErrDataRecord'),
-  dictionaryManager:()=>import('@/views/dictionaryManager'),
+  indexErrDataRecord: () => import('@/views/indexErrDataRecord'),
+  dictionaryManager: () => import('@/views/dictionaryManager'),
   // 会员排课列表
-  memberClassList:()=>import('@/views/teamDetail/components/memberClassList'),
+  memberClassList: () => import('@/views/teamDetail/components/memberClassList'),
   // 设备号管理
-  deviceNum:()=>import('@/views/deviceNumManager'),
+  deviceNum: () => import('@/views/deviceNumManager'),
   // 乐团会员列表
-  teamMemberList:()=>import('@/views/studentManager/memberList')
+  teamMemberList: () => import('@/views/studentManager/memberList'),
+  //2021十一活动
+  memeberActionManager: () => import('@/views/2021memeberActionManager'),
+  // 优惠券管理
+  couponManager:()=>import ('@/views/couponManager'),
+  // 优惠券明细
+  couponDetail:()=>import ('@/views/couponManager/couponDetail'),
 }
 
 export default router

+ 26 - 1
src/store/modules/permission.js

@@ -585,7 +585,32 @@ function setDetailRoute(accessedRoutes) {
             id: 'xx19'
           }
         },
-        // /operateManager/setQuestions /questionOperation   operateManager
+        {
+          name: 'memberActiveDetail',
+          path: 'memberActiveDetail',
+          component: () => import('@/views/2021memeberActionManager/memberActiveDetail'),
+          hidden: true,
+          meta: {
+            noCache: '1',
+            title: '2021十一活动详情',
+            belongTopMenu: "/operateManager",
+            activeMenu: '/2021memeberActionManager',
+            id: 'xx19'
+          }
+        },
+        {
+          name: 'couponUpdate',
+          path: 'couponUpdate',
+          component: () => import('@/views/couponManager/couponUpdate'),
+          hidden: true,
+          meta: {
+            noCache: '1',
+            title: '优惠券详情',
+            belongTopMenu: "/operateManager",
+            activeMenu: '/couponManager',
+            id: 'xx19'
+          }
+        },
       ])
     }
     if (route.path == '/financialManager') {

+ 2 - 1
src/utils/searchArray.js

@@ -1,5 +1,5 @@
 // 搜索用的下拉数据列表
-import { payOrderType, auditType, auditPaymentType, orderServerType, orderAuditType, rewardModeType,classTime,musicClassType,ProbationPeriodStatus,downListType,musicGroupType,conclusion,vipResetType,courseViewType,clientType } from '../constant'
+import { payOrderType, auditType, auditPaymentType, orderServerType, orderAuditType, rewardModeType,classTime,musicClassType,ProbationPeriodStatus,downListType,musicGroupType,conclusion,vipResetType,courseViewType,clientType,couponType } from '../constant'
 // 课程类型
 export const courseType = [
   { label: "声部课", value: "SINGLE" },
@@ -232,6 +232,7 @@ export const ProbationPeriodList = getValueForKey(ProbationPeriodStatus)
 export const downTypeList = getValueForKey(downListType)
 export const conclusionList = getValueForKey(conclusion)
 export const clientList = getValueForKey(clientType)
+export const couponTypeList = getValueForKey(couponType)
 //downListType
 function getValueForKey (obj) {
   let arr = []

+ 4 - 0
src/utils/vueFilter.js

@@ -783,3 +783,7 @@ Vue.filter('conclusionStatus', value => {
 Vue.filter('courseViewType', (value) => {
   return constant.courseViewType[value]
 })
+Vue.filter('couponTypeFilter', (value) => {
+  return constant.couponType[value]
+})
+// couponType

+ 29 - 0
src/views/2021memeberActionManager/api.js

@@ -0,0 +1,29 @@
+import request from '@/utils/request'
+import qs from 'qs'
+let api = '/api-web'
+
+export function getCountCloudTeacherList (data) {
+  return request({
+    url: api + '/studentManage/countCloudTeacherActive',
+    method: 'get',
+    params: data
+  })
+}
+
+export function getCloudTeacherActiveDetail (data) {
+  return request({
+    url: api + '/studentManage/countCloudTeacherActiveDetail',
+    method: 'get',
+    params: data
+  })
+}
+
+// 获取分部年纪
+export function getGradeList (data) {
+  return request({
+    url: api + '/organization/getGradeList',
+    method: 'get',
+    params: data
+  })
+}
+

+ 429 - 0
src/views/2021memeberActionManager/index.vue

@@ -0,0 +1,429 @@
+<!--  -->
+<template>
+  <div class="m-container">
+    <h2>
+      <div class="squrt"></div>
+      2021十一会员活动
+    </h2>
+    <div class="m-core">
+      <save-form
+        :inline="true"
+        :model="searchForm"
+        @submit="search"
+        @reset="onReSet"
+      >
+        <el-form-item prop="organId">
+          <el-select
+            class="multiple"
+            style="width: 180px !important"
+            v-model.trim="searchForm.organId"
+            filterable
+            clearable
+            placeholder="请选择分部"
+          >
+            <el-option
+              v-for="(item, index) in selects.branchs"
+              :key="index"
+              :label="item.name"
+              :value="item.id"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-button native-type="submit" type="primary">搜索</el-button>
+          <el-button native-type="reset" type="danger">重置</el-button>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="onCreateQRCode"
+            >H5统计链接</el-button
+          >
+        </el-form-item>
+        <el-form-item>
+          <auth auths='export/countCloudTeacherActive'>
+            <el-button type="primary" @click="onExport">导出</el-button>
+          </auth>
+        </el-form-item>
+      </save-form>
+      <div style="font-size: 14px; color: #f85043; padding-bottom: 10px">
+        <!-- 应收总金额:{{ totalExpectAmount }}元 &nbsp;&nbsp;&nbsp;&nbsp;
+        现金实收总额:{{ totalActualAmount }}元 &nbsp;&nbsp;&nbsp;&nbsp;
+        余额实收总额:{{ Number((totalExpectAmount - totalActualAmount).toFixed(2)) }}元 -->
+        <!-- 营收金额=2-3
+        实收金额=应收总额(包含余额支付)
+        预收金额=充值总额(发生消费,记负数)
+        预收余额=充值总余额 -->
+        人均购买金额:{{ head.avgBuyAmount | moneyFormat }}元<i
+          style="width: 10px; display: inline-block"
+        ></i>
+        购买总金额:{{ head.buyAmount | moneyFormat }}元<i
+          style="width: 10px; display: inline-block"
+        ></i>
+        购买人数:{{ head.buyNum | moneyFormat }}元<i
+          style="width: 10px; display: inline-block"
+        ></i>
+        购买率:{{ head.buyScale }}%
+        <i style="width: 10px; display: inline-block"></i>
+
+        目标总金额:{{ head.targetAmount | moneyFormat }}元<i
+          style="width: 10px; display: inline-block"
+        ></i>
+        目标完成率:{{ head.targetFinishScale }}%<i
+          style="width: 10px; display: inline-block"
+        ></i>
+        目标购买人数:{{ head.targetNum }}元<i
+          style="width: 10px; display: inline-block"
+        ></i>
+        总人数:{{ head.totalNum }}元<i
+          style="width: 10px; display: inline-block"
+        ></i>
+      </div>
+      <div class="tableWrap">
+        <el-table
+          style="width: 100%"
+          :header-cell-style="{ background: '#EDEEF0', color: '#444' }"
+          :data="tableList"
+          @sort-change="sortChang"
+          :default-sort="{
+            prop: 'targetFinishScale',
+            order: 'descending',
+          }"
+        >
+          <el-table-column
+            align="center"
+            prop="targetNum"
+            label="排名"
+          ></el-table-column>
+          <el-table-column
+            align="center"
+            prop="organName"
+            label="分部"
+          ></el-table-column>
+          <el-table-column
+            align="center"
+            prop="buyNum"
+            sortable="custom"
+            width="150px"
+          >
+            <template slot="header" slot-scope="slot">
+              <div class="titleCell">
+                <span>购买人数</span>
+                <el-tooltip placement="top" popper-class="mTooltip">
+                  <div slot="content">本次活动交易成功总人数(去重)</div>
+                  <i
+                    class="el-icon-question micon el-tooltip"
+                    style="
+                      font-size: 18px;
+                      color: #f56c6c;
+                      top: 2px;
+                      position: relative;
+                    "
+                  ></i>
+                </el-tooltip>
+              </div>
+            </template>
+            <template slot-scope="scope">
+              <div>{{ scope.row.buyNum }}人</div>
+            </template>
+          </el-table-column>
+          <el-table-column
+            align="center"
+            prop="avgBuyAmount"
+            sortable="custom"
+            width="150px"
+          >
+            <template slot="header" slot-scope="slot">
+              <div class="titleCell">
+                <span>人均购买金额</span>
+                <el-tooltip placement="top" popper-class="mTooltip">
+                  <div slot="content">总金额 / 购买人数</div>
+                  <i
+                    class="el-icon-question micon el-tooltip"
+                    style="
+                      font-size: 18px;
+                      color: #f56c6c;
+                      top: 2px;
+                      position: relative;
+                    "
+                  ></i>
+                </el-tooltip>
+              </div>
+            </template>
+            <template slot-scope="scope">
+              <div>{{ scope.row.avgBuyAmount }}元</div>
+            </template>
+          </el-table-column>
+          <el-table-column
+            align="center"
+            prop="totalNum"
+            sortable="custom"
+            width="140px"
+          >
+            <template slot="header" slot-scope="slot">
+              <div class="titleCell">
+                <span>总人数</span>
+                <el-tooltip placement="top" popper-class="mTooltip">
+                  <div slot="content">
+                    进行中乐团在读学员+VIP、网管有课学员总数(除弦乐声部、去重)
+                  </div>
+                  <i
+                    class="el-icon-question micon el-tooltip"
+                    style="
+                      font-size: 18px;
+                      color: #f56c6c;
+                      top: 2px;
+                      position: relative;
+                    "
+                  ></i>
+                </el-tooltip>
+              </div>
+            </template>
+            <template slot-scope="scope">
+              <div>{{ scope.row.totalNum }}人</div>
+            </template>
+          </el-table-column>
+          <el-table-column
+            align="center"
+            prop="buyScale"
+            sortable="custom"
+            width="140px"
+          >
+            <template slot="header" slot-scope="slot">
+              <div class="titleCell">
+                <span>购买率</span>
+                <el-tooltip placement="top" popper-class="mTooltip">
+                  <div slot="content">实际交易成功人数 / 目标购买人数*100%</div>
+                  <i
+                    class="el-icon-question micon el-tooltip"
+                    style="
+                      font-size: 18px;
+                      color: #f56c6c;
+                      top: 2px;
+                      position: relative;
+                    "
+                  ></i>
+                </el-tooltip>
+              </div>
+            </template>
+            <template slot-scope="scope">
+              <div>{{ scope.row.buyScale }}%</div>
+            </template>
+          </el-table-column>
+          <el-table-column
+            align="center"
+            prop="targetNum"
+            sortable="custom"
+            width="140px"
+          >
+            <template slot="header" slot-scope="slot">
+              <div class="titleCell">
+                <span>目标人数</span>
+                <el-tooltip placement="top" popper-class="mTooltip">
+                  <div slot="content">各分部目标人数之和</div>
+                  <i
+                    class="el-icon-question micon el-tooltip"
+                    style="
+                      font-size: 18px;
+                      color: #f56c6c;
+                      top: 2px;
+                      position: relative;
+                    "
+                  ></i>
+                </el-tooltip>
+              </div>
+            </template>
+            <template slot-scope="scope">
+              <div>{{ scope.row.targetNum }}人</div>
+            </template>
+          </el-table-column>
+          <el-table-column
+            align="center"
+            prop="targetFinishScale"
+            sortable="custom"
+            width="140px"
+          >
+            <template slot="header" slot-scope="slot">
+              <div class="titleCell">
+                <span>目标达成率</span>
+                <el-tooltip placement="top" popper-class="mTooltip">
+                  <div slot="content">各分部目标人数之和</div>
+                  <i
+                    class="el-icon-question micon el-tooltip"
+                    style="
+                      font-size: 18px;
+                      color: #f56c6c;
+                      top: 2px;
+                      position: relative;
+                    "
+                  ></i>
+                </el-tooltip>
+              </div>
+            </template>
+            <template slot-scope="scope">
+              <div>{{ scope.row.targetFinishScale }}%</div>
+            </template>
+          </el-table-column>
+          <el-table-column label="详情" align="center">
+            <template slot-scope="scope">
+              <div>
+                <el-button type="text" @click="gotoDetail(scope.row)"
+                  >详情</el-button
+                >
+              </div>
+            </template>
+          </el-table-column>
+        </el-table>
+        <!-- <pagination
+          sync
+          :total.sync="rules.total"
+          :page.sync="rules.page"
+          :limit.sync="rules.limit"
+          :page-sizes="rules.page_size"
+          @pagination="getList"
+        /> -->
+      </div>
+    </div>
+    <qr-code v-model="qrcodeStatus" title="统计二维码" :codeUrl="codeUrl" />
+  </div>
+</template>
+
+<script>
+import axios from "axios";
+import { getToken } from "@/utils/auth";
+import pagination from "@/components/Pagination/index";
+import QrCode from "@/components/QrCode/index";
+import { vaildTeachingUrl } from "@/utils/validate";
+import { getCountCloudTeacherList } from "./api";
+import { Export } from "@/utils/downLoadFile";
+import cleanDeep from "clean-deep";
+import qs from "qs";
+export default {
+  components: { pagination, QrCode },
+  data() {
+    return {
+      searchForm: {
+        organId: null,
+      },
+      searchList: { sort: "targetFinishScale", order: "DESC" },
+      head: {
+        avgBuyAmount: null,
+        buyAmount: null,
+        buyNum: null,
+        buyScale: null,
+        targetAmount: null,
+        targetFinishScale: null,
+        targetNum: null,
+        totalNum: null,
+      },
+      tableList: [],
+      organList: [],
+      rules: {
+        // 分页规则
+        limit: 10, // 限制显示条数
+        page: 1, // 当前页
+        total: 0, // 总条数
+        page_size: [10, 20, 40, 50], // 选择限制显示条数
+      },
+      qrcodeStatus: false,
+      codeUrl: "",
+    };
+  },
+  //生命周期 - 创建完成(可以访问当前this实例)
+  created() {},
+  //生命周期 - 挂载完成(可以访问DOM元素)
+  async mounted() {
+    // 获取分部
+    await this.$store.dispatch("setBranchs");
+    this.init();
+  },
+  methods: {
+    init() {
+      this.getList();
+    },
+    async getList() {
+      try {
+        const res = await getCountCloudTeacherList({
+          organIds: this.searchForm.organId,
+          ...this.searchList,
+        });
+        this.tableList = res.data.resultList;
+        this.head = res.data.head;
+      } catch (e) {
+        console.log(e);
+      }
+    },
+    search() {
+      this.rules.page = 1;
+      this.getList();
+    },
+    onReSet() {
+      this.searchForm.organId = null;
+      this.searchList = { sort: "targetFinishScale", order: "DESC" };
+      this.search();
+    },
+    sortChang(val) {
+      const dates = {
+        ascending: "ASC",
+        descending: "DESC",
+      };
+      this.searchList = {};
+      if (val.prop && val.order) {
+        this.searchList = { sort: val.prop, order: dates[val.order] };
+        // this.searchList[val.prop] = dates[val.order];
+      }
+      this.rules.page = 1;
+      this.getList();
+    },
+    onCreateQRCode(row) {
+      // 生成报名二维码
+      this.qrcodeStatus = true;
+      this.codeUrl = vaildTeachingUrl() + "/#/statisticOctober1st";
+    },
+    gotoDetail(row) {
+      // console.log('跳转详情')
+      this.$router.push({
+        path: "/operateManager/memberActiveDetail",
+        query: { organId: row.organId, organName: row.organName },
+      });
+    },
+    async onExport() {
+      let obj = {
+        organIds: this.searchForm.organId,
+        ...this.searchList,
+      };
+      await Export(
+        this,
+        {
+          url: "/api-web/export/countCloudTeacherActive",
+          fileName: "2021十一会员活动.xls",
+          method: "post",
+          params: qs.stringify(cleanDeep(obj)),
+        },
+        "您确定导出会员活动列表?"
+      );
+    },
+  },
+};
+</script>
+<style lang='scss' scoped>
+.titleCell {
+  display: inline-block;
+}
+.tableWrap {
+  margin-top: 20px;
+}
+.qrcode {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  img {
+    width: 200px;
+    height: 200px;
+    margin: 0 auto;
+  }
+}
+.code-url {
+  font-size: 18px;
+  text-align: center;
+  padding: 15px 15px 0 15px;
+}
+</style>

+ 284 - 0
src/views/2021memeberActionManager/memberActiveDetail.vue

@@ -0,0 +1,284 @@
+<!--  -->
+<template>
+  <div class="m-container">
+    <el-page-header
+      @back="onCancel"
+      :content="title"
+    ></el-page-header>
+    <div class="m-core">
+      <save-form
+        :inline="true"
+        :model="searchForm"
+        @submit="search"
+        @reset="onReSet"
+      >
+        <!-- <el-form-item prop="organId">
+          <el-select
+            class="multiple"
+            style="width: 180px !important"
+            v-model.trim="searchForm.organId"
+            filterable
+            clearable
+            placeholder="请选择分部"
+          >
+            <el-option
+              v-for="(item, index) in selects.branchs"
+              :key="index"
+              :label="item.name"
+              :value="item.id"
+            ></el-option>
+          </el-select>
+        </el-form-item> -->
+        <el-form-item prop="chargeType">
+          <el-select
+            v-model.trim="searchForm.chargeType"
+            filterable
+            clearable
+            placeholder="请选择乐团模式"
+          >
+            <el-option
+              v-for="(item, index) in typeList"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item prop="subjectId">
+          <el-select
+            class="multiple"
+            style="width: 180px !important"
+            v-model.trim="searchForm.subjectId"
+            filterable
+            clearable
+            placeholder="请选择声部"
+          >
+            <el-option
+              v-for="(item, index) in selects.subjects"
+              :key="index"
+              :label="item.name"
+              :value="item.id"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item prop="teacherId">
+          <remote-search
+            :commit="'setTeachers'"
+            aria-placeholder="请选择指导老师"
+            v-model.trim="searchForm.teacherId"
+          />
+        </el-form-item>
+        <el-form-item prop="remarkType">
+          <el-select
+            class="multiple"
+            style="width: 180px !important"
+            v-model.trim="searchForm.remarkType"
+            filterable
+            clearable
+            placeholder="购买套餐"
+          >
+            <el-option label="2赠1" value="2赠1"></el-option>
+            <el-option label="3赠2" value="3赠2"></el-option>
+            <el-option label="单月" value="单月"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-button native-type="submit" type="primary">搜索</el-button>
+          <el-button native-type="reset" type="danger">重置</el-button>
+          <auth  auths='export/countCloudTeacherActiveDetail'></auth>
+          <el-button type="primary" @click="onExport">导出</el-button>
+        </el-form-item>
+      </save-form>
+      <div class="tableWrap">
+        <el-table
+          style="width: 100%"
+          :header-cell-style="{ background: '#EDEEF0', color: '#444' }"
+          :data="tableList"
+        >
+          <el-table-column
+            align="center"
+            prop="studentId"
+            label="学生姓名(编号)"
+          >
+            <template slot-scope="scope">
+              <div>{{ scope.row.username }}({{ scope.row.userId }})</div>
+            </template>
+          </el-table-column>
+          <el-table-column
+            align="center"
+            prop="cooperationName"
+            label="合作单位"
+          ></el-table-column>
+          <el-table-column
+            align="center"
+            prop="musicGroupName"
+            label="乐团"
+          ></el-table-column>
+          <el-table-column
+            align="center"
+            prop="chargeType"
+            label="乐团模式"
+          ></el-table-column>
+          <el-table-column
+            align="center"
+            prop="subjectName"
+            label="声部"
+          ></el-table-column>
+          <el-table-column
+            align="center"
+            prop="currentGradeNum"
+            label="年级"
+          >
+          <template slot-scope="scope">
+            <div>
+              {{gradeList[scope.row.currentGradeNum]}}
+            </div>
+          </template>
+          </el-table-column>
+          <el-table-column
+            align="center"
+            prop="teacherName"
+            label="指导老师"
+          ></el-table-column>
+          <el-table-column
+            align="center"
+            prop="remark"
+            label="购买套餐"
+          ></el-table-column>
+          <el-table-column align="center" prop="studentId" label="购买金额">
+            <template slot-scope="scope">
+              <div>
+                {{ scope.row.amount | hasMoneyFormat }}
+              </div>
+            </template>
+          </el-table-column>
+        </el-table>
+        <pagination
+          sync
+          :total.sync="rules.total"
+          :page.sync="rules.page"
+          :limit.sync="rules.limit"
+          :page-sizes="rules.page_size"
+          @pagination="getList"
+        />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import axios from "axios";
+import { getToken } from "@/utils/auth";
+import pagination from "@/components/Pagination/index";
+import load from "@/utils/loading";
+import { classStatus, courseViewTypeList } from "@/utils/searchArray";
+import { getType } from "@/api/buildTeam";
+import { getCloudTeacherActiveDetail,getGradeList } from "./api";
+import { Export } from "@/utils/downLoadFile";
+import cleanDeep from "clean-deep";
+import qs from "qs";
+export default {
+  components: { pagination },
+  data() {
+    return {
+      searchForm: {
+        search: null,
+        chargeType: null,
+        remarkType: null,
+        subjectId: null,
+        teacherId: null,
+      },
+      courseViewTypeList,
+      tableList: [],
+      organList: [],
+      typeList: [],
+      rules: {
+        // 分页规则
+        limit: 10, // 限制显示条数
+        page: 1, // 当前页
+        total: 0, // 总条数
+        page_size: [10, 20, 40, 50], // 选择限制显示条数
+      },
+      organId: "",
+      title:'',
+      gradeList:{}
+    };
+  },
+  //生命周期 - 创建完成(可以访问当前this实例)
+  created() {},
+  //生命周期 - 挂载完成(可以访问DOM元素)
+  async mounted() {
+    this.organId = this.$route.query.organId;
+    try{
+     const res = await getGradeList({organId:this.organId})
+     this.gradeList = res.data
+    }catch(e){
+      console.log(e)
+    }
+    if (this.$route.query.organName) {
+      this.title = `${this.$route.query.organName}分部会员活动详情`
+    }else{
+        this.title = `分部会员活动详情`
+    }
+    getType({ rows: 1000 }).then((res) => {
+      if (res.code == 200) {
+        this.typeList = res.data.rows;
+      }
+    });
+    // await this.$store.dispatch("setBranchs");
+    await this.$store.dispatch("setSubjects");
+
+    this.init();
+  },
+  methods: {
+    init() {
+      this.getList();
+    },
+    async getList() {
+      console.log("organId", this.organId);
+      try {
+        const res = await getCloudTeacherActiveDetail({
+          organIds: this.organId,
+          ...this.searchForm,
+          page: this.rules.page,
+          rows: this.rules.limit,
+        });
+        this.tableList = res.data.rows;
+        this.rules.total = res.data.total;
+      } catch (e) {
+        console.log(e);
+      }
+    },
+    search() {
+      this.rules.page = 1;
+      this.getList();
+    },
+    onReSet() {
+      this.$nextTick(() => {
+        this.search();
+      });
+    },
+    onCancel() {
+      this.$router.push("/2021memeberActionManager");
+    },
+    async onExport() {
+      let obj = {
+        organIds: this.organId,
+          ...this.searchForm,
+      };
+      await Export(
+        this,
+        {
+          url: "/api-web/export/countCloudTeacherActiveDetail",
+          fileName: "2021十一会员活动详情.xls",
+          method: "post",
+          params: qs.stringify(cleanDeep(obj)),
+        },
+        "您确定导出会员活动详情列表?"
+      );
+    },
+  },
+};
+</script>
+<style lang='scss' scoped>
+</style>

+ 5 - 0
src/views/businessManager/orderManager/income.vue

@@ -378,6 +378,11 @@ export default {
   },
   mounted() {
     this.$store.dispatch("setBranchs");
+    if(this.$route.params?.orderNo){
+      this.searchForm.orderDate = [];
+      this.searchForm.orderNo = this.$route.params.orderNo;
+      this.searchForm.paymentStatus = null
+    }
     this.getList();
   },
   methods: {

+ 42 - 0
src/views/couponManager/api.js

@@ -0,0 +1,42 @@
+import request2 from '@/utils/request2'
+import qs from 'qs'
+let api = '/api-web'
+// 新增优惠券
+export const addSysCoupon = data => request2({
+  url: '/api-web/sysCoupon/add',
+  data,
+  method: 'post',
+  requestType: 'form'
+})
+
+// 修改优惠券
+export const resetSysCoupon = data => request2({
+  url: '/api-web/sysCoupon/updateCoupon',
+  data,
+  method: 'post',
+  requestType: 'form'
+})
+
+// 分页查询优惠券
+export const getSysCoupon = data => request2({
+  url: '/api-web/sysCoupon/queryPage',
+  data,
+  params: data,
+  method: 'get',
+})
+
+// 删除优惠券
+export const delSysCoupon = data => request2({
+  url: '/api-web/sysCoupon/delete',
+  data,
+  method: 'post',
+  requestType: 'form'
+})
+
+// 获取详情列表
+export const getSysCouponCode = data => request2({
+  url: '/api-web/sysCouponCode/queryPage',
+  data,
+  params: data,
+  method: 'get',
+})

+ 271 - 0
src/views/couponManager/couponDetail.vue

@@ -0,0 +1,271 @@
+<!--  -->
+<template>
+  <div class="m-container">
+    <h2>
+      <div class="squrt"></div>
+      优惠券明细
+    </h2>
+    <div class="m-core">
+      <save-form
+        :inline="true"
+        :model="searchForm"
+        @submit="search"
+        @reset="onReSet"
+      >
+        <el-form-item prop="search">
+          <el-input
+            v-model.trim="searchForm.search"
+            clearable
+            @keyup.enter.native="search"
+            placeholder="姓名、编号、手机号"
+          ></el-input>
+        </el-form-item>
+        <el-form-item prop="couponName">
+          <el-input
+            v-model.trim="searchForm.couponName"
+            @keyup.enter.native="search"
+            placeholder="优惠券名称"
+          ></el-input>
+        </el-form-item>
+        <el-form-item prop="paymentOrderId">
+          <el-input
+            v-model.trim="searchForm.paymentOrderId"
+            @keyup.enter.native="search"
+            placeholder="关联订单号"
+          ></el-input>
+        </el-form-item>
+        <el-form-item prop="usageStatus">
+          <el-select
+            placeholder="优惠券状态"
+            v-model.trim="searchForm.usageStatus"
+            filterable
+            clearable
+          >
+            <el-option label="未使用" value="0"></el-option>
+            <el-option label="已使用" value="1"></el-option>
+            <el-option label="已过期" value="2"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item prop="organId">
+          <el-select
+            class="multiple"
+            v-model.trim="searchForm.organId"
+            filterable
+            clearable
+            placeholder="请选择分部"
+          >
+            <el-option
+              v-for="(item, index) in selects.branchs"
+              :key="index"
+              :label="item.name"
+              :value="item.id"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-button native-type="submit" type="primary">搜索</el-button>
+          <el-button native-type="reset" type="danger">重置</el-button>
+        </el-form-item>
+      </save-form>
+      <div class="tableWrap">
+        <el-table
+          style="width: 100%"
+          :header-cell-style="{ background: '#EDEEF0', color: '#444' }"
+          :data="tableList"
+        >
+          <el-table-column
+            align="center"
+            prop="organName"
+            label="分部"
+          ></el-table-column>
+          <el-table-column
+            align="center"
+            prop="organName"
+            label="学生姓名(编号)"
+          >
+            <template slot-scope="scope">
+              <div>{{ scope.row.userName }}({{ scope.row.userId }})</div>
+            </template>
+          </el-table-column>
+          <el-table-column
+            align="center"
+            prop="phone"
+            label="手机号"
+          ></el-table-column>
+          <el-table-column
+            align="center"
+            prop="couponId"
+            label="优惠券编号"
+          ></el-table-column>
+          <el-table-column align="center" prop="couponId" label="优惠券类型">
+            <template slot-scope="scope">
+              <div>
+                {{ scope.row.couponType | couponTypeFilter }}
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column
+            align="center"
+            prop="couponName"
+            label="优惠券名称"
+          ></el-table-column>
+          <el-table-column align="center" prop="description" label="描述">
+            <template slot-scope="scope">
+              <div>
+                <Tooltip
+                  :content="
+                    scope.row.couponDescription
+                      ? scope.row.couponDescription
+                      : ''
+                  "
+                />
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column
+            align="center"
+            prop="code"
+            label="优惠码"
+          ></el-table-column>
+          <el-table-column align="center" prop="couponId" label="关联订单号">
+            <template slot-scope="scope">
+              <div
+                @click="gotoOrder(scope.row.paymentOrderId)"
+                style="color: #14928a; cursor: pointer"
+              >
+                {{ scope.row.paymentOrderId }}
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column
+            align="center"
+            prop="couponId"
+            width="160px"
+            label="有效期"
+          >
+            <template slot-scope="scope">
+              <div>
+                <p>{{ scope.row.useStartDate }}</p>
+                <p>{{ scope.row.useDeadlineDate }}</p>
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column
+            align="center"
+            prop="couponId"
+            width="100px"
+            label="使用时间"
+          >
+            <template slot-scope="scope">
+              <div>
+                <p>{{ scope.row.usedTime }}</p>
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column align="center" prop="couponId" label="状态">
+            <template slot-scope="scope">
+              <div>
+                <p>{{ scope.row.usageStatus | usageStatus }}</p>
+              </div>
+            </template>
+          </el-table-column>
+        </el-table>
+        <pagination
+          sync
+          :total.sync="rules.total"
+          :page.sync="rules.page"
+          :limit.sync="rules.limit"
+          :page-sizes="rules.page_size"
+          @pagination="getList"
+        />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import axios from "axios";
+import { getToken } from "@/utils/auth";
+import pagination from "@/components/Pagination/index";
+import { getSysCouponCode } from "./api";
+import Tooltip from "@/components/Tooltip/index";
+import load from "@/utils/loading";
+export default {
+  components: { pagination, Tooltip },
+  data() {
+    return {
+      searchForm: {
+        search: null,
+        couponName: null,
+        paymentOrderId: null,
+        usageStatus: null,
+        organId: null,
+      },
+
+      tableList: [],
+      organList: [],
+      rules: {
+        // 分页规则
+        limit: 10, // 限制显示条数
+        page: 1, // 当前页
+        total: 0, // 总条数
+        page_size: [10, 20, 40, 50], // 选择限制显示条数
+      },
+    };
+  },
+  //生命周期 - 创建完成(可以访问当前this实例)
+  created() {},
+  //生命周期 - 挂载完成(可以访问DOM元素)
+  async mounted() {
+    // 获取分部
+    await this.$store.dispatch("setBranchs");
+    this.init();
+  },
+  methods: {
+    init() {
+      this.getList();
+    },
+    async getList() {
+      try {
+        const res = await getSysCouponCode({
+          ...this.searchForm,
+          page: this.rules.page,
+          rows: this.rules.limit,
+        });
+        this.tableList = res.data.rows;
+        this.rules.total = res.data.total;
+      } catch (e) {
+        console.log(e);
+      }
+    },
+    search() {
+      this.rules.page = 1;
+      this.getList();
+    },
+    onReSet() {
+      this.$nextTick(()=>{
+          this.search();
+      })
+
+    },
+    gotoOrder(id) {
+      this.$router.push({
+        name: "income",
+        params: { orderNo: id },
+      });
+    },
+  },
+  filters: {
+    usageStatus(val) {
+      let obj = {
+        0: "未使用",
+        1: "已使用",
+        2: "已过期",
+      };
+      return obj[val];
+    },
+  },
+};
+</script>
+<style lang='scss' scoped>
+</style>

+ 402 - 0
src/views/couponManager/couponUpdate.vue

@@ -0,0 +1,402 @@
+<template>
+  <div class="m-container">
+    <el-page-header @back="onCancel" :content="title"></el-page-header>
+    <!-- <h3 class="infoTitle">优惠券信息</h3>
+    <el-divider></el-divider> -->
+    <el-form :model="form" ref="form" class="form">
+      <el-row>
+        <el-col style="width: 500px">
+          <el-form-item
+            label="优惠券名称"
+            prop="name"
+            :rules="[{ required: true, message: '请输入优惠卷名称' }]"
+          >
+            <el-input
+              :disabled="isDisabled"
+              v-model="form.name"
+              placeholder="请输入优惠卷名称"
+            ></el-input>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col style="width: 500px">
+          <el-form-item
+            label="描述"
+            prop="description"
+            :rules="[{ required: true, message: '请输入优惠卷描述' }]"
+          >
+            <el-input
+              :disabled="isDisabled"
+              v-model="form.description"
+              maxlength="20"
+              type="textarea"
+              :rows="3"
+              show-word-limit
+              placeholder="请输入优惠券描述,该描述会在优惠券上展示"
+            ></el-input>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row :gutter="20">
+        <el-col style="width: 395px">
+          <el-form-item
+            label="优惠券类型"
+            prop="type"
+            :rules="[{ required: true, message: '请选择优惠卷类型' }]"
+          >
+            <el-select
+              :disabled="isDisabled"
+              placeholder="优惠券类型"
+              v-model.trim="form.type"
+              filterable
+              clearable
+              @change="changeType"
+              style="width: 355px !important"
+            >
+              <el-option
+                v-for="item in couponTypeList"
+                :key="item.value"
+                :value="item.value"
+                :label="item.label"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col style="width: 395px" v-if="form.type == 'FULL_REDUCTION'">
+          <el-form-item
+            label="面值"
+            prop="faceValue"
+            :rules="[{ required: true, message: '请输入面值' }]"
+          >
+            <el-input
+              v-model="form.faceValue"
+              placeholder="请输入面值"
+              :disabled="isDisabled"
+            >
+              <template slot="append">元</template>
+            </el-input>
+          </el-form-item>
+        </el-col>
+        <el-col style="width: 395px" v-if="form.type == 'FULL_REDUCTION'">
+          <el-form-item
+            label="达标金额"
+            prop="fullAmount"
+            :rules="[{ required: true, message: '请输入达标金额' }]"
+          >
+            <el-input
+              v-model="form.fullAmount"
+              placeholder="请输入达标金额"
+              :disabled="isDisabled"
+            >
+              <template slot="append">元</template>
+            </el-input>
+          </el-form-item>
+        </el-col>
+        <el-col style="width: 395px" v-if="form.type == 'DISCOUNT'">
+          <el-form-item
+            label="折扣"
+            prop="faceValue"
+            :rules="[{ required: true, message: '请输入折扣' }]"
+          >
+            <el-input
+              v-model="form.faceValue"
+              placeholder="请输入折扣"
+              :disabled="isDisabled"
+            >
+              <template slot="append">%</template>
+            </el-input>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row :gutter="20">
+        <el-col style="width: 395px">
+          <el-form-item
+            label="有效期类型"
+            prop="effectiveType"
+            :rules="[{ required: true, message: '请选择有效期类型' }]"
+          >
+            <el-select
+              style="width: 355px !important"
+              placeholder="优惠券类型"
+              v-model.trim="form.effectiveType"
+              filterable
+              clearable
+              @change="changeEffectiveType"
+              :disabled="isDisabled"
+            >
+              <el-option label="固定有效期天数" value="DAYS"></el-option>
+              <el-option label="固定时间段" value="TIME_BUCKET"></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col style="width: 395px" v-if="form.effectiveType == 'DAYS'">
+          <el-form-item
+            prop="deadline"
+            :rules="[{ required: true, message: '请选择有效期天数' }]"
+          >
+            <span style="color: #606266"
+              >有效期天数
+              <el-tooltip placement="top" popper-class="mTooltip">
+                <div slot="content">自领取之日起多少天有效</div>
+                <i
+                  class="el-icon-question"
+                  style="font-size: 18px; color: #f56c6c"
+                ></i> </el-tooltip
+            ></span>
+            <el-input v-model="form.deadline" placeholder="请输入有效期天数">
+              <template slot="append">天</template>
+            </el-input>
+          </el-form-item>
+        </el-col>
+        <el-col style="width: 395px" v-if="form.effectiveType == 'TIME_BUCKET'">
+          <el-form-item
+            prop="effectiveTime"
+            :rules="[{ required: true, message: '请选择有效期' }]"
+          >
+            <span style="color: #606266"
+              >有效期
+              <el-tooltip placement="top" popper-class="mTooltip">
+                <div slot="content">优惠券可使用时间段</div>
+                <i
+                  class="el-icon-question"
+                  style="font-size: 18px; color: #f56c6c"
+                ></i> </el-tooltip
+            ></span>
+            <el-date-picker
+              style="width: 100%"
+              v-model="form.effectiveTime"
+              :picker-options="{ firstDayOfWeek: 1 }"
+              type="datetimerange"
+              :default-time="['00:00:00', '23:59:59']"
+              range-separator="-"
+              start-placeholder="活动开始日期"
+              end-placeholder="活动结束日期"
+            >
+            </el-date-picker>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row :gutter="20">
+        <el-col style="width: 395px">
+          <el-form-item
+            label="库存总量"
+            prop="stockCount"
+            :rules="[{ required: true, message: '请输入库存总量' }]"
+          >
+            <el-input v-model="form.stockCount" placeholder="请输入库存总量">
+              <template slot="append">张</template>
+            </el-input>
+          </el-form-item>
+        </el-col>
+        <el-col style="width: 395px">
+          <el-form-item
+            label="预警值"
+            prop="warningStockNum"
+            :rules="[{ required: true, message: '请输入预警值' }]"
+          >
+            <el-input v-model="form.warningStockNum" placeholder="请输入预警值">
+              <template slot="append">张</template>
+            </el-input>
+          </el-form-item>
+        </el-col>
+        <el-col style="width: 395px">
+          <el-form-item
+            prop="limitExchangeNum"
+            :rules="[{ required: true, message: '请输入领取上限' }]"
+          >
+            <span style="color: #606266"
+              >领取上限
+              <el-tooltip placement="top" popper-class="mTooltip">
+                <div slot="content">用户可领取最大张数</div>
+                <i
+                  class="el-icon-question"
+                  style="font-size: 18px; color: #f56c6c"
+                ></i> </el-tooltip
+            ></span>
+            <el-input
+              :disabled="isDisabled"
+              v-model="form.limitExchangeNum"
+              placeholder="请输入领取上限"
+            >
+              <template slot="append">张</template>
+            </el-input>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row :gutter="20">
+        <el-col style="width: 395px">
+          <el-form-item label="领取时间" prop="getTime">
+            <el-date-picker
+              style="width: 100%"
+              v-model="form.getTime"
+              :picker-options="{ firstDayOfWeek: 1 }"
+              type="datetimerange"
+              :default-time="['00:00:00', '23:59:59']"
+              range-separator="-"
+              start-placeholder="活动开始日期"
+              end-placeholder="活动结束日期"
+            >
+            </el-date-picker>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-form-item>
+        <el-button type="primary" v-if="activeRow" @click="resetCoupon"
+          >保存</el-button
+        >
+        <el-button type="primary" v-else @click="addCoupon">提交</el-button>
+        <el-button type="danger" @click="resetForm">重置</el-button>
+      </el-form-item>
+    </el-form>
+  </div>
+</template>
+<script>
+import { addSysCoupon, resetSysCoupon } from "./api.js";
+import { couponTypeList } from "@/utils/searchArray";
+import { getTimes } from "@/utils";
+export default {
+  data() {
+    return {
+      couponTypeList,
+      form: {
+        name: "",
+        description: "",
+        type: "",
+        faceValue: "",
+        fullAmount: "",
+        effectiveType: "",
+        effectiveTime: [],
+        stockCount: "",
+        warningStockNum: "",
+        limitExchangeNum: "",
+        getTime: [],
+      },
+      activeRow: null,
+      isDisabled: false,
+      title: "新增优惠券",
+    };
+  },
+  mounted() {
+    if (this.$route.query.row) {
+      this.activeRow = JSON.parse(this.$route.query.row);
+      this.form = { ...this.activeRow };
+      let effectiveStartTime = this.activeRow.effectiveStartTime;
+      let effectiveExpireTime = this.activeRow.effectiveExpireTime;
+      let startDate = this.activeRow.startDate;
+      let endDate = this.activeRow.endDate;
+      this.$set(this.form, "effectiveTime", [
+        effectiveStartTime,
+        effectiveExpireTime,
+      ]);
+      this.$set(this.form, "getTime", [startDate, endDate]);
+      this.title = this.activeRow.name;
+      if (this.activeRow?.consumeNum > 0) {
+        this.isDisabled = true;
+      }
+    }
+  },
+  methods: {
+    changeType(val) {
+      this.form.faceValue = "";
+      this.form.fullAmount = "";
+    },
+    changeEffectiveType() {
+      // this.form.effectiveTime = [];
+      this.$set(this.form,'effectiveTime',[])
+      this.form.deadline = "";
+    },
+    onCancel() {
+      this.$router.push("/couponManager");
+    },
+    resetForm() {
+      this.$refs.form.resetFields();
+      if (this.activeRow) {
+        this.form = { ...this.activeRow };
+        let effectiveStartTime = this.activeRow.effectiveStartTime;
+        let effectiveExpireTime = this.activeRow.effectiveExpireTime;
+        let startDate = this.activeRow.startDate;
+        let endDate = this.activeRow.endDate;
+        this.$set(this.form, "effectiveTime", [
+          effectiveStartTime,
+          effectiveExpireTime,
+        ]);
+        this.$set(this.form, "getTime", [startDate, endDate]);
+      }
+    },
+    async addCoupon() {
+      this.$refs.form.validate(async (some) => {
+        if (some) {
+          this.$confirm("您确定新增优惠券?", "提示", {
+            confirmButtonText: "确定",
+            cancelButtonText: "取消",
+            type: "warning",
+          })
+            .then(async () => {
+              try {
+                let { effectiveTime, getTime, ...rest } = this.form;
+                let params = {
+                  ...rest,
+                  ...getTimes(effectiveTime, [
+                    "effectiveStartTime",
+                    "effectiveExpireTime",
+                  ]),
+                  ...getTimes(getTime, ["startDate", "endDate"]),
+                };
+                const res = await addSysCoupon(params);
+                this.$message.success("新增成功");
+                this.onCancel();
+              } catch (e) {
+                console.log(e);
+              }
+            })
+            .catch(() => {});
+        }
+      });
+    },
+    resetCoupon() {
+      this.$refs.form.validate(async (some) => {
+        if (some) {
+          this.$confirm("您确定修改优惠券?", "提示", {
+            confirmButtonText: "确定",
+            cancelButtonText: "取消",
+            type: "warning",
+          })
+            .then(async () => {
+              try {
+                let { effectiveTime, getTime, ...rest } = this.form;
+                let params = {
+                  ...rest,
+                  ...getTimes(effectiveTime, [
+                    "effectiveStartTime",
+                    "effectiveExpireTime",
+                  ]),
+                  ...getTimes(getTime, ["startDate", "endDate"]),
+                };
+                const res = await resetSysCoupon(params);
+                this.$message.success("新增成功");
+                this.onCancel();
+              } catch (e) {
+                console.log(e);
+              }
+            })
+            .catch(() => {});
+        }
+      });
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+.form {
+  margin-top: 30px;
+}
+.infoTitle {
+  font-weight: 400;
+  margin-top: 30px;
+  font-size: 18px;
+}
+/deep/label {
+  font-weight: 400;
+}
+</style>

+ 480 - 0
src/views/couponManager/index.vue

@@ -0,0 +1,480 @@
+<!--  -->
+<template>
+  <div class="m-container">
+    <h2>
+      <div class="squrt"></div>
+      优惠券管理
+    </h2>
+    <div class="m-core">
+      <save-form
+        :inline="true"
+        :model="searchForm"
+        @submit="search"
+        @reset="onReSet"
+        ref="searchForm"
+      >
+        <el-form-item prop="search">
+          <el-input
+            v-model.trim="searchForm.search"
+            clearable
+            @keyup.enter.native="search"
+            placeholder="优惠券名称、编号"
+          ></el-input>
+        </el-form-item>
+        <el-form-item prop="type">
+          <el-select
+            placeholder="优惠券类型"
+            v-model.trim="searchForm.type"
+            filterable
+            clearable
+          >
+            <el-option
+              v-for="item in couponTypeList"
+              :key="item.value"
+              :value="item.value"
+              :label="item.label"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item prop="status">
+          <el-select
+            placeholder="优惠券状态"
+            v-model.trim="searchForm.status"
+            filterable
+            clearable
+          >
+            <el-option label="启用" value="1"></el-option>
+            <el-option label="停用" value="0"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-button native-type="submit" type="primary">搜索</el-button>
+          <el-button native-type="reset" type="danger">重置</el-button>
+        </el-form-item>
+      </save-form>
+      <auth auths="sysCoupon/add">
+        <el-button
+          type="primary"
+          style="margin-bottom: 30px"
+          @click="gotoDetail()"
+          >新增优惠券</el-button
+        >
+      </auth>
+
+      <div class="tableWrap">
+        <el-table
+          style="width: 100%"
+          :header-cell-style="{ background: '#EDEEF0', color: '#444' }"
+          :data="tableList"
+
+        >
+          <el-table-column
+            align="center"
+            prop="id"
+            label="优惠券编号"
+          ></el-table-column>
+          <el-table-column
+            align="center"
+            prop="name"
+            label="优惠券名称"
+          ></el-table-column>
+          <el-table-column align="center" prop="description" label="描述">
+            <template slot-scope="scope">
+              <div>
+                <Tooltip
+                  :content="scope.row.description ? scope.row.description : ''"
+                />
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column align="center" prop="studentId" label="类型">
+            <template slot-scope="scope">
+              <div>
+                {{ scope.row.type | couponTypeFilter }}
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column
+            align="center"
+            prop="cloudStudyUseStudentDuty"
+            width="140px"
+          >
+            <template slot="header" slot-scope="slot">
+              <div class="titleCell">
+                <span>面值</span>
+                <el-tooltip placement="top" popper-class="mTooltip">
+                  <div slot="content">可优惠面值</div>
+                  <i
+                    class="el-icon-question micon el-tooltip"
+                    style="
+                      font-size: 18px;
+                      color: #f56c6c;
+                      top: 2px;
+                      position: relative;
+                    "
+                  ></i>
+                </el-tooltip>
+              </div>
+            </template>
+            <template slot-scope="scope">
+              <div v-if="scope.row.type == 'FULL_REDUCTION'">
+                {{ scope.row.faceValue | hasMoneyFormat }}
+              </div>
+              <div v-if="scope.row.type == 'DISCOUNT'">
+                {{ scope.row.faceValue }}%
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column
+            align="center"
+            prop="cloudStudyUseStudentDuty"
+            width="140px"
+          >
+            <template slot="header" slot-scope="slot">
+              <div class="titleCell">
+                <span>达标金额</span>
+                <el-tooltip placement="top" popper-class="mTooltip">
+                  <div slot="content">消费满多少才可使用</div>
+                  <i
+                    class="el-icon-question micon el-tooltip"
+                    style="
+                      font-size: 18px;
+                      color: #f56c6c;
+                      top: 2px;
+                      position: relative;
+                    "
+                  ></i>
+                </el-tooltip>
+              </div>
+            </template>
+            <template slot-scope="scope">
+              <div>{{ scope.row.fullAmount | hasMoneyFormat }}</div>
+            </template>
+          </el-table-column>
+          <el-table-column
+            align="center"
+            prop="cloudStudyUseStudentDuty"
+            width="140px"
+          >
+            <template slot="header" slot-scope="slot">
+              <div class="titleCell">
+                <span>领取上限</span>
+                <el-tooltip placement="top" popper-class="mTooltip">
+                  <div slot="content">用户最大领取数量</div>
+                  <i
+                    class="el-icon-question micon el-tooltip"
+                    style="
+                      font-size: 18px;
+                      color: #f56c6c;
+                      top: 2px;
+                      position: relative;
+                    "
+                  ></i>
+                </el-tooltip>
+              </div>
+            </template>
+            <template slot-scope="scope">
+              <div>{{ scope.row.limitExchangeNum }}</div>
+            </template>
+          </el-table-column>
+          <el-table-column
+            align="center"
+            prop="cloudStudyUseStudentDuty"
+            width="140px"
+          >
+            <template slot="header" slot-scope="slot">
+              <div class="titleCell">
+                <span>有效期天数</span>
+                <el-tooltip placement="top" popper-class="mTooltip">
+                  <div slot="content">自领取之日起多少天有效</div>
+                  <i
+                    class="el-icon-question micon el-tooltip"
+                    style="
+                      font-size: 18px;
+                      color: #f56c6c;
+                      top: 2px;
+                      position: relative;
+                    "
+                  ></i>
+                </el-tooltip>
+              </div>
+            </template>
+            <template slot-scope="scope">
+              <div v-if="scope.row.deadline">{{ scope.row.deadline }}天</div>
+              <div v-else>--</div>
+            </template>
+          </el-table-column>
+          <el-table-column
+            align="center"
+            prop="cloudStudyUseStudentDuty"
+            width="160px"
+          >
+            <template slot="header" slot-scope="slot">
+              <div class="titleCell">
+                <span>有效期</span>
+                <el-tooltip placement="top" popper-class="mTooltip">
+                  <div slot="content">优惠券可使用时间段</div>
+                  <i
+                    class="el-icon-question micon el-tooltip"
+                    style="
+                      font-size: 18px;
+                      color: #f56c6c;
+                      top: 2px;
+                      position: relative;
+                    "
+                  ></i>
+                </el-tooltip>
+              </div>
+            </template>
+            <template slot-scope="scope">
+              <div>
+                <p>{{ scope.row.effectiveStartTime }}</p>
+                <p>{{ scope.row.effectiveExpireTime }}</p>
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column
+            align="center"
+            prop="cloudStudyUseStudentDuty"
+            width="160px"
+          >
+            <template slot="header" slot-scope="slot">
+              <div class="titleCell">
+                <span>领取时间</span>
+                <el-tooltip placement="top" popper-class="mTooltip">
+                  <div slot="content">用户可领取优惠券时间段</div>
+                  <i
+                    class="el-icon-question micon el-tooltip"
+                    style="
+                      font-size: 18px;
+                      color: #f56c6c;
+                      top: 2px;
+                      position: relative;
+                    "
+                  ></i>
+                </el-tooltip>
+              </div>
+            </template>
+            <template slot-scope="scope">
+              <div>
+                <p>{{ scope.row.startDate }}</p>
+                <p>{{ scope.row.endDate }}</p>
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column
+            align="center"
+            prop="stockCount"
+            label="总库存"
+          ></el-table-column>
+          <el-table-column
+            align="center"
+            prop="warningStockNum"
+            label="剩余库存"
+          >
+            <template slot-scope="scope">
+              <div>
+                {{ scope.row.stockCount - scope.row.consumeNum }}
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column align="center" prop="status" label="状态">
+            <template slot-scope="scope">
+              <div>
+                {{ scope.row.status ? "启用" : "停用" }}
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column
+            align="center"
+            prop="studentId"
+            label="操作"
+            width="120px"
+          >
+            <template slot-scope="scope">
+              <div>
+                <auth auths="sysCoupon/updateCoupon">
+                <!-- <el-button type="text" @click="gotoDetail(scope.row)"
+                  >查看</el-button
+                > -->
+                <el-button
+                  type="text"
+                  v-if="scope.row.status"
+                  @click="stop(scope.row)"
+                  >停用</el-button
+                >
+                <el-button type="text" v-else @click="start(scope.row)"
+                  >启用</el-button
+                >
+                <el-button
+                  type="text"
+                  v-if="!scope.row.status"
+                  @click="gotoDetail(scope.row)"
+                  >修改</el-button
+                >
+                </auth>
+                <auth auths="sysCoupon/delete">
+                  <el-button
+                    type="text"
+                    v-if="!scope.row.consumeNum > 0 && !scope.row.status"
+                    @click="removeCoupon(scope.row)"
+                    >删除</el-button
+                  >
+                </auth>
+              </div>
+            </template>
+          </el-table-column>
+        </el-table>
+        <pagination
+          sync
+          :total.sync="rules.total"
+          :page.sync="rules.page"
+          :limit.sync="rules.limit"
+          :page-sizes="rules.page_size"
+          @pagination="getList"
+        />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import axios from "axios";
+import { getToken } from "@/utils/auth";
+import pagination from "@/components/Pagination/index";
+import load from "@/utils/loading";
+import { getSysCoupon, resetSysCoupon, delSysCoupon } from "./api";
+import { couponTypeList } from "@/utils/searchArray";
+import Tooltip from "@/components/Tooltip/index";
+export default {
+  components: { pagination, Tooltip },
+  data() {
+    return {
+      couponTypeList,
+      searchForm: {
+        search: null,
+        type: null,
+        status: null,
+      },
+
+      tableList: [],
+      organList: [],
+      rules: {
+        // 分页规则
+        limit: 10, // 限制显示条数
+        page: 1, // 当前页
+        total: 0, // 总条数
+        page_size: [10, 20, 40, 50], // 选择限制显示条数
+      },
+    };
+  },
+  //生命周期 - 创建完成(可以访问当前this实例)
+  created() {},
+  //生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {
+    // 获取分部
+
+    this.init();
+  },
+  methods: {
+    init() {
+      this.getList();
+    },
+    async getList() {
+      try {
+        const res = await getSysCoupon({
+          ...this.searchForm,
+          page: this.rules.page,
+          rows: this.rules.limit,
+        });
+        this.tableList = res.data.rows;
+        this.rules.total = res.data.total;
+      } catch (e) {
+        console.log(e);
+      }
+    },
+    search() {
+      this.rules.page = 1;
+      this.getList();
+    },
+    onReSet() {
+      this.$refs.searchForm.resetFields();
+      this.search();
+    },
+    gotoDetail(row) {
+      if (row) {
+        this.$router.push({
+          path: "/operateManager/couponUpdate",
+          query: { row: JSON.stringify(row) },
+        });
+      } else {
+        this.$router.push("/operateManager/couponUpdate");
+      }
+    },
+    stop(row) {
+      this.$confirm("您确定停用优惠券?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(async () => {
+          try {
+            let params = {
+              ...row,
+            };
+            params.status = 0;
+            const res = await resetSysCoupon(params);
+            this.$message.success("停用成功");
+            this.getList();
+          } catch (e) {
+            console.log(e);
+          }
+        })
+        .catch(() => {});
+    },
+    start(row) {
+      this.$confirm("您确定启用优惠券?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(async () => {
+          try {
+            let params = {
+              ...row,
+            };
+            params.status = 1;
+            const res = await resetSysCoupon(params);
+            this.$message.success("启用成功");
+            this.getList();
+          } catch (e) {
+            console.log(e);
+          }
+        })
+        .catch(() => {});
+    },
+    removeCoupon(row) {
+      this.$confirm("您确定删除优惠券?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(async () => {
+          try {
+            const res = await delSysCoupon({ id: row.id });
+            this.$message.success("删除成功");
+            this.getList();
+          } catch (e) {
+            console.log(e);
+          }
+        })
+        .catch(() => {});
+    },
+  },
+};
+</script>
+<style lang='scss' scoped>
+.titleCell {
+  display: inline-block;
+}
+</style>

+ 1 - 1
src/views/stuRecodeManager/index.vue

@@ -370,7 +370,7 @@ import { getTimes } from "@/utils";
 import qs from "qs";
 import { permission } from "@/utils/directivePage";
 import { findStudentAttendance } from "@/api/buildTeam";
-import { Export } from "@/utils/downLoadFile";
+import { Export } from "@/utils/downLoadFile"; 
 import cleanDeep from "clean-deep";
 // import { queryTeacherAttendances } from "@/api/recodeManager";
 import { courseType, courseListType, stuAttendance } from "@/utils/searchArray";