Prechádzať zdrojové kódy

Merge branch 'master' of http://1.14.104.71:10880/root/ylrz_his_scrm_adminUI

caoliqin 2 mesiacov pred
rodič
commit
f74cc7904d

+ 1 - 1
.env.prod-kyt

@@ -34,7 +34,7 @@ ENV = 'development'
 VUE_APP_BASE_API = '/prod-api'
 
 #默认 1、会员 2、企微
-VUE_APP_COURSE_DEFAULT = 1
+VUE_APP_COURSE_DEFAULT = 2
 
 # 路由懒加载
 VUE_CLI_BABEL_TRANSPILE_MODULES = true

+ 13 - 2
src/api/company/statistics.js

@@ -100,7 +100,7 @@ export function exportCustomer(query) {
   })
 }
 
- 
+
 export function customerVisit(query) {
   return request({
     url: '/company/statistics/customerVisit',
@@ -116,6 +116,17 @@ export function exportCustomerVisit(query) {
   })
 }
 
-
+export function ipadStaticTotal(dateTime) {
+  return request({
+    url: '/company/statistics/ipadStaticTotal/' + dateTime,
+    method: 'get'
+  })
+}
+export function exportIpadStaticByTime(dateTime) {
+  return request({
+    url: '/company/statistics/exportIpadStaticByTime/' + dateTime,
+    method: 'get'
+  })
+}
 
 

+ 55 - 0
src/api/recharge/template.js

@@ -0,0 +1,55 @@
+import request from '@/utils/request'
+
+// 查询充值模板列表
+export function listRechargeTemplate(query) {
+  return request({
+    url: '/recharge-templates/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询充值模板详细
+export function getRechargeTemplate(id) {
+  return request({
+    url: '/recharge-templates/' + id,
+    method: 'get'
+  })
+}
+
+// 新增充值模板
+export function addRechargeTemplate(data) {
+  return request({
+    url: '/recharge-templates',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改充值模板
+export function updateRechargeTemplate(data) {
+  return request({
+    url: '/recharge-templates/' + data.id,
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除充值模板
+export function delRechargeTemplate(id) {
+  return request({
+    url: '/recharge-templates/' + id,
+    method: 'delete'
+  })
+}
+
+// 修改充值模板状态
+export function updateRechargeTemplateStatus(id, status) {
+  return request({
+    url: '/recharge-templates/' + id + '/status',
+    method: 'put',
+    params: {
+      status: status
+    }
+  })
+}

BIN
src/assets/logo/hcl.png


+ 33 - 31
src/views/components/course/userCourseCatalogDetails.vue

@@ -6,7 +6,7 @@
     <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
       <el-form-item label="小节名称" prop="title">
         <el-input v-model="queryParams.title" placeholder="请输入小节名称" clearable size="small"
-          @keyup.enter.native="handleQuery" />
+                  @keyup.enter.native="handleQuery" />
       </el-form-item>
       <el-form-item>
         <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
@@ -16,23 +16,23 @@
     <el-row :gutter="10" class="mb8">
       <el-col :span="1.5">
         <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
-          v-hasPermi="['course:userCourseVideo:add']">新增目录</el-button>
+                   v-hasPermi="['course:userCourseVideo:add']">新增目录</el-button>
       </el-col>
       <el-col :span="1.5">
         <el-button type="primary" plain :disabled="!ids || ids.length <= 0" size="mini" @click="openUpdates"
-          v-hasPermi="['course:userCourseVideo:updateTime']">修改时间</el-button>
+                   v-hasPermi="['course:userCourseVideo:updateTime']">修改时间</el-button>
       </el-col>
       <el-col :span="1.5">
         <el-button type="primary" plain size="mini" @click="openAdds"
-          v-hasPermi="['course:userCourseVideo:batchAdd']">批量添加</el-button>
+                   v-hasPermi="['course:userCourseVideo:batchAdd']">批量添加</el-button>
       </el-col>
       <el-col :span="1.5">
         <el-button type="primary" plain size="mini" @click="updateRedPageckeOpen"
-          v-hasPermi="['course:userCourseVideo:updateRed']">修改红包</el-button>
+                   v-hasPermi="['course:userCourseVideo:updateRed']">修改红包</el-button>
       </el-col>
       <el-col :span="1.5">
         <el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete"
-          v-hasPermi="['course:userCourseVideo:remove']">删除</el-button>
+                   v-hasPermi="['course:userCourseVideo:remove']">删除</el-button>
       </el-col>
       <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
     </el-row>
@@ -72,17 +72,17 @@
       <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
         <template slot-scope="scope">
           <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
-            v-hasPermi="['course:userCourseVideo:edit']">修改</el-button>
+                     v-hasPermi="['course:userCourseVideo:edit']">修改</el-button>
           <el-button size="mini" type="text" icon="el-icon-edit" @click="handleComment(scope.row)"
-            v-hasPermi="['course:courseWatchComment:list']">查看评论</el-button>
+                     v-hasPermi="['course:courseWatchComment:list']">查看评论</el-button>
           <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
-            v-hasPermi="['course:userCourseVideo:remove']">删除</el-button>
+                     v-hasPermi="['course:userCourseVideo:remove']">删除</el-button>
         </template>
       </el-table-column>
     </el-table>
 
     <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
-      @pagination="getList" />
+                @pagination="getList" />
     <el-dialog :title="title" :visible.sync="open" width="1000px" append-to-body>
       <el-form ref="form" :model="form" :rules="rules" label-width="110px" v-loading="uploadLoading">
         <el-form-item label="视频标题" prop="title">
@@ -120,17 +120,17 @@
 
         <el-form-item label="视频缩略图" prop="thumbnail">
           <el-upload v-model="form.thumbnail" class="avatar-uploader" :action="uploadUrl" :show-file-list="false"
-            :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload">
+                     :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload">
             <img v-if="form.thumbnail" :src="form.thumbnail" class="avatar" width="300px">
             <i v-else class="el-icon-plus avatar-uploader-icon"></i>
           </el-upload>
         </el-form-item>
         <video-upload :type="1" :isPrivate="isPrivate" :fileKey.sync="form.fileKey" :fileSize.sync="form.fileSize"
-          :videoUrl.sync="videoUrl" :fileName.sync="form.fileName" :line_1.sync="form.lineOne"
-          :line_2.sync="form.lineTwo" :line_3.sync="form.lineThree" :thumbnail.sync="form.thumbnail"
-          :uploadType.sync="form.uploadType" :isTranscode.sync="form.isTranscode"
-          :transcodeFileKey.sync="form.transcodeFileKey" @video-duration="handleVideoDuration"
-          @change="handleVideoChange" @selectProjects="handleSelectProjects" ref="videoUpload" append-to-body />
+                      :videoUrl.sync="videoUrl" :fileName.sync="form.fileName" :line_1.sync="form.lineOne"
+                      :line_2.sync="form.lineTwo" :line_3.sync="form.lineThree" :thumbnail.sync="form.thumbnail"
+                      :uploadType.sync="form.uploadType" :isTranscode.sync="form.isTranscode"
+                      :transcodeFileKey.sync="form.transcodeFileKey" @video-duration="handleVideoDuration"
+                      @change="handleVideoChange" @selectProjects="handleSelectProjects" ref="videoUpload" append-to-body />
 
         <el-form-item label="课题选择" prop="questionBankId">
           <el-button size="small" type="primary" @click="chooseQuestionBank">选取课题</el-button>
@@ -155,7 +155,7 @@
             <el-table-column label="操作" align="center" width="100px" fixed="right">
               <template slot-scope="scope">
                 <el-button size="mini" type="text" icon="el-icon-delete"
-                  @click="handleQuestionBankDelete(scope.row)">删除</el-button>
+                           @click="handleQuestionBankDelete(scope.row)">删除</el-button>
               </template>
             </el-table-column>
           </el-table>
@@ -177,7 +177,7 @@
             <el-table-column label="操作" align="center" width="100px" fixed="right">
               <template slot-scope="scope">
                 <el-button size="mini" type="text" icon="el-icon-delete"
-                  @click="handleCourseProductDelete(scope.row)">删除</el-button>
+                           @click="handleCourseProductDelete(scope.row)">删除</el-button>
               </template>
             </el-table-column>
           </el-table>
@@ -204,12 +204,12 @@
       <el-form ref="form" :model="updateBatchData.form" label-width="110px">
         <el-form-item label="看课时间" prop="timeRange">
           <el-time-picker is-range v-model="updateBatchData.form.timeRange" range-separator="至" start-placeholder="开始时间"
-            value-format="HH:mm:ss" end-placeholder="结束时间" placeholder="选择时间范围">
+                          value-format="HH:mm:ss" end-placeholder="结束时间" placeholder="选择时间范围">
           </el-time-picker>
         </el-form-item>
         <el-form-item label="领取红包时间" prop="lastJoinTime">
           <el-time-picker v-model="updateBatchData.form.lastJoinTime" :selectableRange="updateBatchData.form.timeRange"
-            value-format="HH:mm:ss" placeholder="选择时间范围">
+                          value-format="HH:mm:ss" placeholder="选择时间范围">
           </el-time-picker>
           <p style="color: red;margin: 0;font-size: 12px">超过领取红包时间,只允许看课,不允许领取红包</p>
         </el-form-item>
@@ -230,19 +230,19 @@
       <el-form :inline="true" :model="addBatchData.queryParams" class="library-search">
         <el-form-item label="素材名称">
           <el-input v-model="addBatchData.queryParams.resourceName" placeholder="请输入素材名称" clearable size="small"
-            @keyup.enter.native="resourceList" />
+                    @keyup.enter.native="resourceList" />
         </el-form-item>
         <el-form-item label="类型">
           <el-select v-model="addBatchData.queryParams.typeId" @change="changeCateType" placeholder="请选择素材类型" clearable
-            size="small">
+                     size="small">
             <el-option v-for="item in addBatchData.typeOptions" :key="item.dictValue" :label="item.dictLabel"
-              :value="item.dictValue" />
+                       :value="item.dictValue" />
           </el-select>
         </el-form-item>
         <el-form-item label="子类型">
           <el-select v-model="addBatchData.queryParams.typeSubId" placeholder="请选择素材子类型" clearable size="small">
             <el-option v-for="item in addBatchData.typeSubOptions" :key="item.dictValue" :label="item.dictLabel"
-              :value="item.dictValue" />
+                       :value="item.dictValue" />
           </el-select>
         </el-form-item>
         <el-form-item>
@@ -252,7 +252,7 @@
 
       <!-- 视频列表 -->
       <el-table v-loading="addBatchData.loading" :data="addBatchData.list"
-        @selection-change="handVideoleSelectionChange" height="400px">
+                @selection-change="handVideoleSelectionChange" height="400px">
         <el-table-column type="selection" width="55" align="center" />
         <el-table-column label="素材名称" align="center" prop="resourceName" />
         <el-table-column label="文件名称" align="center" prop="fileName" />
@@ -274,8 +274,8 @@
 
       <!-- 分页 -->
       <pagination v-show="addBatchData.total > 0" :total="addBatchData.total"
-        :page.sync="addBatchData.queryParams.pageNum" :limit.sync="addBatchData.queryParams.pageSize"
-        @pagination="resourceList" />
+                  :page.sync="addBatchData.queryParams.pageNum" :limit.sync="addBatchData.queryParams.pageSize"
+                  @pagination="resourceList" />
 
       <div slot="footer" class="dialog-footer">
         <el-button type="primary" @click="batchVideoSave">确 定</el-button>
@@ -304,9 +304,9 @@
       </div>
     </el-dialog>
     <el-dialog :title="commentDialog.title" :visible.sync="commentDialog.open" width="1000px" append-to-body
-      :close-on-click-modal="false">
+               :close-on-click-modal="false">
       <course-watch-comment ref="courseWatchComment" :courseId="commentDialog.courseId" :videoId="commentDialog.videoId"
-        v-if="commentDialog.open">
+                            v-if="commentDialog.open">
       </course-watch-comment>
     </el-dialog>
 
@@ -429,7 +429,9 @@ export default {
       // 非多个禁用
       multiple: true,
       // 表单参数
-      form: {},
+      form: {
+        courseProducts:[]
+      },
       updateBatchData: {
         open: false,
         form: {}
@@ -779,7 +781,7 @@ export default {
             return
           }
           if (this.form.isProduct != null && this.form.isProduct == 1 && this.form.courseProducts.length < 1) {
-             this.$message({
+            this.$message({
               message: '请选择关联商品',
               type: 'warning'
             });

+ 4 - 0
src/views/his/company/index.vue

@@ -203,6 +203,9 @@
          <el-form-item  label="管理员密码" prop="password" v-if="form.companyId==null">
           <el-input type="password" v-model="form.password" placeholder="请输入管理员密码" />
         </el-form-item>
+      <el-form-item label="掉线通知群名" prop="groupName">
+        <el-input v-model="form.groupName" :maxlength="15" placeholder="请输入掉线通知群名" />
+      </el-form-item>
         <el-form-item label="地址" prop="companyAddress">
           <el-input v-model="form.companyAddress" placeholder="请输入地址" />
         </el-form-item>
@@ -644,6 +647,7 @@ export default {
         restartTime: '13:10',
         balance: null,
         companyType: null,
+        groupName: null,
         userId: null,
         remark: null,
         linkName: null,

+ 252 - 0
src/views/his/statistics/ipadStatic.vue

@@ -0,0 +1,252 @@
+<template>
+    <div class="app-container">
+      <el-card>
+        <div slot="header" class="clearfix">
+          <span>设备绑定统计</span>
+        </div>
+
+        <el-tabs v-model="activeTab" @tab-click="handleTabClick">
+          <el-tab-pane label="按天统计" name="daily">
+            <el-form :inline="true" class="demo-form-inline">
+              <el-form-item label="日期">
+                <el-date-picker
+                  v-model="dailyDate"
+                  type="date"
+                  placeholder="选择日期"
+                  value-format="yyyy-MM-dd"
+                  @change="handleDailyDateChange"
+                ></el-date-picker>
+              </el-form-item>
+
+              <el-form-item>
+                <el-button type="primary" @click="searchDaily">查询</el-button>
+                <el-button @click="resetDaily">重置</el-button>
+                <el-button type="success" @click="exportDaily">导出</el-button>
+              </el-form-item>
+            </el-form>
+
+            <el-table
+              v-loading="dailyLoading"
+              border
+              :data="companyList"
+              style="width: 100%"
+            >
+              <el-table-column prop="date" label="日期" width="180" />
+              <el-table-column prop="companyName" label="公司名称" />
+              <el-table-column prop="bindCount" label="绑定台数" />
+            </el-table>
+
+            <div class="chart-container" style="margin-top: 20px; height: 400px">
+              <div ref="dailyChart" style="height: 100%; width: 100%"></div>
+            </div>
+          </el-tab-pane>
+
+          <el-tab-pane label="按月统计" name="monthly">
+            <el-form :inline="true" class="demo-form-inline">
+              <el-form-item label="月份">
+                <el-date-picker
+                  v-model="monthlyDate"
+                  type="month"
+                  placeholder="选择月份"
+                  value-format="yyyy-MM"
+                  @change="handleMonthlyDateChange"
+                ></el-date-picker>
+              </el-form-item>
+
+              <el-form-item>
+                <el-button type="primary" @click="searchMonthly">查询</el-button>
+                <el-button @click="resetMonthly">重置</el-button>
+                <el-button type="success" @click="exportMonthly">导出</el-button>
+              </el-form-item>
+            </el-form>
+
+            <el-table
+              v-loading="monthlyLoading"
+              border
+              :data="companyList"
+              style="width: 100%"
+            >
+              <el-table-column prop="date" label="月份" width="180" />
+              <el-table-column prop="companyName" label="公司名称" />
+              <el-table-column prop="bindCount" label="绑定台数" />
+            </el-table>
+
+            <div class="chart-container" style="margin-top: 20px; height: 400px">
+              <div ref="monthlyChart" style="height: 100%; width: 100%"></div>
+            </div>
+          </el-tab-pane>
+        </el-tabs>
+      </el-card>
+    </div>
+  </template>
+
+  <script>
+  import { ipadStaticTotal,exportIpadStaticByTime} from "@/api/company/statistics";
+
+  export default {
+    name: 'ipadStatic',
+    data() {
+      const today = this.parseTime(new Date(), '{y}-{m}-{d}')
+      const yesterday = this.parseTime(new Date(new Date().getTime() - 24 * 60 * 60 * 1000), '{y}-{m}-{d}')
+      return {
+        // 激活的标签页
+        activeTab: 'daily',
+        // 按天统计数据
+        dailyLoading: false,
+        dailyDate: yesterday, // 默认当天
+        // 按月统计数据
+        monthlyLoading: false,
+        monthlyDate: this.parseTime(new Date(), '{y}-{m}'), // 默认当月
+        companyList: [],
+      }
+    },
+    created() {
+      // 获取当天数据
+      this.getList()
+    },
+    methods: {
+      // 标签页切换
+      handleTabClick(tab) {
+        if (tab.name === 'daily') {
+          this.getList()
+        } else if (tab.name === 'monthly') {
+          this.getMonthlyList()
+        }
+      },
+
+      // 按天统计相关方法
+      handleDailyDateChange(val) {
+        if (val) {
+          this.dailyDate = val
+        }
+      },
+      searchDaily() {
+        this.getList()
+      },
+      resetDaily() {
+        const today = this.parseTime(new Date(), '{y}-{m}-{d}')
+        const yesterday = this.parseTime(new Date(new Date().getTime() - 24 * 60 * 60 * 1000), '{y}-{m}-{d}')
+        this.dailyDate = yesterday
+        this.getList()
+      },
+
+      // 导出
+      exportDaily() {
+        this.$confirm("是否确认导出数据项?", "警告", {
+            confirmButtonText: "确定",
+            cancelButtonText: "取消",
+            type: "warning",
+        })
+            .then(() => {
+            this.exportLoading = true;
+            return exportIpadStaticByTime(this.dailyDate);
+            })
+            .then((response) => {
+            this.download(response.msg);
+            this.exportLoading = false;
+            })
+            .catch(() => { });
+      },
+      getList() {
+        this.dailyLoading = true
+        ipadStaticTotal(this.dailyDate).then(response => {
+          // 处理返回数据,添加日期字段用于表格和图表显示
+          this.companyList = response.list;
+          this.dailyLoading = false;
+        }).catch(() => {
+          this.dailyLoading = false;
+        });
+      },
+
+      // 按月统计相关方法
+      handleMonthlyDateChange(val) {
+        if (val) {
+          this.monthlyDate = val
+        }
+      },
+      searchMonthly() {
+        this.getMonthlyList()
+      },
+      resetMonthly() {
+        this.monthlyDate = this.parseTime(new Date(), '{y}-{m}')
+        this.getMonthlyList()
+      },
+      exportMonthly() {
+        this.$confirm("是否确认导出数据项?", "警告", {
+            confirmButtonText: "确定",
+            cancelButtonText: "取消",
+            type: "warning",
+        })
+            .then(() => {
+            this.exportLoading = true;
+            return exportIpadStaticByTime(this.monthlyDate);
+            })
+            .then((response) => {
+            this.download(response.msg);
+            this.exportLoading = false;
+            })
+            .catch(() => { });
+      },
+      getMonthlyList() {
+        this.monthlyLoading = true
+        ipadStaticTotal(this.monthlyDate).then(response => {
+          // 处理返回数据,添加月份字段用于表格和图表显示
+          this.companyList = response.list;
+          this.monthlyLoading = false;
+        }).catch(() => {
+          this.monthlyLoading = false;
+          this.monthlyTotal = 0;
+        });
+      },
+
+      // 日期格式化
+      parseTime(time, pattern) {
+        let date;
+        if (arguments.length === 0 || !time) {
+          return null
+        }
+        const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
+
+        if (typeof time === 'object') {
+          date = time
+        } else {
+          if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
+            time = parseInt(time)
+          } else if (typeof time === 'string') {
+            time = time.replace(new RegExp(/-/gm), '/')
+          }
+          if ((typeof time === 'number') && (time.toString().length === 10)) {
+            time = time * 1000
+          }
+          date = new Date(time)
+        }
+        const formatObj = {
+          y: date.getFullYear(),
+          m: date.getMonth() + 1,
+          d: date.getDate(),
+          h: date.getHours(),
+          i: date.getMinutes(),
+          s: date.getSeconds(),
+          a: date.getDay()
+        }
+        const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
+          let value = formatObj[key]
+          // Note: getDay() returns 0 on Sunday
+          if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
+          if (result.length > 0 && value < 10) {
+            value = '0' + value
+          }
+          return value || 0
+        })
+        return time_str
+      }
+    }
+  }
+  </script>
+
+  <style scoped>
+  .chart-container {
+    position: relative;
+    padding: 20px 0;
+  }
+  </style>

+ 479 - 0
src/views/user/rechargeTemplate/index.vue

@@ -0,0 +1,479 @@
+<template>
+  <div class="app-container">
+    <!-- 查询条件 -->
+    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="模板名称" prop="templateName">
+        <el-input
+          v-model="queryParams.templateName"
+          placeholder="请输入模板名称"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="状态" prop="status">
+        <el-select v-model="queryParams.status" placeholder="请选择状态" clearable>
+          <el-option label="启用" value="1" />
+          <el-option label="禁用" value="0" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="标签" prop="tag">
+        <el-input
+          v-model="queryParams.tag"
+          placeholder="请输入标签"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <!-- 操作按钮 -->
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+          v-hasPermi="['recharge:template:add']"
+        >新增</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="el-icon-delete"
+          size="mini"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['recharge:template:remove']"
+        >删除</el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <!-- 表格数据 -->
+    <el-table v-loading="loading" :data="templateList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="模板ID" align="center" prop="id" width="80" />
+      <el-table-column label="模板名称" align="center" prop="templateName" :show-overflow-tooltip="true" />
+      <el-table-column label="储值金额" align="center" prop="rechargeAmount" width="100">
+        <template slot-scope="scope">
+          <span>¥{{ scope.row.rechargeAmount }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="赠送金额" align="center" prop="bonusAmount" width="100">
+        <template slot-scope="scope">
+          <span>¥{{ scope.row.bonusAmount || 0 }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="标签" align="center" prop="tag" width="100">
+        <template slot-scope="scope">
+          <el-tag v-if="scope.row.tag" size="mini">{{ scope.row.tag }}</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="限购次数" align="center" prop="purchaseLimit" width="100" />
+      <el-table-column label="排序" align="center" prop="sortOrder" width="80" />
+      <el-table-column label="状态" align="center" prop="status" width="100">
+        <template slot-scope="scope">
+          <el-switch
+            v-model="scope.row.status"
+            :active-value="1"
+            :inactive-value="0"
+            @change="handleStatusChange(scope.row)"
+          ></el-switch>
+        </template>
+      </el-table-column>
+      <el-table-column label="默认选中" align="center" prop="isDefault" width="100">
+        <template slot-scope="scope">
+          <el-tag v-if="scope.row.isDefault === 1" type="success" size="mini">是</el-tag>
+          <el-tag v-else type="info" size="mini">否</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="有效期" align="center" width="180">
+        <template slot-scope="scope">
+          <span v-if="scope.row.startTime && scope.row.endTime">
+            {{ parseTime(scope.row.startTime, '{y}-{m}-{d}') }} 至 {{ parseTime(scope.row.endTime, '{y}-{m}-{d}') }}
+          </span>
+          <span v-else>永久有效</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="180">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-view"
+            @click="handleDetail(scope.row)"
+          >详情</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['recharge:template:edit']"
+          >修改</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['recharge:template:remove']"
+          >删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <!-- 分页 -->
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改充值模板对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="120px">
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="模板名称" prop="templateName">
+              <el-input v-model="form.templateName" placeholder="请输入模板名称" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="储值金额" prop="rechargeAmount">
+              <el-input-number v-model="form.rechargeAmount" :precision="2" :min="0" placeholder="请输入储值金额" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="赠送金额" prop="bonusAmount">
+              <el-input-number v-model="form.bonusAmount" :precision="2" :min="0" placeholder="请输入赠送金额" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="限购次数" prop="purchaseLimit">
+              <el-input-number v-model="form.purchaseLimit" :min="0" placeholder="请输入限购次数,0为不限制" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="排序序号" prop="sortOrder">
+              <el-input-number v-model="form.sortOrder" :min="0" placeholder="请输入排序序号" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="标签" prop="tag">
+              <el-input v-model="form.tag" placeholder="请输入标签" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="状态" prop="status">
+              <el-radio-group v-model="form.status">
+                <el-radio :label="1">启用</el-radio>
+                <el-radio :label="0">禁用</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="默认选中" prop="isDefault">
+              <el-radio-group v-model="form.isDefault">
+                <el-radio :label="1">是</el-radio>
+                <el-radio :label="0">否</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="有效期" prop="validTime">
+              <el-date-picker
+                v-model="validTime"
+                type="datetimerange"
+                range-separator="至"
+                start-placeholder="开始日期"
+                end-placeholder="结束日期"
+                value-format="yyyy-MM-dd HH:mm:ss"
+                format="yyyy-MM-dd HH:mm:ss"
+              ></el-date-picker>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="图标URL" prop="iconUrl">
+              <el-input v-model="form.iconUrl" placeholder="请输入图标URL" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="详情链接" prop="detailUrl">
+              <el-input v-model="form.detailUrl" placeholder="请输入详情链接" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="描述文案" prop="shortDesc">
+              <el-input v-model="form.shortDesc" type="textarea" placeholder="请输入描述文案" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="权益详情" prop="benefitDetails">
+              <el-input v-model="form.benefitDetails" type="textarea" placeholder="请输入权益详情" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+
+    <!-- 详情对话框 -->
+    <el-dialog title="充值模板详情" :visible.sync="detailOpen" width="800px" append-to-body>
+      <el-descriptions :column="2" border>
+        <el-descriptions-item label="模板名称">{{ detailData.templateName }}</el-descriptions-item>
+        <el-descriptions-item label="储值金额">¥{{ detailData.rechargeAmount }}</el-descriptions-item>
+        <el-descriptions-item label="赠送金额">¥{{ detailData.bonusAmount || 0 }}</el-descriptions-item>
+        <el-descriptions-item label="限购次数">{{ detailData.purchaseLimit || '不限制' }}</el-descriptions-item>
+        <el-descriptions-item label="排序序号">{{ detailData.sortOrder }}</el-descriptions-item>
+        <el-descriptions-item label="标签">{{ detailData.tag || '无' }}</el-descriptions-item>
+        <el-descriptions-item label="状态">
+          <el-tag :type="detailData.status === 1 ? 'success' : 'danger'">
+            {{ detailData.status === 1 ? '启用' : '禁用' }}
+          </el-tag>
+        </el-descriptions-item>
+        <el-descriptions-item label="默认选中">
+          <el-tag :type="detailData.isDefault === 1 ? 'success' : 'info'">
+            {{ detailData.isDefault === 1 ? '是' : '否' }}
+          </el-tag>
+        </el-descriptions-item>
+        <el-descriptions-item label="有效期" :span="2">
+          <span v-if="detailData.startTime && detailData.endTime">
+            {{ parseTime(detailData.startTime, '{y}-{m}-{d} {h}:{i}:{s}') }} 至 {{ parseTime(detailData.endTime, '{y}-{m}-{d} {h}:{i}:{s}') }}
+          </span>
+          <span v-else>永久有效</span>
+        </el-descriptions-item>
+        <el-descriptions-item label="图标URL" :span="2">{{ detailData.iconUrl || '无' }}</el-descriptions-item>
+        <el-descriptions-item label="详情链接" :span="2">{{ detailData.detailUrl || '无' }}</el-descriptions-item>
+        <el-descriptions-item label="描述文案" :span="2">{{ detailData.shortDesc || '无' }}</el-descriptions-item>
+        <el-descriptions-item label="权益详情" :span="2">{{ detailData.benefitDetails || '无' }}</el-descriptions-item>
+      </el-descriptions>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="detailOpen = false">关 闭</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { listRechargeTemplate, getRechargeTemplate, delRechargeTemplate, addRechargeTemplate, updateRechargeTemplate, updateRechargeTemplateStatus } from "@/api/recharge/template";
+
+export default {
+  name: "RechargeTemplate",
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 充值模板表格数据
+      templateList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 是否显示详情弹出层
+      detailOpen: false,
+      // 详情数据
+      detailData: {},
+      // 有效期时间范围
+      validTime: [],
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        templateName: null,
+        status: null,
+        tag: null
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        templateName: [
+          { required: true, message: "模板名称不能为空", trigger: "blur" }
+        ],
+        rechargeAmount: [
+          { required: true, message: "储值金额不能为空", trigger: "blur" }
+        ],
+        status: [
+          { required: true, message: "状态不能为空", trigger: "change" }
+        ],
+        sortOrder: [
+          { required: true, message: "排序序号不能为空", trigger: "blur" }
+        ]
+      }
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    /** 查询充值模板列表 */
+    getList() {
+      this.loading = true;
+      listRechargeTemplate(this.queryParams).then(response => {
+        this.templateList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        templateName: null,
+        rechargeAmount: null,
+        bonusAmount: null,
+        benefitDetails: null,
+        status: 1,
+        sortOrder: 0,
+        startTime: null,
+        endTime: null,
+        userType: null,
+        purchaseLimit: null,
+        tag: null,
+        shortDesc: null,
+        detailUrl: null,
+        iconUrl: null,
+        isDefault: 0
+      };
+      this.validTime = [];
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length!==1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加充值模板";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const id = row.id || this.ids
+      getRechargeTemplate(id).then(response => {
+        this.form = response.data;
+        // 设置有效期时间范围
+        if (this.form.startTime && this.form.endTime) {
+          this.validTime = [this.form.startTime, this.form.endTime];
+        }
+        this.open = true;
+        this.title = "修改充值模板";
+      });
+    },
+    /** 详情按钮操作 */
+    handleDetail(row) {
+      const id = row.id;
+      getRechargeTemplate(id).then(response => {
+        this.detailData = response.data;
+        this.detailOpen = true;
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          // 处理有效期时间
+          if (this.validTime && this.validTime.length === 2) {
+            this.form.startTime = this.validTime[0];
+            this.form.endTime = this.validTime[1];
+          } else {
+            this.form.startTime = null;
+            this.form.endTime = null;
+          }
+
+          if (this.form.id != null) {
+            updateRechargeTemplate(this.form).then(response => {
+              this.$modal.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            addRechargeTemplate(this.form).then(response => {
+              this.$modal.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$modal.confirm('是否确认删除充值模板编号为"' + ids + '"的数据项?').then(function() {
+        return delRechargeTemplate(ids);
+      }).then(() => {
+        this.getList();
+        this.$modal.msgSuccess("删除成功");
+      }).catch(() => {});
+    },
+    /** 状态修改 */
+    handleStatusChange(row) {
+      let text = row.status === 1 ? "启用" : "停用";
+      this.$modal.confirm('确认要"' + text + '""' + row.templateName + '"模板吗?').then(function() {
+        return updateRechargeTemplateStatus(row.id, row.status);
+      }).then(() => {
+        this.$modal.msgSuccess(text + "成功");
+      }).catch(function() {
+        row.status = row.status === 0 ? 1 : 0;
+      });
+    }
+  }
+};
+</script>