wolyshaw 4 роки тому
батько
коміт
99be1fa6da

+ 1 - 0
package.json

@@ -55,6 +55,7 @@
     "vue-quill-editor": "^3.0.6",
     "vue-resize": "^1.0.1",
     "vue-router": "3.0.6",
+    "vuedraggable": "^2.24.3",
     "vuex": "3.1.0",
     "wangeditor": "^4.0.0",
     "webpack-merge": "^5.3.0"

+ 95 - 26
src/views/photo-detail/index.vue

@@ -9,7 +9,7 @@
         <el-button type="primary" v-if="!editing" @click="changeMode()">编辑照片</el-button>
         <el-button type="danger" v-if="editing" @click="remove()">删除照片</el-button>
         <el-button type="primary" v-if="editing" @click="confirm()">确定</el-button>
-        <el-button type="primary" v-if="editing" @click="editing = false">取消</el-button>
+        <el-button type="primary" v-if="editing" @click="cancel">取消</el-button>
       </div>
       <el-alert
         v-if="editing"
@@ -23,25 +23,35 @@
         </div>
       </el-alert>
       <el-checkbox-group v-model="checked">
-        <div
-          v-for="(item) in list"
-          :key="item.url"
-          class="img-container"
-        >
-          <div v-if="editing" class="ctrl-bar">
-            <el-checkbox class="check" :label="item.id"></el-checkbox>
-            <i class="el-icon-view" :class="{active: views.includes(item.id)}" @click="setView(item)"></i>
+        <draggable :list="list" :disabled="!editing" style="display: flex;">
+          <div
+            v-for="(item) in list"
+            :key="item.url"
+            class="img-container"
+          >
+            <div v-if="editing" class="ctrl-bar">
+              <el-checkbox class="check" :label="item.id"></el-checkbox>
+              <i class="el-icon-view" :class="{active: views.includes(item.id)}" @click="setView(item)"></i>
+            </div>
+            <div v-else class="ctrl-bar-view">
+              <el-tooltip effect="dark" content="设为封面" placement="top" :open-delay=".5">
+                <i class="el-icon-picture-outline-round" @click="setCover(item)"></i>
+              </el-tooltip>
+              <el-tooltip effect="dark" :content="views.includes(item.id) ? '设为不可见' : '设为可见'" placement="top" :open-delay=".5">
+                <i class="el-icon-view" :class="{active: views.includes(item.id)}" @click="setViewItem(item)"></i>
+              </el-tooltip>
+            </div>
+            <el-image
+              :src="item.url"
+              class="img"
+              :preview-src-list="list.map(item => item.url)">
+            </el-image>
+            <el-tooltip v-if="!editing" class="item" effect="dark" :content="item.name" placement="top" :open-delay=".5">
+              <div class="name">{{item.name}}</div>
+            </el-tooltip>
+            <el-input class="nameinput" v-else v-model="item.name" size="mini" placeholder="请输入照片名称" clearable/>
           </div>
-          <el-image
-            :src="item.url"
-            class="img"
-            :preview-src-list="list.map(item => item.url)">
-          </el-image>
-          <el-tooltip v-if="!editing" class="item" effect="dark" :content="item.name" placement="top" :open-delay=".3">
-            <div class="name">{{item.name}}</div>
-          </el-tooltip>
-          <el-input class="nameinput" v-else v-model="item.name" size="mini" placeholder="请输入照片名称" clearable/>
-        </div>
+        </draggable>
       </el-checkbox-group>
       <empty v-if="list.length == 0"/>
     </div>
@@ -59,11 +69,13 @@
   </div>
 </template>
 <script>
+import draggable from 'vuedraggable'
 import uploadPopup from '@/views/resetTeaming/components/training-photos/upload'
-import { photoQueryPage, photoDel } from '@/views/resetTeaming/components/training-photos/api'
+import { photoQueryPage, photoDel, photoUpdate, photoAlbumUpdate } from '@/views/resetTeaming/components/training-photos/api'
 export default {
   components: {
     'upload-popup': uploadPopup,
+    draggable,
   },
   computed: {
     detailName() {
@@ -92,11 +104,40 @@ export default {
     openUpload() {
       this.uploadVisible = true
     },
+    setInitViwes() {
+      this.views = this.list.filter(item => item.clientShow).map(item => item.id)
+    },
+    async setCover(item) {
+      try {
+        await this.$confirm('是否确认设置为封面?', '提示')
+        await photoAlbumUpdate({
+          id: this.$route.params.id,
+          coverUrl: item.url
+        })
+        this.$message.success('设置成功')
+        this.FetchList()
+      } catch (error) {}
+    },
+    async setViewItem(item) {
+      try {
+        await this.$confirm('是否确认修改可见状态?', '提示')
+        await photoUpdate([{
+          ...item,
+          clientShow: +!item.clientShow
+        }])
+        this.$message.success('设置成功')
+        this.FetchList()
+      } catch (error) {}
+    },
     changeMode() {
       this.checked = []
-      this.views = this.list.filter(item => item.clientShow).map(item => item.id)
+      this.setInitViwes()
       this.editing = true
     },
+    cancel() {
+      this.editing = false
+      this.list = this.list.sort((a, b) => a.order - b.order)
+    },
     submited() {
       this.FetchList()
     },
@@ -114,15 +155,26 @@ export default {
     async FetchList() {
       try {
         const res = await photoQueryPage({photoAlbumId: this.$route.params.id})
-        console.log(res.data.rows)
+        // console.log(res.data.rows)
+        this.setInitViwes()
         this.list = res.data.rows
       } catch (error) {}
     },
     async confirm() {
       try {
         await this.$confirm('是否确认修改照片信息?', '提示')
-
-      } catch (error) {}
+        const data = this.list.map((item, index) => ({
+          ...item,
+          order: index,
+          clientShow: +this.views.includes(item.id)
+        }))
+        await photoUpdate(data)
+        this.editing = false
+        this.$message.success('修改成功')
+        this.FetchList()
+      } catch (error) {
+        console.log(error)
+      }
     },
     async remove() {
       try {
@@ -130,6 +182,9 @@ export default {
         await photoDel({
           ids: this.checked.join(',')
         })
+        this.$message.success('删除成功')
+        this.editing = false
+        this.FetchList()
       } catch (error) {}
     }
   }
@@ -143,6 +198,7 @@ export default {
   flex-direction: column;
   text-align: center;
   position: relative;
+  cursor: move;
   >.name{
     width: 150px;
     height: 30px;
@@ -160,7 +216,8 @@ export default {
     margin-top: 10px;
   }
 }
-.ctrl-bar{
+.ctrl-bar,
+.ctrl-bar-view{
   background-color: rgba(0, 0, 0, .45);
   height: 30px;
   position: absolute;
@@ -172,7 +229,19 @@ export default {
   align-items: center;
   padding: 0 15px;
 }
-.el-icon-view{
+.ctrl-bar-view{
+  opacity: 0;
+  visibility: hidden;
+  transition: all .3s;
+}
+.img-container:hover{
+  .ctrl-bar-view{
+    opacity: 1;
+    visibility: visible;
+  }
+}
+.el-icon-view,
+.el-icon-picture-outline-round{
   font-size: 14px;
   color: #fff;
   cursor: pointer;

+ 1 - 1
src/views/resetTeaming/components/training-photos/api.js

@@ -63,7 +63,7 @@ export const photoDel = (data) => {
 
 export const photoUpdate = (data) => {
   return request({
-    url: '/api-web/photo/update',
+    url: '/api-web/photo/batchUpdate',
     data: data,
     method: 'post',
   })

+ 14 - 9
src/views/resetTeaming/components/training-photos/group/index.vue

@@ -1,14 +1,19 @@
 <template>
   <div class="group">
     <div class="list">
-      <el-image
+      <!-- <el-image
         v-for="(item, index) in list"
         :src="item"
         :key="item"
         class="img"
         :style="{marginRight: (index % 2 ? 0 : '10px'), marginTop: (index > 1 ? '6px' : '0')}"
         :preview-src-list="list">
-      </el-image>
+      </el-image> -->
+      <el-image
+        :src="detail.coverUrl || require('../icons/initbg.svg')"
+        class="img"
+        fit="contain"
+      />
     </div>
     <el-tooltip class="item" effect="dark" :content="name" placement="top" :open-delay=".3">
       <div class="title">{{name}}</div>
@@ -24,18 +29,17 @@ export default {
     name: {
       type: String,
     },
-    list: {
-      type: Array,
-      default: []
+    detail: {
+      type: Object
     }
   }
 }
 </script>
 <style scoped lang="less">
   .group{
-    width: 190px;
+    width: 290px;
     .list{
-      width: 190px;
+      width: 290px;
       padding: 10px;
       background-color: rgba(0, 0, 0, .05);
       border-radius: 6px;
@@ -51,8 +55,9 @@ export default {
       white-space: pre;
     }
     .img{
-      width: 80px;
-      height: 80px;
+      width: 100%;
+      // width: 130px;
+      height: 130px;
       border-radius: 3px;
     }
     .viewer{

+ 1 - 0
src/views/resetTeaming/components/training-photos/icons/initbg.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1626165672568" class="icon" viewBox="0 0 1110 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="43357" xmlns:xlink="http://www.w3.org/1999/xlink" width="216.796875" height="200"><defs><style type="text/css"></style></defs><path d="M991.279151 39.681651A39.834078 39.834078 0 0 0 951.597499 0H39.681651A39.783269 39.783269 0 0 0 0 39.681651V753.494095a39.783269 39.783269 0 0 0 39.681651 39.681652h33.889452a39.783269 39.783269 0 0 0 39.681651-39.681652V154.915947a39.783269 39.783269 0 0 1 39.681651-39.681651h798.510668a39.834078 39.834078 0 0 0 39.681651-39.681651V39.681651z m0 0" fill="#e6e6e6" p-id="43358"></path><path d="M1064.240548 191.498263H231.942046a46.235983 46.235983 0 0 0-46.286791 46.235983V977.560782a46.235983 46.235983 0 0 0 46.286791 46.235983h832.349311a46.185174 46.185174 0 0 0 46.235982-46.235983V237.937481a46.235983 46.235983 0 0 0-46.235982-46.235983z m-92.471966 693.539744H324.363203V653.908901l138.758758-138.758757 231.179915 231.179915 138.758757-138.707949 138.707949 138.707949v138.707948z m-92.471966-369.887863a92.471966 92.471966 0 1 1 92.471966-92.471966 92.421157 92.421157 0 0 1-92.471966 92.471966z m0 0" fill="#e6e6e6" p-id="43359"></path></svg>

+ 22 - 7
src/views/resetTeaming/components/training-photos/index.vue

@@ -12,11 +12,12 @@
     >
       <group
         class="item"
-        :list="imgs"
+        :detail="item"
         :name="item.name"
       />
       <div class="ctrls">
-        <el-dropdown @command="command => handleCommand(command, item)">
+        <div class="photoNum">{{item.photoNum}} 张</div>
+        <el-dropdown class="dropdown" @command="command => handleCommand(command, item)">
           <span class="el-dropdown-link">
             更多操作 <i class="el-icon-arrow-down el-icon--right"></i>
           </span>
@@ -70,11 +71,6 @@ export default {
       uploadVisible: false,
       detail: null,
       list: [],
-      imgs: [
-        'https://t7.baidu.com/it/u=1595072465,3644073269&fm=193&f=GIF',
-        'https://t7.baidu.com/it/u=1956604245,3662848045&fm=193&f=GIF',
-        'https://t7.baidu.com/it/u=2511982910,2454873241&fm=193&f=GIF'
-      ]
     }
   },
   mounted() {
@@ -144,6 +140,25 @@ export default {
     opacity: 0;
     border-radius: 10px;
     transition: all .3s;
+    text-align: right;
+    display: flex;
+    flex-direction: column;
+    .photoNum{
+      margin: auto;
+      text-align: center;
+      font-size: 24px;
+      font-weight: bold;
+      color: #fff;
+    }
+    .dropdown{
+      position: absolute;
+      top: 10px;
+      right: 0;
+    }
+    .el-dropdown-link{
+      color: #fff;
+      padding: 10px;;
+    }
   }
 }
 .item-container:hover,

+ 25 - 1
src/views/resetTeaming/components/training-photos/upload/index.vue

@@ -37,10 +37,13 @@
       <div class="img-container">
         <div class="list" v-if="uploaded.length > 0">
           <div
-            v-for="(item) in uploaded"
+            v-for="(item, index) in uploaded"
             :key="item.url"
             class="item"
           >
+            <div class="ctrl-bar">
+              <i class="el-icon-circle-close" @click="remove(index)"></i>
+            </div>
             <el-image
               :src="item.url"
               :preview-src-list="uploaded.map(item => item.url)"
@@ -136,6 +139,9 @@ export default {
         })
       } catch (error) {}
     },
+    remove(index) {
+      this.uploaded.splice(index, 1)
+    }
   }
 }
 </script>
@@ -150,9 +156,27 @@ export default {
   width: 150px;
   margin-top: 10px;
   margin-right: 10px;
+  display: inline-block;
+  position: relative;
 }
 .img{
   width: 150px;
   height: 150px;
 }
+.ctrl-bar{
+  background-color: rgba(0, 0, 0, .45);
+  height: 30px;
+  position: absolute;
+  top: 0;
+  width: 100%;
+  z-index: 1;
+  display: flex;
+  justify-content: flex-end;
+  align-items: center;
+  padding: 0 15px;
+  i{
+    color: #fff;
+    cursor: pointer;
+  }
+}
 </style>