瀏覽代碼

Merge branch 'test'

DESKTOP-2S67K1S\31396 2 年之前
父節點
當前提交
14b69a7873
共有 54 個文件被更改,包括 3165 次插入931 次删除
  1. 43 0
      src/api/device/music.js
  2. 43 0
      src/api/operation/dialog.js
  3. 61 0
      src/api/operation/scene.js
  4. 36 0
      src/api/order/list.js
  5. 35 0
      src/api/push/update.js
  6. 27 0
      src/api/service/quota.js
  7. 9 0
      src/api/user/list.js
  8. 二進制
      src/assets/images/operation/kugou.png
  9. 15 9
      src/common/main.scss
  10. 16 11
      src/components/Upload/index.vue
  11. 3 0
      src/main.js
  12. 21 2
      src/mixin/index.js
  13. 554 522
      src/router/index.js
  14. 0 4
      src/views/content/banner/detail.vue
  15. 1 3
      src/views/device/article/detail.vue
  16. 26 9
      src/views/device/list/detail.vue
  17. 17 1
      src/views/device/list/index.vue
  18. 293 0
      src/views/device/music/index.vue
  19. 52 71
      src/views/device/version/detail.vue
  20. 0 2
      src/views/goods/list/detail.vue
  21. 25 32
      src/views/music/album/detail.vue
  22. 0 4
      src/views/music/anchor/detail.vue
  23. 1 5
      src/views/music/blog/detail.vue
  24. 1 5
      src/views/music/choiceness/detail.vue
  25. 0 4
      src/views/music/list/detail.vue
  26. 3 4
      src/views/music/list/index.vue
  27. 1 3
      src/views/music/menu/detail.vue
  28. 1 5
      src/views/music/program/detail.vue
  29. 1 0
      src/views/music/program/index.vue
  30. 1 5
      src/views/music/radio/detail.vue
  31. 1 8
      src/views/music/singer/detail.vue
  32. 0 4
      src/views/ohplay/operation/index.vue
  33. 7 4
      src/views/operation/channel/detail.vue
  34. 223 0
      src/views/operation/dialog/index.vue
  35. 155 66
      src/views/operation/recommend/index.vue
  36. 205 0
      src/views/operation/scene/detail.vue
  37. 95 0
      src/views/operation/scene/index.vue
  38. 0 4
      src/views/operation/startPage/detail.vue
  39. 7 9
      src/views/operation/tag/detail.vue
  40. 14 16
      src/views/operation/waken/detail.vue
  41. 366 0
      src/views/order/list/index.vue
  42. 0 2
      src/views/project/list/detail.vue
  43. 1 4
      src/views/push/message/index.vue
  44. 135 0
      src/views/push/update/detail.vue
  45. 136 0
      src/views/push/update/index.vue
  46. 0 4
      src/views/registration/content/detail.vue
  47. 0 4
      src/views/registration/exchange/detail.vue
  48. 1 5
      src/views/registration/lottery/detail.vue
  49. 0 4
      src/views/registration/regConfig/index.vue
  50. 62 37
      src/views/service/package/detail.vue
  51. 60 29
      src/views/service/package/index.vue
  52. 10 30
      src/views/service/qqmusic/index.vue
  53. 172 0
      src/views/service/quota/index.vue
  54. 229 0
      src/views/user/list/index.vue

+ 43 - 0
src/api/device/music.js

@@ -0,0 +1,43 @@
+import request from '@/utils/request'
+
+// 列表
+export function list(data){
+  return request({
+    url: `/admin/musicRights/selectMusicRightsPage`,
+    method: 'post',
+    data
+  })
+}
+
+// 新增 / 编辑
+export function submit(data){
+  return request({
+    url: `/admin/musicRights/saveOrUpdateMusicRights`,
+    method: 'post',
+    data
+  })
+}
+
+// 详情
+export function detail(id) {
+  return request({
+    url: `/admin/musicRights/getMusicRightsById/${id}`,
+    method: 'get'
+  })
+}
+
+// 上下架
+export function change(id, status){
+  return request({
+    url: `/admin/musicRights/hitOrSold/${id}/${status}`,
+    method: 'get'
+  })
+}
+
+// 设备列表
+export function devList(type) {
+  return request({
+    url: `/admin/musicRights/getIsExistclientTypeList/${type}`,
+    method: 'get'
+  })
+}

+ 43 - 0
src/api/operation/dialog.js

@@ -0,0 +1,43 @@
+import request from '@/utils/request'
+
+// 列表
+export function list(data) {
+  return request({
+    url: `/admin/bullframe/selectBullframePage`,
+    method: 'post',
+    data
+  })
+}
+
+// 新增 / 编辑
+export function submit(data){
+  return request({
+    url: `/admin/bullframe/saveOrUpdateBullframe`,
+    method: 'post',
+    data
+  })
+}
+
+// 上下架
+export function change(id, status) {
+  return request({
+    url: `/admin/bullframe/hitOrSold/${id}/${status}`,
+    method: 'get'
+  })
+}
+
+// 产品型号
+export function devList(type) {
+  return request({
+    url: `/admin/bullframe/getIsExistclientTypeList/${type}`,
+    method: 'get'
+  })
+}
+
+// 详情
+export function detail(id){
+  return request({
+    url: `/admin/bullframe/getBullframeById/${id}`,
+    method: 'get'
+  })
+}

+ 61 - 0
src/api/operation/scene.js

@@ -0,0 +1,61 @@
+import request from '@/utils/request'
+
+// 列表
+export function list(data) {
+  return request({
+    url: `/admin/scenezone/list`,
+    method: 'post',
+    data
+  })
+}
+
+// 上下架
+export function change(type, ids, status){
+  return request({
+    url: `/admin/scenezone/hitOrSold/${type}/${ids}/${status}`,
+    method: 'get'
+  })
+}
+
+// 详情
+export function detail(id){
+  return request({
+    url: `/admin/scenezone/getGroupDetailById/${id}`,
+    method: 'get'
+  })
+}
+
+// 编辑详情
+export function edit(data){
+  return request({
+    url: `/admin/scenezone/editGroup`,
+    method: 'post',
+    data
+  })
+}
+
+// 专区列表
+export function detailList(data){
+  return request({
+    url: `/admin/scenezone/selectMenuPage`,
+    method: 'post',
+    data
+  })
+}
+
+// 专区详情
+export function menuDetail(menuId){
+  return request({
+    url: `/admin/scenezone/getMenuDetailById/${menuId}`,
+    method: 'get'
+  })
+}
+
+// 编辑专区
+export function editMenu(data){
+  return request({
+    url: `/admin/scenezone/editMenu`,
+    method: 'post',
+    data
+  })
+}

+ 36 - 0
src/api/order/list.js

@@ -0,0 +1,36 @@
+import request from "@/utils/request"
+
+// 列表
+export function list(data){
+  return request({
+    url: `/admin/order/page`,
+    method: 'post',
+    data
+  })
+}
+
+// 历史导出列表
+export function dialogList(data) {
+  return request({
+    url: `/admin/order/export/page`,
+    method: 'post',
+    data
+  })
+}
+
+// 导出
+export function download(data){
+  return request({
+    url: `/admin/order/excelDownload`,
+    method: 'post',
+    data
+  })
+}
+
+// 历史订单下载
+export function downLoadHistory(msgId) {
+  return request({
+    url: `/admin/order/getexportUrlBymsgId/${msgId}`,
+    method: 'get'
+  })
+}

+ 35 - 0
src/api/push/update.js

@@ -0,0 +1,35 @@
+import request from '@/utils/request'
+
+// 列表
+export function list(data) {
+  return request({
+    url: `/admin/appupdate/page`,
+    method: 'post',
+    data
+  })
+}
+
+// 详情
+export function detail(id) {
+  return request({
+    url: `/admin/appupdate/queryById/${id}`,
+    method: 'get'
+  })
+}
+
+// 新增 编辑
+export function submit(data) {
+  return request({
+    url: `/admin/appupdate/addOrUpdate`,
+    method: 'post',
+    data
+  })
+}
+
+// 删除
+export function remove(id, status) {
+  return request({
+    url: `/admin/appupdate/hitOrSold/${id}/${status}`,
+    method: 'get'
+  })
+}

+ 27 - 0
src/api/service/quota.js

@@ -0,0 +1,27 @@
+import request from '@/utils/request'
+
+// 列表
+export function list(data){
+  return request({
+    url: `/admin/Atmd/quota/selectQuotaPage`,
+    method: 'post',
+    data
+  })
+}
+
+// 详情
+export function detail(id){
+  return request({
+    url: `/admin/Atmd/quota/getQuotaById/${id}`,
+    method: 'get'
+  })
+}
+
+// 新增
+export function create(data){
+  return request({
+    url: `/admin/Atmd/quota/createQuota`,
+    method: 'post',
+    data
+  })
+}

+ 9 - 0
src/api/user/list.js

@@ -0,0 +1,9 @@
+import request from '@/utils/request'
+
+export function list(data) {
+  return request({
+    url: `/admin/user/page`,
+    method: 'post',
+    data
+  })
+}

二進制
src/assets/images/operation/kugou.png


+ 15 - 9
src/common/main.scss

@@ -18,19 +18,19 @@
 .el-button--delete.is-active,
 .el-button--delete:active,
 .el-button--delete:focus,
-.el-button--delete:hover{
+.el-button--delete:hover {
   background: none;
   color: #f56c6c;
 }
 
-.el-button--delete.is-disabled, 
-.el-button--delete.is-disabled:hover, 
-.el-button--delete.is-disabled:focus{
+.el-button--delete.is-disabled,
+.el-button--delete.is-disabled:hover,
+.el-button--delete.is-disabled:focus {
   background: transparent;
 }
 
-/* 分页透明样式 */ 
-.el-pagination{
+/* 分页透明样式 */
+.el-pagination {
   text-align: center;
   margin: 16px 0;
 }
@@ -54,14 +54,14 @@
   color: rgba(0, 0, 0, 0.65);
 }
 
-.el-pagination.is-background .el-pager li:not(.disabled).active{
+.el-pagination.is-background .el-pager li:not(.disabled).active {
   background: none;
   border: 1px solid #1890ff;
   color: #1890ff;
 }
 
 /* 表单按钮 */
-.form-btn{
+.form-btn {
   margin-left: 100px;
 }
 
@@ -73,6 +73,12 @@
 /* 级联选择器 */
 .el-select,
 .el-range-editor--medium.el-input__inner,
-.el-date-editor--datetimerange.el-input, .el-date-editor--datetimerange.el-input__inner {
+.el-date-editor--datetimerange.el-input,
+.el-date-editor--datetimerange.el-input__inner {
   width: 100%;
+}
+
+input::-webkit-outer-spin-button,
+input::-webkit-inner-spin-button {
+  -webkit-appearance: none;
 }

+ 16 - 11
src/components/Upload/index.vue

@@ -1,9 +1,9 @@
 <template>
   <div class="upload">
-    <el-upload v-if="isBtn()" :action="action" :headers="headers" :multiple="multiple" :data="data"
-      :name="name" :show-file-list="showFileList" :drag="drag" :accept="accept" :listType="listType"
-      :autoUpload="autoUpload" :disabled="disabled" :before-upload="beforeUpload" :on-progress="onProgress"
-      :on-success="onSuccess" :on-error="onError">
+    <el-upload v-if="isBtn()" :action="action" :headers="headers" :multiple="multiple" :data="data" :name="name"
+      :show-file-list="showFileList" :drag="drag" :accept="accept" :listType="listType" :autoUpload="autoUpload"
+      :disabled="disabled" :before-upload="beforeUpload" :on-progress="onProgress" :on-success="onSuccess"
+      :on-error="onError">
       <el-button v-if="listType !== 'picture-card'" :type="type" ref="upload">
         <slot v-if="percentage <= 0 && !form.file">点击上传</slot>
         <span v-if="percentage > 0 && !form.file">{{ title }}</span>
@@ -61,6 +61,11 @@ export default {
     },
     // 最大允许上传个数
     limit: Number,
+    // 文件类型
+    accept: {
+      type: String,
+      default: ''
+    },
     // 图片尺寸
     width: Number,
     height: Number,
@@ -73,7 +78,8 @@ export default {
       obj: {
         'text': `${baseUrl}/system/file/file/upload`,
         'picture-card': `${baseUrl}/system/file/picture/upload`,
-        'audio': `${baseUrl}/system/file/mp3/upload`
+        'audio': `${baseUrl}/system/file/mp3/upload`,
+        'zip': `${baseUrl}/system/file/file/uploadFolderZip`
       },
       // 上传地址
       action: '#',
@@ -85,8 +91,6 @@ export default {
       data: {},
       // 文件名
       name: 'multipartFile',
-      // 文件类型
-      accept: '',
       // 进度条
       percentage: 0,
       title: '',
@@ -100,16 +104,17 @@ export default {
       }
     }
   },
-  watch:{
+  watch: {
     url(val) {
       this.form.file = val
+    },
+    listType(val) {
+      this.action = this.obj[val]
     }
   },
   created() {
     // 根据上传类型 变更 上传地址
     this.action = this.obj[this.listType]
-    // 根据上传类型 变更 文件类型
-    this.accept = this.listType === 'picture-card' ? '.jpg, .jpeg, .png, .bmp, .icon, .gif' : ''
     // 回显图片
     this.form.file = this.url
   },
@@ -184,7 +189,7 @@ export default {
 
     // 上传按钮
     isBtn() {
-      return ['text', 'audio'].includes(this.listType) || (this.listType === 'picture-card' && this.percentage == 0 && !this.form.file)
+      return ['text', 'audio', 'zip'].includes(this.listType) || (this.listType === 'picture-card' && this.percentage == 0 && !this.form.file)
     },
     // 显示进度条
     isPercentage() {

+ 3 - 0
src/main.js

@@ -37,6 +37,8 @@ import DictTag from '@/components/DictTag'
 import VueMeta from 'vue-meta'
 // 字典数据组件
 import DictData from '@/components/DictData'
+// 上传组件
+import Upload from '@/components/Upload'
 
 // 全局方法挂载
 Vue.prototype.getDicts = getDicts
@@ -57,6 +59,7 @@ Vue.component('Editor', Editor)
 Vue.component('FileUpload', FileUpload)
 Vue.component('ImageUpload', ImageUpload)
 Vue.component('ImagePreview', ImagePreview)
+Vue.component('Upload', Upload)
 
 Vue.use(directive)
 Vue.use(plugins)

+ 21 - 2
src/mixin/index.js

@@ -62,6 +62,9 @@ const serviceTimeMixin = {
   data() {
     return {
       serviceTimeOptions: [{
+        value: -1,
+        label: '1天'
+      }, {
         value: 1,
         label: '7天'
       }, {
@@ -117,7 +120,7 @@ const serviceTypeMixin = {
         label: '积分兑换'
       }, {
         value: 5,
-        label: '服务中心'
+        label: '会员中心'
       }],
     }
   }
@@ -542,6 +545,21 @@ const channelMixin = {
   }
 }
 
+// 手机系统
+const systemMixin = {
+  data() {
+    return {
+      systemOptions: [{
+        value: 1,
+        label: 'Android'
+      }, {
+        value: 2,
+        label: 'iOS'
+      }]
+    }
+  }
+}
+
 export {
   devMixin,
   devTypeMixin,
@@ -563,5 +581,6 @@ export {
   classifyMixin,
   currentMixin,
   coverMixin,
-  channelMixin
+  channelMixin,
+  systemMixin
 }

文件差異過大導致無法顯示
+ 554 - 522
src/router/index.js


+ 0 - 4
src/views/content/banner/detail.vue

@@ -41,12 +41,8 @@
 </template>
 
 <script>
-import Upload from '@/components/Upload/index'
 import { submit, detail, edit } from '@/api/content/banner'
 export default {
-  components: {
-    Upload
-  },
   data() {
     return {
       date: '',

+ 1 - 3
src/views/device/article/detail.vue

@@ -38,12 +38,10 @@ import { create, detail, edit } from '@/api/device/article'
 import { devMixin } from '@/mixin/index'
 import { statusMixin } from './mixin'
 import Editor from '@/components/Editor/index'
-import Upload from '@/components/Upload/index.vue'
 export default {
   mixins: [devMixin, statusMixin],
   components: {
-    Editor,
-    Upload
+    Editor
   },
   data() {
     return {

+ 26 - 9
src/views/device/list/detail.vue

@@ -7,6 +7,9 @@
       <el-form-item label="设备名称:" prop="name">
         <el-input v-model="form.name" placeholder="请输入设备名称" />
       </el-form-item>
+      <el-form-item label="蓝牙名称:" prop="bluetoothName">
+        <el-input v-model="form.bluetoothName" placeholder="请输入蓝牙名称" />
+      </el-form-item>
       <el-form-item label="版本号:" prop="firstVersion">
         <el-input v-model="form.firstVersion" placeholder="请输入初始版本号" />
       </el-form-item>
@@ -24,11 +27,16 @@
           <el-option v-for="item in manuOptions" :key="item.value" :label="item.label" :value="item.value" />
         </el-select>
       </el-form-item>
-      <el-form-item label="设备类:" prop="categoryId">
-        <el-select v-model="form.categoryId" placeholder="请选择设备类">
+      <el-form-item label="设备类:" prop="categoryId">
+        <el-select v-model="form.categoryId" placeholder="请选择设备类">
           <el-option v-for="item in categoryOptions" :key="item.id" :label="item.name" :value="item.id" />
         </el-select>
       </el-form-item>
+      <el-form-item label="设备类型:" prop="deviceType">
+        <el-select v-model="form.deviceType" placeholder="请选择设备类型">
+          <el-option v-for="item in deviceTypeOptions" :key="item.value" :value="item.value" :label="item.label" />
+        </el-select>
+      </el-form-item>
       <el-form-item label="是否热门:" prop="isHot">
         <el-select v-model="form.isHot" placeholder="请选择是否热门">
           <el-option v-for="item in hotOptions" :key="item.value" :label="item.label" :value="Number(item.value)" />
@@ -93,15 +101,14 @@
           <el-input v-model="item.guideUrl" placeholder="请输入引导页网址" />
         </el-form-item>
         <el-form-item v-if="item.type === 1 || item.type === 3" label="引导页内容:"
-          :prop="`typeList.${index}.guidePageContent`"
-          :rules="{ required: true, message: '请输入引导页内容', trigger: 'blur' }">
+          :prop="`typeList.${index}.guidePageContent`" :rules="{ required: true, message: '请输入引导页内容', trigger: 'blur' }">
           <Editor v-model="item.guidePageContent" :min-height="250" :readOnly="disabled" />
         </el-form-item>
         <!-- 删除按钮 -->
         <el-link class="el-icon-close" v-if="form.typeList.length > 1" :underline="false" @click="getDelete(index)" />
       </div>
     </el-form>
-    <div class="form-btn">
+    <div style="margin-left: 120px;">
       <el-button @click="getCancel">取消</el-button>
       <el-button v-if="disabled === false" type="primary" @click="getSubmit">提交</el-button>
     </div>
@@ -113,13 +120,11 @@ import { categoryList } from "@/api/device/category";
 import { functionList } from "@/api/device/function";
 import { Add, Detail, Edit } from "@/api/device/list";
 import { devTypeMixin } from "@/mixin/index";
-import Upload from "@/components/Upload/index";
 import Editor from "@/components/Editor/index";
 
 export default {
   mixins: [devTypeMixin],
   components: {
-    Upload,
     Editor
   },
   data() {
@@ -139,10 +144,12 @@ export default {
       rules: {
         clientType: [{ required: true, message: "请输入设备型号", trigger: "blur" }],
         name: [{ required: true, message: "请输入设备名称", trigger: "blur" }],
+        bluetoothName: [{ required: true, message: '请输入蓝牙名称', trigger: 'blur' }],
         firstVersion: [{ required: true, message: "请输入初始版本号", trigger: "blur" }],
         upgradeType: [{ required: true, message: "请选择升级方式", trigger: "change" }],
         isHot: [{ required: true, message: "是否热门", trigger: "change" }],
-        categoryId: [{ required: true, message: "请选择设备类型", trigger: "change" }],
+        categoryId: [{ required: true, message: "请选择设备分类", trigger: "change" }],
+        deviceType: [{ required: true, message: "请选择设备类型", trigger: 'change' }],
         img: [{ required: true, message: "请上传在线图片", trigger: "change" }],
         offlineImg: [{ required: true, message: "请上传离线图片", trigger: "change" }],
       },
@@ -185,7 +192,17 @@ export default {
         label: 'QiXinWei'
       }],
       functionOptions: [],
-      categoryOptions: []
+      categoryOptions: [],
+      deviceTypeOptions: [{
+        value: 0,
+        label: '音响'
+      }, {
+        value: 1,
+        label: '耳机'
+      }, {
+        value: 2,
+        label: '穿戴'
+      }]
     };
   },
   mounted() {

+ 17 - 1
src/views/device/list/index.vue

@@ -32,12 +32,14 @@
       <el-table-column label="设备ID" prop="id" align="center" />
       <el-table-column label="设备型号" prop="clientType" align="center" />
       <el-table-column label="设备名称" prop="name" align="center" />
+      <el-table-column label="蓝牙名称" prop="bluetoothName" align="center" />
       <el-table-column label="设备图片" prop="img" align="center" width="100">
         <template slot-scope="scope">
           <el-image :src="scope.row.img" />
         </template>
       </el-table-column>
-      <el-table-column label="设备类型" prop="categoryName" align="center" />
+      <el-table-column label="设备分类" prop="categoryName" align="center" />
+      <el-table-column label="设备类型" prop="deviceType" align="center" :formatter="deviceTypeFormatter" />
       <el-table-column label="是否热门" prop="isHot" align="center" :formatter="hotFormatter" />
       <el-table-column label="升级方式" align="center" :formatter="upgradeTypeFormatter" />
       <el-table-column label="创建时间" prop="createTimeText" align="center" />
@@ -106,6 +108,16 @@ export default {
         value: 2,
         label: '指定'
       }],
+      deviceTypeOptions: [{
+        value: 0,
+        label: '音响'
+      }, {
+        value: 1,
+        label: '耳机'
+      }, {
+        value: 2,
+        label: '穿戴'
+      }]
     }
   },
   mounted() {
@@ -204,6 +216,10 @@ export default {
 
     upgradeTypeFormatter(row) {
       return this.selectDictLabel(this.upgradeTypeOptions, row.upgradeType)
+    },
+
+    deviceTypeFormatter(row) {
+      return this.selectDictLabel(this.deviceTypeOptions, row.deviceType)
     }
   }
 }

+ 293 - 0
src/views/device/music/index.vue

@@ -0,0 +1,293 @@
+<template>
+  <div class="app-container">
+    <!-- 搜索 -->
+    <el-form inline size="mini">
+      <el-form-item label="配置名称:">
+        <el-input v-model="form.name" placeholder="请输入配置名称" />
+      </el-form-item>
+      <el-form-item label="当前状态:">
+        <el-select v-model="form.status" placeholder="请选择当前状态">
+          <el-option v-for="item in disabledOptions" :key="item.value" :value="item.value" :label="item.label" />
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" @click="getSearch">搜索</el-button>
+        <el-button icon="el-icon-refresh" @click="getRefresh">重置</el-button>
+        <el-button type="primary" icon="el-icon-plus" plain @click="getDialog('新增')"
+          v-hasPermi="['device:music:add']">新增</el-button>
+      </el-form-item>
+    </el-form>
+    <!-- 列表 -->
+    <el-table :data="tableData" v-loading="loading">
+      <el-table-column label="序号" type="index" align="center" />
+      <el-table-column label="配置名称" prop="name" align="center" show-overflow-tooltip />
+      <el-table-column label="关联设备" prop="deviceIds" align="center" show-overflow-tooltip>
+        <template slot-scope="scope">
+          {{ scope.row.deviceIds.split(',').map(i => selectDictLabel(allDev, i)).join(',') }}
+        </template>
+      </el-table-column>
+      <el-table-column label="创建时间" prop="createTime" align="center" />
+      <el-table-column label="当前状态" prop="status" align="center" :formatter="statusFormatter" />
+      <el-table-column label="操作" align="center">
+        <template slot-scope="scope">
+          <el-button type="text" @click="getDialog('查看', scope.row.id)">查看</el-button>
+          <el-button type="text" v-if="scope.row.status === 0" @click="getChange('禁用', scope.row, 1)"
+            v-hasPermi="['device:music:down']">禁用</el-button>
+          <span v-else>
+            <el-button type="text" style="margin-left: 10px" @click="getDialog('编辑', scope.row.id)"
+              v-hasPermi="['device:music:edit']">编辑</el-button>
+            <el-button type="text" @click="getChange('启用', scope.row, 0)"
+              v-hasPermi="['device:music:up']">启用</el-button>
+            <el-button type="delete" @click="getChange('删除', scope.row, 2)"
+              v-hasPermi="['device:music:delete']">删除</el-button>
+          </span>
+        </template>
+      </el-table-column>
+    </el-table>
+    <pagination v-show="total > 0" :total="total" :page.sync="form.pageNum" :limit.sync="form.pageSize"
+      @pagination="getList" />
+    <!-- 弹窗 -->
+    <el-dialog :visible.sync="dialogVisible" :title="title" width="500px" :before-close="close">
+      <el-form :model="dialogForm" :rules="rules" ref="dialogForm" label-width="100px"
+        :disabled="title === '查看' ? true : false">
+        <el-form-item label="配置名称:" prop="name">
+          <el-input v-model="dialogForm.name" placeholder="请输入配置名称" />
+        </el-form-item>
+        <el-form-item label="关联设备:" prop="deviceIds">
+          <el-select v-model="dialogForm.deviceIds" multiple filterable placeholder="请选择关联设备">
+            <el-option v-for="item in devOptions" :key="item.value" :value="item.value" :label="item.label" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="赠送信息:">
+          <el-form-item label="资源平台:" prop="bullframeMusicGiveReqList.platformId">
+            <el-select v-model="dialogForm.bullframeMusicGiveReqList.platformId" placeholder="请选择资源平台">
+              <el-option v-for="item in platformOptions" :key="item.value" :value="item.value" :label="item.label" />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="栏目:" prop="bullframeMusicGiveReqList.groupIdList">
+            <el-select v-model="dialogForm.bullframeMusicGiveReqList.groupIdList" multiple placeholder="请选择栏目">
+              <el-option v-for="item in sceneOptions" :key="item.value" :value="item.id" :label="item.name" />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="有效时长:" prop="bullframeMusicGiveReqList.indate">
+            <el-select v-model="dialogForm.bullframeMusicGiveReqList.indate" placeholder="请选择有效时长">
+              <el-option v-for="item in timeOptions" :key="item.value" :value="item.value" :label="item.label" />
+            </el-select>
+          </el-form-item>
+        </el-form-item>
+      </el-form>
+      <div slot="footer">
+        <el-button @click="close">取消</el-button>
+        <el-button v-if="title !== '查看' ? true : false" type="primary" @click="getSubmit">确定</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { list, detail, submit, change, devList } from '@/api/device/music'
+import { list as sceneList } from '@/api/operation/scene'
+import { disabledMixin } from '@/mixin/index'
+export default {
+  mixins: [disabledMixin],
+  data() {
+    return {
+      // 遮罩层
+      loading: false,
+      // 表单
+      form: {
+        pageNum: 1,
+        pageSize: 10
+      },
+      // 总数居
+      total: 0,
+      // 列表
+      tableData: [],
+      // 弹窗
+      dialogVisible: false,
+      title: '新增',
+      // 弹窗表单
+      dialogForm: {
+        bullframeMusicGiveReqList: {},
+      },
+      // 设备列表
+      devOptions: [],
+      // 全部列表
+      allDev: [],
+      // 资源平台
+      platformOptions: [{
+        value: 10,
+        label: '爱听音乐'
+      }],
+      // 栏目
+      sceneOptions: [],
+      // 有效时长
+      timeOptions: [
+        { value: -1, label: '1天' },
+        { value: 3, label: '1个月' },
+        { value: 10, label: '2个月' },
+        { value: 4, label: '3个月' },
+        { value: 11, label: '4个月' },
+        { value: 12, label: '5个月' },
+        { value: 5, label: '6个月' },
+        { value: 13, label: '7个月' },
+        { value: 14, label: '8个月' },
+        { value: 15, label: '9个月' },
+        { value: 16, label: '10个月' },
+        { value: 17, label: '11个月' },
+        { value: 6, label: '12个月' },
+      ],
+      // 校验
+      rules: {
+        name: [{
+          required: true, message: '请输入配置名称', trigger: 'blur'
+        }],
+        deviceIds: [{
+          required: true, message: '请选择关联设备', trigger: 'blur'
+        }],
+        platformId: [{
+          required: true, message: '请选择资源平台', trigger: 'blur'
+        }],
+        groupIdList: [{
+          required: true, message: '请选择栏目', trigger: 'blur'
+        }],
+        indate: [{
+          required: true, message: '请选择有效时长', trigger: 'blur'
+        }]
+      }
+    }
+  },
+  mounted() {
+    this.getDev(1)
+    this.getList()
+  },
+  methods: {
+    // 列表
+    getList() {
+      this.loading = false
+      list(this.form).then(res => {
+        if (res.code === 0) {
+          this.tableData = res.data.records
+          this.total = res.data.total
+          this.loading = false
+        }
+      })
+    },
+
+    // 搜索
+    getSearch() {
+      this.form.pageNum = 1
+      this.getList()
+    },
+
+    // 重置
+    getRefresh() {
+      this.form = {
+        bullframeMusicGiveReqList: {}
+      }
+      this.getList()
+    },
+
+    // 弹窗
+    getDialog(title, id) {
+      this.dialogVisible = true
+      this.title = title
+      this.getDev(2)
+      this.getScene()
+      if (id) {
+        detail(id).then(res => {
+          this.dialogForm = res.data
+          this.dialogForm.deviceIds = res.data.deviceIds.split(',')
+          res.data.existDeviceList.map(i => {
+            this.devOptions.unshift({
+              value: i.clientTypeId,
+              label: i.name
+            })
+          })
+        })
+      }
+    },
+
+    // 关闭弹窗
+    close() {
+      this.dialogVisible = false
+      this.dialogForm = {
+        bullframeMusicGiveReqList: {}
+      }
+    },
+
+    // 上下架
+    getChange(title, row, status) {
+      this.$confirm(`是否${title}${row.name}?`, '提示', {
+        type: 'warning'
+      }).then(() => {
+        change(row.id, status).then(res => {
+          if (res.code === 0) {
+            this.$message.success(`${title}成功!`)
+            this.getList()
+          }
+        })
+      }).catch(() => { })
+    },
+
+    // 设备列表
+    getDev(type) {
+      this.devOptions = []
+      devList(type).then(res => {
+        if (res.code === 0) {
+          res.data.map(i => {
+            let obj = {
+              value: i.clientTypeId,
+              label: i.name
+            }
+            type === 1 ? this.allDev.push(obj) : this.devOptions.push(obj)
+          })
+        }
+      })
+    },
+
+    // 栏目接口
+    getScene() {
+      sceneList().then(res => {
+        if (res.code === 0) {
+          this.sceneOptions = res.data
+        }
+      })
+    },
+
+    // 提交
+    getSubmit() {
+      console.log(this.dialogForm);
+      this.$refs.dialogForm.validate((valid) => {
+        if (valid) {
+          this.dialogForm.deviceIds = this.dialogForm.deviceIds.join(',')
+          submit(this.dialogForm).then(res => {
+            if (res.code === 0) {
+              this.$message.success(`${this.title}成功!`)
+              this.close()
+              this.getList()
+            }
+          })
+        } else {
+          return false
+        }
+      })
+    },
+
+    // 字典翻译
+    statusFormatter(row) {
+      return this.selectDictLabel(this.disabledOptions, row.status)
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.el-form-item .el-form-item {
+  margin-bottom: 22px;
+}
+
+.el-form-item .el-form-item:last-child {
+  margin: 0;
+}
+</style>

+ 52 - 71
src/views/device/version/detail.vue

@@ -14,13 +14,18 @@
       <el-form-item prop="version" label="版本号:">
         <el-input v-model="form.version" placeholder="请输入版本号" />
       </el-form-item>
+      <el-form-item label="上传类型:">
+        <el-select v-model="listType" placeholder="请选择上传类型" @change="handleChange">
+          <el-option v-for="item in updateOptions" :key="item.value" :value="item.value" :label="item.label" />
+        </el-select>
+      </el-form-item>
       <el-form-item prop="url" label="下载路径:">
         <el-row type="flex" justify="space-between">
           <el-col :span="16">
             <el-input v-model="form.url" placeholder="请输入 或 上传下载路径" clearable />
           </el-col>
           <el-col :span="6">
-            <Upload @upload="getUpload" style="float:right" />
+            <Upload :listType="listType" :accept="accept" @upload="getUpload" style="float:right" />
           </el-col>
         </el-row>
       </el-form-item>
@@ -47,8 +52,7 @@
       </el-form-item>
       <el-form-item prop="userType" label="升级对象:">
         <el-select v-model="form.userType" placeholder="请选择升级对象">
-          <el-option v-for="item in pushOptions" :key="item.value" :label="item.label"
-            :value="Number(item.value)" />
+          <el-option v-for="item in pushOptions" :key="item.value" :label="item.label" :value="Number(item.value)" />
         </el-select>
       </el-form-item>
       <el-form-item :prop="user" v-if="form.userType === 3" label="指定用户:">
@@ -64,13 +68,9 @@
 
 <script>
 import { getDetailInfo, updateEdit, getVersionAdd } from "@/api/device/version";
-import Upload from "@/components/Upload/index";
 import { devMixin, devTypeMixin } from '@/mixin/index'
 export default {
   mixins: [devMixin, devTypeMixin],
-  components: {
-    Upload,
-  },
   data() {
     return {
       // 遮罩层
@@ -83,69 +83,33 @@ export default {
       user: "",
       // 表单验证
       rules: {
-        deviceTypeId: [
-          {
-            required: true,
-            message: "请选择设备型号",
-            trigger: "change",
-          },
-        ],
-        type: [
-          {
-            required: true,
-            message: "请选择设备类型",
-            trigger: "change",
-          },
-        ],
-        version: [
-          {
-            required: true,
-            message: "请输入版本号",
-            trigger: "blur",
-          },
-        ],
-        url: [
-          {
-            required: true,
-            message: "请输入 或 上传下载路径",
-            trigger: "change",
-          },
-        ],
-        title: [
-          {
-            required: true,
-            message: "请输入升级标题",
-            trigger: "blur",
-          },
-        ],
-        content: [
-          {
-            required: true,
-            message: "请输入升级描述",
-            trigger: "blur",
-          },
-        ],
-        isEnforcement: [
-          {
-            required: true,
-            message: "是否强制升级",
-            trigger: "change",
-          },
-        ],
-        isPush: [
-          {
-            required: true,
-            message: "是否同步推送",
-            trigger: "change",
-          },
-        ],
-        userType: [
-          {
-            required: true,
-            message: "请选择推送类型",
-            trigger: "change",
-          },
-        ],
+        deviceTypeId: [{
+          required: true, message: "请选择设备型号", trigger: "change"
+        }],
+        type: [{
+          required: true, message: "请选择设备类型", trigger: "change"
+        }],
+        version: [{
+          required: true, message: "请输入版本号", trigger: "blur"
+        }],
+        url: [{
+          required: true, message: "请输入 或 上传下载路径", trigger: "change"
+        }],
+        title: [{
+          required: true, message: "请输入升级标题", trigger: "blur"
+        }],
+        content: [{
+          required: true, message: "请输入升级描述", trigger: "blur"
+        }],
+        isEnforcement: [{
+          required: true, message: "是否强制升级", trigger: "change"
+        }],
+        isPush: [{
+          required: true, message: "是否同步推送", trigger: "change"
+        }],
+        userType: [{
+          required: true, message: "请选择推送类型", trigger: "change"
+        }],
       },
       // 设备是否
       statusOptions: [{
@@ -162,7 +126,18 @@ export default {
       }, {
         value: 3,
         label: '指定'
-      }]
+      }],
+      // 上传类型
+      updateOptions: [{
+        value: 'text',
+        label: '文件'
+      }, {
+        value: 'zip',
+        label: '文件夹'
+      }],
+      listType: 'text',
+      // 文件类型
+      accept: '.bin'
     };
   },
   mounted() {
@@ -182,6 +157,12 @@ export default {
     getUpload(e) {
       this.form.url = e.file;
     },
+
+    // 上传类型
+    handleChange(e) {
+      this.accept = e === 'text' ? '.bin' : '.zip'
+    },
+
     // 提交
     getSubmit() {
       this.$refs.form.validate((valid) => {

+ 0 - 2
src/views/goods/list/detail.vue

@@ -40,9 +40,7 @@
 <script>
 import { create, detail, edit } from '@/api/goods/list'
 import { locMixin } from './mixin'
-import Upload from '@/components/Upload/index'
 export default {
-  components: { Upload },
   mixins: [locMixin],
   data() {
     return {

+ 25 - 32
src/views/music/album/detail.vue

@@ -2,59 +2,55 @@
   <div class="app-container">
     <el-form :model="form" ref="form" :rules="rules" label-width="100px" :disabled="disabled">
       <el-form-item label="专辑名称:" prop="name">
-        <el-input v-model="form.name" placeholder="请输入专辑名称" maxlength="10" show-word-limit />
+        <el-input v-model="form.name" placeholder="请输入专辑名称" show-word-limit />
       </el-form-item>
       <el-form-item label="专辑介绍" prop="description">
-        <el-input v-model="form.description" type="textarea" :autosize="{ minRows: 5, maxRows: 10}"
-          maxlength="100" show-word-limit placeholder="请输入专辑介绍" />
+        <el-input v-model="form.description" type="textarea" :autosize="{ minRows: 5, maxRows: 10 }" maxlength="100"
+          show-word-limit placeholder="请输入专辑介绍" />
       </el-form-item>
       <el-form-item label="专辑类型:" prop="albumType">
         <el-select v-model="form.albumType" placeholder="请选择专辑类型">
-          <el-option v-for="item in albumTypeOptions" :key="item.value" :value="item.value"
-            :label="item.label" />
+          <el-option v-for="item in albumTypeOptions" :key="item.value" :value="item.value" :label="item.label" />
         </el-select>
       </el-form-item>
       <el-form-item label="资源平台:" prop="platformId">
         <el-select v-model="form.platformId" placeholder="请选择资源平台">
-          <el-option v-for="item in platformOptions" :key="item.value" :value="item.value"
-            :label="item.label" />
+          <el-option v-for="item in platformOptions" :key="item.value" :value="item.value" :label="item.label" />
         </el-select>
       </el-form-item>
       <el-form-item label="付费类型:" prop="payType">
         <el-select v-model="form.payType" placeholder="请选择付费类型">
-          <el-option v-for="item in payTypeOptions" :key="item.value" :value="item.value"
-            :label="item.label" />
+          <el-option v-for="item in payTypeOptions" :key="item.value" :value="item.value" :label="item.label" />
         </el-select>
       </el-form-item>
       <el-form-item v-if="form.payType !== 1" label="原价:" prop="price">
         <el-input-number v-model="form.price" placeholder="请输入原价" :min="1" :precision="2" :controls="false" />
       </el-form-item>
       <el-form-item v-if="form.payType !== 1" label="折扣价:" prop="discount">
-        <el-input-number v-model="form.discount" placeholder="请输入折扣价" :min="1" :precision="2"
-          :controls="false" />
+        <el-input-number v-model="form.discount" placeholder="请输入折扣价" :min="1" :precision="2" :controls="false" />
       </el-form-item>
       <el-form-item label="专辑封面:" prop="coverUrl">
         <Upload listType="picture-card" :url="form.coverUrl" @upload="upload($event, 'coverUrl')"
           :disabled="disabled" />
       </el-form-item>
-      <el-form-item label="歌曲列表:">
+      <el-form-item label="歌曲列表:" style="width: 1000px;">
         <el-button type="primary" icon="el-icon-plus" @click="getDialog">添加歌曲</el-button>
+        <!-- 列表 -->
+        <el-table class="table" :data="form.programList" height="329px" v-loading="form_loading">
+          <el-table-column label="ID" prop="id" align="center" />
+          <el-table-column label="歌曲名称" prop="name" align="center" show-overflow-tooltip />
+          <el-table-column label="歌手名称" prop="singerName" align="center" show-overflow-tooltip />
+          <el-table-column label="播放时长" prop="playTime" align="center" />
+          <el-table-column label="当前状态" prop="status" align="center" :formatter="statusFormatter" />
+          <el-table-column label="操作" align="center">
+            <template slot-scope="scope">
+              <Audio :src="scope.row.progaramUrl" />
+              <el-button type="delete" :disabled="disabled" @click="getDelete(scope.$index)">删除</el-button>
+            </template>
+          </el-table-column>
+        </el-table>
       </el-form-item>
     </el-form>
-    <!-- 列表 -->
-    <el-table class="table" :data="form.programList" height="329px" v-loading="form_loading">
-      <el-table-column label="ID" prop="id" align="center" />
-      <el-table-column label="歌曲名称" prop="name" align="center" show-overflow-tooltip />
-      <el-table-column label="歌手名称" prop="singerName" align="center" show-overflow-tooltip />
-      <el-table-column label="播放时长" prop="playTime" align="center" />
-      <el-table-column label="当前状态" prop="status" align="center" :formatter="statusFormatter" />
-      <el-table-column label="操作" align="center">
-        <template slot-scope="scope">
-          <Audio :src="scope.row.progaramUrl" />
-          <el-button type="delete" :disabled="disabled" @click="getDelete(scope.$index)">删除</el-button>
-        </template>
-      </el-table-column>
-    </el-table>
     <div class="form-btn">
       <el-button @click="cancel">取消</el-button>
       <el-button v-if="!disabled" type="primary" @click="getSubmit">确定</el-button>
@@ -71,8 +67,7 @@
         </el-form-item>
         <el-form-item label="资源平台:">
           <el-select v-model="dialogForm.platformId" placeholder="请选择资源平台">
-            <el-option v-for="item in platformOptions" :key="item.value" :value="item.value"
-              :label="item.label" />
+            <el-option v-for="item in platformOptions" :key="item.value" :value="item.value" :label="item.label" />
           </el-select>
         </el-form-item>
         <el-form-item>
@@ -94,8 +89,8 @@
           </template>
         </el-table-column>
       </el-table>
-      <pagination v-show="total>0" :total="total" :page.sync="dialogForm.pageNum"
-        :limit.sync="dialogForm.pageSize" @pagination="getList" />
+      <pagination v-show="total > 0" :total="total" :page.sync="dialogForm.pageNum" :limit.sync="dialogForm.pageSize"
+        @pagination="getList" />
     </el-dialog>
   </div>
 </template>
@@ -104,12 +99,10 @@
 import { submit, detail } from '@/api/music/menu'
 import { list } from '@/api/music/list'
 import { platformMixin, onOrOffMixin, payTypeMixin, albumTypeMixin } from '@/mixin/index'
-import Upload from '@/components/Upload/index.vue'
 import Audio from '@/components/Audio/index.vue'
 export default {
   mixins: [platformMixin, onOrOffMixin, payTypeMixin, albumTypeMixin],
   components: {
-    Upload,
     Audio
   },
   data() {

+ 0 - 4
src/views/music/anchor/detail.vue

@@ -27,13 +27,9 @@
 
 <script>
 import { submit, detail } from '@/api/music/anchor'
-import Upload from '@/components/Upload/index.vue'
 import { platformMixin } from '@/mixin/index'
 export default {
   mixins: [platformMixin],
-  components: {
-    Upload
-  },
   data() {
     return {
       // 表单

+ 1 - 5
src/views/music/blog/detail.vue

@@ -2,7 +2,7 @@
   <div class="app-container">
     <el-form :model="form" ref="form" :rules="rules" label-width="100px" :disabled="disabled">
       <el-form-item label="播客名称:" prop="name">
-        <el-input v-model="form.name" placeholder="请输入播客名称" maxlength="50" show-word-limit />
+        <el-input v-model="form.name" placeholder="请输入播客名称" show-word-limit />
       </el-form-item>
       <el-form-item label="主播名称:" prop="podcasterIds">
         <el-select v-model="form.podcasterIds" multiple filterable remote reserve-keyword
@@ -110,15 +110,11 @@
 </template>
 
 <script>
-import Upload from '@/components/Upload/index.vue'
 import { classifyMixin, platformMixin, payTypeMixin, onOrOffMixin, isFreeMixin } from '@/mixin/index'
 import { selectAnchor } from '@/api/music/anchor'
 import { detail, submit, relieve, checkList } from '@/api/music/blog'
 export default {
   mixins: [classifyMixin, platformMixin, payTypeMixin, onOrOffMixin, isFreeMixin],
-  components: {
-    Upload
-  },
   data() {
     // 判断原价是否大于折扣价
     var checkPrice = (rule, value, callback) => {

+ 1 - 5
src/views/music/choiceness/detail.vue

@@ -3,7 +3,7 @@
     <el-form :model="form" ref="form" :rules="rules" label-width="100px" style="width: 500px"
       :disabled="disabled">
       <el-form-item label="电台名称:" prop="name">
-        <el-input v-model="form.name" placeholder="请输入电台名称" maxlength="100" show-word-limit />
+        <el-input v-model="form.name" placeholder="请输入电台名称" show-word-limit />
       </el-form-item>
       <el-form-item label="电台简介:" prop="description">
         <el-input v-model="form.description" type="textarea" :autosize="{ minRows: 5, maxRows: 10}"
@@ -139,13 +139,9 @@
 
 <script>
 import { list, detail, liveList, submit } from '@/api/music/choiceness'
-import Upload from '@/components/Upload/index.vue'
 import { addressMixin, contentMixin, platformMixin } from '@/mixin/index'
 export default {
   mixins: [addressMixin, contentMixin, platformMixin],
-  components: {
-    Upload
-  },
   data() {
     return {
       // 遮罩层

+ 0 - 4
src/views/music/list/detail.vue

@@ -44,15 +44,11 @@
 </template>
 
 <script>
-import Upload from "@/components/Upload/index";
 import { submit, detail } from '@/api/music/list'
 import { selectSinger } from '@/api/music/singer'
 import { platformMixin, languageMixin } from '@/mixin/index'
 export default {
   mixins: [platformMixin, languageMixin],
-  components: {
-    Upload,
-  },
   data() {
     return {
       // 歌手

+ 3 - 4
src/views/music/list/index.vue

@@ -29,7 +29,7 @@
           v-hasPermi="['music:list:up']">批量上架</el-button>
         <el-button type="primary" :disabled="obj.id === ''" @click="getChange(obj, 2)"
           v-hasPermi="['music:list:down']">批量下架</el-button>
-        <Upload style="float: right" @loading="loading = true" @upload="loading = false" />
+        <Upload style="margin-left: 10px;" @loading="loading = true" @upload="loading = false" />
       </el-form-item>
     </el-form>
     <!-- 列表 -->
@@ -50,6 +50,7 @@
         </template>
       </el-table-column>
       <el-table-column label="播放时长" prop="playTime" align="center" />
+      <el-table-column label="所属专辑" prop="songName" align="center" />
       <el-table-column label="当前状态" prop="status" align="center" :formatter="statusFormatter" />
       <el-table-column label="更新时间" prop="updateTime" align="center">
         <template slot-scope="scope">
@@ -80,14 +81,12 @@
 
 <script>
 import Audio from '@/components/Audio/index.vue'
-import Upload from '@/components/AudioUpload/index.vue'
 import { list, remove, change } from '@/api/music/list'
 import { platformMixin, onOrOffMixin } from '@/mixin/index'
 export default {
   mixins: [platformMixin, onOrOffMixin],
   components: {
-    Audio,
-    Upload
+    Audio
   },
   data() {
     return {

+ 1 - 3
src/views/music/menu/detail.vue

@@ -2,7 +2,7 @@
   <div class="app-container">
     <el-form :model="form" ref="form" :rules="rules" label-width="100px" :disabled="disabled">
       <el-form-item label="歌单名称:" prop="name">
-        <el-input v-model="form.name" placeholder="请输入歌单名称" maxlength="10" show-word-limit />
+        <el-input v-model="form.name" placeholder="请输入歌单名称" show-word-limit />
       </el-form-item>
       <el-form-item label="歌单介绍:" prop="description">
         <el-input v-model="form.description" type="textarea" :autosize="{ minRows: 5, maxRows: 10}"
@@ -92,12 +92,10 @@
 import { submit, detail } from '@/api/music/menu'
 import { list } from '@/api/music/list'
 import { platformMixin, onOrOffMixin } from '@/mixin/index'
-import Upload from '@/components/Upload/index.vue'
 import Audio from '@/components/Audio/index.vue'
 export default {
   mixins: [platformMixin, onOrOffMixin],
   components: {
-    Upload,
     Audio
   },
   data() {

+ 1 - 5
src/views/music/program/detail.vue

@@ -2,7 +2,7 @@
   <div class="app-container">
     <el-form :model="form" ref="form" :rules="rules" label-width="100px" :disabled="disabled">
       <el-form-item label="节目名称:" prop="name">
-        <el-input v-model="form.name" placeholder="请输入节目名称" maxlength="20" show-word-limit />
+        <el-input v-model="form.name" placeholder="请输入节目名称" show-word-limit />
       </el-form-item>
       <el-form-item label="节目介绍:">
         <el-input v-model="form.description" type="textarea" :autosize="{ minRows: 5, maxRows: 10}"
@@ -49,12 +49,8 @@
 <script>
 import { submit, detail } from '@/api/music/program'
 import { platformMixin, isFreeMixin } from '@/mixin/index'
-import Upload from "@/components/Upload/index"
 export default {
   mixins: [platformMixin, isFreeMixin],
-  components: {
-    Upload,
-  },
   data() {
     // 小数点后两位 正则
     var str = /^\d+.?\d{0,2}$/

+ 1 - 0
src/views/music/program/index.vue

@@ -38,6 +38,7 @@
       <el-table-column label="付费类型" prop="isFree" align="center" :formatter="freeFormatter" width="100px" />
       <el-table-column label="原价 / 元" prop="price" align="center" />
       <el-table-column label="折扣价 / 元" prop="discountedPrice" align="center" />
+      <el-table-column label="所属专辑" prop="podcastName" align="center" />
       <el-table-column label="资源平台" prop="platformId" align="center" :formatter="platformFormatter" />
       <el-table-column label="当前状态" prop="status" align="center" :formatter="statusFormatter" width="100px" />
       <el-table-column label="更新时间" align="center" show-overflow-tooltip>

+ 1 - 5
src/views/music/radio/detail.vue

@@ -2,7 +2,7 @@
   <div class="app-container">
     <el-form :model="form" ref="form" :rules="rules" label-width="100px" :disabled="disabled">
       <el-form-item label="电台名称:" prop="name">
-        <el-input v-model="form.name" placeholder="请输入电台名称" maxlength="100" show-word-limit />
+        <el-input v-model="form.name" placeholder="请输入电台名称" show-word-limit />
       </el-form-item>
       <el-form-item label="资源平台:" prop="platformId">
         <el-select v-model="form.platformId" placeholder="请选择资源平台">
@@ -41,14 +41,10 @@
 </template>
 
 <script>
-import Upload from "@/components/Upload/index";
 import { submit, detail } from '@/api/music/radio'
 import { platformMixin, addressMixin, contentMixin } from '@/mixin/index'
 export default {
   mixins: [platformMixin, addressMixin, contentMixin],
-  components: {
-    Upload,
-  },
   data() {
     return {
       // 表单

+ 1 - 8
src/views/music/singer/detail.vue

@@ -2,7 +2,7 @@
   <div class="app-container">
     <el-form :model="form" ref="form" :rules="rules" label-width="100px" :disabled="disabled">
       <el-form-item label="歌手名称:" prop="name">
-        <el-input v-model="form.name" placeholder="请输入歌手名称" maxlength="100" show-word-limit />
+        <el-input v-model="form.name" placeholder="请输入歌手名称" show-word-limit />
       </el-form-item>
       <el-form-item label="歌手性别:" prop="sex">
         <el-select v-model="form.sex" placeholder="请选择歌手性别">
@@ -39,11 +39,7 @@
 <script>
 import { detail, submit } from '@/api/music/singer'
 import { sexMixin, regionMixin, platformMixin } from '@/mixin/index'
-import Upload from '@/components/Upload/index.vue'
 export default {
-  components: {
-    Upload
-  },
   mixins: [sexMixin, regionMixin, platformMixin],
   data() {
     return {
@@ -66,9 +62,6 @@ export default {
         status: [{
           required: true, message: '请选择当前状态', trigger: 'change'
         }],
-        description: [{
-          required: true, message: '请输入歌手简介', trigger: 'blur'
-        }],
         coverUrl: [{
           required: true, message: '请上传歌手头像', trigger: 'change'
         }]

+ 0 - 4
src/views/ohplay/operation/index.vue

@@ -45,11 +45,7 @@
 
 <script>
 import { create, list, remove, edit } from '@/api/ohplay/operation'
-import Upload from "@/components/Upload/index"
 export default {
-  components: {
-    Upload
-  },
   data() {
     return {
       img: [{

+ 7 - 4
src/views/operation/channel/detail.vue

@@ -38,6 +38,7 @@
           </el-table-column>
           <el-table-column label="付费类型" prop="isFree" align="center" :formatter="freeFormatter" />
           <el-table-column label="资源平台" align="center" :formatter="platfromFormatter" />
+          <el-table-column label="当前状态" align="center" :formatter="statusFormatter" />
           <el-table-column label="操作" align="center">
             <template slot-scope="scope">
               <el-button type="delete" @click="getDelete(scope.row)">删除</el-button>
@@ -58,13 +59,12 @@
 
 <script>
 import Dialog from '@/components/Dialog/index.vue'
-import Upload from '@/components/Upload/index'
 import { channelDetail, edit } from '@/api/operation/channel'
-import { platformMixin, isFreeMixin } from '@/mixin/index'
+import { platformMixin, isFreeMixin, onOrOffMixin } from '@/mixin/index'
 export default {
-  mixins: [platformMixin, isFreeMixin],
+  mixins: [platformMixin, isFreeMixin, onOrOffMixin],
   components: {
-    Upload, Dialog
+    Dialog
   },
   data() {
     return {
@@ -154,6 +154,9 @@ export default {
     },
     freeFormatter(row) {
       return this.selectDictLabel(this.freeOptions, row.isFree)
+    },
+    statusFormatter(row) {
+      return this.selectDictLabel(this.onOrOffOptions, row.status)
     }
   }
 }

+ 223 - 0
src/views/operation/dialog/index.vue

@@ -0,0 +1,223 @@
+<template>
+  <div class="app-container">
+    <!-- 搜索 -->
+    <el-form inline size="mini">
+      <el-form-item label="弹窗名称:">
+        <el-input v-model="form.name" placeholder="请输入弹窗名称" />
+      </el-form-item>
+      <el-form-item label="当前状态:">
+        <el-select v-model="form.status" placeholder="请选择当前状态">
+          <el-option v-for="item in disabledOptions" :key="item.value" :value="item.value" :label="item.label" />
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" @click="getSearch">搜索</el-button>
+        <el-button icon="el-icon-refresh" @click="getRefresh">重置</el-button>
+        <el-button type="primary" icon="el-icon-plus" plain @click="getDialog('新增')"
+          v-hasPermi="['operation:dialog:add']">新增</el-button>
+      </el-form-item>
+    </el-form>
+    <!-- 列表 -->
+    <el-table :data="tableData" v-loading="loading">
+      <el-table-column label="序号" type="index" align="center" />
+      <el-table-column label="弹窗名称" prop="name" align="center" show-overflow-tooltip />
+      <el-table-column label="弹窗图片" align="center" width="100px">
+        <template slot-scope="scope">
+          <el-image :src="scope.row.pic" />
+        </template>
+      </el-table-column>
+      <el-table-column label="关联设备" align="center" :formatter="devFormatter" show-overflow-tooltip />
+      <el-table-column label="创建时间" prop="createTime" align="center" />
+      <el-table-column label="当前状态" prop="status" align="center" :formatter="statusFormatter" />
+      <el-table-column label="操作" align="center">
+        <template slot-scope="scope">
+          <el-button type="text" @click="getDialog('查看', scope.row.id)">查看</el-button>
+          <el-button v-if="scope.row.status === 0" type="text" @click="getChange(scope.row, 1, '禁用')"
+            v-hasPermi="['operation:dialog:down']">禁用</el-button>
+          <span v-else style="margin-left: 10px">
+            <el-button type="text" @click="getDialog('编辑', scope.row.id)"
+              v-hasPermi="['operation:dialog:edit']">编辑</el-button>
+            <el-button type="text" @click="getChange(scope.row, 0, '启用')"
+              v-hasPermi="['operation:dialog:up']">启用</el-button>
+            <el-button type="delete" @click="getChange(scope.row, 2, '删除')"
+              v-hasPermi="['operation:dialog:delete']">删除</el-button>
+          </span>
+        </template>
+      </el-table-column>
+    </el-table>
+    <pagination v-show="total > 0" :total="total" :page.sync="form.pageNum" :limit.sync="form.pageSize"
+      @pagination="getList" />
+    <!-- 弹窗 -->
+    <el-dialog :visible.sync="dialogVisible" :title="title" width="500px" :before-close="getClose">
+      <el-form label-width="auto" :disabled="title === '查看' ? true : false">
+        <el-form-item label="弹窗名称:">
+          <el-input v-model="dialogForm.name" placeholder="请输入弹窗名称" />
+        </el-form-item>
+        <el-form-item label="关联设备:">
+          <el-select v-model="dialogForm.deviceIds" multiple filterable placeholder="请选择关联设备">
+            <el-option v-for="item in devOptions" :key="item.value" :value="item.value" :label="item.label" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="弹窗图片:">
+          <Upload listType="picture-card" :url="dialogForm.pic" @upload="upload"
+            :disabled="title === '查看' ? true : false" />
+        </el-form-item>
+      </el-form>
+      <div slot="footer">
+        <el-button @click="getClose">取消</el-button>
+        <el-button v-if="title !== '查看'" type="primary" @click="getSubmit">确定</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { list, detail, change, devList, submit } from '@/api/operation/dialog'
+import { disabledMixin } from '@/mixin/index'
+export default {
+  mixins: [disabledMixin],
+  data() {
+    return {
+      // 遮罩层
+      loading: false,
+      // 表单
+      form: {
+        pageNum: 1,
+        pageSize: 10
+      },
+      // 总数据
+      total: 0,
+      // 列表
+      tableData: [],
+      // 弹窗
+      dialogVisible: false,
+      // 弹窗名称
+      title: '新增',
+      // 弹窗表单
+      dialogForm: {},
+      // 设备列表
+      devOptions: [],
+      allDevs: []
+    }
+  },
+  mounted() {
+    this.getList()
+    this.getDev(1)
+  },
+  methods: {
+    // 列表
+    getList() {
+      this.loading = true
+      list(this.form).then(res => {
+        if (res.code === 0) {
+          this.tableData = res.data.records
+          this.total = res.data.total
+          this.loading = false
+        }
+      })
+    },
+
+    // 搜索
+    getSearch() {
+      this.form.pageNum = 1
+      this.getList()
+    },
+
+    // 重置
+    getRefresh() {
+      this.form = {
+        pageNum: 1,
+        pageSize: 10
+      }
+      this.getList()
+    },
+
+    // 上下架
+    getChange(row, status, title) {
+      this.$confirm(`是否${title}${row.name}?`, '提示', {
+        type: 'warning'
+      }).then(res => {
+        change(row.id, status).then(res => {
+          if (res.code === 0) {
+            this.$message.success(`${title}成功!`)
+            this.getList()
+          }
+        })
+      }).catch(() => { })
+    },
+
+    // 弹窗
+    getDialog(title, id) {
+      this.dialogVisible = true
+      this.title = title
+      this.getDev(2)
+      if (id) {
+        detail(id).then(res => {
+          if (res.code === 0) {
+            this.dialogForm = res.data
+            this.dialogForm.deviceIds = res.data.deviceIds.split(',')
+            res.data.existDeviceList.map(i => {
+              this.devOptions.unshift({
+                value: i.clientTypeId,
+                label: i.name
+              })
+            })
+          }
+        })
+      }
+    },
+
+    // 设备列表
+    getDev(type) {
+      this.devOptions = []
+      devList(type).then(res => {
+        if (res.code === 0) {
+          res.data.map(i => {
+            let obj = {
+              value: i.clientTypeId,
+              label: i.name
+            }
+            type === 1 ? this.allDevs.push(obj) : this.devOptions.push(obj)
+          })
+        }
+      })
+    },
+
+    // 上传
+    upload(e) {
+      this.dialogForm.pic = e.file
+    },
+
+    // 关闭
+    getClose() {
+      this.dialogVisible = false
+      this.dialogForm = {}
+    },
+
+    // 确定
+    getSubmit() {
+      this.dialogForm.deviceIds = this.dialogForm.deviceIds.join(',')
+      submit(this.dialogForm).then(res => {
+        if (res.code === 0) {
+          this.$message.success('提交成功!')
+          this.getClose()
+          this.getList()
+        }
+      })
+    },
+
+    // 字典翻译
+    devFormatter(row) {
+      return row.deviceIds ? row.deviceIds.split(',').map(i => this.selectDictLabel(this.allDevs, i)).join(',') : ''
+    },
+
+    statusFormatter(row) {
+      return this.selectDictLabel(this.disabledOptions, row.status)
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 155 - 66
src/views/operation/recommend/index.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="app-container">
     <el-tabs v-model="activeTab" @tab-click="handleClick">
-      <el-tab-pane v-for="item in tabs" :key="item.id" :label="item.name" :name="item.id.toString()" />
+      <el-tab-pane v-for="item in tabs" :key="item.id" :label="item.name" :name="item.tabIndex.toString()" />
     </el-tabs>
 
     <!-- 内容 -->
@@ -32,7 +32,8 @@
           <el-form label-width="auto" v-for="(item, index) in timeList" :key="item.id">
             <el-form-item label-width="0">
               <span style="font-weight: bold">场景电台时间设置</span>
-              <el-link icon="el-icon-close" :underline="false" style="float:right" @click="getChangeTime(item.id, 2)" />
+              <el-link icon="el-icon-close" :underline="false" style="float:right" @click="getChangeTime(item.id, 2)"
+                v-hasPermi="['operation:recommend:delete']" />
             </el-form-item>
             <el-form-item label="时间段:">
               <el-time-picker is-range v-model="item.date" start-placeholder="开始时间" end-placeholder="结束时间"
@@ -55,7 +56,7 @@
                 v-hasPermi="['operation:recommend:down']">下架</el-button>
             </el-form-item>
           </el-form>
-          <el-button type="primary" style="margin-left: 30px" @click="getAdd"
+          <el-button type="primary" style="margin-left: 30px" @click="getAddTime"
             v-hasPermi="['operation:recommend:add']">新增</el-button>
         </div>
 
@@ -70,8 +71,8 @@
         <div v-else :style="{ 'display': tabIndex === 1 && active === 0 ? 'inline-block' : 'block' }">
           <el-form label-width="auto" v-for="(item, index) in list" :key="item.id">
             <el-form-item label-width="0" :label="(index + 1).toString()">
-              <el-link v-if="tabIndex === 2 && active === 1" icon="el-icon-close" :underline="false" style="float:right"
-                @click="getRemoveList(item, index)" />
+              <el-link v-if="close()" icon="el-icon-close" :underline="false" style="float:right"
+                @click="getRemoveList(item, index)" v-hasPermi="['operation:recommend:delete']" />
             </el-form-item>
 
             <el-form-item label="时间:" v-if="time()">
@@ -84,19 +85,25 @@
             </el-form-item>
 
             <el-form-item label="模式:" v-if="model()">
-              <el-select v-model="item.model" placeholder="请选择模式">
+              <el-select v-model="item.model" placeholder="请选择模式" @change="getModel(item)">
                 <el-option v-for="item in contentOptions" :key="item.value" :label="item.label"
                   :value="Number(item.value)" />
               </el-select>
             </el-form-item>
 
             <el-form-item label="跳转方式:" v-if="forwardType()">
-              <el-select v-model="item.forwardType" placeholder="请选择跳转方式">
+              <el-select v-model="item.forwardType" placeholder="请选择跳转方式" @change="getForwardType(item)">
                 <el-option v-for="item in typeOptions" :key="item.value" :label="item.label"
                   :value="Number(item.value)" />
               </el-select>
             </el-form-item>
 
+            <el-form-item label="专区页面:" v-if="forwardType() && item.forwardType === 7">
+              <el-select v-model="item.contentId" placeholder="请选择跳转专区">
+                <el-option v-for="item in sceneOptions" :key="item.value" :value="item.value" :label="item.label" />
+              </el-select>
+            </el-form-item>
+
             <el-form-item label="内容:" v-if="contentName(item)">
               <el-input v-model="item.contentName" prefix-icon="el-icon-search" placeholder="选择内容"
                 @focus="getDialog(index)" />
@@ -121,7 +128,7 @@
               <Upload listType="picture-card" :url="item.pic" @upload="getUpload($event, index)" />
             </el-form-item>
 
-            <el-form-item label="排序:" v-if="tabIndex === 2 && active === 1">
+            <el-form-item label="排序:" v-if="sort()">
               <el-input-number v-model="item.sort" />
             </el-form-item>
 
@@ -153,7 +160,7 @@
                 v-hasPermi="['operation:recommend:down']">下架</el-button>
             </el-form-item>
           </el-form>
-          <el-button v-if="tabIndex === 2 && active === 1" type="primary" style="margin-left: 30px" @click="getAdd"
+          <el-button v-if="add()" type="primary" style="margin-left: 30px" @click="getAdd"
             v-hasPermi="['operation:recommend:add']">新增</el-button>
         </div>
       </div>
@@ -227,14 +234,11 @@ import {
   expandSave,
   removeList
 } from '@/api/operation/recommend'
-import Upload from '@/components/Upload/index'
 import { isFreeMixin, audioMixin, platformMixin, onOrOffMixin, coverMixin } from '@/mixin/index'
+import { list } from '@/api/operation/scene'
 
 export default {
   mixins: [isFreeMixin, audioMixin, platformMixin, onOrOffMixin, coverMixin],
-  components: {
-    Upload
-  },
   data() {
     return {
       // 遮罩层
@@ -242,19 +246,21 @@ export default {
       // 分类列表
       tabs: [],
       // 选中分类
-      activeTab: '77',
+      activeTab: '1',
       // 分类排序
       tabIndex: 1,
+      categoryId: '77',
       // 模板列表
       module: [],
       // 模板图
       imgOptions: {
-        '0': require('@/assets/images/operation/recommend.svg'),
-        '1': require('@/assets/images/operation/radio.svg'),
-        '2': require('@/assets/images/operation/music.svg'),
-        '3': require('@/assets/images/operation/story.svg'),
-        '4': require('@/assets/images/operation/kid.svg'),
-        '5': require('@/assets/images/operation/other.svg')
+        '1': require('@/assets/images/operation/recommend.svg'),
+        '2': require('@/assets/images/operation/radio.svg'),
+        '3': require('@/assets/images/operation/music.svg'),
+        '4': require('@/assets/images/operation/story.svg'),
+        '5': require('@/assets/images/operation/kid.svg'),
+        '6': require('@/assets/images/operation/other.svg'),
+        '7': require('@/assets/images/operation/kugou.png')
       },
       img: require('@/assets/images/operation/recommend.svg'),
       // 选中模块
@@ -327,6 +333,13 @@ export default {
           { top: 1885, height: 385 },
           { top: 2480, height: 390 },
           { top: 2875, height: 590 }
+        ],
+        '7': [
+          { top: 130, height: 160 },
+          { top: 375, height: 205 },
+          { top: 585, height: 205 },
+          { top: 800, height: 150 },
+          { top: 960, height: 300 }
         ]
       },
       active: 0,
@@ -367,9 +380,13 @@ export default {
         type: 8
       }, {
         value: 4,
-        label: 'APP内打开节目',
+        label: 'APP内容跳转节目',
         type: 6
       }, {
+        value: 7,
+        label: 'APP内容跳转专区',
+        type: 16
+      }, {
         value: 5,
         label: 'H5内链'
       }, {
@@ -382,7 +399,9 @@ export default {
       }, {
         value: 1,
         label: '手动推荐内容'
-      }]
+      }],
+      // 专区
+      sceneOptions: []
     }
   },
   watch: {
@@ -398,6 +417,7 @@ export default {
   },
   mounted() {
     this.getTab()
+    this.getSceneList()
   },
   methods: {
     // 分类列表
@@ -405,7 +425,7 @@ export default {
       listAll().then(res => {
         if (res.code === 0) {
           this.tabs = res.data
-          this.getModule(this.activeTab)
+          this.getModule(this.categoryId)
           this.getTimeList()
         }
       })
@@ -413,13 +433,13 @@ export default {
 
     // 切换分类
     handleClick(e) {
-      this.activeTab = this.tabs[e.index].id.toString()
-      this.tabIndex = this.tabs[e.index].tabIndex
-      e.index >= 5 ? e.index = 5 : e.index
-      this.img = this.imgOptions[e.index]
+      this.activeTab = e.name
+      this.tabIndex = Number(e.name)
+      this.categoryId = this.tabs[e.index].id
+      this.img = this.imgOptions[e.name]
       this.active = 0
       this.list = []
-      this.getModule(this.activeTab)
+      this.getModule(this.categoryId)
     },
 
     // 模块列表
@@ -503,7 +523,16 @@ export default {
 
     // 内容列表提交
     getSubmit(item) {
-      if (this.tabIndex === 2 && this.active === 1) {
+      let rules = {
+        '1': this.active === 1,
+        '2': this.active === 1,
+        '3': this.active === 0,
+        '7': this.active !== 3
+      }
+      item.startTime = item.date[0]
+      item.endTime = item.date[1]
+      delete item.date
+      if (rules[this.tabIndex]) {
         expandSave(item).then(res => {
           if (res.code === 0) {
             this.$message.success('提交成功!')
@@ -511,9 +540,6 @@ export default {
           }
         })
       } else {
-        item.startTime = item.date[0]
-        item.endTime = item.date[1]
-        delete item.date
         submit(item).then(res => {
           if (res.code === 0) {
             this.$message.success('提交成功!')
@@ -538,10 +564,7 @@ export default {
         this.form.audioType = this.audioOptions[0].value
       } else {
         this.form.audioType = this.list[index].forwardType ? this.typeOptions.find(i => i.value === this.list[index].forwardType).type : 2
-        // await this.getPlatform({
-        //   audioType: this.form.audioType
-        // })
-        this.disabled = this.tabIndex == 2 && this.active === 1 || this.list[index].forwardType !== null ? true : false
+        this.disabled = this.tabIndex === 2 && this.active === 1 || this.list[index].forwardType !== null ? true : false
       }
       this.getContentList()
     },
@@ -680,15 +703,17 @@ export default {
     },
 
     // 新增时间段
+    getAddTime() {
+      this.timeList.push({})
+    },
+
+    // 新增列表
     getAdd() {
-      if (this.tabIndex === 2 && this.active === 1) {
-        this.list.push({
-          moduleId: this.module[this.active].id,
-          childList: []
-        })
-      } else {
-        this.timeList.push({})
-      }
+      this.list.push({
+        moduleId: this.module[this.active].id,
+        childList: [],
+        forwardType: null
+      })
     },
 
     // 上下架 / 删除时间段
@@ -710,6 +735,30 @@ export default {
       }
     },
 
+    // 监听模式模块
+    getModel(item) {
+      item.isCustom = item.model === 0 ? 1 : 0
+    },
+
+    // 监听跳转方式
+    getForwardType(item) {
+      item.contentType = item.forwardType === 7 ? 16 : null
+    },
+
+    // 爱听专区
+    getSceneList() {
+      list().then(res => {
+        if (res.code === 0) {
+          res.data.map(i => {
+            this.sceneOptions.push({
+              value: i.id,
+              label: i.name
+            })
+          })
+        }
+      })
+    },
+
     // 字典翻译
     audioFormatter(row) {
       return this.selectDictLabel(this.audioOptions, row.audioType)
@@ -730,7 +779,8 @@ export default {
         '3': [2, 4, 6, 7, 8, 9].includes(this.active),
         '4': [2, 4, 6, 8, 9, 10, 11].includes(this.active),
         '5': [2, 4, 5, 6, 7].includes(this.active),
-        '6': [2, 3, 5, 7, 8, 9].includes(this.active)
+        '6': [2, 3, 5, 7, 8, 9].includes(this.active),
+        '7': ![0].includes(this.active)
       }
       return rules[this.tabIndex]
     },
@@ -738,11 +788,22 @@ export default {
     // 标签模块
     label() {
       let rules = {
-        '2': this.tabIndex === 2 && this.active === 2,
-        '3': this.tabIndex === 3 && this.active === 1,
-        '4': [1, 5].includes(this.active) && this.tabIndex === 4,
-        '5': [1, 3].includes(this.active) && this.tabIndex === 5,
-        '6': [1, 4].includes(this.active) && this.tabIndex === 6
+        '2': this.active === 2,
+        '3': this.active === 1,
+        '4': [1, 5].includes(this.active),
+        '5': [1, 3].includes(this.active),
+        '6': [1, 4].includes(this.active),
+      }
+      return rules[this.tabIndex]
+    },
+
+    // 删除按钮
+    close() {
+      let rules = {
+        '1': [1].includes(this.active),
+        '2': [0, 1].includes(this.active),
+        '3': [0].includes(this.active),
+        '7': ![3].includes(this.active)
       }
       return rules[this.tabIndex]
     },
@@ -752,10 +813,11 @@ export default {
       let rules = {
         '1': ![3, 8].includes(this.active),
         '2': [0, 3].includes(this.active),
-        '3': this.active !== 1,
-        '4': this.active !== 1 || this.active !== 5,
-        '5': this.active !== 1 || this.active !== 3,
-        '6': this.active !== 1 || this.active !== 4
+        '3': ![1].includes(this.active),
+        '4': ![1, 5].includes(this.active),
+        '5': ![1, 3].includes(this.active),
+        '6': ![1, 4].includes(this.active),
+        '7': [0, 1, 2, 3, 4].includes(this.active)
       }
       return rules[this.tabIndex]
     },
@@ -763,8 +825,8 @@ export default {
     // 标题
     title() {
       let rules = {
-        '1': this.active === 10,
-        '2': this.active === 1,
+        '1': [10].includes(this.active),
+        '2': [1].includes(this.active),
         '3': [3, 5, 9].includes(this.active),
         '4': [7].includes(this.active),
         '5': [5].includes(this.active)
@@ -780,7 +842,8 @@ export default {
         '3': [4, 7, 8].includes(this.active),
         '4': [2, 4, 6, 8, 9, 10, 11].includes(this.active),
         '5': [2, 4, 6, 7].includes(this.active),
-        '6': [2, 3, 5, 7, 8, 9].includes(this.active)
+        '6': [2, 3, 5, 7, 8, 9].includes(this.active),
+        '7': [4].includes(this.active)
       }
       return rules[this.tabIndex]
     },
@@ -793,7 +856,8 @@ export default {
         '3': [0].includes(this.active),
         '4': [0, 3].includes(this.active),
         '5': [0].includes(this.active),
-        '6': [0].includes(this.active)
+        '6': [0].includes(this.active),
+        '7': [0].includes(this.active)
       }
       return rules[this.tabIndex]
     },
@@ -805,7 +869,8 @@ export default {
         '3': [2, 3, 5, 6, 9].includes(this.active),
         '4': [7].includes(this.active),
         '5': [5].includes(this.active),
-        '6': [6].includes(this.active)
+        '6': [6].includes(this.active),
+        '7': ![0, 4].includes(this.active)
       }
       return rules[this.tabIndex] || [0, 1, 2, 3, 4].includes(item.forwardType) || item.model === 1
     },
@@ -813,11 +878,12 @@ export default {
     // 简介
     description(item) {
       let rules = {
-        '1': (this.active === 7 && item.model === 1) || this.active === 10,
-        '3': [3, 5].includes(this.active) || [4, 7, 8].includes(this.active) && item.model === 1,
-        '4': [7].includes(this.active)
+        '1': [7, 10].includes(this.active),
+        '3': [3, 4, 5, 7, 8].includes(this.active),
+        '4': [7].includes(this.active),
+        '7': [3].includes(this.active)
       }
-      return rules[this.tabIndex]
+      return rules[this.tabIndex] || item.model === 1
     },
 
     // 跳转连接
@@ -829,7 +895,7 @@ export default {
     isCustom(item) {
       let rules = {
         '1': [0, 8].includes(this.active),
-        '5': [5].includes(this.active),
+        '5': [5].includes(this.active)
       }
       return rules[this.tabIndex] || item.model === 1
     },
@@ -837,19 +903,42 @@ export default {
     // 图片
     pic(item) {
       let rules = {
-        '1': [1, 2, 6, 8, 10, 12].includes(this.active),
+        '1': [1, 2, 6, 10, 12].includes(this.active),
         '2': [0, 1].includes(this.active),
         '3': [0, 2, 3, 5, 6, 9].includes(this.active),
         '4': [0, 3, 7].includes(this.active),
         '5': [0, 5].includes(this.active),
-        '6': [0, 6].includes(this.active)
+        '6': [0, 6].includes(this.active),
+        '7': ![4].includes(this.active)
       }
       return rules[this.tabIndex] || item.isCustom === 0
     },
 
+    // 排序
+    sort() {
+      let rules = {
+        '1': [1].includes(this.active),
+        '2': [0, 1].includes(this.active),
+        '3': [0].includes(this.active),
+        '7': ![3].includes(this.active)
+      }
+      return rules[this.tabIndex]
+    },
+
     // 列表
     isList() {
       return this.tabIndex === 2 && this.active === 1
+    },
+
+    // 新增
+    add() {
+      let rules = {
+        '1': [1].includes(this.active),
+        '2': [0, 1].includes(this.active),
+        '3': [0].includes(this.active),
+        '7': ![3].includes(this.active)
+      }
+      return rules[this.tabIndex]
     }
   }
 }

+ 205 - 0
src/views/operation/scene/detail.vue

@@ -0,0 +1,205 @@
+<template>
+  <div class="app-container">
+    <!-- 表单 -->
+    <el-form label-width="100px" :disabled="disabled">
+      <el-form-item label="场景标题:">
+        <el-input v-model="form.name" placeholder="请输入场景标题" />
+      </el-form-item>
+      <el-form-item label="场景副标题:">
+        <el-input v-model="form.subName" placeholder="请输入场景副标题" />
+      </el-form-item>
+      <el-form-item label="场景封面:">
+        <Upload listType="picture-card" :url="form.pic" @upload="upload($event, 'pic')" :disabled="disabled" />
+      </el-form-item>
+      <el-form-item label="专区背景图:">
+        <Upload listType="picture-card" :url="form.backgroundPic" @upload="upload($event, 'backgroundPic')"
+          :disabled="disabled" />
+      </el-form-item>
+    </el-form>
+    <div class="form-btn" style="margin-bottom: 40px">
+      <el-button @click="cancel">取消</el-button>
+      <el-button v-if="!disabled" type="primary" @click="getSubmit">提交</el-button>
+    </div>
+    <el-form label-width="100px" :disabled="disabled">
+      <el-form-item label="专区列表:" style="width: 1200px">
+        <el-table :data="tableData" v-loading="loading" :default-sort="{prop: 'sort'}">
+          <el-table-column label="排序" prop="sort" align="center" />
+          <el-table-column label="标签名称" prop="name" align="center" />
+          <el-table-column label="标签封面" align="center" width="100px">
+            <template slot-scope="scope">
+              <el-image v-if="scope.row.pic" :src="scope.row.pic" />
+            </template>
+          </el-table-column>
+          <el-table-column label="歌单数量" prop="songCount" align="center" />
+          <el-table-column label="当前状态" prop="status" align="center" :formatter="statusFormatter" />
+          <el-table-column label="操作" align="center">
+            <template slot-scope="scope">
+              <el-button type="text" @click="getDialog(scope.row.id, '查看')">查看</el-button>
+              <el-button v-if="scope.row.status === 0" type="text" @click="getChange(scope.row, 1, '禁用')">禁用</el-button>
+              <span v-else style="margin-left: 10px">
+                <el-button type="text" @click="getDialog(scope.row.id, '编辑')">编辑</el-button>
+                <el-button type="text" @click="getChange(scope.row, 0, '启用')">启用</el-button>
+                <el-button type="delete" @click="getChange(scope.row, 2, '删除')">删除</el-button>
+              </span>
+            </template>
+          </el-table-column>
+        </el-table>
+        <pagination v-show="total > 0" :total="total" :page.sync="form.pageNum" :limit.sync="form.pageSize"
+          @pagination="getList" />
+      </el-form-item>
+    </el-form>
+    <!-- 弹窗 -->
+    <el-dialog :visible.sync="dialogVisible" :title="title" width="600px" :before-close="getClose">
+      <el-form :model="dialogForm" ref="dialogForm" label-width="100px" :disabled="title === '查看' ? true : false">
+        <el-form-item label="标签名称:" prop="name">
+          <el-input v-model="dialogForm.name" placeholder="请输入标签名称" />
+        </el-form-item>
+        <el-form-item label="标签封面:" prop="pic">
+          <Upload listType="picture-card" :url="dialogForm.pic" @upload="upload($event, 'pic')"
+            :disabled="title === '查看' ? true : false" />
+        </el-form-item>
+        <el-form-item label="排序:" prop="sort">
+          <el-input-number v-model="dialogForm.sort" step-strictly />
+        </el-form-item>
+      </el-form>
+      <div slot="footer">
+        <el-button @click="getClose">取消</el-button>
+        <el-button v-if="title === '查看' ? false : true" type="primary" @click="getDetailSubmit">确定</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { detail, edit, detailList, change, menuDetail, editMenu } from '@/api/operation/scene'
+import { disabledMixin } from '@/mixin/index'
+export default {
+  mixins: [disabledMixin],
+  data() {
+    return {
+      // 遮罩层
+      loading: false,
+      // 表单
+      form: {},
+      // 列表
+      tableData: [],
+      // 专区表单
+      listForm: {
+        pageNum: 1,
+        pageSize: 10
+      },
+      total: 0,
+      // 弹窗
+      dialogVisible: false,
+      title: '编辑',
+      // 弹窗表单
+      dialogForm: {},
+      // 只读
+      disabled: false
+    }
+  },
+  mounted() {
+    if (this.$route.query.id) {
+      this.form.id = this.listForm.groupId = this.$route.query.id
+      this.disabled = Boolean(this.$route.query.boolean)
+      this.getDetail()
+      this.getList()
+    }
+  },
+  methods: {
+    // 详情
+    getDetail() {
+      detail(this.form.id).then(res => {
+        if (res.code === 0) {
+          this.form = res.data
+        }
+      })
+    },
+
+    // 上传图片
+    upload(e, key) {
+      this.dialogVisible ? this.dialogForm[key] = e.file : this.form[key] = e.file
+    },
+
+    // 提交
+    getSubmit() {
+      edit(this.form).then(res => {
+        if (res.code === 0) {
+          this.$message.success('编辑成功!')
+          this.cancel()
+        }
+      })
+    },
+
+    // 取消
+    cancel() {
+      this.$tab.closeOpenPage('/operation/scene')
+    },
+
+    // 专区列表
+    getList() {
+      this.loading = true
+      detailList(this.listForm).then(res => {
+        if (res.code === 0) {
+          this.tableData = res.data.records
+          this.total = res.data.total
+          this.loading = false
+        }
+      })
+    },
+
+    // 上下架
+    getChange(row, status, title) {
+      this.$confirm(`是否${title}${row.name}?`, '提示', {
+        type: 'warning'
+      }).then(() => {
+        change(row.id, 2, status).then(res => {
+          if (res.code === 0) {
+            this.$message.success(`${title}成功!`)
+            this.getList()
+          }
+        })
+      }).catch(() => { })
+    },
+
+    // 弹窗
+    getDialog(id, title) {
+      this.dialogVisible = true
+      this.title = title
+      menuDetail(id).then(res => {
+        if(res.code === 0){
+          this.dialogForm = res.data
+        }
+      })
+    },
+
+    // 关闭
+    getClose(){
+      this.dialogVisible = false
+      this.$refs.dialogForm.resetFields()
+    },
+
+    // 确定
+    getDetailSubmit() {
+      editMenu(this.dialogForm).then(res => {
+        if (res.code === 0) {
+          this.$message.success('编辑成功!')
+          this.dialogVisible = false
+          this.getList()
+        }
+      })
+    },
+
+    // 字典翻译
+    statusFormatter(row) {
+      return this.selectDictLabel(this.disabledOptions, row.status)
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.el-form {
+  width: 500px;
+}
+</style>

+ 95 - 0
src/views/operation/scene/index.vue

@@ -0,0 +1,95 @@
+<template>
+  <div class="app-container">
+    <!-- 列表 -->
+    <el-table :data="tableData" v-loading="loading">
+      <el-table-column label="序号" type="index" align="center" />
+      <el-table-column label="场景标题" prop="name" align="center" />
+      <el-table-column label="场景副标题" prop="subName" align="center" />
+      <el-table-column label="场景封面" align="center" width="100px">
+        <template slot-scope="scope">
+          <el-image :src="scope.row.pic" />
+        </template>
+      </el-table-column>
+      <el-table-column label="当前状态" prop="status" align="center" :formatter="statusFormatter" />
+      <el-table-column label="操作" align="center">
+        <template slot-scope="scope">
+          <el-button type="text" @click="getDetail(scope.row.id, true)">查看</el-button>
+          <el-button v-if="scope.row.status === 0" type="text" @click="getChange(scope.row, 1, '禁用')"
+            v-hasPermi="['operation:scene:down']">禁用</el-button>
+          <span v-else style="margin-left: 10px">
+            <el-button type="text" @click="getDetail(scope.row.id)" v-hasPermi="['operation:scene:edit']">编辑</el-button>
+            <el-button type="text" @click="getChange(scope.row, 0, '启用')"
+              v-hasPermi="['operation:scene:up']">启用</el-button>
+            <el-button type="delete" @click="getChange(scope.row, 2, '删除')"
+              v-hasPermi="['operation:scene:delete']">删除</el-button>
+          </span>
+        </template>
+      </el-table-column>
+    </el-table>
+  </div>
+</template>
+
+<script>
+import { list, change } from '@/api/operation/scene'
+import { disabledMixin } from '@/mixin/index'
+export default {
+  mixins: [disabledMixin],
+  data() {
+    return {
+      // 遮罩层
+      loading: false,
+      // 列表
+      tableData: []
+    }
+  },
+  mounted() {
+    this.getList()
+  },
+  methods: {
+    // 列表
+    getList() {
+      this.loading = true
+      list().then(res => {
+        if (res.code === 0) {
+          this.tableData = res.data
+          this.loading = false
+        }
+      })
+    },
+
+    // 详情
+    getDetail(id, boolean) {
+      this.$router.push({
+        path: '/operation/scene/detail',
+        query: {
+          id: id,
+          boolean: boolean
+        }
+      })
+    },
+
+    // 上下架
+    getChange(row, status, title) {
+      this.$confirm(`是否${title}${row.name}?`, '提示', {
+        type: 'warning'
+      }).then(() => {
+        change(row.id, 1, status).then(res => {
+          if (res.code === 0) {
+            this.$message.success(`${title}成功!`)
+            this.getList()
+          }
+        })
+      }).catch(() => { })
+    },
+
+    // 字典翻译
+    statusFormatter(row) {
+      return this.selectDictLabel(this.disabledOptions, row.status)
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 0 - 4
src/views/operation/startPage/detail.vue

@@ -39,12 +39,8 @@
 </template>
 
 <script>
-import Upload from '@/components/Upload/index'
 import { submit, detail, edit, checked } from '@/api/operation/startPage'
 export default {
-  components: {
-    Upload
-  },
   data() {
     return {
       // 表单

+ 7 - 9
src/views/operation/tag/detail.vue

@@ -9,8 +9,7 @@
       </el-form-item>
       <el-form-item label="频道属性:" prop="channelType">
         <el-select v-model="form.channelType" placeholder="请选择频道属性" @change="handleChange">
-          <el-option v-for="item in channelTypeOptions" :key="item.value" :value="item.value"
-            :label="item.label" />
+          <el-option v-for="item in channelTypeOptions" :key="item.value" :value="item.value" :label="item.label" />
         </el-select>
       </el-form-item>
       <el-form-item label="频道名称:" prop="channelName">
@@ -18,7 +17,7 @@
       </el-form-item>
       <el-form-item label="频道介绍:" prop="channelDescribe">
         <el-input v-model="form.channelDescribe" type="textarea" placeholder="请输入频道简介"
-          :autosize="{ minRows: 5, maxRows: 10}" maxlength="300" show-word-limit />
+          :autosize="{ minRows: 5, maxRows: 10 }" maxlength="300" show-word-limit />
       </el-form-item>
       <el-form-item label="频道封面:" prop="channelCover">
         <Upload listType="picture-card" :url="form.channelCover" @upload="upload" :disabled="disabled" />
@@ -37,6 +36,7 @@
           </el-table-column>
           <el-table-column label="音频类型" prop="audioType" align="center" :formatter="audioTypeFormatter" />
           <el-table-column label="资源平台" align="center" :formatter="platfromFormatter" />
+          <el-table-column label="当前状态" align="center" :formatter="statusFormatter" />
           <el-table-column label="操作" align="center">
             <template slot-scope="scope">
               <el-button type="delete" @click="getDelete(scope.row.audioId)">删除</el-button>
@@ -51,21 +51,19 @@
     </div>
 
     <!-- 弹窗 -->
-    <Dialog :visible="dialogVisible" :data="form.listagCategoryAudio" :channelType="form.channelType"
-      @close="close" />
+    <Dialog :visible="dialogVisible" :data="form.listagCategoryAudio" :channelType="form.channelType" @close="close" />
   </div>
 </template>
 
 <script>
 import Dialog from '@/components/Dialog/index.vue'
-import Upload from '@/components/Upload/index.vue'
 import { submitThree, detail } from '@/api/operation/tag'
-import { platformMixin, isFreeMixin, audioMixin } from '@/mixin/index'
+import { platformMixin, isFreeMixin, audioMixin, onOrOffMixin } from '@/mixin/index'
 export default {
   components: {
-    Upload, Dialog
+    Dialog
   },
-  mixins: [platformMixin, isFreeMixin, audioMixin],
+  mixins: [platformMixin, isFreeMixin, audioMixin, onOrOffMixin],
   data() {
     return {
       // 表单

+ 14 - 16
src/views/operation/waken/detail.vue

@@ -6,14 +6,13 @@
       </el-form-item>
       <el-form-item label="频道属性:" prop="attributeType">
         <el-select v-model="form.attributeType" placeholder="请选择频道属性">
-          <el-option v-for="item in channelOptions" :key="item.value" :value="item.value"
-            :label="item.label" />
+          <el-option v-for="item in channelOptions" :key="item.value" :value="item.value" :label="item.label" />
         </el-select>
       </el-form-item>
       <el-form-item label="关联设备:" prop="deviceIds">
         <el-select v-model="form.deviceIds" multiple placeholder="请选择关联设备">
-          <el-option v-for="item in deviceOptions" :key="item.clientTypeId"
-            :value="item.clientTypeId.toString()" :label="item.name" />
+          <el-option v-for="item in deviceOptions" :key="item.clientTypeId" :value="item.clientTypeId.toString()"
+            :label="item.name" />
         </el-select>
       </el-form-item>
       <el-form-item label="唤醒音封面:" prop="pic">
@@ -33,6 +32,7 @@
           </el-table-column>
           <el-table-column label="付费类型" align="center" prop="isFree" :formatter="freeFormatter" />
           <el-table-column label="资源平台" align="center" prop="platformId" :formatter="platfromFormatter" />
+          <el-table-column label="当前状态" align="center" :formatter="statusFormatter" />
           <el-table-column label="操作" align="center">
             <template slot-scope="scope">
               <el-button type="delete" @click="getDelete(scope.row)">删除</el-button>
@@ -51,14 +51,13 @@
       <el-form inline size="mini" style="width:100%">
         <el-form-item label="音频类型:">
           <el-select v-if="form.attributeType" v-model="dialogForm.audioType" placeholder="请选择音频类型">
-            <el-option v-for="item in channelOptions.find(i => i.value === form.attributeType).children"
-              :key="item.value" :value="item.value" :label="item.label" />
+            <el-option v-for="item in channelOptions.find(i => i.value === form.attributeType).children" :key="item.value"
+              :value="item.value" :label="item.label" />
           </el-select>
         </el-form-item>
         <el-form-item label="资源平台:">
           <el-select v-model="dialogForm.platformId" placeholder="请选择资源平台">
-            <el-option v-for="item in platformOptions" :key="item.value" :value="item.value"
-              :label="item.label" />
+            <el-option v-for="item in platformOptions" :key="item.value" :value="item.value" :label="item.label" />
           </el-select>
         </el-form-item>
         <el-form-item label="内容名称:">
@@ -82,23 +81,19 @@
         <el-table-column label="资源平台" align="center" prop="platformId" :formatter="platfromFormatter" />
       </el-table>
       <div slot="footer">
-        <pagination v-show="total>0" :total="total" :page.sync="dialogForm.pageNum"
-          :limit.sync="dialogForm.pageSize" @pagination="getList" />
+        <pagination v-show="total > 0" :total="total" :page.sync="dialogForm.pageNum" :limit.sync="dialogForm.pageSize"
+          @pagination="getList" />
       </div>
     </el-dialog>
   </div>
 </template>
 
 <script>
-import Upload from '@/components/Upload/index.vue'
 import { list } from '@/api/operation/channel'
 import { detail, devices, submit } from '@/api/operation/waken'
-import { platformMixin, isFreeMixin } from '@/mixin/index'
+import { platformMixin, isFreeMixin, onOrOffMixin } from '@/mixin/index'
 export default {
-  mixins: [platformMixin, isFreeMixin],
-  components: {
-    Upload
-  },
+  mixins: [platformMixin, isFreeMixin, onOrOffMixin],
   data() {
     return {
       // 表单
@@ -317,6 +312,9 @@ export default {
     },
     freeFormatter(row) {
       return this.selectDictLabel(this.freeOptions, row.isFree)
+    },
+    statusFormatter(row) {
+      return this.selectDictLabel(this.onOrOffOptions, row.status)
     }
   }
 }

+ 366 - 0
src/views/order/list/index.vue

@@ -0,0 +1,366 @@
+<template>
+  <div class="app-container">
+    <!-- 搜索 -->
+    <el-form inline size="mini">
+      <el-form-item label="订单编号:">
+        <el-input v-model="form.orderCode" placeholder="请输入订单编号" clearable />
+      </el-form-item>
+      <el-form-item label="用户账号:">
+        <el-input v-model="form.userName" placeholder="请输入用户账户" clearable />
+      </el-form-item>
+      <el-form-item label="用户手机号:">
+        <el-input type="number" v-model.number="form.phone" placeholder="请输入用户手机号" clearable />
+      </el-form-item>
+      <!-- 流量订单 -->
+      <span v-if="form.searchType === '2'">
+        <el-form-item label="SIM卡号:">
+          <el-input v-model="form.simCode" placeholder="请输入SIM卡号" clearable />
+        </el-form-item>
+        <el-form-item label="生效状态">
+          <el-select v-model="form.flowStatus" placeholder="请选择生效状态">
+            <el-option v-for="item in flowOptions" :key="item.value" :value="item.value" :label="item.label" />
+          </el-select>
+        </el-form-item>
+      </span>
+      <!-- 除充值订单 -->
+      <span v-if="form.searchType !== '3'">
+        <el-form-item label="商品ID:">
+          <el-input v-model="form.goodsid" placeholder="请输入商品ID" />
+        </el-form-item>
+        <el-form-item label="商品名称:">
+          <el-input v-model="form.goodsName" placeholder="请输入商品名称" />
+        </el-form-item>
+      </span>
+      <el-form-item label="操作系统" v-else>
+        <el-select v-model="form.platform" placeholder="请选择操作系统">
+          <el-option v-for="item in systemOptions" :key="item.value" :value="item.value" :label="item.label" />
+        </el-select>
+      </el-form-item>
+      <!-- 会员订单 -->
+      <el-form-item v-if="form.searchType === '4'" label="资源平台:">
+        <el-select v-model="form.platformId" placeholder="请选择资源平台">
+          <el-option v-for="item in platformIdOptions" :key="item.value" :value="item.value" :label="item.label" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="支付状态:">
+        <el-select v-model="form.status" placeholder="请选择订单状态">
+          <el-option v-for="item in statusOptions" :key="item.value" :value="item.value" :label="item.label" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="支付方式:">
+        <el-select v-model="form.payType" placeholder="请选择支付方式">
+          <el-option v-for="item in payOptions" :key="item.value" :value="item.value" :label="item.label" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="下单时间:">
+        <el-date-picker v-model="form.listDate" type="datetimerange" start-placeholder="开始日期" end-placeholder="结束日期"
+          format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss" :picker-options="pickerOptions" />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" @click="getSearch">搜索</el-button>
+        <el-button icon="el-icon-refresh" @click="getRefresh">重置</el-button>
+        <el-button type="primary" icon="el-icon-download" @click="handleExport"
+          v-hasPermi="['order:list:export']">导出</el-button>
+        <el-button type="primary" @click="getDialog" v-hasPermi="['order:list:export']">查看</el-button>
+      </el-form-item>
+    </el-form>
+    <!-- 列表 -->
+    <el-table :data="tableData" v-loading="loading">
+      <el-table-column label="订单编号" prop="orderCode" key="orderCode" align="center" />
+      <el-table-column v-if="form.searchType === '2'" label="第三方订单编号" key="thirdOrderId" align="center">
+        <template slot-scope="scope">
+          <span>{{ scope.row.thirdOrderId | empty(scope.row.thirdOrderId) }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="商品ID" prop="goodsid" key="goodsid" align="center" />
+      <el-table-column label="商品名称" prop="goodsName" key="goodsName" align="center" show-overflow-tooltip />
+      <el-table-column label="订单金额 / 元" prop="amount" key="amount" align="center" :formatter="amountFormatter" />
+      <el-table-column v-if="form.searchType === '2'" label="SIM卡号" prop="simCode" key="simCode" align="center">
+        <template slot-scope="scope">
+          <span>{{ scope.row.simCode | empty(scope.row.simCode) }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column v-if="form.searchType === '1'" label="购买类型" prop="charging" key="charging" align="center"
+        :formatter="chargingFormatter" />
+      <el-table-column v-if="form.searchType === '3'" label="订单来源" prop="platform" key="platform" align="center"
+        :formatter="platformFormatter" />
+      <el-table-column v-if="form.searchType === '4'" label="栏目" prop="groupId" key="groupId" align="center"
+        :formatter="groupFormatter" />
+      <el-table-column v-if="form.searchType === '4'" label="服务时长" prop="expirationTime" key="expirationTime"
+        align="center" :formatter="timeFormatter" />
+      <el-table-column v-if="form.searchType === '4'" label="资源平台" prop="platformId" key="platformId" align="center"
+        :formatter="platformIdFormatter" />
+      <el-table-column label="下单时间" prop="createTime" key="createTime" align="center" />
+      <el-table-column label="支付方式" prop="payType" key="payType" align="center" :formatter="payTypeFormatter" />
+      <el-table-column label="支付状态" prop="status" key="status" align="center" :formatter="statusFormatter" />
+      <el-table-column label="支付时间" prop="goodsUpdateTime" key="goodsUpdateTime" align="center" />
+      <el-table-column label="用户账号" prop="userName" key="userName" align="center" />
+      <el-table-column label="支付流水号" key="payId" align="center">
+        <template slot-scope="scope">
+          <span>{{ scope.row.payId | empty(scope.row.payId) }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column v-if="form.searchType === '2'" label="生效状态" prop="flowStatus" key="flowStatus" align="center"
+        :formatter="flowFormatter" />
+      <el-table-column v-if="form.searchType === '2'" label="生效时间" key="effectTime" align="center">
+        <template slot-scope="scope">
+          <span>{{ scope.row.effectTime | empty(scope.row.effectTime) }}</span>
+        </template>
+      </el-table-column>
+    </el-table>
+    <pagination v-show="total > 0" :total="total" :page.sync="form.pageNum" :limit.sync="form.pageSize"
+      @pagination="getList" />
+    <!-- 弹窗 -->
+    <el-dialog :visible.sync="dialogVisible" title="导出历史" width="1000px">
+      <el-table :data="dialogTable" v-loading="dialogLoading">
+        <el-table-column type="index" label="序号" align="center" />
+        <el-table-column label="任务ID" prop="msgId" align="center" />
+        <el-table-column label="任务名称" prop="jobName" align="center" />
+        <el-table-column label="任务类型" prop="jobType" align="center" />
+        <el-table-column label="导出时间" prop="updateTime" align="center" />
+        <el-table-column label="操作人" prop="useName" align="center" />
+        <el-table-column label="操作" align="center">
+          <template slot-scope="scope">
+            <el-button type="text" @click="getDownLoad(scope.row)" :disabled="scope.row.status === 1">下载</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination v-show="dialogTotal > 0" :total="dialogTotal" :page.sync="dialogForm.pageNum"
+        :limit.sync="dialogForm.pageSize" @pagination="getDialogList" />
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { list, dialogList, download, downLoadHistory } from '@/api/order/list'
+import { list as sceneList } from '@/api/operation/scene'
+import { payTypeMixin, systemMixin, serviceTimeMixin } from '@/mixin/index'
+export default {
+  mixins: [payTypeMixin, systemMixin, serviceTimeMixin],
+  data() {
+    return {
+      // 遮罩层
+      loading: false,
+      dialogLoading: false,
+      // 表单
+      form: {
+        pageNum: 1,
+        pageSize: 10,
+        searchType: this.$route.query.searchType
+      },
+      // 列表
+      tableData: [],
+      // 总数据
+      total: 0,
+      // 弹窗
+      dialogVisible: false,
+      // 弹窗表单
+      dialogForm: {
+        pageNum: 1,
+        pageSize: 10,
+        searchType: this.$route.query.searchType
+      },
+      // 弹窗列表
+      dialogTable: [],
+      // 历史数据
+      dialogTotal: 0,
+      // 支付方式
+      payOptions: [{
+        value: 1,
+        label: '微信'
+      }, {
+        value: 2,
+        label: '支付宝'
+      }],
+      // 支付状态
+      statusOptions: [{
+        value: 2,
+        label: '支付成功'
+      }, {
+        value: 3,
+        label: '支付失败'
+      }],
+      // 栏目
+      sceneOptions: [],
+      // 生效状态
+      flowOptions: [{
+        value: 0,
+        label: '已生效'
+      }, {
+        value: 1,
+        label: '待生效'
+      }, {
+        value: 2,
+        label: '已失效'
+      }],
+      platformIdOptions: [{
+        value: 6,
+        label: 'QQ音乐'
+      }, {
+        value: 9,
+        label: '酷狗音乐'
+      }, {
+        value: 10,
+        label: '爱听音乐'
+      }],
+      // 时间搜索不超过1个月
+      selectDate: '',
+      pickerOptions: {
+        onPick: ({ maxDate, minDate }) => {
+          this.selectDate = minDate.getTime()
+          if (maxDate) {
+            this.selectDate = ''
+          }
+        },
+        disabledDate: (time) => {
+          if (this.selectDate !== '') {
+            const one = 30 * 24 * 3600 * 1000
+            const minTime = this.selectDate - one
+            const maxTime = this.selectDate + one
+            return time.getTime() < minTime || time.getTime() > maxTime
+          }
+        }
+      }
+    }
+  },
+  mounted() {
+    this.getScene()
+    this.getList()
+    this.payOptions.push(this.form.searchType === '3' ? {
+      value: 3,
+      label: '苹果支付'
+    } : {
+      value: 4,
+      label: '猫币支付'
+    })
+  },
+  methods: {
+    // 列表
+    getList() {
+      this.loading = true
+      list(this.form).then(res => {
+        if (res.code === 0) {
+          this.tableData = res.data.records
+          this.total = res.data.total
+          this.loading = false
+        }
+      })
+    },
+
+    // 搜索
+    getSearch() {
+      this.form.pageNum = 1
+      this.getList()
+    },
+
+    // 重置
+    getRefresh() {
+      this.form = {
+        pageNum: 1,
+        pageSize: 10,
+        searchType: this.$route.query.searchType
+      }
+      this.getList()
+    },
+
+    // 导出
+    handleExport() {
+      download(this.form).then(res => {
+        if (res.code === 0) {
+          this.$message.success(`${res.data}`)
+        }
+      })
+    },
+
+    // 弹窗
+    getDialog() {
+      this.dialogVisible = true
+      this.getDialogList()
+    },
+
+    // 历史列表
+    getDialogList() {
+      this.dialogLoading = true
+      dialogList(this.dialogForm).then(res => {
+        if (res.code === 0) {
+          this.dialogTable = res.data.records
+          this.dialogTotal = res.data.total
+          this.dialogLoading = false
+        }
+      })
+    },
+
+    // 历史下载
+    getDownLoad(row) {
+      this.$confirm(`是否下载${row.jobName}?`, '提示', {
+        type: 'warning'
+      }).then(() => {
+        downLoadHistory(row.msgId).then(res => {
+          if (res.code === 0) {
+            this.$message.success('下载成功!')
+            window.location.href = res.data
+            this.getDialogList()
+          }
+        })
+      }).catch(() => { })
+    },
+
+    // 栏目
+    getScene() {
+      sceneList().then(res => {
+        if (res.code === 0) {
+          res.data.map(i => {
+            this.sceneOptions.push({
+              value: i.id,
+              label: i.name
+            })
+          })
+        }
+      })
+    },
+
+    // 字典翻译
+    payTypeFormatter(row) {
+      return this.selectDictLabel(this.payOptions, row.payType)
+    },
+
+    statusFormatter(row) {
+      return this.selectDictLabel(this.statusOptions, row.status)
+    },
+
+    groupFormatter(row) {
+      return row.groupId === null ? '-' : this.selectDictLabel(this.sceneOptions, row.groupId)
+    },
+
+    chargingFormatter(row) {
+      return this.selectDictLabel(this.payTypeOptions, row.charging)
+    },
+
+    platformFormatter(row) {
+      return this.selectDictLabel(this.systemOptions, row.platform)
+    },
+
+    platformIdFormatter(row) {
+      return row.platformId === null ? '-' : this.selectDictLabel(this.platformIdOptions, row.platformId)
+    },
+
+    flowFormatter(row) {
+      return row.flowStatus === null ? '-' : this.selectDictLabel(this.flowOptions, row.flowStatus)
+    },
+
+    amountFormatter(row) {
+      return row.amount.toFixed(2)
+    },
+    
+    timeFormatter(row) {
+      return this.selectDictLabel(this.serviceTimeOptions, row.expirationTime)
+    }
+  },
+  // 过滤器
+  filters: {
+    empty(row) {
+      return !row ? '-' : row
+    }
+  }
+}
+</script>

+ 0 - 2
src/views/project/list/detail.vue

@@ -109,11 +109,9 @@
 
 <script>
 import { add, edit, update, appEdit, updateAdd, updatePage, historyPage, shelves } from "@/api/project/list";
-import Upload from "@/components/Upload/index";
 import Editor from "@/components/Editor";
 export default {
   components: {
-    Upload,
     Editor,
   },
   data() {

+ 1 - 4
src/views/push/message/index.vue

@@ -276,7 +276,4 @@ export default {
     }
   }
 }
-</script>
-
-<style lang="scss" scoped>
-</style>
+</script>

+ 135 - 0
src/views/push/update/detail.vue

@@ -0,0 +1,135 @@
+<template>
+  <div class="app-container">
+    <el-form :model="form" ref="form" :rules="rules" label-width="100px" :disabled="disabled">
+      <el-form-item label="版本号:" prop="lastVersion">
+        <el-input v-model="form.lastVersion" placeholder="请输入版本号" />
+      </el-form-item>
+      <el-form-item label="升级标题:" prop="updateTitle">
+        <el-input v-model="form.updateTitle" placeholder="请输入升级标题" maxlength="100" show-word-limit />
+      </el-form-item>
+      <el-form-item label="升级说明:" prop="updateDesc">
+        <el-input v-model="form.updateDesc" type="textarea" :autosize="{ minRows: 5, maxRows: 10 }" placeholder="请输入升级说明"
+          maxlength="500" show-word-limit />
+      </el-form-item>
+      <el-form-item label="强制升级:" prop="isForceUpdate">
+        <el-select v-model="form.isForceUpdate" placeholder="请选择是否强制">
+          <el-option v-for="item in typeOptions" :key="item.value" :value="item.value" :label="item.label" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="升级系统:" prop="appType">
+        <el-select v-model="form.appType" placeholder="请选择升级系统">
+          <el-option v-for="item in systemOptions" :key="item.value" :value="item.value" :label="item.label" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="下载路径:" prop="downUrl">
+        <el-row type="flex" justify="space-between">
+          <el-col :span="16">
+            <el-input v-model="form.downUrl" placeholder="请输入或上传下载路径" />
+          </el-col>
+          <el-col :span="6">
+            <Upload @upload="upload" style="float:right" />
+          </el-col>
+        </el-row>
+      </el-form-item>
+    </el-form>
+    <div class="form-btn">
+      <el-button @click="cancel">取消</el-button>
+      <el-button v-if="!disabled" type="primary" @click="getSubmit">确定</el-button>
+    </div>
+  </div>
+</template>
+
+<script>
+import { detail, submit } from '@/api/push/update'
+import { systemMixin } from '@/mixin'
+export default {
+  mixins: [systemMixin],
+  data() {
+    var checkVersion = (rule, value, callback) => {
+      if (!value) {
+        return callback(new Error('请输入版本号'))
+      }
+      let reg = /^[1-9](\.(0|[1-9])){2}$/
+      if (reg.test(value)) {
+        callback()
+      } else {
+        return callback(new Error('请输入正确的版本号,示例:x.x.x'))
+      }
+    }
+    return {
+      // 表单
+      form: {
+        downUrl: ""
+      },
+      // 只读
+      disabled: false,
+      // 是否强制
+      typeOptions: [{
+        value: 0,
+        label: '否'
+      }, {
+        value: 1,
+        label: '是'
+      }],
+      // 校验
+      rules: {
+        lastVersion: [{ required: true, validator: checkVersion, trigger: 'blur' }],
+        updateTitle: [{ required: true, message: '请输入升级标题', trigger: 'blur' }],
+        updateDesc: [{ required: true, message: '请输入升级说明', trigger: 'blur' }],
+        isForceUpdate: [{ required: true, message: '请选择是否强制', trigger: 'change' }],
+        appType: [{ required: true, message: '请选择升级系统', trigger: 'change' }],
+        downUrl: [{ required: true, message: '请上传下载路径', trigger: 'blur' }]
+      }
+    }
+  },
+  mounted() {
+    if (this.$route.query.id) {
+      this.form.id = this.$route.query.id
+      this.disabled = Boolean(this.$route.query.boolean)
+      this.getDetail()
+    }
+  },
+  methods: {
+    // 详情
+    getDetail() {
+      detail(this.form.id).then(res => {
+        if (res.code === 0) {
+          this.form = res.data
+        }
+      })
+    },
+
+    // 上传
+    upload(e) {
+      this.form.downUrl = e.file
+    },
+
+    // 取消
+    cancel() {
+      this.$tab.closeOpenPage("/push/update");
+    },
+
+    // 确定
+    getSubmit() {
+      this.$refs.form.validate((valid) => {
+        if (valid) {
+          submit(this.form).then(res => {
+            if (res.code === 0) {
+              this.$message.success('提交成功!')
+              this.cancel()
+            }
+          })
+        } else {
+          return false
+        }
+      })
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.el-form {
+  width: 500px;
+}
+</style>

+ 136 - 0
src/views/push/update/index.vue

@@ -0,0 +1,136 @@
+<template>
+  <div class="app-container">
+    <!-- 搜索 -->
+    <el-form size="mini" inline>
+      <el-form-item label="版本号:">
+        <el-input v-model="form.lastVersion" placeholder="请输入版本号" clearable />
+      </el-form-item>
+      <el-form-item label="升级系统:">
+        <el-select v-model="form.appType" placeholder="请选择升级系统" clearable>
+          <el-option v-for="item in systemOptions" :key="item.value" :value="item.value" :label="item.label" />
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" @click="getSearch">搜索</el-button>
+        <el-button icon="el-icon-refresh" @click="getRefresh">重置</el-button>
+        <el-button type="primary" icon="el-icon-plus" plain @click="getDetail()" v-hasPermi="['push:update:add']">新增</el-button>
+      </el-form-item>
+    </el-form>
+    <!-- 列表 -->
+    <el-table :data="tableData" v-loading="loading">
+      <el-table-column type="index" label="序号" align="center" />
+      <el-table-column label="升级标题" prop="updateTitle" align="center" show-overflow-tooltip />
+      <el-table-column label="版本号" prop="lastVersion" align="center" />
+      <el-table-column label="下载路径" prop="downUrl" align="center" show-overflow-tooltip />
+      <el-table-column label="是否强制升级" prop="isForceUpdate" align="center" :formatter="typeFormatter" />
+      <el-table-column label="升级系统" prop="appType" align="center" :formatter="appTypeFormatter" />
+      <el-table-column label="更新时间" prop="updateTime" align="center" />
+      <el-table-column label="操作" align="center">
+        <template slot-scope="scope">
+          <el-button type="text" @click="getDetail(scope.row.id, true)">查看</el-button>
+          <el-button type="text" @click="getDetail(scope.row.id)" v-hasPermi="['push:update:edit']">编辑</el-button>
+          <el-button type="delete" @click="getDelete(scope.row)" v-hasPermi="['push:update:delete']">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <pagination v-show="total > 0" :total="total" :page.sync="form.pageNum" :limit.sync="form.pageSize"
+      @pagination="getList" />
+  </div>
+</template>
+
+<script>
+import { list, remove } from '@/api/push/update'
+import { systemMixin } from '@/mixin'
+export default {
+  mixins: [systemMixin],
+  data() {
+    return {
+      // 遮罩层
+      loading: false,
+      // 表单
+      form: {
+        pageNum: 1,
+        pageSize: 10
+      },
+      // 列表
+      tableData: [],
+      // 总数据
+      total: 0,
+      // 是否强制
+      typeOptions: [{
+        value: 0,
+        label: '否'
+      }, {
+        value: 1,
+        label: '是'
+      }]
+    }
+  },
+  mounted() {
+    this.getList()
+  },
+  methods: {
+    // 列表
+    getList() {
+      this.loading = true
+      list(this.form).then(res => {
+        if (res.code === 0) {
+          this.tableData = res.data.records
+          this.total = res.data.total
+          this.loading = false
+        }
+      })
+    },
+    // 搜索
+    getSearch() {
+      this.form.pageNum = 1
+      this.getList()
+    },
+
+    // 重置
+    getRefresh() {
+      this.form = {
+        pageNum: 1,
+        pageSize: 10
+      }
+      this.getList()
+    },
+
+    // 新增 编辑
+    getDetail(id, boolean) {
+      this.$router.push({
+        path: '/push/update/detail',
+        query: {
+          id: id,
+          boolean: boolean
+        }
+      })
+    },
+
+    // 删除
+    getDelete(row) {
+      this.$confirm(`是否删除${row.updateTitle}?`, '提示', {
+        type: 'warning'
+      }).then(() => {
+        remove(row.id, 1).then(res => {
+          if (res.code === 0) {
+            this.$message.success('删除成功!')
+            this.getList()
+          }
+        })
+      }).catch(() => { })
+    },
+
+    // 字典翻译
+    typeFormatter(row) {
+      return this.selectDictLabel(this.typeOptions, row.isForceUpdate)
+    },
+
+    appTypeFormatter(row) {
+      return this.selectDictLabel(this.systemOptions, row.appType)
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped></style>

+ 0 - 4
src/views/registration/content/detail.vue

@@ -68,15 +68,11 @@
 </template>
 
 <script>
-import Upload from '@/components/Upload/index.vue'
 import { radioList } from '@/api/operation/recommend'
 import { create, detail, edit } from '@/api/registration/content'
 import { platformMixin, audioMixin, isFreeMixin, coverMixin } from '@/mixin/index'
 export default {
   mixins: [platformMixin, audioMixin, isFreeMixin, coverMixin],
-  components: {
-    Upload
-  },
   data() {
     return {
       // 遮罩层

+ 0 - 4
src/views/registration/exchange/detail.vue

@@ -35,12 +35,8 @@
 </template>
 
 <script>
-import Upload from '@/components/Upload/index.vue'
 import { create, detail, edit, mealList } from '@/api/registration/exchange'
 export default {
-  components: {
-    Upload
-  },
   data() {
     return {
       // 表单

+ 1 - 5
src/views/registration/lottery/detail.vue

@@ -29,7 +29,7 @@
           <el-option v-for="item in numOptions" :key="item.value" :value="item.value" :label="item.label" />
         </el-select>
       </el-form-item>
-      <el-form-item style="width: 1000px">
+      <el-form-item style="width: 1200px">
         <el-table :data="form.lotteryConfigGoodList">
           <el-table-column label="顺序" type="index" align="center" />
           <el-table-column label="奖品类型" align="center">
@@ -78,11 +78,7 @@
 
 <script>
 import { detail, create, checkTime, edit } from '@/api/registration/lottery'
-import Upload from '@/components/Upload/index.vue'
 export default {
-  components: {
-    Upload
-  },
   data() {
     return {
       // 表单

+ 0 - 4
src/views/registration/regConfig/index.vue

@@ -99,13 +99,9 @@
 </template>
 
 <script>
-import Upload from '@/components/Upload/index.vue'
 import { list, submit, removeContinue, removeListenGood } from '@/api/registration/regConfig'
 import { checkPermi } from '@/utils/permission'
 export default {
-  components: {
-    Upload
-  },
   data() {
     return {
       // 遮罩层

+ 62 - 37
src/views/service/package/detail.vue

@@ -2,25 +2,21 @@
   <div class="app-container">
     <el-form :model="form" :rules="rules" ref="form" label-width="100px">
       <el-form-item label="关联设备:">
-        <el-select v-model="deviceIds" multiple placeholder="请选择关联设备">
-          <el-option v-for="item in devOptions" :key="item.value" :label="item.label"
-            :value="item.value.toString()" />
+        <el-select v-model="form.deviceIds" filterable multiple placeholder="请选择关联设备">
+          <el-option v-for="item in devOptions" :key="item.value" :label="item.label" :value="item.value.toString()" />
         </el-select>
       </el-form-item>
-      <el-form-item :label="form.type == 13 ? '套餐名称:': '流量名称:'">
+      <el-form-item label="套餐名称:">
         <el-input v-model="form.name" placeholder="请输入套餐名称" />
       </el-form-item>
       <el-form-item label="服务类型:">
-        <el-select v-model="form.businessType" placeholder="请选择服务类型"
-          :disabled="form.id && form.type == 12 ? true : false">
-          <el-option v-for="item in serviceTypeOptions" :key="item.value" :value="item.value"
-            :label="item.label" />
+        <el-select v-model="form.businessType" placeholder="请选择服务类型" :disabled="form.id && typeList[0] === '12'">
+          <el-option v-for="item in serviceTypeOptions" :key="item.value" :value="item.value" :label="item.label" />
         </el-select>
       </el-form-item>
-      <el-form-item v-if="form.type == 13" label="资源平台:">
+      <el-form-item v-if="typeList[0] === '13'" label="资源平台:">
         <el-select v-model="form.platformId" placeholder="请选择资源平台">
-          <el-option v-for="item in platformOptions" :key="item.value" :label="item.label"
-            :value="item.value" />
+          <el-option v-for="item in platformOptions" :key="item.value" :label="item.label" :value="item.value" />
         </el-select>
       </el-form-item>
       <el-form-item v-else label="流量套餐:">
@@ -28,9 +24,13 @@
           <el-option v-for="(item, index) in goodsOptions" :key="index" :label="item" :value="index" />
         </el-select>
       </el-form-item>
+      <el-form-item v-if="form.platformId === 10" label="栏目:">
+        <el-select v-model="form.groupId" placeholder="请选择爱听栏目">
+          <el-option v-for="item in sceneOptions" :key="item.value" :value="item.value" :label="item.label" />
+        </el-select>
+      </el-form-item>
       <el-form-item label="原价:" prop="price">
-        <el-input-number v-model="form.price" :min="0" :max="500" :controls="false" :precision="2"
-          placeholder="请输入原价" />
+        <el-input-number v-model="form.price" :min="0" :max="500" :controls="false" :precision="2" placeholder="请输入原价" />
       </el-form-item>
       <el-form-item label="活动价:" prop="discount">
         <el-input-number v-model="form.discount" :min="0" :max="500" :controls="false" :precision="2"
@@ -38,14 +38,12 @@
       </el-form-item>
       <el-form-item label="服务时长:">
         <el-select v-model="form.indate" placeholder="请选择服务时长">
-          <el-option v-for="item in serviceTimeOptions" :key="item.value" :label="item.label"
-            :value="item.value" />
+          <el-option v-for="item in serviceTimeOptions" :key="item.value" :label="item.label" :value="item.value" />
         </el-select>
       </el-form-item>
       <el-form-item label="是否推荐:">
         <el-select v-model="form.isRecommend" placeholder="请选择是否推荐">
-          <el-option v-for="item in recommendOptions" :key="item.value" :label="item.label"
-            :value="item.value" />
+          <el-option v-for="item in recommendOptions" :key="item.value" :label="item.label" :value="item.value" />
         </el-select>
       </el-form-item>
       <el-form-item label="排序:" v-if="form.businessType === 5">
@@ -61,6 +59,7 @@
 
 <script>
 import { devMixin, serviceTimeMixin, serviceTypeMixin } from '@/mixin/index'
+import { list } from '@/api/operation/scene'
 import { detail, edit, create, goodsList } from '@/api/service/package'
 export default {
   mixins: [devMixin, serviceTimeMixin, serviceTypeMixin],
@@ -84,17 +83,25 @@ export default {
     }
     return {
       // 表单
-      form: {
-        type: this.$route.query.type
-      },
+      form: {},
+      // 区分
+      typeList: this.$route.query.typeList.split(','),
       // 流量套餐
       goodsOptions: [],
+      // 爱听专区
+      sceneOptions: [],
       // 关联设备
       deviceIds: [],
       // 资源平台
       platformOptions: [{
-        value: 1,
+        value: 6,
         label: 'QQ音乐'
+      }, {
+        value: 9,
+        label: '酷狗音乐'
+      }, {
+        value: 10,
+        label: '爱听音乐'
       }],
       // 是否推荐
       recommendOptions: [{
@@ -117,20 +124,11 @@ export default {
       }
     }
   },
-  watch: {
-    deviceIds(val) {
-      this.form.deviceIds = val.join(',')
-    }
-  },
   mounted() {
-    if (this.form.type == 12) {
-      // 流量套餐
-      goodsList().then(res => {
-        if (res.code === 0) {
-          this.goodsOptions = res.data
-        }
-      })
-    }
+    this.typeList[0] === '12' ? [
+      this.getGoodSList(),
+      this.form.type = 12
+    ] : this.getSceneList()
     if (this.$route.query.id) {
       this.form.id = this.$route.query.id
       this.getList()
@@ -142,14 +140,40 @@ export default {
       detail(this.form.id).then(res => {
         if (res.code === 0) {
           this.form = res.data
-          this.deviceIds = res.data.deviceIds.split(',')
+          this.form.deviceIds = res.data.deviceIds.split(',')
+        }
+      })
+    },
+
+    // 流量套餐
+    getGoodSList() {
+      goodsList().then(res => {
+        if (res.code === 0) {
+          this.goodsOptions = res.data
         }
       })
     },
+
+    // 爱听专区
+    getSceneList() {
+      list().then(res => {
+        if (res.code === 0) {
+          res.data.map(i => {
+            this.sceneOptions.push({
+              value: i.id,
+              label: i.name
+            })
+          })
+        }
+      })
+    },
+
+
     // 提交
     getSubmit() {
       this.$refs.form.validate((valid) => {
         if (valid) {
+          this.form.deviceIds = this.form.deviceIds.join(',')
           if (this.form.id) {
             edit(this.form).then(res => {
               if (res.code === 0) {
@@ -170,10 +194,11 @@ export default {
         }
       })
     },
+
     // 取消
     cancel() {
-      let url = this.form.type == 13 ? 'musicPackage' : 'flowPackage'
-      this.$tab.closeOpenPage(`/service/${url}?type=${this.form.type}`);
+      let url = this.typeList[0] === '13' ? 'musicPackage' : 'flowPackage'
+      this.$tab.closeOpenPage(`/service/${url}?typeList=${this.typeList}`);
     }
   }
 }

+ 60 - 29
src/views/service/package/index.vue

@@ -2,13 +2,12 @@
   <div class="app-container">
     <!-- 搜索 -->
     <el-form inline size="mini">
-      <el-form-item :label="form.type == 13 ? '套餐名称:' : '流量名称:'">
+      <el-form-item :label="form.typeList[0] === '13' ? '套餐名称:' : '流量名称:'">
         <el-input v-model="form.name" placeholder="请输入套餐名称" clearable />
       </el-form-item>
-      <el-form-item v-if="form.type == 13" label="资源平台:">
+      <el-form-item v-if="form.typeList[0] !== '12'" label="资源平台:">
         <el-select v-model="form.platformId" placeholder="请选择资源平台" clearable>
-          <el-option v-for="item in platformOptions" :key="item.value" :label="item.label"
-            :value="item.value" />
+          <el-option v-for="item in platformOptions" :key="item.value" :label="item.label" :value="item.value" />
         </el-select>
       </el-form-item>
       <el-form-item v-else label="流量套餐:">
@@ -17,14 +16,13 @@
         </el-select>
       </el-form-item>
       <el-form-item label="关联设备:">
-        <el-select v-model="form.deviceIds" placeholder="请选择关联设备" clearable>
+        <el-select v-model="form.deviceIds" filterable placeholder="请选择关联设备" clearable>
           <el-option v-for="item in devOptions" :key="item.value" :label="item.label" :value="item.value" />
         </el-select>
       </el-form-item>
       <el-form-item label="当前状态:">
         <el-select v-model="form.status" placeholder="请选择当前状态" clearable>
-          <el-option v-for="item in statusOptions" :key="item.value" :label="item.label"
-            :value="item.value" />
+          <el-option v-for="item in statusOptions" :key="item.value" :label="item.label" :value="item.value" />
         </el-select>
       </el-form-item>
       <el-form-item>
@@ -35,23 +33,24 @@
       </el-form-item>
     </el-form>
     <!-- 列表 -->
-    <el-table :data="tableData" v-loading="loading" :default-sort="{prop: 'sort'}">
+    <el-table :data="tableData" v-loading="loading" :default-sort="{ prop: 'sort' }">
       <el-table-column label="排序" align="center" prop="sort" key="sort" :formatter="sortFormatter" />
-      <el-table-column :label="form.type == 13 ? '套餐名称' : '流量套餐'" align="center" prop="name" key="name"
+      <el-table-column :label="form.typeList[0] === '13' ? '套餐名称' : '流量名称'" align="center" prop="name" key="name"
         show-overflow-tooltip />
       <el-table-column label="关联设备" align="center" prop="deviceIds" key="deviceIds" :formatter="devFormatter"
         show-overflow-tooltip />
       <el-table-column label="原价/元" align="center" prop="price" key="price" />
       <el-table-column label="活动价/元" align="center" prop="discount" key="discount" />
-      <el-table-column v-if="form.type == 12" label="流量套餐" align="center" prop="intro" key="intro"
+      <el-table-column v-if="form.typeList[0] === '12'" label="流量套餐" align="center" prop="intro" key="intro"
         show-overflow-tooltip />
-      <el-table-column v-if="form.type == 13" label="有效期" align="center" prop="indate" key="indate"
+      <el-table-column v-if="form.typeList[0] !== '12'" label="有效期" align="center" prop="indate" key="indate"
         :formatter="timeFormatter" />
-      <el-table-column v-if="form.type == 13" label="资源平台" align="center" prop="platformId" key="platformId"
+      <el-table-column v-if="form.typeList[0] !== '12'" label="资源平台" align="center" prop="platformId" key="platformId"
         :formatter="platformFormatter" />
+      <el-table-column v-if="form.typeList[0] !== '12'" label="栏目" align="center" prop="groupId" key="groupId"
+        :formatter="sceneFormatter" />
       <el-table-column label="当前状态" align="center" prop="status" key="status" :formatter="statusFormatter" />
-      <el-table-column label="是否推荐" align="center" prop="isRecommend" key="isRecommend"
-        :formatter="recommendFormatter" />
+      <el-table-column label="是否推荐" align="center" prop="isRecommend" key="isRecommend" :formatter="recommendFormatter" />
       <el-table-column label="创建时间" align="center" prop="createTime" key="createTime" />
       <el-table-column label="操作" align="center">
         <template slot-scope="scope">
@@ -65,13 +64,14 @@
         </template>
       </el-table-column>
     </el-table>
-    <pagination v-show="total>0" :total="total" :page.sync="form.pageNum" :limit.sync="form.pageSize"
+    <pagination v-show="total > 0" :total="total" :page.sync="form.pageNum" :limit.sync="form.pageSize"
       @pagination="getList" />
   </div>
 </template>
 
 <script>
 import { list, remove, shelve, goodsList } from '@/api/service/package'
+import { list as sceneList } from '@/api/operation/scene'
 import { devMixin, serviceTimeMixin } from '@/mixin/index'
 export default {
   mixins: [devMixin, serviceTimeMixin],
@@ -83,7 +83,7 @@ export default {
       form: {
         pageNum: 1,
         pageSize: 10,
-        type: this.$route.query.type
+        typeList: this.$route.query.typeList.split(',')
       },
       // 列表
       tableData: [],
@@ -107,22 +107,27 @@ export default {
       }],
       // 资源平台
       platformOptions: [{
-        value: 1,
+        value: 6,
         label: 'QQ音乐'
+      }, {
+        value: 9,
+        label: '酷狗音乐'
+      }, {
+        value: 10,
+        label: '爱听音乐'
       }],
       // 流量套餐
-      goodsOptions: []
+      goodsOptions: [],
+      // 爱听专区
+      sceneOptions: []
     }
   },
   mounted() {
     this.getList()
-    if (this.form.type == 12) {
-      // 流量套餐
-      goodsList().then(res => {
-        if (res.code === 0) {
-          this.goodsOptions = res.data
-        }
-      })
+    if (this.form.typeList[0] === '12') {
+      this.getGoodSList()
+    } else {
+      this.getSceneList()
     }
   },
   methods: {
@@ -138,6 +143,29 @@ export default {
       })
     },
 
+    // 流量套餐
+    getGoodSList() {
+      goodsList().then(res => {
+        if (res.code === 0) {
+          this.goodsOptions = res.data
+        }
+      })
+    },
+
+    // 爱听专区
+    getSceneList() {
+      sceneList().then(res => {
+        if (res.code === 0) {
+          res.data.map(i => {
+            this.sceneOptions.push({
+              value: i.id,
+              label: i.name
+            })
+          })
+        }
+      })
+    },
+
     // 搜索
     getSearch() {
       this.form.pageNum = 1
@@ -149,21 +177,21 @@ export default {
       this.form = {
         pageNum: 1,
         pageSize: 10,
-        type: this.$route.query.type
+        typeList: this.$route.query.typeList.split(',')
       }
       this.getList()
     },
 
     // 新增 / 编辑
     getDetail(id) {
+      this.$route.meta.activeMenu = this.form.typeList[0] === '13' ? '/service/musicPackage' : '/service/flowPackage'
       this.$router.push({
         path: `/service/package/detail`,
         query: {
           id: id,
-          type: this.form.type
+          typeList: this.form.typeList.join(',')
         }
       })
-      this.$route.meta.activeMenu = this.form.type == 13 ? '/service/musicPackage' : '/service/flowPackage'
     },
 
     // 删除
@@ -218,7 +246,10 @@ export default {
     devFormatter(row) {
       return row.deviceIds ? row.deviceIds.split(',').map(i => this.selectDictLabel(this.devOptions, i)).join(',') : ''
     },
-
+    // 栏目
+    sceneFormatter(row) {
+      return this.selectDictLabel(this.sceneOptions, row.groupId)
+    }
   }
 }
 </script>

+ 10 - 30
src/views/service/qqmusic/index.vue

@@ -3,20 +3,16 @@
     <!-- 搜索 -->
     <el-form inline size="mini">
       <el-form-item label="批次:">
-        <el-select v-model="form.batchId" placeholder="请选择批次" clearable>
-          <el-option v-for="item in batchOptions" :key="item.value" :label="item.label" :value="item.value" />
-        </el-select>
+        <el-input v-model="form.no" placeholder="请输入批次" clearable />
       </el-form-item>
       <el-form-item label="服务时长:">
         <el-select v-model="form.serviceTime" placeholder="请选择服务时长" clearable>
-          <el-option v-for="item in serviceTimeOptions" :key="item.value" :label="item.label"
-            :value="item.value" />
+          <el-option v-for="item in serviceTimeOptions" :key="item.value" :label="item.label" :value="item.value" />
         </el-select>
       </el-form-item>
       <el-form-item label="当前状态:">
         <el-select v-model="form.status" placeholder="请选择当前状态" clearable>
-          <el-option v-for="item in statusOptions" :key="item.value" :label="item.label"
-            :value="item.value" />
+          <el-option v-for="item in statusOptions" :key="item.value" :label="item.label" :value="item.value" />
         </el-select>
       </el-form-item>
       <el-form-item label="用户姓名:">
@@ -27,8 +23,7 @@
       </el-form-item>
       <el-form-item label="激活状态:">
         <el-select v-model="form.activeStatus" placeholder="请选择激活状态" clearable>
-          <el-option v-for="item in activeOptions" :key="item.value" :value="item.value"
-            :label="item.label" />
+          <el-option v-for="item in activeOptions" :key="item.value" :value="item.value" :label="item.label" />
         </el-select>
       </el-form-item>
       <el-form-item>
@@ -59,7 +54,7 @@
       </el-table-column>
     </el-table>
     <!-- 分页 -->
-    <pagination v-show="total>0" :total="total" :page.sync="form.pageNum" :limit.sync="form.pageSize"
+    <pagination v-show="total > 0" :total="total" :page.sync="form.pageNum" :limit.sync="form.pageSize"
       @pagination="getList" />
     <!-- 弹窗 -->
     <el-dialog :visible.sync="dialogVisible" :title="title">
@@ -67,8 +62,7 @@
       <el-form v-if="title === '批量推送短信'">
         <el-form-item label="服务时长:" label-width="100px" style="width: 300px">
           <el-select v-model="dialogForm.serviceTime" placeholder="请选择服务时长">
-            <el-option v-for="item in serviceTimeOptions" :key="item.value" :label="item.label"
-              :value="item.value" />
+            <el-option v-for="item in serviceTimeOptions" :key="item.value" :label="item.label" :value="item.value" />
           </el-select>
         </el-form-item>
         <el-form-item>
@@ -104,7 +98,7 @@
           </el-table-column>
         </el-table>
         <!-- 分页 -->
-        <pagination v-show="batchTotal>0" :total="batchTotal" :page.sync="batchForm.pageNum"
+        <pagination v-show="batchTotal > 0" :total="batchTotal" :page.sync="batchForm.pageNum"
           :limit.sync="batchForm.pageSize" @pagination="getBatchPage" />
       </div>
 
@@ -133,12 +127,8 @@
 <script>
 import { page, send, importData, detail, past, batchList, batchPage } from '@/api/service/qqmusic'
 import { serviceTimeMixin } from '@/mixin/index'
-import Upload from '@/components/Upload/index'
 export default {
   mixins: [serviceTimeMixin],
-  components: {
-    Upload
-  },
   data() {
     return {
       // 遮罩层
@@ -178,7 +168,7 @@ export default {
         value: 2,
         label: '删除'
       }],
-      batchOptions: [],
+      // batchOptions: [], (3.0.6版本舍弃)
       // 当前状态
       statusOptions: [
         { value: 0, label: '已发送' },
@@ -192,17 +182,7 @@ export default {
     }
   },
   mounted() {
-    // 批次列表
-    batchList().then(res => {
-      if (res.code === 0) {
-        res.data.map(i => {
-          this.batchOptions.push({
-            value: i.id,
-            label: i.no
-          })
-        })
-      }
-    })
+    // this.getBatchList() (3.0.6版本舍弃)
     this.getList()
   },
   methods: {
@@ -217,7 +197,7 @@ export default {
         }
       })
     },
-
+    
     // 搜索
     getSearch() {
       this.form.pageNum = 1

+ 172 - 0
src/views/service/quota/index.vue

@@ -0,0 +1,172 @@
+<template>
+  <div class="app-container">
+    <!-- 搜索 -->
+    <el-form inline size="mini">
+      <el-form-item label="额度库编码:">
+        <el-input v-model="form.quotaNo" placeholder="请输入额度库编码" clearable />
+      </el-form-item>
+      <el-form-item label="当前状态:">
+        <el-select v-model="form.status" placeholder="请选择当前状态" clearable>
+          <el-option v-for="item in statusOptions" :key="item.value" :value="item.value" :label="item.label" />
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" @click="getSearch">搜索</el-button>
+        <el-button icon="el-icon-refresh" @click="getRefresh">重置</el-button>
+        <el-button type="primary" icon="el-icon-plus" plain @click="getDialog('新增')"
+          v-hasPermi="['service:quota:add']">新增</el-button>
+      </el-form-item>
+    </el-form>
+    <!-- 列表 -->
+    <el-table :data="tableData" v-loading="loading">
+      <el-table-column label="额度库编码" prop="packetNo" align="center" show-overflow-tooltip />
+      <el-table-column label="总额度 / 天" prop="totalQuota" align="center" />
+      <el-table-column label="额度剩余 / 天" prop="mayQuota" align="center" />
+      <el-table-column label="生效起始时间" prop="startDate" align="center" />
+      <el-table-column label="生效结束时间" prop="expireDate" align="center" />
+      <el-table-column label="创建时间" prop="createTime" align="center" />
+      <el-table-column label="当前状态" prop="status" align="center" :formatter="statusFormatter" />
+      <el-table-column label="操作" align="center">
+        <template slot-scope="scope">
+          <el-button type="text" @click="getDialog('查看', scope.row.id)">查看</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <pagination v-show="total > 0" :total="total" :page.sync="form.pageNum" :limit.sync="form.pageSize"
+      @pagination="getList" />
+    <!-- 弹窗 -->
+    <el-dialog :visible.sync="dialogVisible" :title="title" width="600px" :before-close="getCancel">
+      <el-form :model="dialogForm" ref="dialogForm" label-width="120px" :disabled="disabled">
+        <el-form-item label="额度库时间:" prop="totalQuota">
+          <el-input-number v-model="dialogForm.totalQuota" :min="1" step-strictly :controls="false" /> / 天
+        </el-form-item>
+        <el-form-item label="生效起始时间:" prop="startDate">
+          <el-date-picker v-model="dialogForm.startDate" type="datetime" placeholder="请选择生效起始时间"
+            :picker-options="pickerOptions" value-format="yyyy-MM-dd HH:mm:ss" />
+        </el-form-item>
+      </el-form>
+      <div slot="footer">
+        <el-button @click="getCancel">取消</el-button>
+        <el-button v-if="!disabled" type="primary" @click="getSubmit">确定</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { list, detail, create } from '@/api/service/quota'
+export default {
+  data() {
+    return {
+      // 遮罩层
+      loading: false,
+      // 表单
+      form: {
+        pageNum: 1,
+        pageSize: 10
+      },
+      // 总数据
+      total: 0,
+      // 列表
+      tableData: [],
+      // 弹窗
+      dialogVisible: false,
+      // 弹窗名称
+      title: '新增',
+      // 弹窗表单
+      dialogForm: {},
+      // 当前状态
+      statusOptions: [{
+        value: 0,
+        label: '待生效'
+      }, {
+        value: 1,
+        label: '生效中'
+      }, {
+        value: 2,
+        label: '已失效'
+      }, {
+        value: 3,
+        label: '已过期'
+      }],
+      // 定义时间选择器
+      pickerOptions: {
+        disabledDate(time) {
+          return time.getTime() < (Date.now() - (24 * 60 * 60 * 1000))
+        }
+      },
+      // 只读
+      disabled: false
+    }
+  },
+  mounted() {
+    this.getList()
+  },
+  methods: {
+    // 列表
+    getList() {
+      this.loading = true
+      list(this.form).then(res => {
+        if (res.code === 0) {
+          this.tableData = res.data.records
+          this.total = res.data.total
+          this.loading = false
+        }
+      })
+    },
+
+    // 搜索
+    getSearch() {
+      this.form.pageNum = 1
+      this.getList()
+    },
+
+    // 重置
+    getRefresh() {
+      this.form = {
+        pageNum: 1,
+        pageSize: 10
+      }
+      this.getList()
+    },
+
+    // 新增 / 查看
+    getDialog(title, id) {
+      this.dialogVisible = true
+      this.title = title
+      this.disabled = title === '查看' ? true : false
+      if (id) {
+        detail(id).then(res => {
+          this.dialogForm = res.data
+        })
+      }
+    },
+
+    // 取消
+    getCancel() {
+      this.dialogVisible = false
+      this.dialogForm = {}
+    },
+
+    // 确定
+    getSubmit() {
+      create(this.dialogForm).then(res => {
+        if (res.code === 0) {
+          this.$message.success('新增成功!')
+          this.getCancel()
+          this.getList()
+        }
+      })
+    },
+
+    // 字典翻译
+    statusFormatter(row) {
+      return this.selectDictLabel(this.statusOptions, row.status)
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 229 - 0
src/views/user/list/index.vue

@@ -0,0 +1,229 @@
+<template>
+  <div class="app-container">
+    <!-- 搜索 -->
+    <el-form inline size="mini">
+      <el-form-item label="用户账号:">
+        <el-input v-model="form.userName" placeholder="请输入用户账号" clearable />
+      </el-form-item>
+      <el-form-item label="用户手机号:">
+        <el-input type="number" v-model="form.phone" placeholder="请输入用户手机号" clearable />
+      </el-form-item>
+      <el-form-item label="注册来源:">
+        <el-select v-model="form.registerChannel" placeholder="请选择注册来源" clearable>
+          <el-option v-for="item in regOptions" :key="item.value" :value="item.value" :label="item.label" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="注册时间:">
+        <el-date-picker v-model="form.startsignTime" type="datetimerange" start-placeholder="开始日期" end-placeholder="结束日期"
+          format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss" />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" @click="getSearch">搜索</el-button>
+        <el-button icon="el-icon-refresh" @click="getRefresh">重置</el-button>
+      </el-form-item>
+    </el-form>
+    <!-- 列表 -->
+    <el-table :data="tableData" v-loading="loading">
+      <el-table-column label="用户ID" prop="id" align="center" show-overflow-tooltip />
+      <el-table-column label="用户账号" prop="nickname" align="center" />
+      <el-table-column label="用户手机号" prop="phone" align="center" />
+      <el-table-column label="用户头像" align="center" width="100px">
+        <template slot-scope="scope">
+          <el-image :src="scope.row.headUrl" />
+        </template>
+      </el-table-column>
+      <el-table-column label="用户性别" prop="sex" align="center" :formatter="sexFormatter" />
+      <el-table-column label="注册来源" prop="registerChannel" align="center" :formatter="regFormatter" />
+      <el-table-column label="注册系统" prop="mtype" align="center" :formatter="typeFormatter" />
+      <el-table-column label="注册时间" prop="createTime" align="center" />
+      <el-table-column label="用户积分" align="center">
+        <template slot-scope="scope">
+          <span>{{ scope.row.totalPoint | empty(scope.row.totalPoint) }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column align="center">
+        <template slot="header">
+          <div>钱包余额</div>
+          <div>(Android)</div>
+        </template>
+        <template slot-scope="scope">
+          <span>{{ scope.row.balanceAndroid.toFixed(2) }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column align="center">
+        <template slot="header">
+          <div>钱包余额</div>
+          <div>(iOS)</div>
+        </template>
+        <template slot-scope="scope">
+          <span>{{ scope.row.balanceIos.toFixed(2) }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="已绑设备" align="center" show-overflow-tooltip>
+        <template slot-scope="scope">
+          <span v-if="scope.row.deviceList">
+            {{ scope.row.deviceList.join(',') }}
+          </span>
+          <span v-else>
+            暂无绑定
+          </span>
+        </template>
+      </el-table-column>
+      <el-table-column label="购买次数" align="center">
+        <template slot-scope="scope">
+          <span>{{ scope.row.buyCount | empty(scope.row.buyCount) }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="累计消费 / 元" align="center">
+        <template slot-scope="scope">
+          <span>{{ scope.row.buyAmount | emptyCount(scope.row.buyAmount) }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="上次消费" prop="lastBuyTime" align="center">
+        <template slot-scope="scope">
+          <span>{{ scope.row.lastBuyTime | emptyDate(scope.row.lastBuyTime) }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="累计充值 / 元" prop="rechargeAmount" align="center">
+        <template slot-scope="scope">
+          <span>{{ scope.row.rechargeAmount | emptyCount(scope.row.rechargeAmount) }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="上次充值" prop="lastRechargeTime" align="center">
+        <template slot-scope="scope">
+          <span>{{ scope.row.lastRechargeTime | emptyDate(scope.row.lastRechargeTime) }}</span>
+        </template>
+      </el-table-column>
+    </el-table>
+    <pagination v-show="total > 0" :total="total" :page.sync="form.pageNum" :limit.sync="form.pageSize"
+      @pagination="getList" />
+  </div>
+</template>
+
+<script>
+import { list } from '@/api/user/list'
+import { sexMixin } from '@/mixin/index'
+export default {
+  mixins: [sexMixin],
+  data() {
+    return {
+      // 遮罩层
+      loading: false,
+      // 表单
+      form: {
+        pageNum: 1,
+        pageSize: 10
+      },
+      // 列表
+      tableData: [],
+      // 总数据
+      total: 0,
+      // 注册来源
+      regOptions: [{
+        value: -1,
+        label: '未知'
+      }, {
+        value: 0,
+        label: '小米应用市场'
+      }, {
+        value: 1,
+        label: '360应用市场'
+      }, {
+        value: 2,
+        label: '腾讯应用市场'
+      }, {
+        value: 3,
+        label: 'OPPP应用市场'
+      }, {
+        value: 4,
+        label: 'ViVO应用市场'
+      }, {
+        value: 5,
+        label: '魅族应用市场'
+      }, {
+        value: 6,
+        label: '华为应用市场'
+      }, {
+        value: 7,
+        label: '微信小程序'
+      }, {
+        value: 8,
+        label: 'AppStore'
+      }],
+      // 注册系统
+      typeOptions: [{
+        value: 0,
+        label: '未知'
+      }, {
+        value: 1,
+        label: 'Android'
+      }, {
+        value: 2,
+        label: 'iOS'
+      }]
+    }
+  },
+  mounted() {
+    this.getList()
+  },
+  methods: {
+    // 列表
+    getList() {
+      this.loading = true
+      list(this.form).then(res => {
+        if (res.code === 0) {
+          this.tableData = res.data.records
+          this.total = res.data.total
+          this.loading = false
+        }
+      })
+    },
+
+    // 搜索
+    getSearch() {
+      this.form.pageNum = 1
+      this.getList()
+    },
+
+    // 重置
+    getRefresh() {
+      this.form = {
+        pageNum: 1,
+        pageSize: 10
+      }
+      this.getList()
+    },
+
+    // 字典翻译
+    regFormatter(row) {
+      return this.selectDictLabel(this.regOptions, row.registerChannel)
+    },
+
+    sexFormatter(row) {
+      return this.selectDictLabel(this.sexOptions, row.sex)
+    },
+
+    typeFormatter(row) {
+      return this.selectDictLabel(this.typeOptions, row.mtype)
+    }
+  },
+
+  // 过滤器
+  filters: {
+    // 是否为空
+    empty(item) {
+      return !item ? 0 : item
+    },
+
+    // 金额是否为空
+    emptyCount(item) {
+      return !item ? '0.00' : Number(item).toFixed(2)
+    },
+
+    // 时间为空
+    emptyDate(item) {
+      return !item ? '-' : item
+    }
+  }
+}
+</script>