Pārlūkot izejas kodu

Merge branch 'develop/3.1.0' into test

DESKTOP-SVI9JE1\muzen 2 gadi atpakaļ
vecāks
revīzija
eee666af1f

+ 35 - 0
src/api/operation/activity.js

@@ -0,0 +1,35 @@
+import request from '@/utils/request'
+
+// 列表
+export function list(data) {
+  return request({
+    url: `/admin/activity/list`,
+    method: 'post',
+    data
+  })
+}
+
+// 详情
+export function detail(id) {
+  return request({
+    url: `/admin/activity/queryById/${id}`,
+    method: 'get'
+  })
+}
+
+// 提交
+export function submit(data) {
+  return request({
+    url: `/admin/activity/addOrUpdate`,
+    method: 'post',
+    data
+  })
+}
+
+// 上下架
+export function change(id, status) {
+  return request({
+    url: `/admin/activity/hitOrSold/${id}/${status}`,
+    method: 'get'
+  })
+}

+ 35 - 0
src/api/operation/agreement.js

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

+ 10 - 0
src/api/service/recovery.js

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

+ 27 - 0
src/api/user/store.js

@@ -0,0 +1,27 @@
+import request from '@/utils/request'
+
+// 列表
+export function list(data) {
+  return request({
+    url: `/admin/appWareHouse/page`,
+    method: 'post',
+    data
+  })
+}
+
+// 新增
+export function submit(data) {
+  return request({
+    url: `/admin/appWareHouse/addOrUpdate`,
+    method: 'post',
+    data
+  })
+}
+
+// 删除
+export function remove(id) {
+  return request({
+    url: `/admin/appWareHouse/remove/${id}`,
+    method: 'delete'
+  })
+}

+ 1 - 1
src/mixin/index.js

@@ -23,7 +23,7 @@ const devMixin = {
     }
   },
   mounted() {
-    getClientTypeList().then(res => {
+    getClientTypeList(this.types ? { types: this.types } : {}).then(res => {
       if (res.code === 0) {
         res.data.map(i => {
           this.devOptions.push({

+ 34 - 32
src/router/index.js

@@ -505,38 +505,40 @@ export const dynamicRoutes = [{
     }
   }]
 },
-// {
-//   path: '/operation',
-//   component: Layout,
-//   hidden: true,
-//   permissions: ['operation:agreement:list'],
-//   name: 'agreement',
-//   children: [{
-//     path: 'agreement/detail',
-//     component: () => import('@/views/operation/agreement/detail'),
-//     name: 'agreementDetail',
-//     meta: {
-//       title: '协议详情',
-//       activeMenu: '/operation/agreement'
-//     }
-//   }]
-// },
-// {
-//   path: '/operation',
-//   component: Layout,
-//   hidden: true,
-//   permissions: ['operation:activity:list'],
-//   name: 'activity',
-//   children: [{
-//     path: 'activity/detail',
-//     component: () => import('@/views/operation/activity/detail'),
-//     name: 'activityDetail',
-//     meta: {
-//       title: '活动详情',
-//       activeMenu: '/operation/activity'
-//     }
-//   }]
-// },
+// 协议管理
+{
+  path: '/operation',
+  component: Layout,
+  hidden: true,
+  permissions: ['operation:agreement:list'],
+  name: 'agreement',
+  children: [{
+    path: 'agreement/detail',
+    component: () => import('@/views/operation/agreement/detail'),
+    name: 'agreementDetail',
+    meta: {
+      title: '协议详情',
+      activeMenu: '/operation/agreement'
+    }
+  }]
+},
+// 活动管理
+{ 
+  path: '/operation',
+  component: Layout,
+  hidden: true,
+  permissions: ['operation:activity:list'],
+  name: 'activity',
+  children: [{
+    path: 'activity/detail',
+    component: () => import('@/views/operation/activity/detail'),
+    name: 'activityDetail',
+    meta: {
+      title: '活动详情',
+      activeMenu: '/operation/activity'
+    }
+  }]
+},
 // 商品管理
 // 商品推荐
 {

+ 22 - 19
src/views/device/yxw/index.vue

@@ -3,18 +3,21 @@
     <!-- 搜索 -->
     <el-form inline size="mini">
       <el-form-item label="设备号:">
-        <el-input v-model="form1.dsn" placeholder="请输入设备号" clearable />
+        <el-input v-model="form.dsn" placeholder="请输入设备号" clearable />
       </el-form-item>
       <el-form-item label="设备型号:">
-        <el-input v-model="form1.clientType" placeholder="请输入设备型号" clearable />
+        <el-input v-model="form.clientType" placeholder="请输入设备型号" clearable />
+      </el-form-item>
+      <el-form-item label="设备标识:">
+        <el-input v-model="form.deviceMac" placeholder="请输入设备标识" clearable />
       </el-form-item>
       <el-form-item label="设备类型:">
-        <el-select v-model="form1.deviceType" placeholder="请选择设备类型" clearable>
+        <el-select v-model="form.deviceType" placeholder="请选择设备类型" clearable>
           <el-option v-for="item in typeOptions" :key="item.value" :label="item.label" :value="item.value" />
         </el-select>
       </el-form-item>
       <el-form-item label="当前状态:">
-        <el-select v-model="form1.status" placeholder="请选择当前状态" clearable>
+        <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-select>
       </el-form-item>
@@ -45,13 +48,13 @@
       <el-table-column prop="updateTimeStr" label="激活时间" align="center" />
       <el-table-column prop="statusStr" label="当前状态" align="center" />
     </el-table>
-    <pagination v-show="total > 0" :total="total" :page.sync="form1.pageIndex" :limit.sync="form1.pageSize"
+    <pagination v-show="total > 0" :total="total" :page.sync="form.pageIndex" :limit.sync="form.pageSize"
       @pagination="getList" />
     <!-- 弹窗 -->
     <el-dialog title="新增" :visible.sync="dialogVisible" width="500px">
-      <el-form :model="form2" ref="form" label-width="100px">
+      <el-form :model="dialogForm" ref="form" label-width="100px">
         <el-form-item prop="num" label="设备数量:" :rules="[{ required: true, message: '请输入设备数量', trigger: 'blur' }]">
-          <el-input v-model="form2.num" placeholder="请输入设备数量" />
+          <el-input v-model="dialogForm.num" placeholder="请输入设备数量" />
         </el-form-item>
       </el-form>
       <div slot="footer">
@@ -83,7 +86,7 @@ export default {
         },
       ],
       // 表单
-      form1: {
+      form: {
         pageIndex: 1,
         pageSize: 10,
       },
@@ -98,19 +101,19 @@ export default {
       // 弹窗
       dialogVisible: false,
       // 新增设备数量
-      form2: {
+      dialogForm: {
         num: ""
       }
     };
   },
   watch: {
     createTime(val) {
-      this.form1.startCreateTime = val[0]
-      this.form1.endCreateTime = val[1]
+      this.form.startCreateTime = val[0]
+      this.form.endCreateTime = val[1]
     },
     updateTime(val) {
-      this.form1.startUpdateTime = val[0]
-      this.form1.endUpdateTime = val[1]
+      this.form.startUpdateTime = val[0]
+      this.form.endUpdateTime = val[1]
     },
   },
   mounted() {
@@ -119,13 +122,13 @@ export default {
   methods: {
     // 搜索
     getSearch() {
-      this.form1.pageIndex = 1;
+      this.form.pageIndex = 1;
       this.getList();
     },
 
     // 重置
     getRefresh() {
-      this.form1 = {
+      this.form = {
         pageIndex: 1,
         pageSize: 10,
       };
@@ -136,7 +139,7 @@ export default {
     // 分页
     getList() {
       this.loading = true;
-      getYxwPage(this.form1).then((res) => {
+      getYxwPage(this.form).then((res) => {
         if (res.code === 0) {
           this.tableData = res.data.records;
           this.total = res.data.total;
@@ -149,7 +152,7 @@ export default {
     getSubmit() {
       this.$refs.form.validate((valid) => {
         if (valid) {
-          getYxwAdd(this.form2).then((res) => {
+          getYxwAdd(this.dialogForm).then((res) => {
             if (res.code === 0) {
               this.$message.success("新增成功!");
               this.dialogVisible = false;
@@ -167,7 +170,7 @@ export default {
     getDownLoadNo() {
       this.download(
         `/device/yunxiaowei/exportDeviceNo`,
-        this.form1,
+        this.form,
         `云小微设备号.xlsx`
       );
     },
@@ -176,7 +179,7 @@ export default {
     getDownLoadData() {
       this.download(
         `/device/yunxiaowei/exportDeviceData`,
-        this.form1,
+        this.form,
         `云小微设备数据.xlsx`
       );
     }

+ 15 - 6
src/views/music/radio/detail.vue

@@ -1,13 +1,13 @@
 <template>
   <div class="app-container">
-    <el-form :model="form" ref="form" :rules="rules" label-width="100px" :disabled="disabled">
+    <el-form :model="form" ref="form" :rules="rules" label-width="110px" :disabled="disabled">
       <el-form-item label="电台名称:" prop="name">
         <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="请选择资源平台" :disabled="disabledPlatformId(form.platformId)">
-          <el-option v-for="item in platformOptions" :key="item.value" :value="item.value"
-            :label="item.label" :disabled="disabledJoinType(item.joinType)" />
+          <el-option v-for="item in platformOptions" :key="item.value" :value="item.value" :label="item.label"
+            :disabled="disabledJoinType(item.joinType)" />
         </el-select>
       </el-form-item>
       <el-form-item v-if="form.platformId !== 4" label="地域分类:" prop="addressClassifyId">
@@ -26,14 +26,17 @@
         <el-input v-model="form.description" type="textarea" rows="5" maxlength="300" show-word-limit
           placeholder="请输入电台简介" />
       </el-form-item>
-      <el-form-item label="电台链接:" prop="fullUrl">
-        <el-input v-model="form.fullUrl" placeholder="请输入电台链接" />
+      <el-form-item label="非加速链接:" prop="noStreamUrl">
+        <el-input v-model="form.noStreamUrl" placeholder="请输入非加速链接" />
+      </el-form-item>
+      <el-form-item label="加速链接:" prop="fullUrl">
+        <el-input v-model="form.fullUrl" placeholder="请输入加速链接" />
       </el-form-item>
       <el-form-item label="电台封面:" prop="thumb">
         <Upload listType="picture-card" :url="form.thumb" @upload="upload" :disabled="disabled" />
       </el-form-item>
     </el-form>
-    <div class="form-btn">
+    <div style="margin-left: 110px">
       <el-button @click="cancel">取消</el-button>
       <el-button v-if="!disabled" type="primary" @click="getSubmit">确定</el-button>
     </div>
@@ -68,6 +71,12 @@ export default {
         platformId: [{
           required: true, message: '请选择资源平台', trigger: 'change'
         }],
+        noStreamUrl: [{
+          required: true, message: '请输入非加速链接', trigger: 'blur'
+        }],
+        fullUrl: [{
+          required: true, message: '请输入加速链接', trigger: 'blur'
+        }],
         thumb: [{
           required: true, message: '请上传电台封面', trigger: 'change'
         }]

+ 13 - 12
src/views/music/radio/index.vue

@@ -2,13 +2,12 @@
   <div class="app-container">
     <!-- 搜索 -->
     <el-form inline size="mini">
-      <el-form-item label="电台名称:"> 
+      <el-form-item label="电台名称:">
         <el-input v-model="form.name" placeholder="请输入电台名称" clearable />
       </el-form-item>
       <el-form-item label="资源平台:">
         <el-select v-model="form.platformId" placeholder="请选择资源平台" clearable>
-          <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="地域分类:">
@@ -23,16 +22,18 @@
       </el-form-item>
       <el-form-item label="当前状态:">
         <el-select v-model="form.status" placeholder="请选择当前状态" clearable>
-          <el-option v-for="item in onOrOffOptions" :key="item.value" :value="item.value"
-            :label="item.label" />
+          <el-option v-for="item in onOrOffOptions" :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" plain icon="el-icon-plus" @click="getDetail()" v-hasPermi="['music:radio:add']">新增</el-button>
-        <el-button type="primary" :disabled="obj.id === ''" @click="getChange(obj, 1)" v-hasPermi="['music:radio:up']">批量上架</el-button>
-        <el-button type="primary" :disabled="obj.id === ''" @click="getChange(obj, 2)" v-hasPermi="['music:radio:down']">批量下架</el-button>
+        <el-button type="primary" plain icon="el-icon-plus" @click="getDetail()"
+          v-hasPermi="['music:radio:add']">新增</el-button>
+        <el-button type="primary" :disabled="obj.id === ''" @click="getChange(obj, 1)"
+          v-hasPermi="['music:radio:up']">批量上架</el-button>
+        <el-button type="primary" :disabled="obj.id === ''" @click="getChange(obj, 2)"
+          v-hasPermi="['music:radio:down']">批量下架</el-button>
       </el-form-item>
     </el-form>
     <!-- 列表 -->
@@ -53,7 +54,8 @@
         <template slot-scope="scope">
           <el-button type="text" @click="getDetail(scope.row.id, true)">查看</el-button>
           <span v-if="scope.row.status === 2">
-            <el-button type="text" @click="getDetail(scope.row.id)" v-hasPermi="['music:radio:edit']" style="margin-left: 10px">编辑</el-button>
+            <el-button type="text" @click="getDetail(scope.row.id)" v-hasPermi="['music:radio:edit']"
+              style="margin-left: 10px">编辑</el-button>
             <el-button type="text" @click="getChange(scope.row, 1)" v-hasPermi="['music:radio:up']">上架</el-button>
             <el-button type="delete" @click="getDelete(scope.row)" v-hasPermi="['music:radio:delete']">删除</el-button>
           </span>
@@ -62,7 +64,7 @@
         </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>
@@ -202,5 +204,4 @@ export default {
 }
 </script>
 
-<style lang="scss" scoped>
-</style>
+<style lang="scss" scoped></style>

+ 144 - 0
src/views/operation/activity/detail.vue

@@ -0,0 +1,144 @@
+<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="活动图片:">
+        <Upload listType="picture-card" :url="form.pic" @upload="upload" />
+      </el-form-item>
+      <el-form-item label="有效时间:">
+        <el-date-picker type="datetimerange" v-model="form.timeList" start-placeholder="开始日期" end-placeholder="结束日期" value-format="yyyy-MM-dd HH:mm:ss" />
+      </el-form-item>
+      <el-form-item label="活动设备:" style="width: 1000px">
+        <el-button type="primary" icon="el-icon-plus" @click="handlePush">添加</el-button>
+        <el-table :data="form.deviceRespList">
+          <el-table-column label="关联设备" align="center">
+            <template slot-scope="scope">
+              <el-select v-model="scope.row.deviceId" placeholder="请选择关联设备" :disabled="disabledActivity">
+                <el-option v-for="item in devOptions" :key="item.value" :value="item.value" :label="item.label"
+                  :disabled="item.disabled" />
+              </el-select>
+            </template>
+          </el-table-column>
+          <el-table-column label="活动权益" align="center">
+            <template slot-scope="scope">
+              <el-select v-model="scope.row.indate" placeholder="请选择活动权益" :disabled="disabledActivity">
+                <el-option v-for="item in serviceTimeOptions" :key="item.value" :value="item.value" :label="item.label" />
+              </el-select>
+            </template>
+          </el-table-column>
+          <el-table-column label="领取数量" align="center">
+            <template slot-scope="scope">
+              <el-input-number v-model="scope.row.totalNum" :controls="false" :min="1" />
+            </template>
+          </el-table-column>
+          <el-table-column label="操作" align="center">
+            <template slot-scope="scope">
+              <el-button type="delete" @click="getDelete(scope.row.deviceId, scope.$index)" :disabled="disabledActivity">删除</el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+      </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/operation/activity"
+import { serviceTimeMixin, devMixin } from '@/mixin/index'
+export default {
+  mixins: [serviceTimeMixin, devMixin],
+  data() {
+    return {
+      // 表单
+      form: {
+        deviceRespList: []
+      },
+      // 除蓝牙设备
+      types: [2, 4],
+      // 生效期内禁止修改活动设备
+      disabledActivity: this.$route.query.activityState == 0 ? true : false,
+      // 只读
+      disabled: Boolean(this.$route.query.boolean)
+    }
+  },
+  watch: {
+    // 禁用已关联设备
+    'form.deviceRespList': {
+      handler(val) {
+        for (let i in this.devOptions) {
+          this.devOptions[i].disabled = false
+        }
+        val.map(i => {
+          if (i.deviceId) {
+            let index = this.devOptions.findIndex(j => j.value === i.deviceId)
+            this.devOptions[index].disabled = true
+          }
+        })
+      },
+      deep: true
+    }
+  },
+  mounted() {
+    if (this.$route.query.id) {
+      this.getDetail()
+    }
+  },
+  methods: {
+    // 详情
+    getDetail() {
+      detail(this.$route.query.id).then(res => {
+        if (res.code === 0) {
+          this.form = res.data
+        }
+      })
+    },
+
+    // 上传图片
+    upload(e) {
+      this.form.pic = e.file
+    },
+
+    // 添加
+    handlePush() {
+      this.form.deviceRespList.push({})
+    },
+
+    // 删除
+    getDelete(deviceId, index) {
+      this.form.deviceRespList.splice(index, 1)
+      this.devOptions.map(i => {
+        if (i.value === deviceId) {
+          i.disabled = false
+        }
+      })
+    },
+
+    // 取消
+    cancel() {
+      this.$tab.closeOpenPage('/operation/activity')
+    },
+
+    // 确定
+    getSubmit() {
+      submit(this.form).then(res => {
+        if (res.code === 0) {
+          this.$message.success('提交成功!')
+          this.cancel()
+        }
+      })
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.el-form-item {
+  width: 500px;
+}
+</style>

+ 162 - 0
src/views/operation/activity/index.vue

@@ -0,0 +1,162 @@
+<template>
+  <div class='app-container'>
+    <!-- 搜索 -->
+    <el-form inline size="mini">
+      <el-form-item label="活动名称:">
+        <el-input v-model="form.name" placeholder="请输入活动名称" clearable />
+      </el-form-item>
+      <el-form-item label="当前状态:">
+        <el-select v-model="form.activityState" placeholder="请选择当前状态" clearable>
+          <el-option v-for="item in currentOptions" :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="请选择上下架状态" clearable>
+          <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="getDetail">新增</el-button>
+      </el-form-item>
+    </el-form>
+    <!-- 列表 -->
+    <el-table :data="tableData" v-loading="loading">
+      <el-table-column label="序号" align="center" type="index" />
+      <el-table-column label="活动id" align="center" prop="id" show-overflow-tooltip />
+      <el-table-column label="活动名称" align="center" prop="name" 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" prop="createTime" />
+      <el-table-column label="有效时间" align="center" show-overflow-tooltip>
+        <template slot-scope="scope">
+          {{ scope.row.timeList.join(' - ') }}
+        </template>
+      </el-table-column>
+      <el-table-column label="当前状态" align="center" :formatter="activityFormatter" width="150px" />
+      <el-table-column label="上下架状态" align="center" :formatter="statusFormatter" width="150px" />
+      <el-table-column label="操作" align="center">
+        <template slot-scope="scope">
+          <el-button type="text" @click="getDetail(scope.row, true)">查看</el-button>
+          <el-button type="text" v-if="scope.row.status === 1" @click="getChange(scope.row.id, 0, '上架')">上架</el-button>
+          <span v-else style="margin: 0 10px">
+            <el-button type="text" @click="getDetail(scope.row)">编辑</el-button>
+            <el-button type="text" @click="getChange(scope.row.id, 1, '下架')">下架</el-button>
+            <el-button type="delete" @click="getDelete(scope.row)">删除</el-button>
+          </span>
+          <el-button type="text" v-clipboard:copy="scope.row.copyUrl" v-clipboard:success="getCopy">复制链接</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, change } from '@/api/operation/activity'
+import { currentMixin, disabledMixin } from '@/mixin/index'
+export default {
+  mixins: [currentMixin, disabledMixin],
+  data() {
+    return {
+      // 遮罩层
+      loading: false,
+      // 表单
+      form: {
+        pageNum: 1,
+        pageSize: 10
+      },
+      // 总数据
+      total: 0,
+      // 列表
+      tableData: []
+    }
+  },
+  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(row, boolean) {
+      this.$router.push({
+        path: `/operation/activity/detail`,
+        query: {
+          id: row.id,
+          boolean: boolean,
+          activityState: row.activityState
+        }
+      })
+    },
+
+    // 上下架
+    getChange(id, status, title) {
+      change(id, status).then(res => {
+        if (res.code === 0) {
+          this.$message.success(`${title}成功!`)
+          this.getList()
+        }
+      })
+    },
+
+    // 删除
+    getDelete(row) {
+      this.$confirm(`是否删除${row.name}?`, '提示', {
+        type: 'warning'
+      }).then(() => {
+        change(row.id, 2).then(res => {
+          if (res.code === 0) {
+            this.$message.success('删除成功!')
+            this.getList()
+          }
+        })
+      })
+    },
+
+    // 复制链接
+    getCopy() {
+      this.$message.success('复制成功!')
+    },
+
+    // 字典翻译
+    activityFormatter(row) {
+      return this.selectDictLabel(this.currentOptions, row.activityState)
+    },
+
+    statusFormatter(row) {
+      return this.selectDictLabel(this.disabledOptions, row.status)
+    }
+  }
+}
+</script>

+ 112 - 0
src/views/operation/agreement/detail.vue

@@ -0,0 +1,112 @@
+<template>
+  <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="请输入协议名称" />
+      </el-form-item>
+      <el-form-item label="协议类型:" prop="type">
+        <el-select v-model="form.type" 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="content">
+        <Editor v-model="form.content" :height="500" :readOnly="disabled" />
+      </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 Editor from "@/components/Editor/index";
+import { submit, detail } from '@/api/operation/agreement'
+export default {
+  components: {
+    Editor
+  },
+  data() {
+    return {
+      // 表单
+      form: {},
+      // 协议类型
+      typeOptions: [{
+        value: 0,
+        label: '用户协议'
+      }, {
+        value: 1,
+        label: '隐私协议'
+      }, {
+        value: 2,
+        label: '音乐服务许可协议'
+      }, {
+        value: 3,
+        label: '儿童隐私保护指南'
+      }, {
+        value: 4,
+        label: 'VIP音乐服务协议'
+      }, {
+        value: 5,
+        label: '爱听付费协议'
+      }],
+      // 校验
+      rules: {
+        name: [{
+          required: true, message: '请输入协议名称', trigger: 'blur'
+        }],
+        type: [{
+          required: true, message: '请选择协议类型', trigger: 'change'
+        }],
+        content: [{
+          required: true, message: '请输入协议内容', trigger: 'blur'
+        }]
+      },
+      // 只读
+      disabled: this.$route.query.boolean ? true : false
+    }
+  },
+  mounted() {
+    if (this.$route.query.id) {
+      this.getDetail()
+    }
+  },
+  methods: {
+    // 详情
+    getDetail() {
+      detail(this.$route.query.id).then(res => {
+        if (res.code === 0) {
+          this.form = res.data
+        }
+      })
+    },
+
+    // 取消
+    cancel() {
+      this.$tab.closeOpenPage('/operation/agreement')
+    },
+    // 提交
+    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-item {
+  width: 500px;
+}
+</style>

+ 109 - 0
src/views/operation/agreement/index.vue

@@ -0,0 +1,109 @@
+<template>
+  <div class='app-container'>
+    <el-button type="primary" icon="el-icon-plus" size="mini" @click="getDetail()">新增</el-button>
+    <!-- 列表 -->
+    <el-table :data="tableData" v-loading="loading">
+      <el-table-column label="序号" align="center" type="index" />
+      <el-table-column label="协议名称" align="center" prop="name" />
+      <el-table-column label="协议类型" align="center" prop="type" :formatter="typeFormatter" />
+      <el-table-column label="更新时间" align="center" prop="updateTime" />
+      <el-table-column label="创建时间" align="center" prop="createTime" />
+      <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)">编辑</el-button>
+          <el-button type="delete" @click="getDelete(scope.row)">删除</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/operation/agreement'
+export default {
+  data() {
+    return {
+      // 遮罩层
+      loading: false,
+      // 表单
+      form: {
+        pageNum: 1,
+        pageSize: 10
+      },
+      // 列表
+      tableData: [],
+      // 总数据
+      total: 0,
+      // 协议类型
+      typeOptions: [{
+        value: 0,
+        label: '用户协议'
+      }, {
+        value: 1,
+        label: '隐私协议'
+      }, {
+        value: 2,
+        label: '音乐服务许可协议'
+      }, {
+        value: 3,
+        label: '儿童隐私保护指南'
+      }, {
+        value: 4,
+        label: 'VIP音乐服务协议'
+      }, {
+        value: 5,
+        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
+        }
+      })
+    },
+
+    // 详情
+    getDetail(id, boolean) {
+      this.$router.push({
+        path: `/operation/agreement/detail`,
+        query: {
+          id: id,
+          boolean: boolean
+        }
+      })
+    },
+
+    // 删除
+    getDelete(row) {
+      this.$confirm(`是否删除${row.name}?`, '提示', {
+        type: 'warning'
+      }).then(() => {
+        remove(row.id).then(res => {
+          if (res.code === 0) {
+            this.$message.success('删除成功!')
+            this.getList()
+          }
+        })
+      }).catch(() => { })
+    },
+
+    // 字典翻译
+    typeFormatter(row) {
+      return this.selectDictLabel(this.typeOptions, row.type)
+    }
+  }
+}
+</script>

+ 1 - 1
src/views/operation/tag/index.vue

@@ -45,7 +45,7 @@
             新增
           </el-button>
           <el-button type="text" v-if="scope.row.status === 0" @click="getChange(scope.row, 1)"
-            v-hasPermi="['operation:tag:down']">禁用</el-button>
+            v-hasPermi="['operation:tag:down']">下架</el-button>
           <span v-else>
             <el-button type="text" @click="getDialog('编辑', scope.row)" style="margin-left: 10px"
               v-hasPermi="['operation:tag:edit']">

+ 6 - 8
src/views/service/code/index.vue

@@ -3,17 +3,16 @@
     <!-- 搜索 -->
     <el-form inline size="mini">
       <el-form-item label="批次号:">
-        <el-input v-model="form.no" placeholder="请输入批次号" />
+        <el-input v-model="form.no" placeholder="请输入批次号" clearable />
       </el-form-item>
       <el-form-item label="服务时长:">
-        <el-select v-model="form.serviceTime" placeholder="请选择服务时长">
-          <el-option v-for="item in serviceTimeOptions" :key="item.value" :label="item.label"
-            :value="item.value" />
+        <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-select>
       </el-form-item>
       <el-form-item label="创建时间:">
         <el-date-picker v-model="date" type="datetimerange" start-placeholder="开始时间" end-placeholder="结束时间"
-          value-format="yyyy-MM-dd HH:mm:ss" clearable />
+          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>
@@ -36,7 +35,7 @@
         </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" />
     <!-- 弹窗 -->
     <el-dialog :visible.sync="dialogVisible" title="新增" width="500px" :before-close="cancel">
@@ -46,8 +45,7 @@
         </el-form-item>
         <el-form-item label="服务时长:" prop="serviceTime">
           <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>

+ 108 - 0
src/views/service/recovery/index.vue

@@ -0,0 +1,108 @@
+<template>
+  <div class='app-container'>
+    <!-- 搜索 -->
+    <el-form inline size="mini">
+      <el-form-item label="dsn状态:">
+        <el-select v-model="form.dsnStatus" placeholder="请选择dsn状态" 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 label="音乐VIP状态:">
+        <el-select v-model="form.vipStatus" placeholder="请选择音乐VIP状态" 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-form-item>
+    </el-form>
+    <!-- 列表 -->
+    <el-table :data="tableData" v-loading="loading">
+      <el-table-column label="创建时间" align="center" prop="createTime"></el-table-column>
+      <el-table-column label="兑换码编码" align="center" prop="code"></el-table-column>
+      <el-table-column label="设备标识" align="center" prop="deviceMac"></el-table-column>
+      <el-table-column label="设备型号" align="center" prop="clientType"></el-table-column>
+      <el-table-column label="用户账号" align="center" prop="userName"></el-table-column>
+      <el-table-column label="用户手机号" align="center" prop="phone"></el-table-column>
+      <el-table-column label="服务时长" align="center" prop="serviceTime" :formatter="timeFormatter"></el-table-column>
+      <el-table-column label="VIP领取时间" align="center" prop="vipReceiveTime"></el-table-column>
+      <el-table-column label="音乐VIP状态" align="center" prop="vipStatus" :formatter="statusFormatter"></el-table-column>
+      <el-table-column label="dsn激活时间" align="center" prop="dsnActiveTime"></el-table-column>
+      <el-table-column label="dsn状态" align="center" prop="dsnStatus" :formatter="statusFormatter"></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/service/recovery'
+import { serviceTimeMixin } from '@/mixin/index'
+export default {
+  mixins: [serviceTimeMixin],
+  data() {
+    return {
+      // 遮罩层
+      loading: false,
+      // 表单
+      form: {
+        pageNum: 1,
+        pageSize: 10
+      },
+      // 总数据
+      total: 0,
+      // 列表
+      tableData: [],
+      // dsn vip
+      statusOptions: [{
+        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()
+    },
+
+    // 字典翻译
+    statusFormatter(row, column, cellValue) {
+      return this.selectDictLabel(this.statusOptions, cellValue)
+    },
+
+    timeFormatter(row) {
+      return this.selectDictLabel(this.serviceTimeOptions, row.serviceTime)
+    }
+  }
+}
+</script>

+ 7 - 7
src/views/user/list/index.vue

@@ -124,25 +124,25 @@ export default {
         label: '未知'
       }, {
         value: 0,
-        label: '小米应用市场'
+        label: '小米'
       }, {
         value: 1,
-        label: '360应用市场'
+        label: '360'
       }, {
         value: 2,
-        label: '腾讯应用市场'
+        label: '应用宝'
       }, {
         value: 3,
-        label: 'OPPP应用市场'
+        label: 'OPPP'
       }, {
         value: 4,
-        label: 'ViVO应用市场'
+        label: 'ViVO'
       }, {
         value: 5,
-        label: '魅族应用市场'
+        label: '魅族'
       }, {
         value: 6,
-        label: '华为应用市场'
+        label: '华为'
       }, {
         value: 7,
         label: '微信小程序'

+ 152 - 0
src/views/user/store/index.vue

@@ -0,0 +1,152 @@
+<template>
+  <div class='app-container'>
+    <el-button type="primary" icon="el-icon-plus" size="mini" @click="dialogVisible = true">新增</el-button>
+    <!-- 列表 -->
+    <el-table :data="tableData" v-loading="loading">
+      <el-table-column label="账号ID" align="center" prop="id" />
+      <el-table-column label="账号名称" align="center" prop="name" />
+      <el-table-column label="手机号" align="center" prop="phone" />
+      <el-table-column label="性别" align="center" prop="sex" :formatter="sexFormatter" />
+      <el-table-column label="创建时间" align="center" prop="createTime" />
+      <el-table-column label="操作" align="center">
+        <template slot-scope="scope">
+          <el-button type="delete" @click="getDelete(scope.row)">删除</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="新增" width="500px" :before-close="cancel">
+      <el-form :model="dialogForm" ref="dialogForm" :rules="rules" label-width="100px">
+        <el-form-item label="账号名称:" prop="name">
+          <el-input v-model="dialogForm.name" placeholder="请输入账号名称" />
+        </el-form-item>
+        <el-form-item label="手机号:" prop="phone">
+          <el-input v-model="dialogForm.phone" placeholder="请输入手机号" />
+        </el-form-item>
+        <el-form-item label="性别:" prop="sex">
+          <el-radio-group v-model="dialogForm.sex">
+            <el-radio v-for="item in sexOptions.slice(0, 2)" :key="item.value" :label="item.value">
+              {{ item.label }}
+            </el-radio>
+          </el-radio-group>
+        </el-form-item>
+      </el-form>
+      <div slot="footer">
+        <el-button @click="cancel">取消</el-button>
+        <el-button type="primary" @click="getSubmit">确定</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { list, submit, remove } from '@/api/user/store'
+import { sexMixin } from '@/mixin/index'
+export default {
+  mixins: [sexMixin],
+  data() {
+    const checkPhone = (rule, value, callback) => {
+      if (!value) {
+        return callback(new Error('请输入手机号'))
+      } else {
+        const reg = /^1[3-9][0-9]\d{8}$/
+        if (reg.test(value)) {
+          callback()
+        } else {
+          return callback(new Error('请输入正确的手机号'))
+        }
+      }
+    }
+    return {
+      // 遮罩层
+      loading: false,
+      // 表单
+      form: {
+        pageNum: 1,
+        pageSize: 10
+      },
+      // 列表
+      tableData: [],
+      // 总数据
+      total: 0,
+      // 弹窗
+      dialogVisible: false,
+      // 弹窗表单
+      dialogForm: {},
+      // 校验
+      rules: {
+        name: [{
+          required: true, message: '请输入账户名称', trigger: 'blur'
+        }],
+        phone: [{
+          required: true, validator: checkPhone, trigger: 'blur'
+        }],
+        sex: [{
+          required: true, message: '请选择性别', trigger: 'change'
+        }]
+      }
+    }
+  },
+  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
+        }
+      })
+    },
+
+    // 取消
+    cancel() {
+      this.$refs.dialogForm.resetFields()
+      this.dialogForm = {}
+      this.dialogVisible = false
+    },
+
+    // 提交
+    getSubmit() {
+      this.$refs.dialogForm.validate((valid) => {
+        if (valid) {
+          submit(this.dialogForm).then(res => {
+            if (res.code === 0) {
+              this.$message.success('提交成功!')
+              this.cancel()
+              this.getList()
+            }
+          })
+        } else {
+          return false
+        }
+      })
+    },
+
+    // 删除
+    getDelete(row) {
+      this.$confirm(`是否删除${row.name}?`, '提示', {
+        type: 'warning'
+      }).then(() => {
+        remove(row.id).then(res => {
+          if (res.code === 0) {
+            this.$message.success('删除成功!')
+            this.getList()
+          }
+        })
+      }).catch(() => { })
+    },
+
+    // 字典翻译
+    sexFormatter(row) {
+      return this.selectDictLabel(this.sexOptions, row.sex)
+    }
+  }
+}
+</script>