shaogen1995 2 年 前
コミット
5588855ddc

+ 97 - 0
houtai/package-lock.json

@@ -11,11 +11,14 @@
         "axios": "^0.24.0",
         "Base64": "^1.1.0",
         "core-js": "^3.6.5",
+        "dayjs": "^1.11.5",
+        "echarts": "^5.4.0",
         "element-ui": "^2.15.6",
         "js-base64": "^3.7.2",
         "moment": "^2.29.1",
         "vant": "^2.12.45",
         "vue": "^2.6.11",
+        "vue-json-excel": "^0.3.0",
         "vue-router": "^3.2.0",
         "wangeditor": "^4.7.11"
       },
@@ -5478,6 +5481,11 @@
       "integrity": "sha1-LnG/CxGRU9u0zE6I2epaz7UNwFw=",
       "dev": true
     },
+    "node_modules/dayjs": {
+      "version": "1.11.5",
+      "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.5.tgz",
+      "integrity": "sha512-CAdX5Q3YW3Gclyo5Vpqkgpj8fSdLQcRuzfX6mC6Phy0nfJ0eGYOeS7m4mt2plDWLAtA4TqTakvbboHvUxfe4iA=="
+    },
     "node_modules/de-indent": {
       "version": "1.0.2",
       "resolved": "https://registry.npm.taobao.org/de-indent/download/de-indent-1.0.2.tgz",
@@ -6025,6 +6033,11 @@
       "integrity": "sha1-P7rwIL/XlIhAcuomsel5HUWmKfA=",
       "dev": true
     },
+    "node_modules/downloadjs": {
+      "version": "1.4.7",
+      "resolved": "https://registry.npmmirror.com/downloadjs/-/downloadjs-1.4.7.tgz",
+      "integrity": "sha512-LN1gO7+u9xjU5oEScGFKvXhYf7Y/empUIIEAGBs1LzUq/rg5duiDrkuH5A2lQGd5jfMOb9X9usDa2oVXwJ0U/Q=="
+    },
     "node_modules/duplexer": {
       "version": "0.1.2",
       "resolved": "https://registry.npm.taobao.org/duplexer/download/duplexer-0.1.2.tgz",
@@ -6062,6 +6075,20 @@
         "safer-buffer": "^2.1.0"
       }
     },
+    "node_modules/echarts": {
+      "version": "5.4.0",
+      "resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.4.0.tgz",
+      "integrity": "sha512-uPsO9VRUIKAdFOoH3B0aNg7NRVdN7aM39/OjovjO9MwmWsAkfGyeXJhK+dbRi51iDrQWliXV60/XwLA7kg3z0w==",
+      "dependencies": {
+        "tslib": "2.3.0",
+        "zrender": "5.4.0"
+      }
+    },
+    "node_modules/echarts/node_modules/tslib": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz",
+      "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
+    },
     "node_modules/ee-first": {
       "version": "1.1.1",
       "resolved": "https://registry.npm.taobao.org/ee-first/download/ee-first-1.1.1.tgz",
@@ -15295,6 +15322,14 @@
       "integrity": "sha1-UylVzB6yCKPZkLOp+acFdGV+CPI=",
       "dev": true
     },
+    "node_modules/vue-json-excel": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmmirror.com/vue-json-excel/-/vue-json-excel-0.3.0.tgz",
+      "integrity": "sha512-FrSh0tVUpw4K+ilLO8g0Qp52eFJw/hkk3rZPTEKo9qVkJgVfQtZwzj3UWc5ACYxA3jLk9HtjK+f9xKHCN4Kgag==",
+      "dependencies": {
+        "downloadjs": "^1.4.7"
+      }
+    },
     "node_modules/vue-lazyload": {
       "version": "1.2.3",
       "resolved": "https://registry.npmmirror.com/vue-lazyload/-/vue-lazyload-1.2.3.tgz",
@@ -16459,6 +16494,19 @@
       "resolved": "https://registry.npm.taobao.org/yallist/download/yallist-2.1.2.tgz",
       "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
       "dev": true
+    },
+    "node_modules/zrender": {
+      "version": "5.4.0",
+      "resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.4.0.tgz",
+      "integrity": "sha512-rOS09Z2HSVGFs2dn/TuYk5BlCaZcVe8UDLLjj1ySYF828LATKKdxuakSZMvrDz54yiKPDYVfjdKqcX8Jky3BIA==",
+      "dependencies": {
+        "tslib": "2.3.0"
+      }
+    },
+    "node_modules/zrender/node_modules/tslib": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz",
+      "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
     }
   },
   "dependencies": {
@@ -20814,6 +20862,11 @@
       "integrity": "sha1-LnG/CxGRU9u0zE6I2epaz7UNwFw=",
       "dev": true
     },
+    "dayjs": {
+      "version": "1.11.5",
+      "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.5.tgz",
+      "integrity": "sha512-CAdX5Q3YW3Gclyo5Vpqkgpj8fSdLQcRuzfX6mC6Phy0nfJ0eGYOeS7m4mt2plDWLAtA4TqTakvbboHvUxfe4iA=="
+    },
     "de-indent": {
       "version": "1.0.2",
       "resolved": "https://registry.npm.taobao.org/de-indent/download/de-indent-1.0.2.tgz",
@@ -21267,6 +21320,11 @@
       "integrity": "sha1-P7rwIL/XlIhAcuomsel5HUWmKfA=",
       "dev": true
     },
+    "downloadjs": {
+      "version": "1.4.7",
+      "resolved": "https://registry.npmmirror.com/downloadjs/-/downloadjs-1.4.7.tgz",
+      "integrity": "sha512-LN1gO7+u9xjU5oEScGFKvXhYf7Y/empUIIEAGBs1LzUq/rg5duiDrkuH5A2lQGd5jfMOb9X9usDa2oVXwJ0U/Q=="
+    },
     "duplexer": {
       "version": "0.1.2",
       "resolved": "https://registry.npm.taobao.org/duplexer/download/duplexer-0.1.2.tgz",
@@ -21301,6 +21359,22 @@
         "safer-buffer": "^2.1.0"
       }
     },
+    "echarts": {
+      "version": "5.4.0",
+      "resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.4.0.tgz",
+      "integrity": "sha512-uPsO9VRUIKAdFOoH3B0aNg7NRVdN7aM39/OjovjO9MwmWsAkfGyeXJhK+dbRi51iDrQWliXV60/XwLA7kg3z0w==",
+      "requires": {
+        "tslib": "2.3.0",
+        "zrender": "5.4.0"
+      },
+      "dependencies": {
+        "tslib": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz",
+          "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
+        }
+      }
+    },
     "ee-first": {
       "version": "1.1.1",
       "resolved": "https://registry.npm.taobao.org/ee-first/download/ee-first-1.1.1.tgz",
@@ -28942,6 +29016,14 @@
       "integrity": "sha1-UylVzB6yCKPZkLOp+acFdGV+CPI=",
       "dev": true
     },
+    "vue-json-excel": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmmirror.com/vue-json-excel/-/vue-json-excel-0.3.0.tgz",
+      "integrity": "sha512-FrSh0tVUpw4K+ilLO8g0Qp52eFJw/hkk3rZPTEKo9qVkJgVfQtZwzj3UWc5ACYxA3jLk9HtjK+f9xKHCN4Kgag==",
+      "requires": {
+        "downloadjs": "^1.4.7"
+      }
+    },
     "vue-lazyload": {
       "version": "1.2.3",
       "resolved": "https://registry.npmmirror.com/vue-lazyload/-/vue-lazyload-1.2.3.tgz",
@@ -29911,6 +29993,21 @@
           "dev": true
         }
       }
+    },
+    "zrender": {
+      "version": "5.4.0",
+      "resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.4.0.tgz",
+      "integrity": "sha512-rOS09Z2HSVGFs2dn/TuYk5BlCaZcVe8UDLLjj1ySYF828LATKKdxuakSZMvrDz54yiKPDYVfjdKqcX8Jky3BIA==",
+      "requires": {
+        "tslib": "2.3.0"
+      },
+      "dependencies": {
+        "tslib": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz",
+          "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
+        }
+      }
     }
   }
 }

+ 3 - 0
houtai/package.json

@@ -11,11 +11,14 @@
     "axios": "^0.24.0",
     "Base64": "^1.1.0",
     "core-js": "^3.6.5",
+    "dayjs": "^1.11.5",
+    "echarts": "^5.4.0",
     "element-ui": "^2.15.6",
     "js-base64": "^3.7.2",
     "moment": "^2.29.1",
     "vant": "^2.12.45",
     "vue": "^2.6.11",
+    "vue-json-excel": "^0.3.0",
     "vue-router": "^3.2.0",
     "wangeditor": "^4.7.11"
   },

+ 17 - 0
houtai/src/apis/tab2.js

@@ -43,3 +43,20 @@ export const logList = (data) => {
     data
   })
 }
+
+// ------------------------------操作日志列表
+export const dictGetTree = (data) => {
+  return axios({
+    method: 'post',
+    url: '/api/cms/dict/getTree',
+    data
+  })
+}
+
+// ------------------------------统计
+export const goodsReport = (data) => {
+  return axios({
+    url: '/api/cms/goods/report',
+    data
+  })
+}

+ 1 - 1
houtai/src/assets/css/base.css

@@ -76,7 +76,7 @@ input[type="number"] {
   width: 100px;
   height: 80px;
   object-fit: cover;
-  border: 3px solid #ccc;
+  border: 1px solid #ccc;
 }
 .table_name{
   cursor: pointer;

+ 3 - 0
houtai/src/main.js

@@ -3,7 +3,10 @@ import ElementUI from 'element-ui'
 import 'element-ui/lib/theme-chalk/index.css'
 import App from './App.vue'
 import router from './router'
+// 表格导出
+import JsonExcel from 'vue-json-excel'
 import './assets/css/base.css'
+Vue.component('downloadExcel', JsonExcel)
 
 Vue.config.productionTip = false
 const imgErr = {

+ 7 - 0
houtai/src/router/index.js

@@ -31,7 +31,14 @@ const routes = [
         name: 'tab3',
         meta: { myInd: 3 },
         component: () => import('../views/tab3/index.vue')
+      },
+      {
+        path: 'tab1',
+        name: 'tab1',
+        meta: { myInd: 1 },
+        component: () => import('../views/tab1/index.vue')
       }
+
     ]
   }
 ]

+ 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:8017', // 本地调试
-  // baseURL: 'http://project.4dage.com:8032', // 线上调试
-  baseURL: '', // build
+  baseURL: 'http://192.168.20.55:8032', // 本地调试
+  // baseURL: 'https://hnbwg.4dage.com', // 线上调试
+  // baseURL: '', // build
   timeout: 5000
 })
 // 请求拦截器

+ 36 - 11
houtai/src/views/layout/index.vue

@@ -2,9 +2,9 @@
   <div class="layout">
     <div class="top">
       <p>河南博物院文物展示平台后台</p>
-      <div class="top_right" @mouseenter='cut=true' @mouseleave='cut=false'>
+      <div class="top_right" @mouseenter="cut = true" @mouseleave="cut = false">
         <div class="user">
-          <span>{{userName}}</span>
+          <span>{{ userName }}</span>
           <!-- 下箭头 -->
           <div class="pull_down" v-if="cut"></div>
           <div class="pull_up" v-else></div>
@@ -18,7 +18,12 @@
     </div>
     <div class="con">
       <div class="left">
-        <div class="biaoji el-icon-message" :class="{biaojiAc: $route.meta.myInd<=2}">内容管理</div>
+        <div
+          class="biaoji el-icon-message"
+          :class="{ biaojiAc: $route.meta.myInd === 2 }"
+        >
+          内容管理
+        </div>
         <ul>
           <li
             v-for="item in tab1"
@@ -29,7 +34,30 @@
             {{ item.name }}
           </li>
         </ul>
-        <div class="biaoji el-icon-setting" :class="{biaojiAc: $route.meta.myInd>2}">系统管理</div>
+
+        <div
+          class="biaoji el-icon-s-data"
+          :class="{ biaojiAc: $route.meta.myInd === 1 }"
+        >
+          统计管理
+        </div>
+        <ul>
+          <li
+            v-for="item in tab3"
+            :key="item.id"
+            :class="{ active: $route.meta.myInd === item.id }"
+            @click="push(item.url)"
+          >
+            {{ item.name }}
+          </li>
+        </ul>
+
+        <div
+          class="biaoji el-icon-setting"
+          :class="{ biaojiAc: $route.meta.myInd === 3 }"
+        >
+          系统管理
+        </div>
         <ul>
           <li
             v-for="item in tab2"
@@ -113,12 +141,9 @@ export default {
       userName: '',
       cut: false,
       isShow: false,
-      tab1: [
-        { name: '典藏管理', id: 2, url: '/layout/tab2' }
-      ],
-      tab2: [
-        { name: '操作日志', id: 3, url: '/layout/tab3' }
-      ]
+      tab1: [{ name: '典藏管理', id: 2, url: '/layout/tab2' }],
+      tab2: [{ name: '操作日志', id: 3, url: '/layout/tab3' }],
+      tab3: [{ name: '文物统计', id: 1, url: '/layout/tab1' }]
     }
   },
   // 监听属性 类似于data概念
@@ -306,7 +331,7 @@ export default {
       padding-left: 20px;
       padding-right: 30px;
     }
-    .biaojiAc{
+    .biaojiAc {
       background-color: #3a80d2;
       color: #fff;
     }

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

@@ -6,7 +6,7 @@
         <p>河南博物院</p>
         <p>文物展示平台后台</p>
       </div>
-      <div class="right">
+      <div class="right" @keyup.enter="login">
         <p>欢迎登录</p>
         <div class="input">
           <el-form

+ 178 - 0
houtai/src/views/tab1/index.vue

@@ -0,0 +1,178 @@
+<template>
+  <div class="tab1">
+    <div class="insideTop">文物统计</div>
+    <div class="obstruct"></div>
+    <!-- 主要内容 -->
+    <div class="conten">
+      <div class="row1">
+        <div class="tit">文物类别</div>
+        <div id="echarts1"></div>
+        <div class="sumNum1">合计:{{num1}}</div>
+      </div>
+      <div class="row2">
+        <div class="tit">文物级别</div>
+        <div id="echarts2"></div>
+        <div class="sumNum2">合计:{{num2}}</div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import * as echarts from 'echarts/core'
+import {
+  TitleComponent,
+  TooltipComponent,
+  LegendComponent
+} from 'echarts/components'
+import { PieChart } from 'echarts/charts'
+import { LabelLayout } from 'echarts/features'
+import { CanvasRenderer } from 'echarts/renderers'
+import { goodsReport } from '../../apis/tab2'
+
+echarts.use([
+  TitleComponent,
+  TooltipComponent,
+  LegendComponent,
+  PieChart,
+  CanvasRenderer,
+  LabelLayout
+])
+
+export default {
+  name: 'tab1',
+  components: {},
+  data () {
+    // 这里存放数据
+    return {
+      num1: 0,
+      num2: 0
+    }
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {},
+  // 方法集合
+  methods: {
+    echartsFu (bs, data, name, centen, radius) {
+      const chartDom = document.getElementById(`echarts${bs}`)
+      const myChart = echarts.init(chartDom)
+
+      const option = {
+        tooltip: {
+          trigger: 'item',
+          formatter: '{a} <br/>{b} : {c} ({d}%)'
+        },
+        legend: {
+          type: 'scroll',
+          orient: 'vertical',
+          right: 20,
+          top: 20,
+          bottom: 20,
+          data,
+          formatter: (name) => {
+            const value = data.filter((v) => v.name === name)
+            return `${name}(${value[0].value})`
+          }
+        },
+        series: [
+          {
+            name,
+            type: 'pie',
+            radius: radius,
+            center: [centen, '50%'],
+            itemStyle: {
+              borderRadius: 10,
+              borderColor: '#fff',
+              borderWidth: 2
+            },
+            data,
+            emphasis: {
+              itemStyle: {
+                shadowBlur: 10,
+                shadowOffsetX: 0,
+                shadowColor: 'rgba(0, 0, 0, 0.5)'
+              }
+            }
+          }
+        ]
+      }
+
+      option && myChart.setOption(option)
+    }
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  async created () {},
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  async mounted () {
+    const res = await goodsReport()
+    const data1 = []
+    const data2 = []
+    let num1 = 0
+    let num2 = 0
+    res.data.textureDetail.forEach((v) => {
+      if (v.psc) data1.push({ value: v.psc, name: v.name })
+      num1 += v.psc
+    })
+
+    res.data.levelDetail.forEach(v => {
+      data2.push({ value: v.psc, name: v.name })
+      num2 += v.psc
+    })
+    this.num1 = num1
+    this.num2 = num2
+    this.echartsFu(1, data1, '文物类别', '35%', ['40%', '70%'])
+    this.echartsFu(2, data2, '文物级别', '40%', ['30%', '60%'])
+  },
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {} // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+.tab1 {
+  height: 100%;
+  .insideTop .add {
+    right: 55px;
+  }
+  .conten {
+    padding: 15px 30px 0;
+    height: calc(100% - 32px);
+    display: flex;
+    justify-content: space-between;
+    .row1 {
+      width: 55%;
+    }
+    .row2 {
+      width: 40%;
+    }
+    .tit {
+      margin: 15px 0;
+    }
+    #echarts1 {
+      width: 100%;
+      height: 520px;
+      border-right: 2px solid #ccc;
+    }
+    #echarts2 {
+      width: 100%;
+      height: 520px;
+    }
+    .sumNum1 {
+      margin-top: 15px;
+      text-align: center;
+      padding-right: 250px;
+    }
+    .sumNum2 {
+      margin-top: 15px;
+      text-align: center;
+      padding-right: 105px;
+    }
+  }
+}
+</style>

+ 287 - 29
houtai/src/views/tab2/add.vue

@@ -8,19 +8,113 @@
     <div class="conten">
       <el-form
         :model="ruleForm"
-        :rules="rules"
         ref="ruleForm"
         label-width="120px"
         class="demo-ruleForm"
       >
         <!-- 名称 -->
-        <el-form-item label="名称:" prop="name">
-          <el-input
-            v-model="ruleForm.name"
-            maxlength="25"
-            show-word-limit
-          ></el-input>
+        <div class="checkBox2">
+          <el-form-item label="名称:">
+            <i class="biaoshi biaoshi2"></i>
+            <el-input
+              v-model="ruleForm.name"
+              maxlength="25"
+              show-word-limit
+            ></el-input>
+          </el-form-item>
+          <!-- 总登记号 -->
+          <el-form-item label="总登记号:">
+            <el-input
+              v-model="ruleForm.registerNum"
+              maxlength="25"
+              show-word-limit
+            ></el-input>
+          </el-form-item>
+        </div>
+        <div class="checkBox">
+          <!-- 类型 -->
+          <el-form-item label="类别:">
+            <el-select
+              v-model="ruleForm.dictTextureId"
+              clearable
+              placeholder="请选择类别"
+            >
+              <el-option
+                v-for="i in dictTextureArr"
+                :key="i.value"
+                :label="i.label"
+                :value="i.value"
+              >
+              </el-option>
+            </el-select>
+          </el-form-item>
+          <!-- 年代 -->
+          <el-form-item label="年代:">
+            <el-cascader
+              ref="elCascader"
+              clearable
+              v-model="dictAgeId"
+              :options="options"
+              @change="handleChange"
+            ></el-cascader>
+          </el-form-item>
+          <!-- 级别 -->
+          <el-form-item label="级别:">
+            <el-select
+              v-model="ruleForm.dictLevelId"
+              clearable
+              placeholder="请选择级别"
+            >
+              <el-option
+                v-for="i in dictLevelArr"
+                :key="i.value"
+                :label="i.label"
+                :value="i.value"
+              >
+              </el-option>
+            </el-select>
+          </el-form-item>
+        </div>
+        <!-- 尺寸 -->
+        <el-form-item label="尺寸:" class="fromSize">
+          <div class="sizeRow">
+            <span>长:</span>
+            <el-input
+              v-model="chang"
+              maxlength="8"
+              :onkeyup="clearNoNum('chang')"
+            ></el-input>
+            <el-select v-model="changDanWei" placeholder="请选择类别">
+              <el-option v-for="i in sizeData" :key="i" :label="i" :value="i">
+              </el-option>
+            </el-select>
+          </div>
+          <div class="sizeRow sizeRow2">
+            <span>宽:</span>
+            <el-input
+              v-model="kuang"
+              maxlength="8"
+              :onkeyup="clearNoNum('kuang')"
+            ></el-input>
+            <el-select v-model="kuangDanWei" placeholder="请选择类别">
+              <el-option v-for="i in sizeData" :key="i" :label="i" :value="i">
+              </el-option>
+            </el-select>
+          </div>
+          <div class="sizeRow sizeRow2">
+            <span>高:</span>
+            <el-input
+              v-model="gao"
+              maxlength="8"
+              :onkeyup="clearNoNum('gao')"
+            ></el-input>
+            <el-select v-model="gaoDanWei" placeholder="请选择类别">
+              <el-option v-for="i in sizeData" :key="i" :label="i" :value="i">
+              </el-option>
+            </el-select>
+          </div>
         </el-form-item>
+
         <!-- 图片 -->
         <el-form-item label="图片:">
           <i class="biaoshi biaoshi1"></i>
@@ -36,7 +130,12 @@
           >
             <div v-if="ruleForm.thumb" class="imgdiv">
               <img
-                style="max-width: 200px; max-height: 200px; display: block"
+                style="
+                  width: 150px;
+                  height: 150px;
+                  display: block;
+                  object-fit: cover;
+                "
                 :src="baseURL + ruleForm.thumb"
               />
               <i
@@ -47,15 +146,31 @@
             <i v-else class="el-icon-plus avatar-uploader-icon"></i>
           </el-upload>
           <p class="upHint">
-            格式要求:1、支持png、jpg、gif和jpeg的图片格式;最大支持20MB。
+            格式要求:支持png、jpg、gif和jpeg的图片格式;最大支持20MB。
           </p>
         </el-form-item>
-        <!-- 介绍 -->
-        <el-form-item label="介绍:" prop="description" v-show="0">
+        <!-- 说明 -->
+        <el-form-item label="说明:">
+          <div class="txtBtn">
+            <el-button
+              :disabled="ruleForm.description.length >= 228"
+              size="small"
+              round
+              @click="ruleForm.description += '&emsp;&emsp;'"
+              >首行缩进</el-button
+            >
+            <el-button
+              :disabled="ruleForm.description.length >= 235"
+              size="small"
+              round
+              @click="ruleForm.description += '<br/>'"
+              >换行</el-button
+            >
+          </div>
           <el-input
             type="textarea"
             v-model="ruleForm.description"
-            maxlength="500"
+            maxlength="240"
             show-word-limit
           ></el-input>
         </el-form-item>
@@ -99,7 +214,7 @@
 </template>
 
 <script>
-import { goodsSave, goodsDetail } from '../../apis/tab2'
+import { goodsSave, goodsDetail, dictGetTree } from '../../apis/tab2'
 import axios from '@/utils/request'
 export default {
   name: 'tab2Add',
@@ -109,7 +224,28 @@ export default {
     return {
       // 服务器前缀地址
       baseURL: '',
+      // 尺寸
+      sizeData: ['米', '厘米', '毫米'],
+      chang: '',
+      changDanWei: '厘米',
+      kuang: '',
+      kuangDanWei: '厘米',
+      gao: '',
+      gaoDanWei: '厘米',
+      // 年代
+      dictAgeId: [],
+      options: [],
+      // 类型数组
+      dictTextureArr: [],
+      // 级别数组
+      dictLevelArr: [],
       ruleForm: {
+        // 总登记号
+        registerNum: '',
+        // 类别
+        dictTextureId: '',
+        // 级别
+        dictLevelId: '',
         name: '',
         type: null,
         description: '',
@@ -118,10 +254,6 @@ export default {
         filePath: '',
         fileName: ''
       },
-      rules: {
-        name: [{ required: true, message: '不能为空', trigger: 'blur' }]
-        // description: [{ required: true, message: '不能为空', trigger: 'blur' }]
-      },
       fileList: []
     }
   },
@@ -131,6 +263,23 @@ export default {
   watch: {},
   // 方法集合
   methods: {
+    clearNoNum (val) {
+      try {
+        this[val] = this[val].replace(/[^\d.]/g, '') // 清除“数字”和“.”以外的字符
+        this[val] = this[val].replace(/\.{2,}/g, '.') // 只保留第一个. 清除多余的
+        // eslint-disable-next-line no-useless-escape
+        this[val] = this[val].replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3') // 只能输入两个小数
+        if (this[val].indexOf('.') < 0 && this[val].trim() !== '') {
+          // 以上已经过滤,此处控制的是如果没有小数点,首位不能为类似于 01、02的金额
+          this[val] = parseFloat(this[val])
+        }
+      } catch (error) {
+        console.log(error)
+      }
+    },
+    handleChange (value) {
+      console.log(value)
+    },
     // 点击取消
     goBack () {
       let k = this.$route.query.k
@@ -148,13 +297,22 @@ export default {
       if (this.ruleForm.thumb === '') {
         return this.$message.warning('图片不能为空')
       }
-      // if (this.ruleForm.description.trim() === '') {
-      //   return this.$message.warning('介绍不能为空')
-      // }
       if (this.ruleForm.filePath === '' && this.ruleForm.type === 'model') {
         return this.$message.warning('文件不能为空')
       }
-      const res = await goodsSave(this.ruleForm)
+      const obj = { ...this.ruleForm }
+      // 年代数据判断
+      if (this.dictAgeId && this.dictAgeId[1]) {
+        obj.dictAgeId = this.dictAgeId[1]
+        // eslint-disable-next-line no-constant-condition
+        const tempArr = this.$refs.elCascader.getCheckedNodes()[0].pathLabels
+        obj.dictAgeFront = tempArr.join('/')
+      }
+      // 长宽高判断
+      if (this.chang) obj.sizeLength = this.chang + ',' + this.changDanWei
+      if (this.kuang) obj.sizeWidth = this.kuang + ',' + this.kuangDanWei
+      if (this.gao) obj.sizeHeight = this.gao + ',' + this.gaoDanWei
+      const res = await goodsSave(obj)
       if (res.code === 0) {
         this.$message.success('操作成功')
         this.goBack()
@@ -234,14 +392,64 @@ export default {
     this.token = localStorage.getItem('HNBWY_token')
     // 拿到路由跳转传过来的数据
     this.ruleForm.type = this.$route.query.typeU
+
+    // 几个下拉框的数据
+    // --------年代
+    const res = await dictGetTree({ type: 'age' })
+    const temp = []
+    res.data.forEach((v, i) => {
+      temp.push({ value: v.id, label: v.name, children: [] })
+      v.children.forEach((p) => {
+        temp[i].children.push({ value: p.id, label: p.name })
+      })
+    })
+    this.options = [...temp]
+    // -------类别
+    const res2 = await dictGetTree({ type: 'texture' })
+    this.dictTextureArr = res2.data.map((v) => {
+      return { value: v.id, label: v.name }
+    })
+    // -------级别
+    const res3 = await dictGetTree({ type: 'level' })
+    this.dictLevelArr = res3.data.map((v) => {
+      return { value: v.id, label: v.name }
+    })
+
     // 如果是编辑
     let id = this.$route.query.id
     if (id) {
       id = Number(id)
-      const res = await goodsDetail(id)
-      this.ruleForm = res.data
+      const resSon = await goodsDetail(id)
+      this.ruleForm = resSon.data
       // 附件回显
-      this.fileList = [{ name: res.data.fileName }]
+      this.fileList = [{ name: resSon.data.fileName }]
+      // 年代回显
+      if (resSon.data.dictAgeId) {
+        res.data.forEach((v) => {
+          v.children.forEach((p) => {
+            if (p.id === resSon.data.dictAgeId) this.dictAgeId = [v.id, p.id]
+          })
+        })
+      }
+      // 尺寸回显
+      const chang = resSon.data.sizeLength
+      const kuang = resSon.data.sizeWidth
+      const gao = resSon.data.sizeHeight
+      if (chang) {
+        const temp = chang.split(',')
+        this.chang = temp[0]
+        this.changDanWei = temp[1]
+      }
+      if (kuang) {
+        const temp = kuang.split(',')
+        this.kuang = temp[0]
+        this.kuangDanWei = temp[1]
+      }
+      if (gao) {
+        const temp = gao.split(',')
+        this.gao = temp[0]
+        this.gaoDanWei = temp[1]
+      }
     }
   },
   // 生命周期 - 挂载完成(可以访问DOM元素)
@@ -257,6 +465,8 @@ export default {
 </script>
 <style lang='less' scoped>
 .tab2Add {
+  width: 100%;
+  height: 100%;
   .top {
     margin-top: -20px;
     height: 50px;
@@ -266,7 +476,7 @@ export default {
     font-weight: 700;
   }
   .conten {
-    width: 800px;
+    padding-right: 300px;
     padding-top: 20px;
     .avatar-uploader .el-upload {
       border-radius: 6px;
@@ -289,14 +499,22 @@ export default {
     .biaoshi1::before {
       left: -64px;
     }
+    .biaoshi2::before {
+      top: -11px;
+      left: -64px;
+    }
+    /deep/.el-form-item {
+      margin-bottom: 12px;
+    }
     /deep/.el-textarea textarea {
-      height: 120px;
+      margin-top: 10px;
+      height: 80px;
       resize: none;
     }
     /deep/.el-textarea .el-input__count {
       position: absolute;
-      top: -25px;
-      right: 0;
+      bottom: -24px;
+      right: 4px;
       background-color: transparent;
       height: 30px;
       line-height: 30px;
@@ -309,12 +527,52 @@ export default {
   }
   .con_btn {
     position: absolute;
+    bottom: 20px;
     left: 50%;
     transform: translateX(-50%);
-    bottom: 15px;
+  }
+  .txtBtn {
+    position: absolute;
+    top: -32px;
+    right: 4px;
   }
   /deep/.imgdiv .el-icon-circle-close {
     font-size: 20px;
   }
+  .checkBox {
+    display: flex;
+  }
+  .checkBox2 {
+    width: 100%;
+    display: flex;
+    & > div {
+      width: 50%;
+    }
+  }
+  .fromSize {
+    /deep/.el-form-item__content {
+      display: flex;
+    }
+    /deep/.el-input {
+      width: 100px;
+    }
+    /deep/.el-input--suffix {
+      width: 90px;
+    }
+    /deep/.el-input__inner {
+      padding: 0 5px !important;
+    }
+    .sizeRow {
+      margin-right: 90px;
+    }
+    .sizeRow2 {
+      /deep/.el-input {
+        width: 110px;
+      }
+    }
+  }
+  /deep/.el-upload-list {
+    margin-top: -12px;
+  }
 }
 </style>

+ 231 - 35
houtai/src/views/tab2/index.vue

@@ -25,9 +25,58 @@
         </ul>
       </div>
       <!-- 右侧主要内容 -->
-      <div class="con_right">
-        <div class="search">
-          <span>创建时间:</span>
+      <div class="con_right" v-loading="loading">
+        <div class="search" @keyup.enter="searchBtn">
+          <span>&emsp;&emsp;名称:</span>
+          <el-input
+            maxlength="25"
+            show-word-limit
+            v-model="formData.searchKey"
+            placeholder="请输入关键字"
+            style="width: 240px"
+          ></el-input>
+          <span class="search_k">&emsp;&emsp;类别:</span>
+          <el-select v-model="formData.dictTextureId" placeholder="请选择类别">
+            <el-option
+              v-for="i in dictTextureArr"
+              :key="i.value"
+              :label="i.label"
+              :value="i.value"
+            >
+            </el-option>
+          </el-select>
+          <span class="search_k">年代:</span>
+          <el-select v-model="formData.dictAgeId" placeholder="请选择类别">
+            <el-option
+              v-for="i in dictAgeArr"
+              :key="i.value"
+              :label="i.label"
+              :value="i.value"
+            >
+            </el-option>
+          </el-select>
+          <span class="search_k">级别:</span>
+          <el-select v-model="formData.dictLevelId" placeholder="请选择类别">
+            <el-option
+              v-for="i in dictLevelArr"
+              :key="i.value"
+              :label="i.label"
+              :value="i.value"
+            >
+            </el-option>
+          </el-select>
+        </div>
+        <div class="search" @keyup.enter="searchBtn">
+          <span>总登记号:</span>
+          <el-input
+            maxlength="25"
+            show-word-limit
+            v-model="formData.registerNum"
+            placeholder="请输入关键字"
+            style="width: 240px"
+          ></el-input>
+
+          <span class="search_k">创建时间:</span>
           <el-date-picker
             style="width: 240px"
             v-model="time"
@@ -37,18 +86,21 @@
             end-placeholder="结束日期"
           >
           </el-date-picker>
-          <span class="search_k">名称:</span>
-          <el-input
-            maxlength="20"
-            show-word-limit
-            v-model="formData.searchKey"
-            placeholder="请输入关键字"
-            style="width: 240px"
-          ></el-input>
+
           <!-- 右侧按钮 -->
           <div class="search_btn">
             <el-button type="primary" @click="searchBtn">查 询</el-button>
             <el-button @click="resetBtn">重 置</el-button>
+            <download-excel
+              :before-generate="derive"
+              class="export-excel-wrapper"
+              :data="json_data"
+              :fields="json_fields"
+              :name="`文物信息清单${nowTime}.xls`"
+            >
+              <!-- 上面可以自定义自己的样式,还可以引用其他组件button -->
+              <el-button>批量导出</el-button>
+            </download-excel>
           </div>
         </div>
         <!-- 表格 -->
@@ -62,6 +114,52 @@
               </template>
             </el-table-column>
             <el-table-column label="名称" prop="name"> </el-table-column>
+            <el-table-column label="总登记号">
+              <template #default="{ row }">
+                <span
+                  style="cursor: pointer"
+                  :title="row.registerNum"
+                  v-if="row.registerNum"
+                  >{{
+                    row.registerNum.length > 10
+                      ? row.registerNum.substring(0, 10) + "..."
+                      : row.registerNum
+                  }}</span
+                >
+                <span v-else>(空)</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="类别">
+              <template #default="{ row }">
+                <span v-if="row.dictTextureName">{{
+                  row.dictTextureName
+                }}</span>
+                <span v-else>(空)</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="年代">
+              <template #default="{ row }">
+                <span v-if="row.dictAgeFront">{{ row.dictAgeFront }}</span>
+                <span v-else>(空)</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="级别">
+              <template #default="{ row }">
+                <span v-if="row.dictLevelName">{{ row.dictLevelName }}</span>
+                <span v-else>(空)</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="说明">
+              <template #default="{ row }">
+                <span
+                  style="cursor: pointer"
+                  :title="handTxt(row.description)"
+                  v-if="handTxt(row.description)"
+                  >{{handTxt(row.description).length > 10?handTxt(row.description).substring(0, 10) + "...":handTxt(row.description)}}</span
+                >
+                <span v-else>(空)</span>
+              </template>
+            </el-table-column>
             <el-table-column label="图片" width="120">
               <template #default="{ row }">
                 <img
@@ -74,23 +172,9 @@
             </el-table-column>
             <el-table-column prop="createTime" label="创建时间">
             </el-table-column>
-            <!-- <el-table-column label="是否显示">
-              <template #default="{ row }">
-                <el-switch
-                  v-model="row.display"
-                  active-color="#b9412e"
-                  :active-value="1"
-                  :inactive-value="0"
-                  @change="changeSwit($event, row.id)"
-                >
-                </el-switch>
-              </template>
-            </el-table-column> -->
             <el-table-column label="操作">
               <template #default="{ row }">
-                <el-button
-                  type="text"
-                  @click="editGood(row.id)"
+                <el-button type="text" @click="editGood(row.id)"
                   >编辑</el-button
                 >
                 <el-button
@@ -98,7 +182,7 @@
                   style="color: #d9001b"
                   :disabled="!!row.display"
                   @click="delGoods(row.id)"
-                  :class="{disNo:row.display}"
+                  :class="{ disNo: row.display }"
                   >删除</el-button
                 >
               </template>
@@ -109,7 +193,7 @@
     </div>
     <!-- 分页 -->
     <div class="paging">
-      <span>共 {{total}} 条</span>
+      <span>共 {{ total }} 条</span>
       <el-pagination
         layout="sizes,prev, pager, next,jumper"
         :total="total"
@@ -124,13 +208,42 @@
 
 <script>
 import axios from '@/utils/request'
-import { goodsList, goodsRemove, goodsDisplay } from '@/apis/tab2'
+import { goodsList, goodsRemove, goodsDisplay, dictGetTree } from '@/apis/tab2'
+import dayjs from 'dayjs'
+import relativeTime from 'dayjs/plugin/relativeTime'
+import 'dayjs/locale/zh-cn'
+dayjs.extend(relativeTime)
+
 export default {
   name: 'tab2',
   components: {},
   data () {
     // 这里存放数据
     return {
+      loading: false,
+      nowTime: '',
+      // 导出表格的数据
+      json_fields: {
+        名称: 'name', // 常规字段
+        总登记号: 'registerNum', // 支持嵌套属性
+        类别: 'dictTextureName',
+        年代: 'dictAgeName',
+        级别: 'dictLevelName',
+        长: 'sizeLength',
+        宽: 'sizeWidth',
+        高: 'sizeHeight',
+        说明: 'description'
+      },
+      json_data: [],
+      json_meta: [
+        [
+          {
+            ' key ': ' charset ',
+            ' value ': ' utf- 8 '
+          }
+        ]
+      ],
+
       baseURL: '',
       total: 0,
       time: '',
@@ -144,9 +257,16 @@ export default {
         pageNum: 1,
         pageSize: 10,
         searchKey: '',
+        registerNum: '',
+        dictTextureId: '',
+        dictLevelId: '',
+        dictAgeId: '',
         type: 'model'
       },
-      tableData: []
+      tableData: [],
+      dictLevelArr: [],
+      dictTextureArr: [],
+      dictAgeArr: []
     }
   },
   // 监听属性 类似于data概念
@@ -159,12 +279,56 @@ export default {
   },
   // 方法集合
   methods: {
+    // 处理说明的文本
+    handTxt (val) {
+      let temp = val.replaceAll('&emsp;', ' ')
+      temp = temp.replaceAll('<br/>', '/')
+      return temp
+    },
+    // 点击导出
+    async derive () {
+      this.searchBtn()
+      this.json_data = []
+      this.loading = true
+      this.nowTime = dayjs().format('YYYYMMDD')
+      // 封装获取列表的函数
+      const res = await goodsList({
+        ...this.formData,
+        pageNum: 1,
+        pageSize: 9999
+      })
+      if (res.code === 0) {
+        if (res.data.records.length === 0) {
+          this.$message.warning('没有符合条件的数据')
+          this.loading = false
+          return
+        }
+        this.json_data = res.data.records.map((v) => {
+          return {
+            name: v.name,
+            registerNum: v.registerNum,
+            dictTextureName: v.dictTextureName,
+            dictAgeName: v.dictAgeName,
+            sizeLength: v.sizeLength.replace(',', ''),
+            sizeWidth: v.sizeWidth.replace(',', ''),
+            sizeHeight: v.sizeHeight.replace(',', ''),
+            description: v.description
+          }
+        })
+        this.loading = false
+      } else this.$message.warning(res.msg)
+    },
     // 点击重置
     resetBtn () {
       this.formData.searchKey = ''
       this.time = ''
       this.formData.pageNum = 1
       this.formData.startTime = this.formData.endTime = ''
+      this.formData.registerNum =
+        this.formData.dictTextureId =
+        this.formData.dictLevelId =
+        this.formData.dictAgeId =
+          ''
       this.goodsList(this.formData)
     },
     // 点击查询
@@ -204,6 +368,9 @@ export default {
           const res = await goodsRemove(id)
           if (res.code === 0) {
             this.$message.success('删除成功')
+            if (this.tableData.length === 1 && this.formData.pageNum > 1) {
+              this.formData.pageNum -= 1
+            }
             this.goodsList(this.formData)
           } else this.$message.warning(res.msg)
         })
@@ -274,7 +441,7 @@ export default {
     }
   },
   // 生命周期 - 创建完成(可以访问当前this实例)
-  created () {
+  async created () {
     // 获取服务器前缀地址
     this.baseURL = axios.defaults.baseURL
     // 判断是第一次进来还是修改或者新增或者查看后返回
@@ -285,6 +452,29 @@ export default {
     const k = this.$route.query.k
     if (k) this.formData.pageNum = Number(k)
     this.goodsList(this.formData)
+    // 几个下拉框的数据
+    // --------年代
+    const res = await dictGetTree({ type: 'age' })
+    const temp = []
+    res.data.forEach((v) => {
+      v.children.forEach((p) => {
+        temp.push({ value: p.id, label: p.name })
+      })
+    })
+    temp.unshift({ value: '', label: '全部' })
+    this.dictAgeArr = [...temp]
+    // -------类别
+    const res2 = await dictGetTree({ type: 'texture' })
+    this.dictTextureArr = res2.data.map((v) => {
+      return { value: v.id, label: v.name }
+    })
+    this.dictTextureArr.unshift({ value: '', label: '全部' })
+    // -------级别
+    const res3 = await dictGetTree({ type: 'level' })
+    this.dictLevelArr = res3.data.map((v) => {
+      return { value: v.id, label: v.name }
+    })
+    this.dictLevelArr.unshift({ value: '', label: '全部' })
   },
   // 生命周期 - 挂载完成(可以访问DOM元素)
   mounted () {},
@@ -344,6 +534,12 @@ export default {
         position: relative;
         margin-top: 12px;
         height: 40px;
+        /deep/.el-input__inner {
+          padding-right: 50px;
+        }
+        /deep/.el-select {
+          width: 150px;
+        }
         .search_k {
           margin-left: 30px;
         }
@@ -351,7 +547,7 @@ export default {
           margin-left: 50px;
           display: flex;
           justify-content: space-between;
-          width: 180px;
+          width: 300px;
         }
       }
     }
@@ -360,7 +556,7 @@ export default {
   //   max-width: 1370px;
   // }
   /deep/.el-table__body-wrapper {
-    max-height: 485px;
+    max-height: 440px;
     overflow-y: auto;
   }
   .paging {
@@ -369,12 +565,12 @@ export default {
     position: absolute;
     bottom: 15px;
     right: 50px;
-    &>span{
+    & > span {
       margin-right: 15px;
       font-size: 13px;
     }
   }
-  .disNo{
+  .disNo {
     color: #ccc !important;
   }
 }

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

@@ -6,7 +6,7 @@
     <div class="obstruct"></div>
     <!-- 主要内容 -->
     <div class="conten">
-      <div class="search">
+      <div class="search"  @keyup.enter="searchBtn">
         <el-input
           v-model="formData.searchKey"
           placeholder="请输入关键字"