Ver código fonte

认证v1.7.11版本优化-接口调试

yuwenjun1997 2 anos atrás
pai
commit
7d6d348299

+ 19 - 0
src/api/personalized.js

@@ -0,0 +1,19 @@
+import request from '@/utils/request'
+
+// 添加/编辑首页Banner
+export function saveBannerData(data) {
+  return request({
+    url: '/banner/save',
+    method: 'post',
+    data
+  })
+}
+
+// 首页Banner回显数据
+export function fetchBannerData(data) {
+  return request({
+    url: '/banner/form/data',
+    method: 'get',
+    data
+  })
+}

+ 9 - 0
src/api/product.js

@@ -177,3 +177,12 @@ export function fetchDeviceAssClubList(data) {
     data
   })
 }
+
+// 获取机构设备sn列表
+export function fetchClubDeviceSnList(params) {
+  return request({
+    url: '/auth/product/sn/list',
+    method: 'get',
+    params
+  })
+}

+ 10 - 1
src/components/UploadImage/index.vue

@@ -1,7 +1,8 @@
 <template>
   <div>
     <el-upload
-      :class="{ 'el-upload-hidden': !chooseState}"
+      ref="upload"
+      :class="{ 'el-upload-hidden': !chooseState }"
       :list-type="listType"
       :action="action"
       :headers="headers"
@@ -16,6 +17,7 @@
       :file-list="imageList"
     >
       <div v-if="tip" slot="tip" class="el-upload__tip">{{ tip }}</div>
+      <button v-if="trigger" ref="trigger" slot="trigger" size="small" type="primary">选取文件</button>
       <i slot="default" class="el-icon-plus" />
     </el-upload>
     <el-dialog :visible.sync="dialogVisible">
@@ -59,6 +61,10 @@ export default {
     beforeUpload: {
       type: Function,
       default: () => true
+    },
+    trigger: {
+      type: Boolean,
+      default: false
     }
   },
   data() {
@@ -97,6 +103,9 @@ export default {
     handlePictureCardPreview(file) {
       this.dialogImageUrl = file.url
       this.dialogVisible = true
+    },
+    handleClick() {
+      this.$refs.trigger.click()
     }
   }
 }

+ 11 - 0
src/utils/index.js

@@ -446,3 +446,14 @@ export function mergeObject(source, target) {
   }
   return source
 }
+
+/**
+ * 获取两个数组交集 第二个数组为第一个数组中元素的某个属性
+ * @param {*} firstArray 源数组
+ * @param {*} secondArray 目标数组
+ * @param {*} key 目标数组中元素的属性
+ * @returns 交集数组
+ * */
+export function getIntersection(firstArray, secondArray, key) {
+  return firstArray.filter((item) => secondArray.includes(item[key]))
+}

+ 67 - 21
src/views/components/SncodeList/index.vue

@@ -1,39 +1,66 @@
 <template>
   <div class="associated-club-list">
     <div class="filter-container">
+      <div class="filter-control">
+        <span>设备筛选:</span>
+        <el-select v-model="listQuery.downStatus" placeholder="全部" size="mini" @change="handleFilter">
+          <el-option label="全部" :value="0" />
+          <el-option label="与该机构有关联" :value="1" />
+        </el-select>
+      </div>
+      <div class="filter-control">
+        <span>设备名称:</span>
+        <el-input
+          v-model="listQuery.productName"
+          placeholder="请输入设备名称"
+          size="mini"
+          clearable
+          @keyup.enter.native="handleFilter"
+          @clear="handleFilter"
+        />
+      </div>
       <div class="filter-control">
         <span>设备SN码:</span>
-        <el-input v-model="listQuery.sncode" placeholder="设备SN码" size="mini" @keyup.enter.native="handleFilter" />
+        <el-input
+          v-model="listQuery.snCode"
+          placeholder="请输入设备SN码"
+          size="mini"
+          clearable
+          @keyup.enter.native="handleFilter"
+          @clear="handleFilter"
+        />
+      </div>
+      <div class="filter-control">
+        <span>所属机构:</span>
+        <el-input
+          v-model="listQuery.authParty"
+          placeholder="请输入机构名称"
+          size="mini"
+          clearable
+          @keyup.enter.native="handleFilter"
+          @clear="handleFilter"
+        />
       </div>
       <div class="filter-control">
         <el-button size="mini" type="primary" @click="handleFilter">搜索</el-button>
       </div>
     </div>
-    <el-table
-      v-if="height"
-      :data="list"
-      :show-header="false"
-      border
-      :height="height"
-      @selection-change="handleSelectionChange"
-    >
+    <el-table v-if="height" :data="codeList" border :height="height" @selection-change="handleSelectionChange">
       <el-table-column v-if="selection" type="selection" width="50" align="center" />
-      <!-- <el-table-column prop="sncode" /> -->
-      <el-table-column>
-        <template slot-scope="{ row }">{{ row }}</template>
-      </el-table-column>
+      <el-table-column prop="productName" label="设备名称" align="center" />
+      <el-table-column prop="snCode" label="设备SN码" align="center" />
+      <el-table-column prop="authParty" label="所属机构" align="center" />
       <el-table-column v-if="control" width="100" align="center">
         <template slot-scope="{ row }">
           <slot name="control" :row="row" />
         </template>
       </el-table-column>
     </el-table>
-    <el-table v-else :data="list" :show-header="false" border @selection-change="handleSelectionChange">
+    <el-table v-else :data="codeList" :show-header="false" border @selection-change="handleSelectionChange">
       <el-table-column v-if="selection" type="selection" width="50" align="center" />
-      <!-- <el-table-column prop="sncode" /> -->
-      <el-table-column>
-        <template slot-scope="{ row }">{{ row }}</template>
-      </el-table-column>
+      <el-table-column prop="productName" label="设备名称" align="center" />
+      <el-table-column prop="snCode" label="设备SN码" align="center" />
+      <el-table-column prop="authParty" label="所属机构" align="center" />
       <el-table-column v-if="control" width="100" align="center">
         <template slot-scope="{ row }">
           <slot name="control" :row="row" />
@@ -75,13 +102,32 @@ export default {
   data() {
     return {
       listQuery: {
-        sncode: ''
-      }
+        downStatus: 0,
+        productName: '',
+        snCode: '',
+        authParty: ''
+      },
+      codeList: []
+    }
+  },
+  watch: {
+    list: {
+      handler(val) {
+        this.handleFilter()
+      },
+      immediate: true
     }
   },
   methods: {
     handleFilter() {
-      this.$emit('filter', this.listQuery)
+      this.codeList = this.list.filter((item) => {
+        return (
+          item.downStatus === this.listQuery.downStatus &&
+          new RegExp(this.listQuery.productName, 'gi').test(item.productName) &&
+          new RegExp(this.listQuery.snCode, 'gi').test(item.snCode) &&
+          new RegExp(this.listQuery.authParty, 'gi').test(item.authParty)
+        )
+      })
     },
     handleSelectionChange(val) {
       if (!this.selection) return

+ 52 - 81
src/views/normal/club/device/bind.vue

@@ -1,25 +1,13 @@
 <template>
-  <div class="page-form-container">
+  <div class="app-container">
     <el-form ref="form" label-width="110px" :model="formData" :rules="rules">
       <el-form-item label="认证方式:">关联已认证设备</el-form-item>
-      <!-- <el-form-item label="选设备SN码:" prop="sncodeType">
-        <el-radio-group v-model="formData.sncodeType" size="mini">
-          <el-radio :label="1">所有设备SN码</el-radio>
-          <el-radio :label="2">关联机构设备SN码</el-radio>
-        </el-radio-group>
-      </el-form-item> -->
       <el-form-item label="SN码列表:" prop="snList">
         <el-checkbox-group v-model="formData.snList" />
         <el-button size="mini" type="primary" @click="onChooseCode">选择SN码</el-button>
       </el-form-item>
       <el-form-item>
-        <sncode-list
-          class="sncode-list"
-          :selection="false"
-          :control="true"
-          :list="filterSelectedCodeList"
-          @filter="onSelectCodeFilter"
-        >
+        <sncode-list class="snCode-list" :selection="false" :control="true" :list="selectedCodeList">
           <template #control="{ row }">
             <el-button size="mini" type="danger" @click="onSelectCodeRemove(row)">删除</el-button>
           </template>
@@ -34,22 +22,13 @@
     </div>
 
     <!-- 选择sn码 -->
-    <el-dialog :title="dialogTextTip" :visible.sync="dialogCodeListVisible" width="30%" :show-close="false">
-      <div class="sncode-cate">
-        <div class="lable">选设备SN码:</div>
-        <el-radio-group v-model="formData.sncodeType" size="mini" @change="onChooseCode">
-          <el-radio :label="1">所有设备SN码</el-radio>
-          <el-radio :label="2">关联机构设备SN码</el-radio>
-        </el-radio-group>
-      </div>
+    <el-dialog title="选择关联设备" :visible.sync="dialogCodeListVisible" width="70%" :show-close="false">
       <sncode-list
-        v-if="dialogCodeListVisible"
         :selection="true"
         :control="false"
-        :list="filterCodeList"
-        height="280"
-        @filter="onCodeFilter"
-        @selected="onCodeChange"
+        :list="unselectedCodeList"
+        height="380"
+        @selected="onCodeSelected"
       />
       <div slot="footer" class="dialog-footer">
         <el-button type="primary" size="mini" @click="onCodeCancel">取 消</el-button>
@@ -61,8 +40,9 @@
 
 <script>
 import { SncodeList } from '@/views/components'
-import { fetchProductSnList, fetchProductSnListType, saveProductRelation } from '@/api/product'
+import { fetchClubDeviceSnList, saveProductRelation } from '@/api/product'
 import { getStorage } from '@/utils/storage'
+import { uniqueArr } from '@/utils'
 export default {
   components: {
     SncodeList
@@ -73,25 +53,30 @@ export default {
       formData: {
         authType: 2,
         authId: '',
-        sncodeType: 1,
         snList: []
       },
       rules: {
         snList: [{ type: 'array', required: true, message: 'SN码列表不能为空', trigger: ['change'] }]
       },
       listQuery: {
-        sncode: ''
+        authId: '',
+        downStatus: 0,
+        productName: '',
+        snCode: '',
+        authParty: ''
       },
-      codeList: [],
-      filterCodeList: [],
-      selectedCodeList: [],
-      selectedCodeListAll: [],
-      filterSelectedCodeList: []
+      codeList: [], // sn码列表
+      preSelectedCodeList: [] // table中已选中的sn码列表
     }
   },
   computed: {
-    dialogTextTip() {
-      return this.formData.sncodeType === 1 ? '所有设备SN码' : '关联机构设备SN码'
+    // 选中的sn码列表
+    selectedCodeList() {
+      return this.codeList.filter((item) => this.formData.snList.includes(item.snCode))
+    },
+    // 剩余未选中的sn码列表
+    unselectedCodeList() {
+      return this.codeList.filter((item) => !this.formData.snList.includes(item.snCode))
     }
   },
   watch: {
@@ -102,37 +87,33 @@ export default {
   created() {
     // 获取当前设备所属机构的id
     this.formData.authId = getStorage('device-setting-authId')
+    this.listQuery.authId = this.formData.authId
+    this.fetchSnCodeList()
   },
   methods: {
     // 选择sn码
     onChooseCode() {
       this.dialogCodeListVisible = true
-      if (this.formData.sncodeType === 1) {
-        this.fetchSnCodeListAll()
-      } else {
-        this.fetchSnCodeListSelf()
-      }
     },
     // 获取全部sn码列表
-    async fetchSnCodeListSelf() {
-      try {
-        const res = await fetchProductSnListType({ authId: this.formData.authId })
-        if (!res.data) return
-        this.codeList = res.data.filter((code) => !this.selectedCodeListAll.includes(code))
-        this.filterCodeList = this.codeList
-        console.log(res)
-      } catch (error) {
-        console.log(error)
-      }
-    },
-    // 获取关联机构sn码列表
-    async fetchSnCodeListAll() {
+    async fetchSnCodeList() {
       try {
-        const res = await fetchProductSnList({ authId: this.formData.authId })
-        if (!res.data) return
-        this.codeList = res.data.filter((code) => !this.selectedCodeListAll.includes(code))
-        this.filterCodeList = this.codeList
-        console.log(res)
+        // 获取全部sn码列表
+        this.listQuery.downStatus = 0
+        const res1 = await fetchClubDeviceSnList(this.listQuery)
+        res1.data = res1.data.map((item) => {
+          item.downStatus = 0
+          return item
+        })
+        // 获取与该机构有关联sn码列表
+        this.listQuery.downStatus = 1
+        const res2 = await fetchClubDeviceSnList(this.listQuery)
+        res2.data = res2.data.map((item) => {
+          item.downStatus = 0
+          return item
+        })
+        this.codeList = [...res1.data, ...res2.data]
+        console.log('🚀 ~ file: bind.vue:108 ~ fetchSnCodeList ~ this.codeList:', this.codeList)
       } catch (error) {
         console.log(error)
       }
@@ -157,44 +138,34 @@ export default {
         console.log(error)
       }
     },
-    // 筛选sn码列表
-    onCodeFilter(query) {
-      this.filterCodeList = this.codeList.filter((code) => new RegExp(query.sncode, 'gi').test(code))
-    },
     // 选中sn码
-    onCodeChange(value) {
-      this.selectedCodeList = value
+    onCodeSelected(list) {
+      this.preSelectedCodeList = list
     },
     // 取消选择sn码
     onCodeCancel() {
-      this.selectedCodeListAll = [...this.selectedCodeListAll, ...this.selectedCodeList]
-      this.selectedCodeList = []
-      this.filterCodeList = []
+      this.preSelectedCodeList = []
       this.dialogCodeListVisible = false
     },
     // 确认选择sn码
     onCodeConfirm() {
-      this.selectedCodeListAll = [...this.selectedCodeListAll, ...this.selectedCodeList]
-      this.filterSelectedCodeList = this.selectedCodeListAll
-      this.filterCodeList = []
+      const sncodeList = this.preSelectedCodeList.map((item) => item.snCode)
+      const snList = [...this.formData.snList, ...sncodeList]
+      this.formData.snList = uniqueArr(snList)
       this.dialogCodeListVisible = false
     },
-    // 已选中sn码筛选
-    onSelectCodeFilter(query) {
-      this.filterSelectedCodeList = this.filterSelectedCodeList.filter((code) =>
-        new RegExp(query.sncode, 'gi').test(code)
-      )
-    },
     // 已选中sn码删除
     onSelectCodeRemove(row) {
-      this.selectedCodeListAll = this.selectedCodeListAll.filter((code) => code !== row)
-      this.filterSelectedCodeList = this.selectedCodeListAll
+      this.formData.snList = this.formData.snList.filter((code) => code !== row.snCode)
     }
   }
 }
 </script>
 
 <style lang="scss" scoped>
+.app-container {
+  width: 80%;
+}
 .filter-container {
   background: #eee;
   padding: 6px 10px;
@@ -203,7 +174,7 @@ export default {
     margin-bottom: 0;
   }
 }
-.sncode-cate {
+.snCode-cate {
   display: flex;
   align-items: center;
   margin-bottom: 16px;

+ 60 - 39
src/views/normal/personalized/banner.vue

@@ -1,32 +1,27 @@
 <template>
   <div class="app-container">
-    <!--
-      使用element-ui表单
-      可以保存banner,移动端banner和pc端banner单独上传
-      跳转方式支持无、上传图片、链接,图片支持单独上传
-    -->
     <div class="form-container">
-      <el-form ref="form" :model="form" :rules="rules" label-width="140px">
-        <el-form-item label="移动端banner:" prop="pcImage">
-          <div class="banner" :style="pcImageStyle">
-            <img v-if="pcImage" :src="pcImage">
+      <el-form ref="form" :model="formData" :rules="rules" label-width="140px">
+        <el-form-item label="移动端banner:" prop="filesBanner">
+          <div class="banner" :style="pcImageStyle" @click="handleChooseFile(0)">
+            <img v-if="formData.filesBanner[0]" :src="formData.filesBanner[0]">
             <span class="tip">请上传图片(1920*530px)</span>
           </div>
         </el-form-item>
-        <el-form-item label="PC端banner:" prop="appImage">
-          <div class="banner" :style="mobileImageStyle">
-            <img v-if="appImage" :src="appImage">
+        <el-form-item label="PC端banner:" prop="filesBanner">
+          <div class="banner" :style="mobileImageStyle" @click="handleChooseFile(1)">
+            <img v-if="formData.filesBanner[1]" :src="formData.filesBanner[1]">
             <span class="tip">请上传图片(800*800px)</span>
           </div>
         </el-form-item>
-        <el-form-item label="跳转方式:" prop="region">
-          <el-radio-group v-model="form.region">
+        <el-form-item label="跳转方式:" prop="jumpStatus">
+          <el-radio-group v-model="formData.jumpStatus">
             <el-radio :label="0">无</el-radio>
             <el-radio :label="1">图片</el-radio>
             <el-radio :label="2">链接</el-radio>
           </el-radio-group>
         </el-form-item>
-        <el-form-item v-if="form.region === 1" label="跳转图片:" prop="linkImage">
+        <el-form-item v-if="formData.jumpStatus === 1" label="跳转图片:" prop="linkImage">
           <UploadImage
             :image-list="linkImageList"
             :limit="1"
@@ -34,24 +29,30 @@
             @remove="handleLinkImageRemove"
           />
         </el-form-item>
-        <el-form-item v-if="form.region === 2" label="跳转链接:" prop="link">
-          <el-input v-model="form.link" />
+        <el-form-item v-if="formData.jumpStatus === 2" label="跳转链接:" prop="jumpLink">
+          <el-input v-model="formData.jumpLink" />
         </el-form-item>
       </el-form>
-
       <!-- 表单提交 返回 -->
       <div class="control-box">
         <el-button type="primary" @click="submit">保存</el-button>
         <el-button type="warning" @click="navigateBack">返回</el-button>
       </div>
     </div>
-
-    <UploadImage v-show="false" @success="uploadImageSuccess" @remove="handleImageRemove" />
+    <UploadImage
+      v-show="false"
+      ref="upload"
+      :image-list="imageList"
+      :trigger="true"
+      :limit="99"
+      @success="uploadImageSuccess"
+    />
   </div>
 </template>
 
 <script>
 import UploadImage from '@/components/UploadImage'
+import { saveBannerData } from '@/api/personalized'
 export default {
   name: 'PersonalBanner',
   components: {
@@ -59,20 +60,22 @@ export default {
   },
   data() {
     return {
-      form: {
-        region: 0,
-        link: '',
-        pcImage: '',
-        appImage: '',
+      formData: {
+        jumpStatus: 0,
+        jumpLink: '',
+        filesBanner: [],
+        filesPicture: [],
         linkImage: ''
       },
+      currentIndex: 0,
       rules: {
-        pcImage: [{ required: true, message: '请上传图片', trigger: 'change' }],
-        appImage: [{ required: true, message: '请上传图片', trigger: 'change' }],
+        filesBanner: [{ type: 'array', required: true, message: '请上传图片', trigger: 'change' }],
+        filesPicture: [{ type: 'array', required: true, message: '请上传图片', trigger: 'change' }],
         linkImage: [{ required: true, message: '请上传图片', trigger: 'change' }],
-        link: [{ required: true, message: '请输入链接', trigger: 'blur' }]
+        jumpLink: [{ required: true, message: '请输入链接', trigger: 'blur' }]
       },
-      linkImageList: []
+      linkImageList: [],
+      imageList: []
     }
   },
   computed: {
@@ -92,22 +95,40 @@ export default {
     }
   },
   methods: {
-    submit() {},
-    uploadImageSuccess({ response, file, fileList }) {
-      this.imageList = fileList
-      this.formData.linkImage = fileList.length > 0 ? fileList.length : ''
+    async submit() {
+      try {
+        await this.$refs.form.validate()
+        this.saveBanner()
+      } catch (error) {
+        console.log(error)
+      }
     },
-    handleImageRemove({ file, fileList }) {
-      this.linkImageList = fileList
-      this.formData.linkImage = fileList.length > 0 ? fileList.length : ''
+    // 保存banner
+    async saveBanner() {
+      try {
+        await saveBannerData(this.formData)
+        this.$message.success('保存成功')
+      } catch (error) {
+        console.log(error)
+      }
     },
+
+    handleChooseFile(index) {
+      this.currentIndex = index
+      this.$refs.upload.handleClick()
+    },
+    // 图片上传
+    uploadImageSuccess({ response, file, fileList }) {
+      this.$set(this.formData.filesBanner, this.currentIndex, response.data)
+    },
+    // 跳转链接为图片,上传图片
     uploadLinkImageSuccess({ response, file, fileList }) {
       this.linkImageList = fileList
-      this.formData.linkImage = fileList.length > 0 ? fileList.length : ''
+      this.$set(this.formData.filesPicture, 0, response.data)
     },
     handleLinkImageRemove({ file, fileList }) {
-      this.linkImageList = fileList
-      this.formData.linkImage = fileList.length > 0 ? fileList.length : ''
+      this.linkImageList = []
+      this.formData.filesPicture = []
     }
   }
 }