caiaa1 1 year ago
parent
commit
f72dbbdd2e

+ 48 - 0
mock/business.js

@@ -0,0 +1,48 @@
+module.exports = [
+  {
+    url: '/business/search',
+    type: 'post',
+    response: config => {
+      return {
+        code: 200,
+        msg: 'success',
+        data: {
+          total: 44,
+          records: [
+            { 'id': '0', 'businessName': 'bizName0', 'businessCode': 'code0', 'appId': 'appCode0', 'appName': 'appName0' },
+            { 'id': '1', 'businessName': 'bizName1', 'businessCode': 'code1', 'appId': 'appCode1', 'appName': 'appName1' },
+            { 'id': '2', 'businessName': 'bizName2', 'businessCode': 'code2', 'appId': 'appCode2', 'appName': 'appName2' },
+            { 'id': '3', 'businessName': 'bizName3', 'businessCode': 'code3', 'appId': 'appCode3', 'appName': 'appName3' },
+            { 'id': '4', 'businessName': 'bizName4', 'businessCode': 'code4', 'appId': 'appCode4', 'appName': 'appName4' },
+            { 'id': '5', 'businessName': 'bizName5', 'businessCode': 'code5', 'appId': 'appCode5', 'appName': 'appName5' },
+            { 'id': '6', 'businessName': 'bizName6', 'businessCode': 'code6', 'appId': 'appCode6', 'appName': 'appName6' },
+            { 'id': '7', 'businessName': 'bizName7', 'businessCode': 'code7', 'appId': 'appCode7', 'appName': 'appName7' },
+            { 'id': '8', 'businessName': 'bizName8', 'businessCode': 'code8', 'appId': 'appCode8', 'appName': 'appName8' },
+            { 'id': '9', 'businessName': 'bizName9', 'businessCode': 'code9', 'appId': 'appCode9', 'appName': 'appName9' }
+          ]
+        }
+      }
+    }
+  },
+  {
+    url: '/business/list',
+    type: 'post',
+    response: config => {
+      return {
+        code: 200,
+        msg: 'success',
+        data: {
+          total: 44,
+          records: [
+            { 'id': '1', 'businessName': 'bizName1', 'businessCode': 'code1', 'appId': 'appCode1', 'appName': 'appName1' },
+            { 'id': '2', 'businessName': 'bizName2', 'businessCode': 'code2', 'appId': 'appCode2', 'appName': 'appName2' },
+            { 'id': '4', 'businessName': 'bizName4', 'businessCode': 'code4', 'appId': 'appCode4', 'appName': 'appName4' },
+            { 'id': '5', 'businessName': 'bizName5', 'businessCode': 'code5', 'appId': 'appCode5', 'appName': 'appName5' },
+            { 'id': '8', 'businessName': 'bizName8', 'businessCode': 'code8', 'appId': 'appCode8', 'appName': 'appName8' },
+            { 'id': '9', 'businessName': 'bizName9', 'businessCode': 'code9', 'appId': 'appCode9', 'appName': 'appName9' }
+          ]
+        }
+      }
+    }
+  }
+]

+ 2 - 0
mock/index.js

@@ -3,8 +3,10 @@ const { param2Obj } = require('./utils')
 
 const user = require('./user')
 const message = require('./message')
+const business = require('./business')
 
 const mocks = [
+  ...business,
   ...message,
   ...user
 ]

+ 1 - 0
package.json

@@ -22,6 +22,7 @@
     "normalize.css": "7.0.0",
     "nprogress": "0.2.0",
     "path-to-regexp": "2.4.0",
+    "querystring": "^0.2.1",
     "sortablejs": "1.8.4",
     "tui-editor": "1.3.3",
     "vue": "2.6.10",

+ 9 - 1
src/api/biz.js

@@ -1,6 +1,14 @@
 import request from '@/utils/request'
 
-export function fetchTableList(data) {
+export function fetchAllBizList(data) {
+  return request({
+    url: 'business/search',
+    method: 'post',
+    data: data
+  })
+}
+
+export function fetchMyBizList(data) {
   return request({
     url: 'business/list',
     method: 'post',

+ 2 - 1
src/api/info.js

@@ -1,7 +1,8 @@
 import request from '@/utils/request'
+import { stringify } from 'querystring'
 
 export function fetchTableList(data) {
   return request({
-    url: `messageInfo/page?${data}`
+    url: `messageInfo/page?${stringify(data)}`
   })
 }

+ 2 - 1
src/api/message.js

@@ -1,8 +1,9 @@
 import request from '@/utils/request'
+import { stringify } from 'querystring'
 
 export function fetchTableList(data) {
   return request({
-    url: `/noticeInfo/page?${data}`
+    url: `/noticeInfo/page?${stringify(data)}`
   })
 }
 

+ 9 - 0
src/api/system.js

@@ -0,0 +1,9 @@
+import request from '@/utils/request'
+
+export function fetchSystemList(data) {
+  return request({
+    url: 'app/list',
+    method: 'post',
+    data: data
+  })
+}

+ 99 - 0
src/components/Kanban/index.vue

@@ -0,0 +1,99 @@
+<template>
+  <div class="board-column">
+    <div class="board-column-header">
+      {{ headerText }}
+    </div>
+    <draggable
+      :list="list"
+      v-bind="$attrs"
+      class="board-column-content"
+      :set-data="setData"
+    >
+      <div v-for="element in list" :key="element.id" class="board-item">
+        {{ element.name }} {{ element.id }}
+      </div>
+    </draggable>
+  </div>
+</template>
+
+<script>
+import draggable from 'vuedraggable'
+
+export default {
+  name: 'DragKanbanDemo',
+  components: {
+    draggable
+  },
+  props: {
+    headerText: {
+      type: String,
+      default: 'Header'
+    },
+    options: {
+      type: Object,
+      default() {
+        return {}
+      }
+    },
+    list: {
+      type: Array,
+      default() {
+        return []
+      }
+    }
+  },
+  methods: {
+    setData(dataTransfer) {
+      // to avoid Firefox bug
+      // Detail see : https://github.com/RubaXa/Sortable/issues/1012
+      dataTransfer.setData('Text', '')
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+.board-column {
+  min-width: 300px;
+  min-height: 100px;
+  height: auto;
+  overflow: hidden;
+  background: #f0f0f0;
+  border-radius: 3px;
+
+  .board-column-header {
+    height: 50px;
+    line-height: 50px;
+    overflow: hidden;
+    padding: 0 20px;
+    text-align: center;
+    background: #333;
+    color: #fff;
+    border-radius: 3px 3px 0 0;
+  }
+
+  .board-column-content {
+    height: auto;
+    overflow: hidden;
+    border: 10px solid transparent;
+    min-height: 60px;
+    display: flex;
+    justify-content: flex-start;
+    flex-direction: column;
+    align-items: center;
+
+    .board-item {
+      cursor: pointer;
+      width: 100%;
+      height: 64px;
+      margin: 5px 0;
+      background-color: #fff;
+      text-align: left;
+      line-height: 54px;
+      padding: 5px 10px;
+      box-sizing: border-box;
+      box-shadow: 0px 1px 3px 0 rgba(0, 0, 0, 0.2);
+    }
+  }
+}
+</style>
+

+ 33 - 20
src/utils/convert.js

@@ -15,6 +15,7 @@ export function toMoney(num) {
   return num
 }
 
+// 空数组 空字符串
 export function isNull(str) {
   if (str === null || str === undefined || str.length === 0) {
     return true
@@ -22,6 +23,33 @@ export function isNull(str) {
   return false
 }
 
+// typeof {a: 'a', b: 'b'} // object
+// typeof Promise.resolve() // object
+// typeof new Date() // object
+// typeof [1, 2, 3] // object
+export function isObject(obj) {
+  return obj !== null && typeof obj === 'object'
+}
+
+export function isPlainObject(obj) {
+  return Object.prototype.toString.call(obj) === '[object Object]'
+}
+
+// Object.keys: 只能遍历可枚举属性
+// Object.getOwnPropertyNames: 可枚举和不可枚举,无法获取到用Symbol表示的属性
+// Reflect.ownKeys: 可枚举和不可枚举和Symbol
+export function isEmptyObj(obj) {
+  return isObject(obj) && Object.keys(obj).length === 0
+}
+
+export function isArray(obj) {
+  if (Array.isArray) {
+    return Array.isArray(obj)
+  } else {
+    return Object.prototype.toString.call(obj) === '[object Array]'
+  }
+}
+
 // 上传文件格式(文件名字)只能是数字字母下划线空格
 export function Regular(str) {
   if (!/^[^`!!@#$%^&*.<>]*$/.test(str)) {
@@ -87,26 +115,7 @@ export function distinct(arr) {
   }
   return newArr
 }
-export function toQuery(data) {
-  if (data === null || data === undefined) {
-    return ''
-  }
-  const query = []
-  let value
-  for (const key in data) {
-    value = data[key]
-    if (value !== null && value !== undefined) {
-      if (typeof value === 'string') {
-        if (value.trim() !== '') {
-          query.push(key + '=' + value.trim())
-        }
-      } else {
-        query.push(key + '=' + value)
-      }
-    }
-  }
-  return query.join('&')
-}
+
 export function formatDictData(data, code) {
   if (code !== null && code !== undefined && data !== null && data !== undefined) {
     for (let i = 0; i < data.length; i++) {
@@ -117,3 +126,7 @@ export function formatDictData(data, code) {
   }
   return ''
 }
+
+export function hasValidRecords(res) {
+  return isObject(res.data) && isArray(res.data.records)
+}

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

@@ -1,5 +1,6 @@
 <template>
-  <div class="app-container">
+  <div>
+    <el-button type="primary" @click="showEdit">Click</el-button>
     <el-input v-model="filterText" placeholder="Filter keyword" style="margin-bottom:30px;" />
 
     <el-tree
@@ -7,15 +8,18 @@
       :data="data2"
       :props="defaultProps"
       :filter-node-method="filterNode"
-      class="filter-tree"
       default-expand-all
     />
 
+    <business-edit ref="businessEdit" />
   </div>
 </template>
 
 <script>
+import BusinessEdit from '../home/components/BusinessEdit.vue'
+
 export default {
+  components: { BusinessEdit },
 
   data() {
     return {
@@ -71,6 +75,9 @@ export default {
     filterNode(value, data) {
       if (!value) return true
       return data.label.indexOf(value) !== -1
+    },
+    showEdit() {
+      this.$refs.businessEdit.open()
     }
   }
 }

+ 2 - 3
src/views/home/Information.vue

@@ -22,7 +22,7 @@
   </div>
 </template>
 <script>
-import { isNull, toQuery } from '@/utils/convert'
+import { isNull } from '@/utils/convert'
 import { fetchTableList } from '@/api/info'
 
 export default {
@@ -59,9 +59,8 @@ export default {
       const params = {
         current: this.current,
         size: this.size
-        // orders: '["column":"createTime","asc":false]',
       }
-      fetchTableList(toQuery(params)).then(response => {
+      fetchTableList(params).then(response => {
         this.loading = false
         if (!isNull(response.data)) {
           this.tableData = response.data.records

+ 2 - 2
src/views/home/Message.vue

@@ -73,7 +73,7 @@
 import MessageList from './components/MessageList'
 
 import { fetchTableList } from '@/api/message'
-import { isNull, toQuery } from '@/utils/convert'
+import { isNull } from '@/utils/convert'
 
 export default {
   name: 'Message',
@@ -117,7 +117,7 @@ export default {
         readStatus: this.curTab === 'Done' ? 1 : 0,
         messageType: this.curTab === 'Done' ? this.doneType : this.todoType
       }
-      fetchTableList(toQuery(params)).then(response => {
+      fetchTableList(params).then(response => {
         this.loading = false
         if (!isNull(response.data)) {
           if (this.curTab === 'Done') {

+ 131 - 113
src/views/home/components/BusinessEdit.vue

@@ -1,85 +1,72 @@
 <template>
   <div>
     <el-dialog
-      v-loading="loading"
       :visible.sync="visible"
       :close-on-press-escape="true"
       :close-on-click-modal="false"
       lock-scroll
       append-to-body
-      custom-class="home-sys-dialog"
-      title="我的业务"
+      custom-class="home-more-dialog"
+      title="My"
       @close="close"
     >
-      <div class="list-filter">
-        <el-form ref="filterForm" :model="formData" inline label-width="100px">
-          <el-form-item label="消息标题">
-            <el-input v-model="formData.title" class="filter-item" clearable />
-          </el-form-item>
-          <el-form-item label="所属应用系统">
-            <el-select v-model="formData.systemCode" clearable filterable placeholder="请输入">
-              <el-option v-for="(item) in systemData" :key="item.code" :label="item.name" :value="item.code" />
-            </el-select>
-          </el-form-item>
-          <el-form-item label="状态">
-            <el-select v-model="formData.status" clearable placeholder="请选择">
-              <el-option v-for="(item) in statusData" :key="item.code" :label="item.name" :value="item.code" />
-            </el-select>
-          </el-form-item>
-          <el-form-item>
-            <el-button type="primary" @click="searchTable">查询</el-button>
-            <el-button type="danger" @click="resetTable('filterForm')">重置</el-button>
-          </el-form-item>
-        </el-form>
+      <div class="drag-container">
+        <div v-loading="allLoading" class="drag-left">
+          <div>list</div>
+          <div class="item-filter">
+            <el-form ref="filterForm" :model="formData" inline size="mini">
+              <el-form-item label="system">
+                <el-input v-model="formData.systemName" clearable />
+              </el-form-item>
+              <el-form-item label="business">
+                <!-- <el-select v-model="formData.businessNumber" clearable filterable placeholder="">
+                  <el-option v-for="(item) in businessData" :key="item.businessNumber" :label="item.businessName" :value="item.businessNumber" />
+                </el-select> -->
+                <el-input v-model="formData.businessName" clearable />
+              </el-form-item>
+              <el-form-item>
+                <el-button type="primary" @click="searchTable">search</el-button>
+                <el-button type="danger" @click="resetTable('filterForm')">reset</el-button>
+              </el-form-item>
+            </el-form>
+          </div>
+          <draggable :list="allBizData" group="business" class="board-column-content" :set-data="setData">
+            <div v-for="element in allBizData" :key="element.id" class="drag-item">
+              {{ element.businessName }}
+            </div>
+          </draggable>
+          <div v-if="allBizTotal > 0" class="page">
+            <el-pagination
+              small
+              layout="prev, pager, next"
+              :current-page="current"
+              :total="allBizTotal"
+              :page-size="size"
+              @current-change="handleCurrentChange"
+            />
+          </div>
+        </div>
+        <div v-loading="myLoading" class="drag-right">
+          <draggable :list="myBizData" group="business" class="board-column-content" :set-data="setData">
+            <div v-for="element in myBizData" :key="element.id" class="drag-item">
+              {{ element.businessName }}
+            </div>
+          </draggable>
+        </div>
       </div>
-      <div class="list-table">
-        <el-table :data="tableData" fit border stripe height="300" style="width: 100%;">
-          <el-table-column type="index" label="序号" width="50" />
-          <el-table-column prop="messageType" label="消息类型" :formatter="formatDictData" width="100" show-overflow-tooltip />
-          <el-table-column prop="title" label="消息标题" show-overflow-tooltip />
-          <el-table-column prop="system" label="所属应用系统" width="160" show-overflow-tooltip />
-          <el-table-column prop="readStatus" label="状态" :formatter="formatDictData" width="60" />
-          <el-table-column prop="createTime" label="消息接收时间" width="160" />
-          <el-table-column prop="createUser" label="消息发送人" width="100" show-overflow-tooltip />
-          <el-table-column label="操作" align="center" width="160" class-name="action-column">
-            <template slot-scope="scope">
-              <!-- <el-button type="text" @click="viewDetail(scope.row.id)">详情</el-button> -->
-              <el-button type="text" @click="viewDetail(scope.row.content)">详情</el-button>
-              <el-button v-if="scope.row.readStatus === 0" type="text" @click="markRead(scope.row)">不再提醒</el-button>
-            </template>
-          </el-table-column>
-        </el-table>
-      </div>
-      <div v-if="total > 0" class="page">
-        <el-pagination
-          layout="total, sizes, prev, pager, next, jumper"
-          :current-page="current"
-          :total="total"
-          :page-sizes="pageSizeAll"
-          :page-size="size"
-          @size-change="handleSizeChange"
-          @current-change="handleCurrentChange"
-        />
-      </div>
-    </el-dialog>
-    <el-dialog
-      :visible.sync="detailVisible"
-      :close-on-press-escape="true"
-      :close-on-click-modal="false"
-      lock-scroll
-      append-to-body
-      title="消息内容"
-      @close="closeDetail"
-    >
-      <pre>{{ content }}</pre>
     </el-dialog>
   </div>
 </template>
 <script>
-import { isNull, toQuery, formatDictData } from '@/utils/convert'
-import { fetchTableList, pushMarkRead } from '@/api/message'
+import draggable from 'vuedraggable'
+
+import { hasValidRecords, formatDictData } from '@/utils/convert'
+import { fetchAllBizList, fetchMyBizList } from '@/api/biz'
 
 export default {
+  components: {
+    draggable
+  },
   props: {},
   data() {
     return {
@@ -88,78 +75,109 @@ export default {
       // table
       current: 1,
       size: 20,
-      total: 0,
       pageSizeAll: [10, 20, 50, 100, 200, 500],
-      tableData: [],
+      allBizTotal: 0,
+      allBizData: [],
+      myBizData: [
+        { businessName: 'bizleft4', id: 4 },
+        { businessName: 'bizleft5', id: 5 },
+        { businessName: 'bizleft6', id: 6 },
+        { businessName: 'bizleft7', id: 7 }
+      ],
       // filter
       formData: {
-        title: '',
-        systemCode: '',
-        status: null
+        systemNumber: '',
+        systemName: '',
+        businessName: '',
+        businessNumber: ''
       },
       // select data
-      typeData: [{ 'code': 4, 'name': '任务类' }, { 'code': 5, 'name': '通知类' }, { 'code': 6, 'name': '超期提醒类' }],
-      systemData: [{ 'code': '1', 'name': 'System1' }, { 'code': '2', 'name': 'System2' }],
-      statusData: [{ 'code': 0, 'name': '待办' }, { 'code': 1, 'name': '已办' }],
+      systemData: [],
+      businessData: [],
       // others
-      loading: false,
-      detailVisible: false,
-      content: ''
+      allLoading: false,
+      myLoading: false
     }
   },
+  created() {
+  },
   methods: {
     // 改变每页显示条数
     handleSizeChange(val) {
       this.current = 1
       this.size = val
-      this.getTablelist()
+      this.getAllBizList()
     },
     // 切换第几页
     handleCurrentChange(val) {
       this.current = val
-      this.getTablelist()
+      this.getAllBizList()
     },
     // 重置搜索项
     resetTable(formName) {
       this.$refs[formName].resetFields()
-      this.getTablelist()
+      this.getAllBizList()
     },
     // 点击搜索按钮
     searchTable() {
       this.current = 1
-      this.getTablelist()
+      this.getAllBizList()
     },
     // 获取table数据
-    getTablelist() {
-      this.loading = true
+    getAllBizList() {
+      this.allLoading = true
       const params = {
         current: this.current,
         size: this.size,
-        // orders: '["column":"createTime","asc":false]',
-        title: this.formData.title,
-        systemCode: this.formData.systemCode,
-        readStatus: this.formData.status
+        systemName: this.formData.systemName,
+        businessName: this.formData.businessName
+      }
+      fetchAllBizList(params).then(response => {
+        this.allLoading = false
+        if (hasValidRecords(response)) {
+          this.allBizData = response.data.records
+          this.allBizTotal = response.data.total
+        } else {
+          this.allBizData = []
+          this.allBizTotal = 0
+        }
+      }).catch(error => {
+        console.log(error)
+        this.allLoading = false
+        this.$message.error({
+          type: 'error',
+          duration: 0,
+          showClose: true,
+          message: error.message
+        })
+      })
+    },
+    getMyBizList() {
+      this.myLoading = true
+      const params = {
+        current: 1,
+        size: 50
       }
-      fetchTableList(toQuery(params)).then(response => {
-        this.loading = false
-        if (!isNull(response.data)) {
-          this.tableData = response.data.records
-          this.total = response.data.total
+      fetchMyBizList(params).then(response => {
+        this.myLoading = false
+        if (hasValidRecords(response)) {
+          this.myBizData = response.data.records
         } else {
-          this.tableData = []
-          this.total = 0
+          this.myBizData = []
         }
       }).catch(error => {
         console.log(error)
-        this.loading = false
+        this.myLoading = false
         this.$message.error({
           type: 'error',
           duration: 0,
           showClose: true,
-          message: '获取消息列表出错: ' + error.message
+          message: error.message
         })
       })
     },
+    getSelectData() {
+    },
     /**
      * 加载附件界面
      */
@@ -167,6 +185,7 @@ export default {
       this.tableData = []
       this.visible = true
       this.searchTable()
+      this.getMyBizList()
     },
     close() {
       this.visible = false
@@ -179,21 +198,10 @@ export default {
       this.content = ''
       this.detailVisible = false
     },
-    markRead(row) {
-      this.loading = true
-      pushMarkRead(row.id).then(res => {
-        row.readStatus = 1
-        this.loading = false
-      }).catch(error => {
-        console.log(error)
-        this.loading = false
-        this.$message.error({
-          type: 'error',
-          duration: 0,
-          showClose: true,
-          message: '不再提醒操作出错: ' + error.message
-        })
-      })
+    setData(dataTransfer) {
+      // to avoid Firefox bug
+      // Detail see : https://github.com/RubaXa/Sortable/issues/1012
+      dataTransfer.setData('Text', '')
     },
     formatDictData(row, column, cellValue) {
       let data
@@ -209,8 +217,18 @@ export default {
 </script>
 
 <style lang="scss" scoped>
-pre {
-  white-space: pre-wrap;
-  word-wrap: break-word;
+.drag-container {
+  display: flex;
+  justify-content: space-between;
+
+  .drag-left, .drag-right {
+    width: 40%;
+  }
+
+  .drag-item {
+    width: 100px;
+    height: 20px;
+    border: 1px solid #cccccc;
+  }
 }
 </style>

+ 2 - 3
src/views/home/components/MessageList.vue

@@ -76,7 +76,7 @@
   </div>
 </template>
 <script>
-import { isNull, toQuery, formatDictData } from '@/utils/convert'
+import { isNull, formatDictData } from '@/utils/convert'
 import { fetchTableList, pushMarkRead } from '@/api/message'
 
 export default {
@@ -135,12 +135,11 @@ export default {
       const params = {
         current: this.current,
         size: this.size,
-        // orders: '["column":"createTime","asc":false]',
         title: this.formData.title,
         systemCode: this.formData.systemCode,
         readStatus: this.formData.status
       }
-      fetchTableList(toQuery(params)).then(response => {
+      fetchTableList(params).then(response => {
         this.loading = false
         if (!isNull(response.data)) {
           this.tableData = response.data.records

+ 2 - 3
src/views/home/components/SystemEdit.vue

@@ -76,7 +76,7 @@
   </div>
 </template>
 <script>
-import { isNull, toQuery, formatDictData } from '@/utils/convert'
+import { isNull, formatDictData } from '@/utils/convert'
 import { fetchTableList, pushMarkRead } from '@/api/message'
 
 export default {
@@ -135,12 +135,11 @@ export default {
       const params = {
         current: this.current,
         size: this.size,
-        // orders: '["column":"createTime","asc":false]',
         title: this.formData.title,
         systemCode: this.formData.systemCode,
         readStatus: this.formData.status
       }
-      fetchTableList(toQuery(params)).then(response => {
+      fetchTableList(params).then(response => {
         this.loading = false
         if (!isNull(response.data)) {
           this.tableData = response.data.records