scorpio пре 2 година
родитељ
комит
b2d47bf6bf

+ 3 - 1
src/api/index.js

@@ -12,6 +12,7 @@ import invest from './invest/index'
 import search from './search/index.js'
 import dispatch from './dispatch/index.js'
 import store from './store/index.js'
+import msg from './msg/index.js'
 
 export default {
   offices: ['pdf', 'doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx', 'PDF'],
@@ -29,5 +30,6 @@ export default {
   invest,
   search,
   dispatch,
-  store
+  store,
+  msg
 }

+ 35 - 0
src/api/msg/index.js

@@ -0,0 +1,35 @@
+import fetch from '../fetch.js'
+
+export default {
+  /**
+   * 通知消息列表
+   * @param params
+   * @returns {Promise | Promise<unknown>}
+   */
+  list(params) {
+    return fetch('/blade-project-manage-v2/announcementsend/v2/page', params)
+  },
+  /**
+   * 未读消息数量
+   * @param params
+   * @returns {Promise | Promise<unknown>}
+   */
+  count(params) {
+    return fetch(
+      '/blade-project-manage-v2/announcementsend/v2/notReadCount',
+      params
+    )
+  },
+  /**
+   * 标记为已读
+   * @param params
+   * @returns {Promise | Promise<unknown>}
+   */
+  markRead(params) {
+    return fetch(
+      '/blade-project-manage-v2/announcementsend/v2/read',
+      params,
+      'post'
+    )
+  }
+}

+ 11 - 0
src/api/store/index.js

@@ -43,5 +43,16 @@ export default {
       '/blade-project-manage-v2/project-dispatch/v2/export-storage-word',
       params
     )
+  },
+  /**
+   * 删除预入库项目
+   * @param params
+   * @returns {Promise | Promise<unknown>}
+   */
+  remove(params) {
+    return fetch(
+      '/blade-project-manage-v2/project-dispatch/v2/pre-storage-delete',
+      params
+    )
   }
 }

+ 4 - 0
src/assets/style/main.scss

@@ -331,6 +331,10 @@ img {
   font-weight: bold;
 }
 
+.radius-5 {
+  border-radius: 5px;
+}
+
 .radius {
   border-radius: 10px;
 }

+ 50 - 0
src/components/tips-custom/index.vue

@@ -0,0 +1,50 @@
+\
+<template>
+  <div class="full-width flex flex-center flex-justify-between mb-20">
+    <div class="flex flex-center">
+      <el-button
+        type="primary"
+        plain
+        icon="Back"
+        circle
+        @click="$router.back()"
+        v-if="nav.menus[nav.menus.length - 1].meta.back !== undefined"
+      ></el-button>
+      <span class="ml-10 tools font-24">{{
+        nav.menus[nav.menus.length - 1].name
+      }}</span>
+    </div>
+    <slot />
+  </div>
+</template>
+
+<script>
+import navStore from '@/store/nav.js'
+import { useStore } from '@/store/user.js'
+
+export default {
+  setup() {
+    const nav = navStore()
+    const user = useStore()
+    return { nav, user }
+  },
+  props: {
+    showTips: {
+      type: Boolean,
+      default: false
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.tips {
+  border-radius: 8px;
+  background-color: white;
+  padding: 10px 20px;
+  margin-top: 20px;
+}
+.tools {
+  flex: 1;
+}
+</style>

+ 7 - 2
src/layout/index.vue

@@ -36,7 +36,10 @@
               </div>
             </div>
           </el-popover>
-          <div class="wrapper">
+          <div
+            class="wrapper"
+            v-if="nav.menus[nav.menus.length - 1].meta.show === undefined"
+          >
             <tips />
           </div>
           <div class="wrapper" @scroll="scroll">
@@ -66,14 +69,16 @@ import top from './top.vue'
 import tips from './tips.vue'
 import keepAliveStore from '../store/keepAlive.js'
 import permissionStore from '@/store/permission.js'
+import navStore from '@/store/nav.js'
 
 export default {
   name: 'index.vue',
   components: { left, top, tips },
   setup() {
     const keepAlive = keepAliveStore()
+    const nav = navStore()
     const permission = permissionStore()
-    return { keepAlive, permission }
+    return { keepAlive, nav, permission }
   },
   data() {
     return {

+ 16 - 2
src/layout/top.vue

@@ -35,7 +35,12 @@
               @click="show = true"
             />
 
-            <el-badge :value="2" :max="99" class="ml-20">
+            <el-badge
+              :value="msgCount"
+              :max="99"
+              class="ml-20"
+              :hidden="msgCount === 0"
+            >
               <el-button
                 icon="Bell"
                 circle
@@ -140,7 +145,8 @@ export default {
       filterTypeName: '全部',
       resultCount: 0,
       title: '',
-      mini: false
+      mini: false,
+      msgCount: 0
     }
   },
   created() {
@@ -164,11 +170,19 @@ export default {
   },
   mounted() {
     this.initWebSocket()
+    this.readCount()
   },
   unmounted() {
     this.websock.close() // 离开路由之后断开websocket连接
   },
   methods: {
+    readCount() {
+      this.$api.msg.count().then(res => {
+        if (res.code === 200) {
+          this.msgCount = res.data
+        }
+      })
+    },
     initWebSocket() {
       const wsuri =
         location.host.indexOf('dev') > -1

+ 0 - 5
src/views/home/component/dash.vue

@@ -521,11 +521,6 @@ export default {
             prop: 'year',
             width: 120
           },
-          {
-            label: '预警提示',
-            prop: 'tips',
-            width: 100
-          },
           {
             label: '项目状态',
             prop: 'report_type',

+ 1 - 18
src/views/home/component/dispatch.vue

@@ -430,25 +430,8 @@ export default {
           this.$message.error('暂无文件或者下载错误,请稍后再试...')
           return
         }
-        this.$message.success('开始下载,请稍后...')
-        this.download(res)
+        this.$message.success('资料打包中,完成后系统将会发送通知消息给您')
       })
-    },
-    download(res) {
-      const url = window.URL.createObjectURL(
-        new Blob([res], { type: 'application/octet-stream;charset=UTF-8' })
-      )
-      const link = document.createElement('a')
-      link.style.display = 'none'
-      link.href = url
-      const excelName = this.year + '年' + this.month + '月.zip'
-      link.setAttribute('download', excelName)
-      document.body.appendChild(link)
-      link.click()
-      link.remove()
-      this.diaType = -1
-      this.$message.success('资料打包中,完成后系统将会发送通知消息给您')
-      this.loading = false
     }
   }
 }

+ 31 - 93
src/views/home/component/owner_serach.vue

@@ -1,6 +1,6 @@
 <template>
   <el-card shadow="hover" class="flex flex-center padding white-bg">
-    <el-form v-model="form" class="lab mt-20 full-width" label-width="145px">
+    <el-form v-model="form" class="lab full-width" label-width="120px">
       <div class="flex">
         <!-------left------->
         <div class="flex flex-col mr-10">
@@ -34,33 +34,6 @@
               </el-select>
             </el-form-item>
           </div>
-          <div>
-            <el-form-item class="full-width" label="计划(实际)开工时间">
-              <el-date-picker
-                v-model="time1"
-                type="daterange"
-                @visible-change="visibleTime($event, 1)"
-                range-separator="至"
-                start-placeholder="开始时间"
-                end-placeholder="结束时间"
-                value-format="YYYY-MM-DD"
-                format="YYYY-MM-DD"
-                clearable
-              />
-            </el-form-item>
-          </div>
-          <div>
-            <el-form-item class="full-width" label="认定时间">
-              <el-select v-model="form.projectYear" style="width: 100%">
-                <el-option
-                  v-for="item in years"
-                  :key="item.value"
-                  :label="item.label"
-                  :value="item.value"
-                />
-              </el-select>
-            </el-form-item>
-          </div>
         </div>
         <!-------right------->
         <div class="flex flex-col ml-10">
@@ -110,50 +83,38 @@
                 />
               </el-select>
             </el-form-item>
-            <el-form-item class="full-width" label="机构选择">
-              <div class="grey-9 pointer chose-box nowrap" @click="getOrg">
-                {{ deptName }}
-              </div>
-            </el-form-item>
           </div>
-          <div>
-            <el-form-item class="full-width" label="计划(实际)入库时间">
-              <el-date-picker
-                v-model="time2"
-                type="daterange"
-                @visible-change="visibleTime($event, 2)"
-                range-separator="至"
-                start-placeholder="开始时间"
-                end-placeholder="结束时间"
-                value-format="YYYY-MM-DD"
-                format="YYYY-MM-DD"
-                clearable
+        </div>
+      </div>
+      <div class="full-width flex flex-center">
+        <div class="flex-child-average flex flex-center">
+          <el-form-item class="full-width" label="项目状态">
+            <el-select
+              v-model="form.reportType"
+              style="width: 98%; margin: 0; padding: 0"
+            >
+              <el-option
+                v-for="item in reportTypes"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value"
               />
-            </el-form-item>
-          </div>
-          <div class="flex flex-center flex-justify-end">
-            <el-form-item class="full-width" label="项目状态">
-              <el-select v-model="form.reportType" style="width: 100%">
-                <el-option
-                  v-for="item in reportTypes"
-                  :key="item.value"
-                  :label="item.label"
-                  :value="item.value"
-                />
-              </el-select>
-            </el-form-item>
-          </div>
-          <div class="flex flex-align-center flex-justify-end">
-            <base-button
-              class="pointer"
-              icon="Delete"
-              title="清空"
-              type="0"
-              :width="130"
-              @click="clear"
-            />
-            <base-button class="pointer ml-20" width="130" @click="sure" />
-          </div>
+            </el-select>
+          </el-form-item>
+        </div>
+        <div
+          class="flex-child-average flex flex-align-center flex-justify-end"
+          style="margin-bottom: 18px"
+        >
+          <base-button
+            class="pointer"
+            icon="Delete"
+            title="清空"
+            type="0"
+            :width="130"
+            @click="clear"
+          />
+          <base-button class="pointer" width="130" @click="sure" />
         </div>
       </div>
     </el-form>
@@ -312,29 +273,6 @@ export default {
           value: 1
         }
       ],
-      years: [
-        {
-          value: 2023
-        },
-        {
-          value: 2022
-        },
-        {
-          value: 2021
-        },
-        {
-          value: 2020
-        },
-        {
-          value: 2019
-        },
-        {
-          value: 2018
-        },
-        {
-          value: 2017
-        }
-      ],
       typeList: [],
       showOrg: false,
       keyWords: '',

+ 150 - 0
src/views/home/component/top-fliter.vue

@@ -0,0 +1,150 @@
+<template>
+  <div class="flex flex-center">
+    <div class="white-bg border radius-5 picker flex flex-center">
+      <span class="padding">认定年份:</span>
+      <el-select
+        v-model="query.projectYear"
+        @change="change($event, 1)"
+        class="padding-right"
+        style="width: 50%"
+        clearable
+      >
+        <el-option
+          v-for="item in years"
+          :key="item.value"
+          :label="item.label"
+          :value="item.value"
+        />
+      </el-select>
+    </div>
+    <div class="white-bg border radius-5 picker flex flex-center ml-10">
+      <span class="padding" style="width: 60px">机构:</span>
+      <el-select
+        v-model="query.deptIds"
+        class="padding-right"
+        style="width: 80%"
+        @change="change($event, 2)"
+        clearable
+      >
+        <el-option
+          v-for="item in depts"
+          :key="item.id"
+          :label="item.deptName"
+          :value="item.id"
+        />
+      </el-select>
+    </div>
+    <div
+      class="white-bg border radius-5 picker flex flex-center ml-10"
+      style="width: 520px"
+    >
+      <span class="padding" style="width: 100px">时间选择</span>
+      <el-select
+        v-model="query.timeType"
+        class="padding-right"
+        style="width: 60%"
+        @change="change($event, 3)"
+      >
+        <el-option
+          v-for="item in types"
+          :key="item.value"
+          :label="item.label"
+          :value="item.value"
+        />
+      </el-select>
+      <el-date-picker
+        v-model="query.time"
+        type="daterange"
+        format="YYYY-MM-DD"
+        start-placeholder="开始日期"
+        end-placeholder="结束日期"
+        value-format="YYYY-MM-DD"
+        @change="change($event, 4)"
+      >
+      </el-date-picker>
+    </div>
+  </div>
+</template>
+
+<script>
+/**
+ * 顶部搜索
+ */
+export default {
+  data() {
+    return {
+      query: {
+        projectYear: '',
+        deptIds: '',
+        timeType: '',
+        time: ''
+      },
+      years: [],
+      dateType: '计划(实际)入库时间',
+      types: [
+        {
+          label: '计划(实际)入库时间',
+          value: 1
+        },
+        {
+          label: '计划(实际)开工时间',
+          value: 2
+        }
+      ],
+      depts: []
+    }
+  },
+  created() {
+    this.init()
+    this.deptList()
+  },
+  methods: {
+    init() {
+      this.query.projectYear = new Date().getFullYear()
+      const count = this.query.projectYear - 2017
+      for (let i = 0; i <= count; i++) {
+        this.years.push({ value: 2017 + i })
+      }
+      this.years.reverse()
+    },
+    deptList() {
+      this.$api.common.deptList().then(res => {
+        if (res.code === 200) {
+          this.showOrg = true
+          this.depts = res.data.map(e => {
+            e.checked = false
+            return e
+          })
+        } else {
+          this.$message.error(res.msg)
+        }
+      })
+    },
+    change(res, type) {
+      if (type === 1) {
+        this.query.projectYear = res
+      } else if (type === 2) {
+        this.query.deptIds = res
+      } else if (type === 3) {
+        this.query.timeType = res
+      } else {
+        if (this.query.timeType === 1) {
+          this.query.planCommencementTime = this.query.time.join(',')
+        } else {
+          this.query.planStorageTime = this.query.time.join(',')
+        }
+      }
+      this.$bus.emit('serach', this.query)
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.picker {
+  width: 200px;
+  :deep(.el-input__wrapper) {
+    box-shadow: none;
+  }
+}
+</style>

+ 6 - 6
src/views/home/excel.vue

@@ -1,16 +1,15 @@
 <template>
-  <el-container>
+  <div class="wrapper light-red">
     <basic-container class="mt-10">
-      <div class="full-width white-bg" style="width: 100vw">
+      <div class="full-width white-bg">
         <div class="flex flex-center flex-justify-start">
-          <el-button type="primary" plain @click="back">返回</el-button>
           <el-button type="primary" @click="exportExcel">导出表格</el-button>
         </div>
         <span class="red full-width text-left flex flex-justify-start mt-10"
           >注:左右滑动,查看更多内容</span
         >
       </div>
-      <div class="mt-10">
+      <div class="mt-10" style="overflow-x: scroll">
         <div class="header flex flex-center flex-justify-start full-width">
           <div
             class="flex flex-center"
@@ -51,12 +50,13 @@
         </div>
       </div>
     </basic-container>
-  </el-container>
+  </div>
 </template>
 
 <route>
 {
-name: '导出预览'
+name: '导出预览',
+meta: { 'back':true}
 }
 </route>
 

+ 9 - 2
src/views/home/index.vue

@@ -1,5 +1,10 @@
 <template>
   <div class="flex flex-col full-height full-width">
+    <tips-custom>
+      <template #default>
+        <top-fliter />
+      </template>
+    </tips-custom>
     <top-serach v-if="type === 0" />
     <owner-serach v-else-if="type === 1" />
     <div class="full-width full-height mt-10">
@@ -12,7 +17,7 @@
 {
 path: '/home',
 name: '固定资产项目管理',
-meta: {keepAlive: true}
+meta: {keepAlive: true,show: false}
 }
 </route>
 
@@ -21,12 +26,14 @@ import topSerach from './component/top_serach.vue'
 import ownerSerach from './component/owner_serach.vue'
 import dash from './component/dash.vue'
 import { useStore } from '@/store/user.js'
+import tipsCustom from '@/components/tips-custom/index.vue'
+import topFliter from '@/views/home/component/top-fliter.vue'
 
 import tokenStore from '../../store/token.js'
 
 export default {
   name: '固定资产项目管理',
-  components: { topSerach, dash, ownerSerach },
+  components: { topSerach, dash, ownerSerach, tipsCustom, topFliter },
   setup() {
     const store = useStore()
     const token = tokenStore()

+ 11 - 5
src/views/home/project.vue

@@ -1,5 +1,10 @@
 <template>
   <div class="flex flex-col full-height full-width">
+    <tips-custom>
+      <template #default>
+        <top-fliter />
+      </template>
+    </tips-custom>
     <top-serach v-if="type === 0" />
     <owner-serach v-else-if="type === 1" />
     <div class="full-width mt-10">
@@ -12,7 +17,7 @@
 {
 path: '/project',
 name: '项目管理',
-meta: {keepAlive: true}
+meta: {keepAlive: true,show: false}
 }
 </route>
 
@@ -21,12 +26,13 @@ import topSerach from './component/top_serach.vue'
 import ownerSerach from './component/owner_serach.vue'
 import dash from './component/dash.vue'
 import { useStore } from '@/store/user.js'
-
 import tokenStore from '../../store/token.js'
+import tipsCustom from '@/components/tips-custom/index.vue'
+import topFliter from '@/views/home/component/top-fliter.vue'
 
 export default {
   name: '项目管理',
-  components: { topSerach, dash, ownerSerach },
+  components: { topSerach, dash, ownerSerach, tipsCustom, topFliter },
   setup() {
     const store = useStore()
     const token = tokenStore()
@@ -34,10 +40,10 @@ export default {
   },
   data() {
     return {
-      type: 1
+      type: 1,
+      topQuery: null
     }
   },
-  created() {},
   methods: {
     push() {
       this.$router.push({ path: '/setting', query: { id: 12, type: 'test' } })

+ 28 - 0
src/views/msg/component/msg2.vue

@@ -0,0 +1,28 @@
+<template>
+  <div class="flex flex-justify-start flex-center full-width padding">
+    <span class="ml-20 font-14">
+      {{ info.msgContent }}
+    </span>
+    <el-button class="ml-20" size="mini" type="text" plain @click="download"
+      >立即下栽</el-button
+    >
+  </div>
+</template>
+
+<script>
+export default {
+  props: {
+    info: {
+      type: Object,
+      default: null
+    }
+  },
+  methods: {
+    download() {
+      window.open(this.info.openPage)
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped></style>

+ 64 - 16
src/views/msg/index.vue

@@ -1,22 +1,28 @@
 <template>
   <el-card shadow="hover">
-    <div class="light-green-bg">
-      <el-collapse v-model="activeName" accordion>
-        <el-collapse-item v-for="i in 20" :name="i" :key="i">
+    <div>
+      <el-empty description="暂无数据" v-if="data"></el-empty>
+      <el-collapse @change="change" accordion v-else>
+        <el-collapse-item v-for="i in data" :name="i.id" :key="i.id">
           <template #title>
-            <div class="padding-left flex flex-align-center flex-justify-start">
-              <div class="dot" />
-              <span>消息标题</span>
+            <div class="flex flex-center flex-justify-between full-width">
+              <div
+                class="padding-left flex flex-align-center flex-justify-start"
+              >
+                <div
+                  class="dot"
+                  :style="i.readFlag === 0 ? '' : 'background-color: #d6d6d6'"
+                />
+                <span>{{ i.titile }}</span>
+              </div>
+              <span class="padding-right">{{ i.createTime }}</span>
             </div>
           </template>
-          <div>
-            Consistent with real life: in line with the process and logic of
-            real life, and comply with languages and habits that the users are
-            used to;
-          </div>
-          <div>
-            Consistent within interface: all elements should be consistent, such
-            as: design style, icons and texts, position of elements, etc.
+          <div class="full-width flex flex-justify-start padding">
+            <span v-if="i.msgCategory === 1" class="ml-20">{{
+              i.msgContent
+            }}</span>
+            <msg2 v-else-if="i.msgCategory === 2" :info="i" />
           </div>
         </el-collapse-item>
       </el-collapse>
@@ -27,11 +33,53 @@
 <route>
 {
 name: '通知中心',
-meta: { 'back':true,'showMsg' : "填写了”项目实际入库时间“的项目将不在预审管理中显示"}
+meta: { 'back':true}
 }
 </route>
 <script>
-export default {}
+import msg2 from '@/views/msg/component/msg2.vue'
+export default {
+  components: {
+    msg2
+  },
+  data() {
+    return {
+      data: [],
+      page: {
+        current: 1,
+        size: 10
+      }
+    }
+  },
+  created() {
+    this.list()
+  },
+  methods: {
+    list() {
+      this.$api.msg.list(this.page).then(res => {
+        if (res.code === 200) {
+          this.data = res.data.records
+        }
+      })
+    },
+    change(res) {
+      const tmp = this.data.find(ele => ele.id === res)
+      if (tmp && tmp.readFlag === 1) {
+        return
+      }
+      this.$api.msg.markRead({ id: res }).then(res => {
+        if (res.code === 200) {
+          this.data = this.data.map(ele => {
+            if (ele.id === res) {
+              ele.readFlag = 1
+            }
+            return ele
+          })
+        }
+      })
+    }
+  }
+}
 </script>
 
 <style lang="scss" scoped>

+ 11 - 2
src/views/store/component/info3.vue

@@ -50,14 +50,23 @@
         </template>
         <template #menu="{ row }">
           <div>
+            <el-button
+              icon="Download"
+              type="primary"
+              size="mini"
+              text
+              @click="show = true"
+              >查 看
+            </el-button>
             <el-button
               icon="View"
               type="primary"
               size="mini"
               text
               @click="previewFile(row)"
-              >查 看
+              >预 览
             </el-button>
+
             <el-button
               icon="Download"
               type="primary"
@@ -138,7 +147,7 @@ export default {
       },
       option: {
         align: 'center',
-        menuWidth: 380,
+        menuWidth: 420,
         height: 525,
         size: 'mini',
         addBtn: false,

+ 24 - 1
src/views/store/index.vue

@@ -28,9 +28,12 @@
       >
         <template #menu-left>
           <div class="mt-20 mb-10">
-            <el-button type="primary" plain v-if="user.info.viewStage !== 1"
+            <el-button type="primary" v-if="user.info.viewStage !== 1"
               >上报预审</el-button
             >
+            <el-button type="primary" plain v-if="user.info.viewStage !== 1"
+              >删 除</el-button
+            >
           </div>
         </template>
 
@@ -70,6 +73,7 @@ export default {
         size: 'mini',
         viewBtn: true,
         editBtn: false,
+        selection: true,
         addBtn: false,
         refreshBtn: false,
         columnBtn: false,
@@ -80,6 +84,10 @@ export default {
             label: '项目名称',
             prop: 'name'
           },
+          {
+            label: '责任单位',
+            prop: 'unitName'
+          },
           {
             label: '上传时间',
             prop: 'createTime'
@@ -105,6 +113,21 @@ export default {
         }
       })
     },
+    rowDel(row) {
+      this.$confirm('确定删除选择的项目?', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(res => {
+        if (res === 'confirm') {
+          this.$api.store.remove({ ids: row.id }).then(res => {
+            if (res.code === 200) {
+              this.onLoad()
+            }
+          })
+        }
+      })
+    },
     beforeOpen(done, type) {
       if (type === 'view') {
         const data = this.$router.resolve({