shaogen1995 3 лет назад
Родитель
Сommit
7c2d860594

+ 23 - 35
houtai/src/apis/tab1.js

@@ -1,53 +1,41 @@
 import axios from '../utils/request'
 // 获取列表
-export const goodsList = (data) => {
+export const villageList = () => {
   return axios({
-    method: 'post',
-    url: '/cms/goods/list',
-    data
+    method: 'get',
+    url: '/cms/village/getList'
   })
 }
-// 点击删除
-export const goodsRemove = (id) => {
+
+// 获取菜单树
+export const getTreeMenu = () => {
   return axios({
-    url: `/cms/goods/remove/${id}`
+    method: 'get',
+    url: '/cms/village/getTreeMenu'
   })
 }
-// 新增、编辑
-export const goodsSave = (data) => {
+
+// 删除文件
+export const delFileApi = (fileIds) => {
   return axios({
     method: 'post',
-    url: '/cms/goods/save',
-    data
-  })
-}
-// 是否显示
-export const goodsDisplay = (id, display) => {
-  return axios({
-    url: `/cms/goods/display/${id}/${display}`
-  })
-}
-// 排序
-export const goodsSort = (id, sort) => {
-  return axios({
-    url: `/cms/goods/sort/${id}/${sort}`
+    url: `/cms/content/delFile/${fileIds}`
   })
 }
-// 设为封面
-export const goodsImgIndex = (id, fileId) => {
+
+// 新增和编辑村落信息
+export const saveEntity = (data) => {
   return axios({
-    url: `/cms/goods/imgIndex/${id}/${fileId}`
-  })
-}
-// 通过id获取详情
-export const goodsDetail = (id) => {
-  return axios({
-    url: `/cms/goods/detail/${id}`
+    method: 'post',
+    url: '/cms/content/saveEntity',
+    data
   })
 }
-// 删除图片
-export const goodsimgRemove = (id) => {
+
+// 获取信息,用户回显数据
+export const contentList = (villageId, menuId) => {
   return axios({
-    url: `/cms/goods/imgRemove/${id}`
+    method: 'get',
+    url: `/cms/content/list/${villageId}/${menuId}`
   })
 }

+ 23 - 17
houtai/src/assets/css/base.css

@@ -75,9 +75,6 @@ input[type="number"] {
 .el-dialog{
   min-width: 652px;
 }
-.el-upload__tip{
-  font-size: 14px;
-}
 .el-range-editor.is-active, .el-range-editor.is-active:hover{
   border-color: #b9412e;
 }
@@ -193,20 +190,7 @@ input[type="number"] {
 .w-e-toolbar .w-e-menu:nth-of-type(26) {
 	display: none !important;
 }
-.avatar-uploader .el-upload-list__item-name{
-  display: none;
-}
-.avatar-uploader .el-upload-list__item.is-success .el-upload-list__item-status-label{
-  display: none;
-}
-.el-upload-list__item .el-progress{
-  width: 500px;
-  position: static;
-  margin-bottom: 15px;
-}
-.el-upload-list__item{
-  width: 500px;
-}
+
 .el-month-table td.end-date .cell, .el-month-table td.start-date .cell{
   background-color: #b9412e;
 }
@@ -217,3 +201,25 @@ input[type="number"] {
 .el-message-box__title{
   color: #b9412e;
 }
+textarea{
+  resize: none !important;
+}
+.el-textarea__inner {
+  height: 150px;
+}
+.el-textarea .el-input__count {
+  bottom: -30px;
+  right: 0px;
+  background-color: transparent;
+}
+.el-upload-dragger .smEl {
+  color: #ccc;
+  font-size: 12px;
+  margin-top: -15px;
+}
+.el-upload-list{
+  width: 360px;
+}
+.el-textarea__inner:focus {
+  border-color: #b9412e;
+}

+ 3 - 3
houtai/src/utils/request.js

@@ -1,8 +1,8 @@
 import axios from 'axios'
 const service = axios.create({
-  // baseURL: 'http://192.168.0.135:8005/', // 本地调试
-  // baseURL: 'http://192.168.0.245:8005/', // 线上调试
-  baseURL: '', // build
+  baseURL: 'http://192.168.0.135:8016', // 本地调试
+  // baseURL: '', // 线上调试
+  // baseURL: '', // build
   timeout: 5000
 })
 // 请求拦截器

+ 1 - 1
houtai/src/views/layout/index.vue

@@ -4,7 +4,7 @@
       <p>江门市中国传统村落一张图管理后台</p>
       <div class="top_right" @mouseenter='cut=true' @mouseleave='cut=false'>
         <div class="user">
-          <span>Admin88</span>
+          <span>{{userName}}</span>
           <!-- 下箭头 -->
           <div class="pull_down" v-if="cut"></div>
           <div class="pull_up" v-else></div>

+ 15 - 15
houtai/src/views/login.vue

@@ -24,6 +24,7 @@
             </el-form-item>
             <el-form-item prop="passWord">
               <el-input
+                show-password
                 v-model="ruleForm.passWord"
                 placeholder="密码"
               ></el-input>
@@ -37,9 +38,9 @@
 </template>
 
 <script>
-// import { encodeStr } from '../utils/pass'
-// import { Base64 } from 'js-base64'
-// import { userLogin } from '@/apis/login'
+import { encodeStr } from '../utils/pass'
+import { Base64 } from 'js-base64'
+import { userLogin } from '@/apis/login'
 export default {
   name: 'login',
   components: {},
@@ -65,21 +66,20 @@ export default {
     async login () {
       try {
         await this.$refs.ruleForm.validate()
-        this.$router.push('/layout/tab1')
+        const data = {
+          userName: this.ruleForm.userName,
+          passWord: encodeStr(Base64.encode(this.ruleForm.passWord))
+        }
+        const res = await userLogin(data)
+        if (res.code === 0) {
+          localStorage.setItem('JMYZU_token', res.data.token)
+          localStorage.setItem('JMYZU_userName', res.data.user.userName)
+          this.$router.push('/layout/tab1')
+          this.$message.success('登录成功')
+        } else this.$message.warning(res.msg)
       } catch (error) {
         console.log(error)
       }
-      // const data = {
-      //   userName: this.from.userName,
-      //   passWord: encodeStr(Base64.encode(this.from.passWord))
-      // }
-      // const res = await userLogin(data)
-      // if (res.code === 0) {
-      //   localStorage.setItem('JMYZU_token', res.data.token)
-      //   localStorage.setItem('JMYZU_userName', res.data.user.userName)
-      //   this.$router.push('/layout/tab1')
-      //   this.$message.success('登录成功')
-      // } else this.$message.warning(res.msg)
     }
   },
   // 生命周期 - 创建完成(可以访问当前this实例)

+ 10 - 17
houtai/src/views/tab1/index.vue

@@ -19,10 +19,12 @@
         <el-table :data="tableData" style="width: 100%">
           <el-table-column prop="id" label="编号" width="200"></el-table-column>
           <el-table-column prop="name" label="村落名称"></el-table-column>
-          <el-table-column prop="time" label="最近更新时间"></el-table-column>
+          <el-table-column prop="updateTime" label="最近更新时间"></el-table-column>
           <el-table-column label="操作">
             <template #default="{ row }">
-              <el-button type="text" @click="$router.push(`/layout/tab1Main/${row.id}/1.1`)"
+              <el-button
+                type="text"
+                @click="$router.push(`/layout/tab1Main/${row.id}/1001`)"
                 >编辑</el-button
               >
             </template>
@@ -34,6 +36,7 @@
 </template>
 
 <script>
+import { villageList } from '@/apis/tab1'
 export default {
   name: 'tab1',
   components: {},
@@ -41,20 +44,7 @@ export default {
     // 这里存放数据
     return {
       name: '',
-      tableData: [
-        { name: '东宁村', id: 1, time: '2022-03-25 10:48:16' },
-        { name: '良溪村', id: 2, time: '2022-03-25 10:48:16' },
-        { name: '卢边村', id: 1, time: '2022-03-25 10:48:16' },
-        { name: '田心村', id: 1, time: '2022-03-25 10:48:16' },
-        { name: '仓前村', id: 1, time: '2022-03-25 10:48:16' },
-        { name: '霄南村', id: 1, time: '2022-03-25 10:48:16' },
-        { name: '歇马村', id: 1, time: '2022-03-25 10:48:16' },
-        { name: '自力村', id: 1, time: '2022-03-25 10:48:16' },
-        { name: '马降龙村', id: 1, time: '2022-03-25 10:48:16' },
-        { name: '浮石村', id: 1, time: '2022-03-25 10:48:16' },
-        { name: '浮月村', id: 1, time: '2022-03-25 10:48:16' },
-        { name: '横江村', id: 1, time: '2022-03-25 10:48:16' }
-      ]
+      tableData: []
     }
   },
   // 监听属性 类似于data概念
@@ -64,7 +54,10 @@ export default {
   // 方法集合
   methods: {},
   // 生命周期 - 创建完成(可以访问当前this实例)
-  created () {},
+  async created () {
+    const res = await villageList()
+    this.tableData = res.data
+  },
   // 生命周期 - 挂载完成(可以访问DOM元素)
   mounted () {},
   beforeCreate () {}, // 生命周期 - 创建之前

+ 533 - 0
houtai/src/views/tab1Main/five.vue

@@ -0,0 +1,533 @@
+<!--  -->
+<template>
+  <div class="five">
+    <div class="main">
+      <div class="row" v-for="(item, index) in data" :key="item.id">
+        <div class="top">
+          <span
+            @click="data[index].flag = !data[index].flag"
+            :class="`${item.flag ? 'el-icon-arrow-up' : 'el-icon-arrow-down'}`"
+            >&emsp;{{ index + 1 }}</span
+          >
+          <el-input
+            v-model="item.name"
+            placeholder="请输入名称"
+            maxlength="25"
+          ></el-input>
+          <i
+            v-if="index !== 0"
+            class="el-icon-close"
+            @click="delMen(index)"
+          ></i>
+        </div>
+        <div class="txt" v-show="item.flag">
+          <div class="txtBox">
+            <span>产权归属:</span>
+            <el-input
+              v-model="item.txt1"
+              maxlength="25"
+              show-word-limit
+            ></el-input>
+          </div>
+          <div class="txtBox">
+            <span>占地面积:</span>
+            <el-input
+              v-model="item.txt2"
+              maxlength="25"
+              show-word-limit
+            ></el-input>
+          </div>
+          <div class="txtBox">
+            <span>建筑面积:</span>
+            <el-input
+              v-model="item.txt3"
+              maxlength="25"
+              show-word-limit
+            ></el-input>
+          </div>
+          <div class="txtBox">
+            <span>保护级别:</span>
+            <el-input
+              v-model="item.txt4"
+              maxlength="25"
+              show-word-limit
+            ></el-input>
+          </div>
+          <div class="txtBox">
+            <span>建筑概况:</span>
+            <el-input
+              type="textarea"
+              v-model="item.txt5"
+              maxlength="1000"
+              show-word-limit
+            ></el-input>
+          </div>
+          <div class="txtBox">
+            <span class="upImgSpan">上传图片:</span>
+
+            <div class="imgBox">
+              <div
+                @click="lookImg(val)"
+                class="imgdiv"
+                v-for="(val, indSon) in item.imgList"
+                :key="val.id"
+              >
+                <img :src="baseURL + val.filePath" alt="" />
+                <!-- 封面显示 -->
+                <div class="cover" v-if="item.imgActive === val.id">封面</div>
+                <!-- 下面的按钮 -->
+                <div
+                  class="handle"
+                  v-else
+                  @click.stop="goodsImgIndex(item, val.id)"
+                >
+                  设为封面
+                </div>
+                <!-- 删除 -->
+                <div
+                  class="delImg el-icon-delete"
+                  @click.stop="delGoodsImg(indSon, item, val.id)"
+                  v-if="item.imgActive !== val.id"
+                ></div>
+              </div>
+              <el-upload
+                v-if="item.imgList.length < 10"
+                accept=".png,.jpg,.jpeg"
+                :action="baseURL + '/cms/content/upload'"
+                :data="{
+                  menuId: menuId,
+                  type: 'img',
+                  villageId: villageId,
+                }"
+                :show-file-list="true"
+                class="avatar-uploader"
+                :headers="{ token }"
+                :before-upload="beforethumbUploadImg"
+                :on-success="
+                  (res) => {
+                    return upload_thumb_successImg(res, item);
+                  }
+                "
+              >
+                <div class="upImg">
+                  <i slot="default" class="el-icon-plus"></i>
+                </div>
+              </el-upload>
+            </div>
+            <p class="upHint">支持格式:jpg, png,最大支持 20M</p>
+          </div>
+        </div>
+      </div>
+    </div>
+    <!-- 底部按钮 -->
+    <div class="btnn">
+      <!-- 增加人物 -->
+      <div class="el-icon-plus" @click="addMen">增加内容</div>
+
+      <el-button @click="$router.push('/layout/tab1')">返 回</el-button>&emsp;
+      <el-button type="primary" @click="save">保 存</el-button>
+    </div>
+    <!-- 照片墙的查看照片 -->
+    <el-dialog :visible.sync="dialogVisible">
+      <img width="100%" :src="dialogImageUrl" alt="" />
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import axios from '@/utils/request'
+import { saveEntity, contentList, delFileApi } from '@/apis/tab1'
+export default {
+  components: {},
+  data () {
+    return {
+      // 服务器前缀地址
+      token: '',
+      baseURL: '',
+
+      // 村落ID
+      villageId: null,
+      // 菜单ID
+      menuId: null,
+      // 本身自己的id
+      id: null,
+      // 查看图片
+      imgListLook: [],
+      data: [
+        {
+          id: Date.now(),
+          name: '',
+          txt1: '',
+          txt2: '',
+          txt3: '',
+          txt4: '',
+          txt5: '',
+          flag: true,
+          imgActive: 0,
+          imgList: []
+        }
+      ],
+      // 照片墙数据
+      dialogImageUrl: '',
+      dialogVisible: false
+    }
+  },
+  computed: {},
+  methods: {
+    // ---------------照片墙
+    beforethumbUploadImg (file) {
+      // console.log(998, file)
+      // 限制图片大小和格式
+      const sizeOk = file.size / 1024 / 1024 < 20
+      const typeOk =
+        file.type === 'image/png' ||
+        (file.type === 'image/jpeg' && !file.name.includes('.jfif'))
+
+      return new Promise((resolve, reject) => {
+        if (!typeOk) {
+          this.$message.error('图片格式有误!')
+          reject(file)
+        } else if (!sizeOk) {
+          this.$message.error('图片大小超过20M!')
+          reject(file)
+        } else {
+          resolve(file)
+        }
+      })
+    },
+    upload_thumb_successImg (data, item) {
+      this.$message.success('上传图片成功')
+      item.imgList.push(data.data)
+      // 如果是第一张上传的图片,把id变成第一张
+      if (item.imgList.length === 1) item.imgActive = data.data.id
+    },
+    // 点击删除图片
+    delGoodsImg (indSon, item, id) {
+      this.$confirm('此操作将永久删除图片', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      })
+        .then(async () => {
+          item.imgList.splice(indSon, 1)
+          this.$message.success('删除成功')
+          await delFileApi(id)
+          const obj = {
+            menuId: this.menuId,
+            villageId: this.villageId,
+            contentJson: JSON.stringify(this.data),
+            id: this.id
+          }
+          await saveEntity(obj)
+        })
+        .catch(() => {})
+    },
+    // 点击设为封面
+    goodsImgIndex (item, id) {
+      item.imgActive = id
+      // this.ruleForm.thumb = this.imgList[index].filePath
+      this.$message.success('操作成功')
+    },
+    // 点击图片看大图
+    lookImg (val) {
+      this.dialogImageUrl = this.baseURL + val.filePath
+      this.dialogVisible = true
+    },
+
+    // 点击删除
+    delMen (index) {
+      this.data.splice(index, 1)
+    },
+    // 点击增加人物
+    addMen () {
+      this.data.push({
+        id: Date.now(),
+        name: '',
+        txt1: '',
+        txt2: '',
+        txt3: '',
+        txt4: '',
+        txt5: '',
+        flag: true,
+        imgActive: 0,
+        imgList: []
+      })
+    },
+    // 点击保存
+    async save () {
+      let tempFlag = false
+      this.data.forEach((v) => {
+        v.flag = true
+        if (
+          v.name.trim() === '' ||
+          v.txt1.trim() === '' ||
+          v.txt2.trim() === '' ||
+          v.txt3.trim() === '' ||
+          v.txt4.trim() === '' ||
+          v.imgList.length <= 0
+        ) {
+          tempFlag = true
+        }
+      })
+      if (tempFlag) return this.$message.warning('信息或图片不能为空')
+
+      const obj = {
+        menuId: this.menuId,
+        villageId: this.villageId,
+        contentJson: JSON.stringify(this.data),
+        id: this.id
+      }
+      const res = await saveEntity(obj)
+      if (res.code === 0) {
+        this.$message.success('操作成功')
+      } else this.$message.warning(res.msg)
+    }
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  async created () {
+    // 获取服务器前缀地址
+    this.baseURL = axios.defaults.baseURL
+    // 获取用户token
+    this.token = localStorage.getItem('JMYZU_token')
+    this.villageId = Number(this.$route.params.id)
+    this.menuId = Number(this.$route.params.k)
+    const res = await contentList(this.villageId, this.menuId)
+    if (res.data.length > 0) {
+      const temp = res.data[0]
+      this.id = temp.id
+      this.data = JSON.parse(temp.contentJson)
+    }
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted () {},
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {} // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+.five {
+  /deep/.avatar-uploader .el-upload-list__item-name {
+    display: none;
+  }
+  /deep/.avatar-uploader
+    .el-upload-list__item.is-success
+    .el-upload-list__item-status-label {
+    display: none;
+  }
+  /deep/.el-upload-list__item .el-progress {
+    width: 500px;
+    position: static;
+    margin-bottom: 15px;
+  }
+  /deep/.el-upload-list__item {
+    width: 500px;
+  }
+  width: 100%;
+  height: 100%;
+  position: relative;
+  .main {
+    padding: 30px 20px;
+    height: calc(100% - 120px);
+    overflow-y: auto;
+    .row {
+      margin-bottom: 50px;
+      .top {
+        position: relative;
+        width: 100%;
+        padding: 0 20px;
+        height: 50px;
+        line-height: 50px;
+        background-color: #f2f2f2;
+        .el-icon-close {
+          cursor: pointer;
+          font-weight: 700;
+          font-size: 26px;
+          position: absolute;
+          top: 50%;
+          right: 24px;
+          transform: translateY(-50%);
+        }
+        & > span {
+          cursor: pointer;
+          font-weight: 700;
+          margin-right: 15px;
+        }
+        /deep/.el-input {
+          height: 36px;
+          width: 380px;
+        }
+        /deep/.el-input__inner {
+          color: black;
+          height: 36px;
+          line-height: 36px;
+          background-color: transparent;
+          border: none;
+          border-bottom: 1px solid black;
+          border-radius: 0;
+        }
+        /*修改提示文字的颜色*/
+        /deep/input::-webkit-input-placeholder {
+          /* WebKit browsers */
+          color: #999;
+        }
+        /deep/input:-moz-placeholder {
+          /* Mozilla Firefox 4 to 18 */
+          color: #999;
+        }
+        /deep/input::-moz-placeholder {
+          /* Mozilla Firefox 19+ */
+          color: #999;
+        }
+        /deep/input:-ms-input-placeholder {
+          /* Internet Explorer 10+ */
+          color: #999;
+        }
+      }
+      .txt {
+        width: 90%;
+        margin: 20px auto;
+        .txtBox {
+          margin-bottom: 10px;
+          position: relative;
+          width: 100%;
+          display: flex;
+          & > span {
+            width: 90px;
+            text-align: right;
+            line-height: 40px;
+            &::after {
+              position: absolute;
+              top: 0px;
+              left: -6px;
+              content: "*";
+              color: #f56c6c;
+            }
+          }
+          .upImgSpan {
+            width: 84px;
+            &::after {
+              left: -6px;
+            }
+          }
+          .imgBox {
+            display: flex;
+            flex-wrap: wrap;
+            /deep/.el-icon-plus {
+              font-size: 28px;
+              color: #8c939d;
+              display: flex;
+              align-items: center;
+              justify-content: center;
+              border: 1px dashed #ccc;
+              width: 148px;
+              height: 148px;
+              background-color: #fbfdff;
+              border: 1px dashed #c0ccda;
+              border-radius: 6px;
+            }
+            /deep/.el-icon-plus:hover {
+              border-color: #409eff;
+            }
+            .imgdiv {
+              border-radius: 5px;
+              overflow: hidden;
+              position: relative;
+              margin-right: 30px;
+              margin-bottom: 10px;
+              height: 148px;
+              & > img {
+                width: 148px;
+                height: 148px;
+                object-fit: cover;
+              }
+              .handle {
+                cursor: pointer;
+                color: #fff;
+                font-size: 16px;
+                display: flex;
+                justify-content: center;
+                align-items: center;
+                width: 100%;
+                z-index: 999;
+                position: absolute;
+                bottom: 0;
+                left: 0;
+                height: 30px;
+                background-color: rgba(163, 0, 20, 0.8);
+              }
+              .delImg {
+                cursor: pointer;
+                border-radius: 10px;
+                color: #fff;
+                background-color: #a30014;
+                padding: 3px;
+                font-size: 26px;
+                position: absolute;
+                top: 5px;
+                right: 5px;
+              }
+              .cover {
+                color: #fff;
+                pointer-events: none;
+                font-size: 16px;
+                display: flex;
+                justify-content: center;
+                align-items: center;
+                width: 100%;
+                z-index: 999;
+                position: absolute;
+                bottom: 0;
+                left: 0;
+                height: 30px;
+                background-color: rgba(0, 0, 0, 0.6);
+              }
+            }
+          }
+          .upHint {
+            position: absolute;
+            bottom: -25px;
+            left: 80px;
+            font-size: 12px;
+            color: #606266;
+          }
+        }
+        /deep/.el-textarea .el-input__count {
+          bottom: -20px;
+        }
+      }
+      /deep/.el-textarea__inner {
+        height: 80px;
+      }
+    }
+  }
+  .btnn {
+    border-top: 1px solid #d7d7d7;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    position: absolute;
+    bottom: 0;
+    left: 0;
+    height: 70px;
+    width: 100%;
+    .el-icon-plus {
+      position: absolute;
+      top: -50px;
+      left: 50%;
+      transform: translateX(-50%);
+      font-weight: 700;
+      color: #02aff4;
+      cursor: pointer;
+      width: 100px;
+      text-align: center;
+      line-height: 40px;
+      height: 40px;
+    }
+  }
+}
+</style>

+ 490 - 12
houtai/src/views/tab1Main/four.vue

@@ -1,28 +1,295 @@
 <!--  -->
 <template>
-<div class='four'>four</div>
+  <div class="four">
+    <div class="main">
+      <div class="row" v-for="(item, index) in data" :key="item.id">
+        <div class="top">
+          <span
+            @click="data[index].flag = !data[index].flag"
+            :class="`${item.flag ? 'el-icon-arrow-up' : 'el-icon-arrow-down'}`"
+            >&emsp;{{ index + 1 }}</span
+          >
+          <el-input
+            v-model="item.name"
+            placeholder="请输入名称"
+            maxlength="25"
+          ></el-input>
+          <i
+            v-if="index !== 0"
+            class="el-icon-close"
+            @click="delMen(index)"
+          ></i>
+        </div>
+        <div class="txt" v-show="item.flag">
+          <div class="txtBox">
+            <span>编号:</span>
+            <el-input
+              v-model="item.txt1"
+              maxlength="25"
+              show-word-limit
+            ></el-input>
+          </div>
+          <div class="txtBox">
+            <span>类型:</span>
+            <el-input
+              v-model="item.txt2"
+              maxlength="25"
+              show-word-limit
+            ></el-input>
+          </div>
+          <div class="txtBox">
+            <span>年代:</span>
+            <el-input
+              v-model="item.txt3"
+              maxlength="25"
+              show-word-limit
+            ></el-input>
+          </div>
+          <div class="txtBox">
+            <span>简介:</span>
+            <el-input
+              type="textarea"
+              v-model="item.txt4"
+              maxlength="1000"
+              show-word-limit
+            ></el-input>
+          </div>
+          <div class="txtBox">
+            <span class="upImgSpan">上传图片:</span>
+
+            <div class="imgBox">
+              <div
+                @click="lookImg(val)"
+                class="imgdiv"
+                v-for="(val, indSon) in item.imgList"
+                :key="val.id"
+              >
+                <img :src="baseURL + val.filePath" alt="" />
+                <!-- 封面显示 -->
+                <div class="cover" v-if="item.imgActive === val.id">封面</div>
+                <!-- 下面的按钮 -->
+                <div
+                  class="handle"
+                  v-else
+                  @click.stop="goodsImgIndex(item, val.id)"
+                >
+                  设为封面
+                </div>
+                <!-- 删除 -->
+                <div
+                  class="delImg el-icon-delete"
+                  @click.stop="delGoodsImg(indSon, item, val.id)"
+                  v-if="item.imgActive !== val.id"
+                ></div>
+              </div>
+              <el-upload
+                v-if="item.imgList.length < 10"
+                accept=".png,.jpg,.jpeg"
+                :action="baseURL + '/cms/content/upload'"
+                :data="{
+                  menuId: menuId,
+                  type: 'img',
+                  villageId: villageId,
+                }"
+                :show-file-list="true"
+                class="avatar-uploader"
+                :headers="{ token }"
+                :before-upload="beforethumbUploadImg"
+                :on-success="
+                  (res) => {
+                    return upload_thumb_successImg(res, item);
+                  }
+                "
+              >
+                <div class="upImg">
+                  <i slot="default" class="el-icon-plus"></i>
+                </div>
+              </el-upload>
+            </div>
+            <p class="upHint">支持格式:jpg, png,最大支持 20M</p>
+          </div>
+        </div>
+      </div>
+    </div>
+    <!-- 底部按钮 -->
+    <div class="btnn">
+      <!-- 增加人物 -->
+      <div class="el-icon-plus" @click="addMen">增加内容</div>
+
+      <el-button @click="$router.push('/layout/tab1')">返 回</el-button>&emsp;
+      <el-button type="primary" @click="save">保 存</el-button>
+    </div>
+    <!-- 照片墙的查看照片 -->
+    <el-dialog :visible.sync="dialogVisible">
+      <img width="100%" :src="dialogImageUrl" alt="" />
+    </el-dialog>
+  </div>
 </template>
 
 <script>
+import axios from '@/utils/request'
+import { saveEntity, contentList, delFileApi } from '@/apis/tab1'
 export default {
   components: {},
   data () {
     return {
+      // 服务器前缀地址
+      token: '',
+      baseURL: '',
 
+      // 村落ID
+      villageId: null,
+      // 菜单ID
+      menuId: null,
+      // 本身自己的id
+      id: null,
+      // 查看图片
+      imgListLook: [],
+      data: [
+        {
+          id: Date.now(),
+          name: '',
+          txt1: '',
+          txt2: '',
+          txt3: '',
+          txt4: '',
+          flag: true,
+          imgActive: 0,
+          imgList: []
+        }
+      ],
+      // 照片墙数据
+      dialogImageUrl: '',
+      dialogVisible: false
     }
   },
   computed: {},
   methods: {
+    // ---------------照片墙
+    beforethumbUploadImg (file) {
+      // console.log(998, file)
+      // 限制图片大小和格式
+      const sizeOk = file.size / 1024 / 1024 < 20
+      const typeOk =
+        file.type === 'image/png' ||
+        (file.type === 'image/jpeg' && !file.name.includes('.jfif'))
+
+      return new Promise((resolve, reject) => {
+        if (!typeOk) {
+          this.$message.error('图片格式有误!')
+          reject(file)
+        } else if (!sizeOk) {
+          this.$message.error('图片大小超过20M!')
+          reject(file)
+        } else {
+          resolve(file)
+        }
+      })
+    },
+    upload_thumb_successImg (data, item) {
+      this.$message.success('上传图片成功')
+      item.imgList.push(data.data)
+      // 如果是第一张上传的图片,把id变成第一张
+      if (item.imgList.length === 1) item.imgActive = data.data.id
+    },
+    // 点击删除图片
+    delGoodsImg (indSon, item, id) {
+      this.$confirm('此操作将永久删除图片', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      })
+        .then(async () => {
+          item.imgList.splice(indSon, 1)
+          this.$message.success('删除成功')
+          await delFileApi(id)
+          const obj = {
+            menuId: this.menuId,
+            villageId: this.villageId,
+            contentJson: JSON.stringify(this.data),
+            id: this.id
+          }
+          await saveEntity(obj)
+        })
+        .catch(() => {})
+    },
+    // 点击设为封面
+    goodsImgIndex (item, id) {
+      item.imgActive = id
+      // this.ruleForm.thumb = this.imgList[index].filePath
+      this.$message.success('操作成功')
+    },
+    // 点击图片看大图
+    lookImg (val) {
+      this.dialogImageUrl = this.baseURL + val.filePath
+      this.dialogVisible = true
+    },
 
+    // 点击删除
+    delMen (index) {
+      this.data.splice(index, 1)
+    },
+    // 点击增加人物
+    addMen () {
+      this.data.push({
+        id: Date.now(),
+        name: '',
+        txt1: '',
+        txt2: '',
+        txt3: '',
+        txt4: '',
+        flag: true,
+        imgActive: 0,
+        imgList: []
+      })
+    },
+    // 点击保存
+    async save () {
+      let tempFlag = false
+      this.data.forEach((v) => {
+        v.flag = true
+        if (
+          v.name.trim() === '' ||
+          v.txt1.trim() === '' ||
+          v.txt2.trim() === '' ||
+          v.txt3.trim() === '' ||
+          v.txt4.trim() === '' ||
+          v.imgList.length <= 0
+        ) {
+          tempFlag = true
+        }
+      })
+      if (tempFlag) return this.$message.warning('信息或图片不能为空')
+
+      const obj = {
+        menuId: this.menuId,
+        villageId: this.villageId,
+        contentJson: JSON.stringify(this.data),
+        id: this.id
+      }
+      const res = await saveEntity(obj)
+      if (res.code === 0) {
+        this.$message.success('操作成功')
+      } else this.$message.warning(res.msg)
+    }
   },
   // 生命周期 - 创建完成(可以访问当前this实例)
-  created () {
-
+  async created () {
+    // 获取服务器前缀地址
+    this.baseURL = axios.defaults.baseURL
+    // 获取用户token
+    this.token = localStorage.getItem('JMYZU_token')
+    this.villageId = Number(this.$route.params.id)
+    this.menuId = Number(this.$route.params.k)
+    const res = await contentList(this.villageId, this.menuId)
+    if (res.data.length > 0) {
+      const temp = res.data[0]
+      this.id = temp.id
+      this.data = JSON.parse(temp.contentJson)
+    }
   },
   // 生命周期 - 挂载完成(可以访问DOM元素)
-  mounted () {
-
-  },
+  mounted () {},
   beforeCreate () {}, // 生命周期 - 创建之前
   beforeMount () {}, // 生命周期 - 挂载之前
   beforeUpdate () {}, // 生命周期 - 更新之前
@@ -33,13 +300,224 @@ export default {
 }
 </script>
 <style lang='less' scoped>
-.four{
+.four {
+  /deep/.avatar-uploader .el-upload-list__item-name {
+    display: none;
+  }
+  /deep/.avatar-uploader
+    .el-upload-list__item.is-success
+    .el-upload-list__item-status-label {
+    display: none;
+  }
+  /deep/.el-upload-list__item .el-progress {
+    width: 500px;
+    position: static;
+    margin-bottom: 15px;
+  }
+  /deep/.el-upload-list__item {
+    width: 500px;
+  }
   width: 100%;
   height: 100%;
-  background-color: blue;
-  display: flex;
-  justify-content: center;
-  align-items: center;
+  position: relative;
+  .main {
+    padding: 30px 20px;
+    height: calc(100% - 120px);
+    overflow-y: auto;
+    .row {
+      margin-bottom: 50px;
+      .top {
+        position: relative;
+        width: 100%;
+        padding: 0 20px;
+        height: 50px;
+        line-height: 50px;
+        background-color: #f2f2f2;
+        .el-icon-close {
+          cursor: pointer;
+          font-weight: 700;
+          font-size: 26px;
+          position: absolute;
+          top: 50%;
+          right: 24px;
+          transform: translateY(-50%);
+        }
+        & > span {
+          cursor: pointer;
+          font-weight: 700;
+          margin-right: 15px;
+        }
+        /deep/.el-input {
+          height: 36px;
+          width: 380px;
+        }
+        /deep/.el-input__inner {
+          color: black;
+          height: 36px;
+          line-height: 36px;
+          background-color: transparent;
+          border: none;
+          border-bottom: 1px solid black;
+          border-radius: 0;
+        }
+        /*修改提示文字的颜色*/
+        /deep/input::-webkit-input-placeholder {
+          /* WebKit browsers */
+          color: #999;
+        }
+        /deep/input:-moz-placeholder {
+          /* Mozilla Firefox 4 to 18 */
+          color: #999;
+        }
+        /deep/input::-moz-placeholder {
+          /* Mozilla Firefox 19+ */
+          color: #999;
+        }
+        /deep/input:-ms-input-placeholder {
+          /* Internet Explorer 10+ */
+          color: #999;
+        }
+      }
+      .txt {
+        width: 90%;
+        margin: 20px auto;
+        .txtBox {
+          margin-bottom: 10px;
+          position: relative;
+          width: 100%;
+          display: flex;
+          & > span {
+            width: 85px;
+            text-align: right;
+            line-height: 40px;
+            &::after {
+              position: absolute;
+              top: 0px;
+              left: 20px;
+              content: "*";
+              color: #f56c6c;
+            }
+          }
+          .upImgSpan {
+            width: 80px;
+            &::after {
+              left: -10px;
+            }
+          }
+          .imgBox {
+            display: flex;
+            flex-wrap: wrap;
+            /deep/.el-icon-plus {
+              font-size: 28px;
+              color: #8c939d;
+              display: flex;
+              align-items: center;
+              justify-content: center;
+              border: 1px dashed #ccc;
+              width: 148px;
+              height: 148px;
+              background-color: #fbfdff;
+              border: 1px dashed #c0ccda;
+              border-radius: 6px;
+            }
+            /deep/.el-icon-plus:hover {
+              border-color: #409eff;
+            }
+            .imgdiv {
+              border-radius: 5px;
+              overflow: hidden;
+              position: relative;
+              margin-right: 30px;
+              margin-bottom: 10px;
+              height: 148px;
+              & > img {
+                width: 148px;
+                height: 148px;
+                object-fit: cover;
+              }
+              .handle {
+                cursor: pointer;
+                color: #fff;
+                font-size: 16px;
+                display: flex;
+                justify-content: center;
+                align-items: center;
+                width: 100%;
+                z-index: 999;
+                position: absolute;
+                bottom: 0;
+                left: 0;
+                height: 30px;
+                background-color: rgba(163, 0, 20, 0.8);
+              }
+              .delImg {
+                cursor: pointer;
+                border-radius: 10px;
+                color: #fff;
+                background-color: #a30014;
+                padding: 3px;
+                font-size: 26px;
+                position: absolute;
+                top: 5px;
+                right: 5px;
+              }
+              .cover {
+                color: #fff;
+                pointer-events: none;
+                font-size: 16px;
+                display: flex;
+                justify-content: center;
+                align-items: center;
+                width: 100%;
+                z-index: 999;
+                position: absolute;
+                bottom: 0;
+                left: 0;
+                height: 30px;
+                background-color: rgba(0, 0, 0, 0.6);
+              }
+            }
+          }
+          .upHint {
+            position: absolute;
+            bottom: -25px;
+            left: 80px;
+            font-size: 12px;
+            color: #606266;
+          }
+        }
+        /deep/.el-textarea .el-input__count {
+          bottom: -20px;
+        }
+      }
+      /deep/.el-textarea__inner {
+        height: 80px;
+      }
+    }
+  }
+  .btnn {
+    border-top: 1px solid #d7d7d7;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    position: absolute;
+    bottom: 0;
+    left: 0;
+    height: 70px;
+    width: 100%;
+    .el-icon-plus {
+      position: absolute;
+      top: -50px;
+      left: 50%;
+      transform: translateX(-50%);
+      font-weight: 700;
+      color: #02aff4;
+      cursor: pointer;
+      width: 100px;
+      text-align: center;
+      line-height: 40px;
+      height: 40px;
+    }
+  }
 }
-
 </style>

+ 61 - 68
houtai/src/views/tab1Main/index.vue

@@ -5,90 +5,70 @@
     <div class="conten">
       <div class="top">编辑资料</div>
       <div class="left">
-        <div class="name">卢边村</div>
-        <div class="row" v-for="(item, index) in data" :key="index">
-          <div class="rowOne el-icon-menu" @click="cutTab(item.id)">
+        <div class="name">{{info.name}}</div>
+        <div
+          class="row"
+          v-for="(item, index) in data"
+          :key="index"
+          :class="{ open: tabInd == item.id }"
+        >
+          <div
+            class="rowOne el-icon-menu"
+            @click="cutTab(item.id)"
+            :class="{ noneClick: tabInd == item.id }"
+          >
             <span class="txt">{{ item.name }}</span>
             <i
               :class="`${
-                tabInd === item.id ? 'el-icon-arrow-up' : 'el-icon-arrow-down'
+                tabInd == item.id ? 'el-icon-arrow-up' : 'el-icon-arrow-down'
               }`"
             ></i>
           </div>
           <div
             class="rowList"
             :class="{
-              open: tabInd === item.id,
               active: $route.params.k == val.id,
             }"
-            @click="
-              $router.push(`/layout/tab1Main/${$route.params.id}/${val.id}`)
-            "
-            v-for="(val, ind) in item.son"
+            @click="cutSon(val.id)"
+            v-for="(val, ind) in item.children"
             :key="ind"
           >
-            {{ val.tit }}
+            {{ val.name }}
           </div>
         </div>
       </div>
       <div class="right">
-        <One v-if="$route.params.k == 1.1" />
-        <Tow v-else-if="$route.params.k == 1.2" />
-        <Three v-else-if="$route.params.k == 1.3" />
-        <Four v-else />
+        <Tow v-if="towCom.includes($route.params.k)" :key="$route.params.k"/>
+        <Three v-else-if="threeCom.includes($route.params.k)" :key="$route.params.k"/>
+        <Four v-else-if="fourCom.includes($route.params.k)" :key="$route.params.k"/>
+        <Five v-else-if="fiveCom.includes($route.params.k)" :key="$route.params.k"/>
+        <One v-else :key="$route.params.k"/>
       </div>
     </div>
   </div>
 </template>
 
 <script>
+import { villageList, getTreeMenu } from '@/apis/tab1'
 import One from './one.vue'
 import Tow from './tow.vue'
 import Three from './three.vue'
 import Four from './four.vue'
+import Five from './five.vue'
 export default {
   name: 'tab1Main',
-  components: { One, Tow, Three, Four },
+  components: { One, Tow, Three, Four, Five },
   data () {
     // 这里存放数据
     return {
-      tabInd: 1,
-      data: [
-        {
-          name: '历史文化',
-          id: 1,
-          son: [
-            { tit: '建村历史', id: 1.1 },
-            { tit: '历史人物', id: 1.2 },
-            { tit: '历史事件', id: 1.3 },
-            { tit: '族谱家训', id: 1.4 },
-            { tit: '口述史', id: 1.5 },
-            { tit: '视频集', id: 1.6 }
-          ]
-        },
-        {
-          name: '环境格局',
-          id: 2,
-          son: [
-            { tit: '村落选址', id: 2.1 },
-            { tit: '村落格局', id: 2.2 },
-            { tit: '建村智慧', id: 2.3 },
-            { tit: '自然环境', id: 2.4 },
-            { tit: '风景名胜', id: 2.5 },
-            { tit: '文物古迹', id: 2.6 },
-            { tit: '历史环境要素', id: 2.7 }
-          ]
-        },
-        {
-          name: '传统建筑',
-          id: 3,
-          son: [
-            { tit: '建筑信息', id: 3.1 },
-            { tit: '村落风貌', id: 3.2 },
-            { tit: '视频集', id: 3.3 }
-          ]
-        }
-      ]
+      tabInd: null,
+      tabSon: null,
+      data: [],
+      info: {},
+      towCom: '1002',
+      threeCom: '1006,3003,4006,5008',
+      fourCom: '2007',
+      fiveCom: '3001'
     }
   },
   // 监听属性 类似于data概念
@@ -97,25 +77,35 @@ export default {
   watch: {},
   // 方法集合
   methods: {
+    cutSon (id) {
+      this.tabSon = id
+      this.$router.push(`/layout/tab1Main/${this.$route.params.id}/${id}`)
+    },
     cutTab (id) {
-      if (this.tabInd === id) {
-        this.tabInd = null
-        return
-      }
       this.tabInd = id
-      let k = Number(this.$route.params.k)
-      k = Math.floor(k)
-      if (this.tabInd !== k) {
-        this.$router.push(`/layout/tab1Main/${this.$route.params.id}/${id}.1`)
-      }
+      const temp = (Number(id) + 1).toString()
+      this.tabSon = temp
+      this.$router.push(`/layout/tab1Main/${this.$route.params.id}/${temp}`)
     }
   },
   // 生命周期 - 创建完成(可以访问当前this实例)
-  created () {},
+  async created () {
+    const res = await getTreeMenu()
+    this.data = res.data
+    const res2 = await villageList()
+    res2.data.forEach((v) => {
+      if (v.id === Number(this.$route.params.id)) this.info = v
+    })
+  },
   // 生命周期 - 挂载完成(可以访问DOM元素)
   mounted () {
-    const k = Number(this.$route.params.k)
-    this.tabInd = Math.floor(k)
+    let k = this.$route.params.k
+    this.tabSon = k
+    const length = k.length
+    const arr = k.split('')
+    arr[length - 1] = '0'
+    k = arr.join('')
+    this.tabInd = k
   },
   beforeCreate () {}, // 生命周期 - 创建之前
   beforeMount () {}, // 生命周期 - 挂载之前
@@ -167,6 +157,9 @@ export default {
             margin-left: 10px;
           }
         }
+        .noneClick {
+          pointer-events: none;
+        }
         .rowList {
           cursor: pointer;
           padding-left: 18px;
@@ -177,15 +170,15 @@ export default {
             color: #a30014;
           }
         }
-        .open {
-          margin-top: 10px;
-          height: auto;
-        }
         .active {
           pointer-events: none;
           color: #a30014;
         }
       }
+      .open .rowList {
+        margin-top: 10px;
+        height: auto;
+      }
     }
     .right {
       width: calc(100% - 140px);

+ 293 - 13
houtai/src/views/tab1Main/one.vue

@@ -1,28 +1,296 @@
 <!--  -->
 <template>
-<div class='one'>one</div>
+  <div class="one">
+    <div class="from">
+      <el-form
+        :model="ruleForm"
+        :rules="rules"
+        ref="ruleForm"
+        label-width="100px"
+        class="demo-ruleForm"
+      >
+        <!-- 文本域 -->
+        <el-form-item :label="txtobj[menuId]" prop="name">
+          <el-input
+            placeholder="请输入内容"
+            type="textarea"
+            v-model="ruleForm.name"
+            maxlength="1000"
+            show-word-limit
+          ></el-input>
+        </el-form-item>
+        <!-- 照片墙 -->
+        <el-form-item label="上传图片:">
+          <el-upload
+            accept=".png,.jpg,.jpeg"
+            :action="baseURL + '/cms/content/upload'"
+            :data="{
+              menuId: menuId,
+              type: 'img',
+              villageId:villageId,
+            }"
+            :file-list="imgUpList"
+            :headers="{ token }"
+            :limit="10"
+            :on-exceed="handleExceed"
+            list-type="picture-card"
+            :on-preview="handlePictureCardPreview"
+            :on-remove="handleRemove"
+            :before-remove="beforeRemove"
+            :before-upload="beforethumbUploadImg"
+            :on-success="upload_thumb_successImg"
+          >
+            <i class="el-icon-plus"></i>
+            <div slot="tip" class="el-upload__tip">
+              支持格式:jpg, png,最大支持 20M
+            </div>
+          </el-upload>
+        </el-form-item>
+        <!-- 上传视频 -->
+        <el-form-item label="上传视频:">
+          <el-upload
+            accept=".mp4"
+            multiple
+            drag
+            class="upload-demo"
+            :data="{
+              menuId: this.menuId,
+              type: 'video',
+              villageId: this.villageId,
+            }"
+            :file-list="fileList"
+            :action="baseURL + '/cms/content/upload'"
+            :headers="{ token }"
+            :before-upload="beforeFujian"
+            :on-success="successFujian"
+            :before-remove="beforeRemoveFujian"
+            :on-remove="handleRemoveFujian"
+            :limit="5"
+            :on-exceed="handleExceedFujian"
+            :show-file-list="true"
+          >
+            <i class="el-icon-upload"></i>
+            <div class="el-upload__text">
+              将文件拖到此处,或<em>点击上传</em>
+            </div>
+            <div class="el-upload__text smEl">
+              仅支持mp4格式的视频文件,大小不得超过500MB
+            </div>
+          </el-upload>
+        </el-form-item>
+      </el-form>
+    </div>
+    <!-- 底部按钮 -->
+    <div class="btnn">
+      <el-button @click="$router.push('/layout/tab1')">返 回</el-button>&emsp;
+      <el-button type="primary" @click="save">保 存</el-button>
+    </div>
+    <!-- 照片墙的查看照片 -->
+    <el-dialog :visible.sync="dialogVisible">
+      <img width="100%" :src="dialogImageUrl" alt="" />
+    </el-dialog>
+  </div>
 </template>
 
 <script>
+import axios from '@/utils/request'
+import { delFileApi, saveEntity, contentList } from '@/apis/tab1'
 export default {
+  name: 'mainOne',
   components: {},
   data () {
     return {
-
+      txtobj: {
+        1001: '建村文化:',
+        1003: '历史事件:',
+        1004: '族谱家训:',
+        1005: '口述史:',
+        2001: '村落选址:',
+        2002: '村落格局:',
+        2003: '建村智慧:',
+        2004: '自然环境:',
+        2005: '风景名胜:',
+        2006: '文物古迹:',
+        3002: '村落风貌:',
+        4001: '节日活动:',
+        4002: '祭祀崇礼:',
+        4003: '婚丧嫁娶:',
+        4004: '地方方言:',
+        4005: '特色文化:',
+        5001: '特色物产:',
+        5002: '商业集市:',
+        5003: '生产工艺:',
+        5004: '服装服饰:',
+        5005: '美味美食:',
+        5006: '运输工具:',
+        5007: '村规民约:',
+        6001: '入村路线:',
+        6002: '村内导览:'
+      },
+      // 服务器前缀地址
+      token: '',
+      baseURL: '',
+      // 村落ID
+      villageId: null,
+      // 菜单ID
+      menuId: null,
+      ruleForm: {
+        name: '',
+        id: null
+      },
+      rules: {
+        name: [{ required: true, message: '不能为空', trigger: 'blur' }]
+      },
+      // 照片墙数据
+      dialogImageUrl: '',
+      dialogVisible: false,
+      imgIdArr: [],
+      imgUpList: [],
+      // 上传视频数据
+      fileList: [],
+      videoIdArr: []
     }
   },
   computed: {},
   methods: {
+    // 点击保存
+    async save () {
+      if (this.ruleForm.name.trim() === '') return this.$message.warning('文字信息不能为空')
+      const obj = {
+        menuId: this.menuId,
+        villageId: this.villageId,
+        content: this.ruleForm.name,
+        id: this.ruleForm.id,
+        imgIds: this.imgIdArr.join(','),
+        videoIds: this.videoIdArr.join(',')
+      }
+      const res = await saveEntity(obj)
+      if (res.code === 0) {
+        this.$message.success('保存成功')
+      } else this.$message.warning(res.msg)
+    },
+    // ---------------照片墙
+    beforeRemove (file, fileList) {
+      if (file && file.status === 'success') {
+        return this.$confirm(`此操作将永久删除 ${file.name}`)
+      }
+    },
+    async handleRemove (file, fileList) {
+      const id = file.id || file.response.data.id
+      const res = await delFileApi(id)
+      if (res.code === 0) {
+        this.$message.success('删除成功')
+        this.imgIdArr = this.imgIdArr.filter((v) => v !== id)
+      } else this.$message.warning(res.msg)
+    },
+    handlePictureCardPreview (file) {
+      this.dialogImageUrl = file.url
+      this.dialogVisible = true
+    },
+    beforethumbUploadImg (file) {
+      // console.log(998, file)
+      // 限制图片大小和格式
+      const sizeOk = file.size / 1024 / 1024 < 20
+      const typeOk =
+        file.type === 'image/png' ||
+        (file.type === 'image/jpeg' && !file.name.includes('.jfif'))
+
+      return new Promise((resolve, reject) => {
+        if (!typeOk) {
+          this.$message.error('图片格式有误!')
+          reject(file)
+        } else if (!sizeOk) {
+          this.$message.error('图片大小超过20M!')
+          reject(file)
+        } else {
+          resolve(file)
+        }
+      })
+    },
+    upload_thumb_successImg (data) {
+      this.$message.success('上传图片成功')
+      this.imgIdArr.push(data.data.id)
+    },
+    handleExceed (files, fileList) {
+      this.$message.warning('最多上传10张图片')
+    },
 
+    // -------------------上传视频
+    beforeFujian (file) {
+      console.log('附件上传前', file)
+      const sizeOk = file.size / 1024 / 1024 < 500
+      const typeOk = file.type === 'video/mp4'
+      return new Promise((resolve, reject) => {
+        if (!sizeOk) {
+          this.$message.error('视频大小超过500M!')
+          reject(file)
+        } else if (!typeOk) {
+          this.$message.error('视频格式有误!')
+          reject(file)
+        } else {
+          resolve(file)
+        }
+      })
+    },
+    successFujian (file) {
+      console.log('上传视频成功', file)
+      if (file.code === 0) {
+        this.$message.success('上传成功')
+        this.videoIdArr.push(file.data.id)
+      } else if (file.code === -1) {
+        this.$message.warning('上传失败,不支持的文件格式')
+      }
+    },
+    beforeRemoveFujian (file, fileList) {
+      if (file && file.status === 'success') {
+        return this.$confirm(`此操作将永久删除 ${file.name}`)
+      }
+    },
+    async handleRemoveFujian (file, fileList) {
+      const id = file.id || file.response.data.id
+      const res = await delFileApi(id)
+      if (res.code === 0) {
+        this.$message.success('删除成功')
+        this.videoIdArr = this.videoIdArr.filter((v) => v !== id)
+      } else this.$message.warning(res.msg)
+    },
+    handleExceedFujian (files, fileList) {
+      this.$message.warning('最多上传5个视频')
+    }
   },
   // 生命周期 - 创建完成(可以访问当前this实例)
-  created () {
-
+  async created () {
+    this.villageId = Number(this.$route.params.id)
+    this.menuId = Number(this.$route.params.k)
+    // 获取服务器前缀地址
+    this.baseURL = axios.defaults.baseURL
+    // 获取用户token
+    this.token = localStorage.getItem('JMYZU_token')
+    const res = await contentList(this.villageId, this.menuId)
+    if (res.data.length > 0) {
+      const temp = res.data[0]
+      this.ruleForm.name = temp.content
+      this.ruleForm.id = temp.id
+      // 附件回显
+      this.fileList = temp.videos || []
+      // 图片回显
+      if (temp.images) {
+        temp.images.forEach(v => {
+          v.url = this.baseURL + v.filePath
+        })
+      }
+      this.imgUpList = temp.images || []
+      // id存储
+      this.fileList.forEach(v => {
+        this.videoIdArr.push(v.id)
+      })
+      this.imgUpList.forEach(v => {
+        this.imgIdArr.push(v.id)
+      })
+    }
   },
   // 生命周期 - 挂载完成(可以访问DOM元素)
-  mounted () {
-
-  },
+  mounted () {},
   beforeCreate () {}, // 生命周期 - 创建之前
   beforeMount () {}, // 生命周期 - 挂载之前
   beforeUpdate () {}, // 生命周期 - 更新之前
@@ -33,13 +301,25 @@ export default {
 }
 </script>
 <style lang='less' scoped>
-.one{
+.one {
   width: 100%;
   height: 100%;
-  background-color: aliceblue;
-  display: flex;
-  justify-content: center;
-  align-items: center;
+  position: relative;
+  .from {
+    padding: 30px 20px;
+    height: calc(100% - 70px);
+    overflow-y: auto;
+  }
+  .btnn {
+    border-top: 1px solid #d7d7d7;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    position: absolute;
+    bottom: 0;
+    left: 0;
+    height: 70px;
+    width: 100%;
+  }
 }
-
 </style>

+ 150 - 14
houtai/src/views/tab1Main/three.vue

@@ -1,28 +1,151 @@
 <!--  -->
 <template>
-<div class='three'>three</div>
+  <div class="three">
+    <div class="from">
+      <!-- 上传视频 -->
+      <el-form label-width="100px" class="demo-ruleForm">
+        <el-form-item label="上传视频:">
+          <el-upload
+            accept=".mp4"
+            multiple
+            drag
+            class="upload-demo"
+            :data="{
+              menuId: this.menuId,
+              type: 'video',
+              villageId: this.villageId,
+            }"
+            :file-list="fileList"
+            :action="baseURL + '/cms/content/upload'"
+            :headers="{ token }"
+            :before-upload="beforeFujian"
+            :on-success="successFujian"
+            :before-remove="beforeRemoveFujian"
+            :on-remove="handleRemoveFujian"
+            :limit="5"
+            :on-exceed="handleExceedFujian"
+            :show-file-list="true"
+          >
+            <i class="el-icon-upload"></i>
+            <div class="el-upload__text">
+              将文件拖到此处,或<em>点击上传</em>
+            </div>
+            <div class="el-upload__text smEl">
+              仅支持mp4格式的视频文件,大小不得超过500MB
+            </div>
+          </el-upload>
+        </el-form-item>
+      </el-form>
+    </div>
+    <!-- 底部按钮 -->
+    <div class="btnn">
+      <el-button @click="$router.push('/layout/tab1')">返 回</el-button>&emsp;
+      <el-button type="primary" @click="save">保 存</el-button>
+    </div>
+  </div>
 </template>
 
 <script>
+import axios from '@/utils/request'
+import { delFileApi, saveEntity, contentList } from '@/apis/tab1'
 export default {
   components: {},
   data () {
     return {
-
+      // 服务器前缀地址
+      token: '',
+      baseURL: '',
+      // 村落ID
+      villageId: null,
+      // 菜单ID
+      menuId: null,
+      // 本身的id
+      id: null,
+      // 上传视频数据
+      fileList: [],
+      videoIdArr: []
     }
   },
   computed: {},
   methods: {
-
+    // 点击保存
+    async save () {
+      const obj = {
+        menuId: this.menuId,
+        villageId: this.villageId,
+        id: this.id,
+        videoIds: this.videoIdArr.join(',')
+      }
+      const res = await saveEntity(obj)
+      if (res.code === 0) {
+        this.$message.success('保存成功')
+      } else this.$message.warning(res.msg)
+    },
+    // -------------------上传视频
+    beforeFujian (file) {
+      console.log('附件上传前', file)
+      const sizeOk = file.size / 1024 / 1024 < 500
+      const typeOk = file.type === 'video/mp4'
+      return new Promise((resolve, reject) => {
+        if (!sizeOk) {
+          this.$message.error('视频大小超过500M!')
+          reject(file)
+        } else if (!typeOk) {
+          this.$message.error('视频格式有误!')
+          reject(file)
+        } else {
+          resolve(file)
+        }
+      })
+    },
+    successFujian (file) {
+      console.log('上传视频成功', file)
+      if (file.code === 0) {
+        this.$message.success('上传成功')
+        this.videoIdArr.push(file.data.id)
+      } else if (file.code === -1) {
+        this.$message.warning('上传失败,不支持的文件格式')
+      }
+    },
+    beforeRemoveFujian (file, fileList) {
+      if (file && file.status === 'success') {
+        return this.$confirm(`此操作将永久删除 ${file.name}`)
+      }
+    },
+    async handleRemoveFujian (file, fileList) {
+      const id = file.id || file.response.data.id
+      const res = await delFileApi(id)
+      if (res.code === 0) {
+        this.$message.success('删除成功')
+        this.videoIdArr = this.videoIdArr.filter((v) => v !== id)
+      } else this.$message.warning(res.msg)
+    },
+    handleExceedFujian (files, fileList) {
+      this.$message.warning('最多上传5个视频')
+    }
   },
   // 生命周期 - 创建完成(可以访问当前this实例)
-  created () {
-
+  async created () {
+    this.villageId = Number(this.$route.params.id)
+    this.menuId = Number(this.$route.params.k)
+    // 获取服务器前缀地址
+    this.baseURL = axios.defaults.baseURL
+    // 获取用户token
+    this.token = localStorage.getItem('JMYZU_token')
+    const res = await contentList(this.villageId, this.menuId)
+    if (res.data.length > 0) {
+      const temp = res.data[0]
+      this.id = temp.id
+      // 附件回显
+      this.fileList = temp.videos || []
+      // id存储
+      this.fileList.forEach((v) => {
+        this.videoIdArr.push(v.id)
+      })
+    }
   },
   // 生命周期 - 挂载完成(可以访问DOM元素)
-  mounted () {
-
-  },
+  mounted () {},
   beforeCreate () {}, // 生命周期 - 创建之前
   beforeMount () {}, // 生命周期 - 挂载之前
   beforeUpdate () {}, // 生命周期 - 更新之前
@@ -33,13 +156,26 @@ export default {
 }
 </script>
 <style lang='less' scoped>
-.three{
+.three {
   width: 100%;
   height: 100%;
-  background-color: red;
-  display: flex;
-  justify-content: center;
-  align-items: center;
-}
+  position: relative;
+  .from {
+    padding: 30px 20px;
+    height: calc(100% - 70px);
+    overflow-y: auto;
+  }
 
+  .btnn {
+    border-top: 1px solid #d7d7d7;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    position: absolute;
+    bottom: 0;
+    left: 0;
+    height: 70px;
+    width: 100%;
+  }
+}
 </style>

+ 190 - 13
houtai/src/views/tab1Main/tow.vue

@@ -1,28 +1,106 @@
 <!--  -->
 <template>
-<div class='tow'>tow</div>
+  <div class="tow">
+    <div class="main">
+      <div class="row" v-for="(item, index) in data" :key="item.id">
+        <div class="top">
+          <span
+            @click="data[index].flag = !data[index].flag"
+            :class="`${item.flag ? 'el-icon-arrow-up' : 'el-icon-arrow-down'}`"
+            >&emsp;{{ index + 1 }}</span
+          >
+          <el-input
+            v-model="item.name"
+            placeholder="请输入人物名称"
+            maxlength="8"
+          ></el-input>
+          <i
+            v-if="index !== 0"
+            class="el-icon-close"
+            @click="delMen(index)"
+          ></i>
+        </div>
+        <div class="txt" v-show="item.flag">
+          <span>人物介绍:</span>
+          <el-input
+            type="textarea"
+            v-model="item.txt"
+            maxlength="1000"
+            show-word-limit
+          ></el-input>
+        </div>
+      </div>
+    </div>
+    <!-- 底部按钮 -->
+    <div class="btnn">
+      <!-- 增加人物 -->
+      <div class="el-icon-plus" @click="addMen">增加人物</div>
+
+      <el-button @click="$router.push('/layout/tab1')">返 回</el-button>&emsp;
+      <el-button type="primary" @click="save">保 存</el-button>
+    </div>
+  </div>
 </template>
 
 <script>
+import { saveEntity, contentList } from '@/apis/tab1'
 export default {
   components: {},
   data () {
     return {
-
+      // 村落ID
+      villageId: null,
+      // 菜单ID
+      menuId: null,
+      // 本身自己的id
+      id: null,
+      data: [{ id: Date.now(), name: '', txt: '', flag: true }]
     }
   },
   computed: {},
   methods: {
+    // 点击删除
+    delMen (index) {
+      this.data.splice(index, 1)
+    },
+    // 点击增加人物
+    addMen () {
+      this.data.push({ id: Date.now(), name: '', txt: '', flag: true })
+    },
+    // 点击保存
+    async save () {
+      let tempFlag = false
+      this.data.forEach((v) => {
+        v.flag = true
+        if (v.name.trim() === '' || v.txt.trim() === '') tempFlag = true
+      })
+      if (tempFlag) return this.$message.warning('名称或介绍不能为空')
 
+      const obj = {
+        menuId: this.menuId,
+        villageId: this.villageId,
+        contentJson: JSON.stringify(this.data),
+        id: this.id
+      }
+      const res = await saveEntity(obj)
+      if (res.code === 0) {
+        this.$message.success('操作成功')
+      } else this.$message.warning(res.msg)
+    }
   },
   // 生命周期 - 创建完成(可以访问当前this实例)
-  created () {
-
+  async created () {
+    this.villageId = Number(this.$route.params.id)
+    this.menuId = Number(this.$route.params.k)
+    const res = await contentList(this.villageId, this.menuId)
+    if (res.data.length > 0) {
+      const temp = res.data[0]
+      this.id = temp.id
+      this.data = JSON.parse(temp.contentJson)
+    }
   },
   // 生命周期 - 挂载完成(可以访问DOM元素)
-  mounted () {
-
-  },
+  mounted () {},
   beforeCreate () {}, // 生命周期 - 创建之前
   beforeMount () {}, // 生命周期 - 挂载之前
   beforeUpdate () {}, // 生命周期 - 更新之前
@@ -33,13 +111,112 @@ export default {
 }
 </script>
 <style lang='less' scoped>
-.tow{
+.tow {
   width: 100%;
   height: 100%;
-  background-color: orange;
-  display: flex;
-  justify-content: center;
-  align-items: center;
+  position: relative;
+  .main {
+    padding: 30px 20px;
+    height: calc(100% - 120px);
+    overflow-y: auto;
+    .row {
+      margin-bottom: 50px;
+      .top {
+        position: relative;
+        width: 100%;
+        padding: 0 20px;
+        height: 50px;
+        line-height: 50px;
+        background-color: #f2f2f2;
+        .el-icon-close {
+          cursor: pointer;
+          font-weight: 700;
+          font-size: 26px;
+          position: absolute;
+          top: 50%;
+          right: 24px;
+          transform: translateY(-50%);
+        }
+        & > span {
+          cursor: pointer;
+          font-weight: 700;
+          margin-right: 15px;
+        }
+        /deep/.el-input {
+          height: 36px;
+          width: 145px;
+        }
+        /deep/.el-input__inner {
+          color: black;
+          height: 36px;
+          line-height: 36px;
+          background-color: transparent;
+          border: none;
+          border-bottom: 1px solid black;
+          border-radius: 0;
+        }
+        /*修改提示文字的颜色*/
+        /deep/input::-webkit-input-placeholder {
+          /* WebKit browsers */
+          color: #999;
+        }
+        /deep/input:-moz-placeholder {
+          /* Mozilla Firefox 4 to 18 */
+          color: #999;
+        }
+        /deep/input::-moz-placeholder {
+          /* Mozilla Firefox 19+ */
+          color: #999;
+        }
+        /deep/input:-ms-input-placeholder {
+          /* Internet Explorer 10+ */
+          color: #999;
+        }
+      }
+      .txt {
+        position: relative;
+        width: 90%;
+        margin: 20px auto;
+        display: flex;
+        & > span {
+          width: 100px;
+        }
+        &::after {
+          position: absolute;
+          top: 0px;
+          left: -10px;
+          content: "*";
+          color: #f56c6c;
+        }
+      }
+      /deep/.el-textarea__inner {
+        height: 100px;
+      }
+    }
+  }
+  .btnn {
+    border-top: 1px solid #d7d7d7;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    position: absolute;
+    bottom: 0;
+    left: 0;
+    height: 70px;
+    width: 100%;
+    .el-icon-plus {
+      position: absolute;
+      top: -50px;
+      left: 50%;
+      transform: translateX(-50%);
+      font-weight: 700;
+      color: #02aff4;
+      cursor: pointer;
+      width: 100px;
+      text-align: center;
+      line-height: 40px;
+      height: 40px;
+    }
+  }
 }
-
 </style>