From 34413216b5fe45d05d473f27ec6cb640a79e0c58 Mon Sep 17 00:00:00 2001
From: liukangdong <898885815@qq.com>
Date: 星期四, 16 五月 2024 11:04:04 +0800
Subject: [PATCH] 任务中心

---
 admin/src/components/common/QueryForm/index.js      |    3 
 admin/src/components/common/GlobalWindow.vue        |    6 
 admin/src/components/common/QueryForm/queryForm.vue |  241 +++++++++++++++
 admin/src/views/task/taskDetail.vue                 |  308 +++++++++++++++++++
 admin/src/views/task/index.vue                      |   86 +++++
 admin/src/assets/style/style.scss                   |  155 +++++++++
 admin/package-lock.json                             |  160 +++++----
 7 files changed, 879 insertions(+), 80 deletions(-)

diff --git a/admin/package-lock.json b/admin/package-lock.json
index c401a1d..1c372e3 100644
--- a/admin/package-lock.json
+++ b/admin/package-lock.json
@@ -1876,63 +1876,6 @@
           "integrity": "sha1-/q7SVZc9LndVW4PbwIhRpsY1IPo=",
           "dev": true
         },
-        "ansi-styles": {
-          "version": "4.3.0",
-          "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz",
-          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "color-convert": "^2.0.1"
-          }
-        },
-        "chalk": {
-          "version": "4.1.2",
-          "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
-          "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "ansi-styles": "^4.1.0",
-            "supports-color": "^7.1.0"
-          }
-        },
-        "color-convert": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
-          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "color-name": "~1.1.4"
-          }
-        },
-        "color-name": {
-          "version": "1.1.4",
-          "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
-          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
-          "dev": true,
-          "optional": true
-        },
-        "has-flag": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz",
-          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
-          "dev": true,
-          "optional": true
-        },
-        "loader-utils": {
-          "version": "2.0.4",
-          "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.4.tgz",
-          "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "big.js": "^5.2.2",
-            "emojis-list": "^3.0.0",
-            "json5": "^2.1.2"
-          }
-        },
         "ssri": {
           "version": "8.0.1",
           "resolved": "https://registry.npm.taobao.org/ssri/download/ssri-8.0.1.tgz?cache=0&sync_timestamp=1617826515595&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fssri%2Fdownload%2Fssri-8.0.1.tgz",
@@ -1940,28 +1883,6 @@
           "dev": true,
           "requires": {
             "minipass": "^3.1.1"
-          }
-        },
-        "supports-color": {
-          "version": "7.2.0",
-          "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz",
-          "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "has-flag": "^4.0.0"
-          }
-        },
-        "vue-loader-v16": {
-          "version": "npm:vue-loader@16.8.3",
-          "resolved": "https://registry.npmmirror.com/vue-loader/-/vue-loader-16.8.3.tgz",
-          "integrity": "sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "chalk": "^4.1.0",
-            "hash-sum": "^2.0.0",
-            "loader-utils": "^2.0.0"
           }
         }
       }
@@ -13937,6 +13858,87 @@
         }
       }
     },
+    "vue-loader-v16": {
+      "version": "npm:vue-loader@16.8.3",
+      "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.8.3.tgz",
+      "integrity": "sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "chalk": "^4.1.0",
+        "hash-sum": "^2.0.0",
+        "loader-utils": "^2.0.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "color-convert": "^2.0.1"
+          }
+        },
+        "chalk": {
+          "version": "4.1.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+          "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true,
+          "optional": true
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true,
+          "optional": true
+        },
+        "loader-utils": {
+          "version": "2.0.4",
+          "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
+          "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "big.js": "^5.2.2",
+            "emojis-list": "^3.0.0",
+            "json5": "^2.1.2"
+          }
+        },
+        "supports-color": {
+          "version": "7.2.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+          "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        }
+      }
+    },
     "vue-property-decorator": {
       "version": "8.5.1",
       "resolved": "https://registry.npmjs.org/vue-property-decorator/-/vue-property-decorator-8.5.1.tgz",
diff --git a/admin/src/assets/style/style.scss b/admin/src/assets/style/style.scss
index 4718bce..f7e3036 100644
--- a/admin/src/assets/style/style.scss
+++ b/admin/src/assets/style/style.scss
@@ -20,6 +20,7 @@
     margin: 0;
     overflow: scroll;
     overflow: hidden;
+    font-size: 14px;
     scrollbar-width: none; /* firefox */
     -ms-overflow-style: none; /* IE 10+ */
     &::-webkit-scrollbar {
@@ -124,3 +125,157 @@
     top: 1px;
   }
 }
+
+.main_app {
+  background-color: #fff;
+  padding: 30px;
+  margin: 0 16px;
+}
+/** 鍩虹閫氱敤 **/
+ // 澶у皬 澶栬竟璺�
+ .flex1{
+  flex: 1;
+ }
+ .w100{
+  width: 100px !important;
+ }
+ .w120{
+  width: 120px !important;
+ }
+ .w200{
+  width: 200px !important;
+ }
+ .w300{
+  width: 300px;
+ }
+ .w400{
+  width: 400px !important;
+ }
+ .pt5 {
+  padding-top: 5px;
+}
+
+.pr5 {
+  padding-right: 5px;
+}
+
+.pb5 {
+  padding-bottom: 5px;
+}
+
+.mt5 {
+  margin-top: 5px;
+}
+
+.mr5 {
+  margin-right: 5px;
+}
+
+.mb5 {
+  margin-bottom: 5px;
+}
+
+.mb8 {
+  margin-bottom: 8px;
+}
+
+.ml5 {
+  margin-left: 5px;
+}
+
+.mt10 {
+  margin-top: 10px;
+}
+
+.mr10 {
+  margin-right: 10px;
+}
+
+.mb10 {
+  margin-bottom: 10px;
+}
+
+.ml10 {
+  margin-left: 10px;
+}
+
+.mt20 {
+  margin-top: 20px;
+}
+
+.mr20 {
+  margin-right: 20px;
+}
+
+.mb20 {
+  margin-bottom: 20px;
+}
+
+.ml20 {
+  margin-left: 20px;
+}
+.mt30 {
+  margin-top: 30px;
+}
+
+.mr30 {
+  margin-right: 30px;
+}
+
+.mb30 {
+  margin-bottom: 30px;
+}
+.pr20{
+  padding-right: 20px;
+}
+
+.ml30 {
+  margin-left: 30px;
+}
+.h24{
+  height: 24px;
+  line-height: 24px;
+}
+
+// flex甯冨眬
+.df{
+  display: flex;
+}
+.df_ac{
+  display: flex;
+  align-items: center;
+  p {
+    margin: 0;
+  }
+}
+.df_sb{
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+// 鏂囨湰鏍峰紡
+.underline{
+  text-decoration: underline;
+}
+.fs12{
+  font-size: 12px;
+}
+.fs_12{
+  font-size: 12px;
+}
+.fs_16{
+  font-size: 16px;
+}
+.fs_18{
+  font-size: 18px;
+}
+.fs_24{
+  font-size: 24px;
+}
+.text{
+  color: #333333;
+}
+.tac{
+  text-align: center;
+}
diff --git a/admin/src/components/common/GlobalWindow.vue b/admin/src/components/common/GlobalWindow.vue
index 298b468..c1d0c9c 100644
--- a/admin/src/components/common/GlobalWindow.vue
+++ b/admin/src/components/common/GlobalWindow.vue
@@ -21,7 +21,7 @@
     <div v-if="withFooter" class="window__footer">
       <slot name="footer">
         <el-button @click="confirm" :loading="confirmWorking" type="primary">{{text}}</el-button>
-        <el-button @click="close">杩斿洖</el-button>
+        <el-button @click="close">{{ backText }}</el-button>
       </slot>
     </div>
   </el-drawer>
@@ -45,6 +45,10 @@
       type: String,
       default: '纭畾'
     },
+    backText: {
+      type: String,
+      default: '杩斿洖'
+    },
     // 纭鎸夐挳loading鐘舵��
     confirmWorking: {
       type: Boolean,
diff --git a/admin/src/components/common/QueryForm/index.js b/admin/src/components/common/QueryForm/index.js
new file mode 100644
index 0000000..0114373
--- /dev/null
+++ b/admin/src/components/common/QueryForm/index.js
@@ -0,0 +1,3 @@
+import QueryForm from './queryForm.vue'
+
+export default QueryForm
diff --git a/admin/src/components/common/QueryForm/queryForm.vue b/admin/src/components/common/QueryForm/queryForm.vue
new file mode 100644
index 0000000..66563cb
--- /dev/null
+++ b/admin/src/components/common/QueryForm/queryForm.vue
@@ -0,0 +1,241 @@
+<template>
+  <div class="doumee-filter">
+    <el-form inline label-suffix="锛�" @submit.native.prevent>
+      <template v-for="(item, index) in queryFormConfig.formItems">
+        <el-form-item v-if="item.type === 'input' && (showZk || index < listLength)" :key="item.filed"
+          :label="item.label">
+          <el-input v-model="searchForm[item.filed]"
+            :clearable="(item.clearable !== null && item.clearable !== undefined && item.clearable !== '') ? item.clearable : true"
+            :placeholder="item.placeholder ? item.placeholder : '璇疯緭鍏�' + item.label" class="w200"
+            @change="changeForm(item.filed)" @keyup.enter.native="handlekeyup(item.keyup || false)" />
+        </el-form-item>
+        <el-form-item v-if="item.type === 'moneySelect' && (showZk || index < listLength)" :key="item.label"
+          :label="item.label">
+          <el-input v-model="searchForm[item.filedStrt]"
+            :clearable="(item.clearable !== null && item.clearable !== undefined && item.clearable !== '') ? item.clearable : true"
+            :placeholder="item.start" style="width: 150px" />
+          <div class="date-division-line" style="margin-left: 10px;margin-bottom: 0;">~</div>
+          <el-input v-model="searchForm[item.filedEnd]"
+            :clearable="(item.clearable !== null && item.clearable !== undefined && item.clearable !== '') ? item.clearable : true"
+            :placeholder="item.end" style="width: 150px" />
+        </el-form-item>
+        <el-form-item v-if="item.type === 'select' && (showZk || index < listLength)" :key="item.filed"
+          :label="item.label">
+          <el-select v-model="searchForm[item.filed]" :filterable="item.filterable || true"
+            :clearable="(item.clearable !== null && item.clearable !== undefined && item.clearable !== '') ? item.clearable : true"
+            :placeholder="item.placeholder ? item.placeholder : '璇烽�夋嫨' + item.label" class="w200"
+            @change="changeForm(item.filed)">
+            <el-option v-for="opt, i in item.options" :key="i" :value="item.valueCode ? opt[item.valueCode] : opt.value"
+              :label="item.labelCode ? opt[item.labelCode] : opt.label" />
+          </el-select>
+        </el-form-item>
+        <el-form-item v-if="item.type === 'date' && (showZk || index < listLength)" :key="item.filed"
+          :label="item.label || '鏃ユ湡'">
+          <el-date-picker v-model="searchForm[item.filed]" type="date" value-format="yyyy-MM-dd" class="w200"
+            :clearable="(item.clearable !== null && item.clearable !== undefined && item.clearable !== '') ? item.clearable : true"
+            :placeholder="item.placeholder || '璇烽�夋嫨鏃ユ湡'" :picker-options="item.pickerOptions || {}"
+            @change="changeForm(item.filed)" />
+        </el-form-item>
+        <el-form-item v-if="item.type === 'daterange' && (showZk || index < listLength)" :key="item.filed"
+          :label="item.label || ''">
+          <el-date-picker v-model="searchForm[item.filed]" value-format="yyyy-MM-dd" type="daterange"
+            range-separator="鑷�"
+            :clearable="(item.clearable !== null && item.clearable !== undefined && item.clearable !== '') ? item.clearable : true"
+            :start-placeholder="item.start || ''" :end-placeholder="item.end || ''"
+            :picker-options="item.pickerOptions || {}" class="w400" @change="changeForm(item.filed)" />
+        </el-form-item>
+        <el-form-item v-if="item.type === 'timePicker' && (showZk || index < listLength)" :key="item.filed"
+          :label="item.label || '閫夋嫨鏃堕棿'">
+          <el-time-picker v-model="searchForm[item.filed]" is-range range-separator="鑷�" format="HH:mm"
+            value-format="HH:mm" start-placeholder="寮�濮嬫椂闂�" end-placeholder="缁撴潫鏃堕棿" placeholder="閫夋嫨鏃堕棿鑼冨洿" class="w400"
+            @change="changeForm(item.filed)" />
+        </el-form-item>
+        <el-form-item v-if="item.type === 'datetimerange' && (showZk || index < listLength)" :key="item.filed"
+          :label="item.label || '閫夋嫨鏃ユ湡'">
+          <el-date-picker v-model="searchForm[item.filed]" format="yyyy-MM-dd HH:mm:ss"
+            value-format="yyyy-MM-dd HH:mm:ss" type="datetimerange"
+            :picker-options="item.pickerOptions || pickerOptions" range-separator="鑷�"
+            :clearable="(item.clearable !== null && item.clearable !== undefined && item.clearable !== '') ? item.clearable : true"
+            :start-placeholder="item.start || '寮�濮嬫椂闂�'" :end-placeholder="item.end || '缁撴潫鏃堕棿'" class="w400"
+            @change="changeForm(item.filed)" />
+        </el-form-item>
+        <el-form-item v-if="item.type === 'slot' && (showZk || index < listLength)" :key="item.filed"
+          :label="item.label">
+          <slot :name="item.filed" />
+        </el-form-item>
+      </template>
+      <!-- 鎿嶄綔 -->
+      <el-form-item>
+        <el-button type="primary" @click="handleQuery">鎼滅储</el-button>
+        <el-button v-if="showQk" @click="clear">閲嶇疆</el-button>
+        <slot name="btns" />
+        <template v-if="queryFormConfig.formItems.length > listLength">
+          <el-button v-if="!showZk" type="text" @click="zkBtn">灞曞紑<i
+              class="el-icon-caret-bottom primaryColor" /></el-button>
+          <el-button v-if="showZk" type="text" @click="zkBtn">鏀惰捣<i class="el-icon-caret-top primaryColor" /></el-button>
+        </template>
+      </el-form-item>
+    </el-form>
+  </div>
+</template>
+
+<script>
+export default {
+  props: {
+    value: {
+      type: Object,
+      default: () => { }
+    },
+    showQk: {
+      type: Boolean,
+      default: true
+    },
+    listLength: {
+      type: Number,
+      default: 3
+    },
+    queryFormConfig: {
+      type: Object,
+      default: () => { }
+    }
+  },
+  data() {
+    return {
+      showZk: false,
+      pickerOptions: {
+        shortcuts: [{
+          text: '杩�7澶�',
+          onClick(picker) {
+            const end = new Date()
+            const start = new Date()
+            start.setTime(end.getTime() - 3600 * 1000 * 24 * 6)
+            picker.$emit('pick', [start, end])
+          }
+        },
+        {
+          text: '杩�30澶�',
+          onClick(picker) {
+            const end = new Date()
+            const start = new Date()
+            start.setTime(end.getTime() - 3600 * 1000 * 24 * 29)
+            picker.$emit('pick', [start, end])
+          }
+        },
+        {
+          text: '杩�60澶�',
+          onClick(picker) {
+            const end = new Date()
+            const start = new Date()
+            start.setTime(end.getTime() - 3600 * 1000 * 24 * 59)
+            picker.$emit('pick', [start, end])
+          }
+        },
+        {
+          text: '杩�90澶�',
+          onClick(picker) {
+            const end = new Date()
+            const start = new Date()
+            start.setTime(end.getTime() - 3600 * 1000 * 24 * 89)
+            picker.$emit('pick', [start, end])
+          }
+        }],
+        disabledDate(time) {
+          var curDate = new Date(new Date().toLocaleDateString()).getTime()
+          var preDate = new Date(curDate + 24 * 60 * 60 * 1000 - 1)
+          return time.getTime() > preDate
+        }
+      }
+    }
+  },
+  emits: ['input', 'handleQuery', 'clear'],
+  computed: {
+    searchForm: {
+      get() {
+        return this.value
+      },
+      set(value) {
+        this.$emit('input', value)
+      }
+    }
+  },
+  methods: {
+    handleQuery() {
+      this.$emit('handleQuery')
+    },
+    handlekeyup(pd) {
+      if (pd) {
+        this.$emit('handleQuery')
+      }
+    },
+    changeForm(filed) {
+      this.$emit('changeForm', filed)
+    },
+    zkBtn() {
+      this.showZk = !this.showZk
+      this.$emit('zkBtn', this.zk)
+    },
+    clear() {
+      this.$emit('clear')
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.doumee-filter {
+  display: flex;
+  align-items: center;
+  position: relative;
+  flex-wrap: wrap;
+  align-items: center;
+  background-color: #fff;
+  border-bottom: 10px solid #f7f8f9;
+  margin: 0 -30px;
+  padding: 0 0 0 30px;
+
+  .el-input,
+  .el-select {
+    width: 200px;
+    margin-right: 20px;
+    margin-bottom: 20px;
+    height: 36px;
+
+    .el-input__inner {
+      /* color: $textColor; */
+      padding: 0 16px;
+    }
+  }
+
+  .el-date-editor {
+    width: 200px;
+    margin-right: 20px;
+    margin-bottom: 20px;
+
+    .el-input__inner {
+      padding-left: 30px;
+    }
+  }
+
+  .el-button {
+    margin-bottom: 20px;
+  }
+
+  .el-form-item {
+    margin-bottom: 20px;
+    margin-right: 20px;
+
+    .el-input,
+    .el-select,
+    .el-date-editor {
+      margin-right: 0;
+    }
+
+    .el-input,
+    .el-select,
+    .el-date-editor,
+    .el-button {
+      margin-bottom: 0;
+    }
+  }
+}
+</style>
diff --git a/admin/src/views/task/index.vue b/admin/src/views/task/index.vue
new file mode 100644
index 0000000..131db2c
--- /dev/null
+++ b/admin/src/views/task/index.vue
@@ -0,0 +1,86 @@
+<template>
+  <div class="main_app">
+    <QueryForm v-model="filters" :query-form-config="queryFormConfig" @handleQuery="getList(1)" @clear="clear" />
+    <!--  -->
+    <el-tabs v-model="activeTab">
+      <el-tab-pane label="寰呭鐞�" name="0"></el-tab-pane>
+      <el-tab-pane label="宸插鐞�" name="1"></el-tab-pane>
+      <el-tab-pane label="鎴戝彂璧风殑" name="2"></el-tab-pane>
+      <el-tab-pane label="鎶勯�佹垜鐨�" name="3"></el-tab-pane>
+    </el-tabs>
+    <el-table v-loading="loading" :data="list" stripe row-key="id" default-expand-all>
+      <el-table-column prop="name" label="浠诲姟绫诲瀷" min-width="100"></el-table-column>
+      <el-table-column prop="name" label="鎻愪氦浜�" min-width="80"></el-table-column>
+      <el-table-column prop="companyNamePath" label="鎻愪氦鏃堕棿" min-width="100"></el-table-column>
+      <el-table-column label="鎿嶄綔" width="230" fixed="right">
+        <template slot-scope="{row}">
+          <el-button type="text" @click="handleDetail(row)" v-permissions="['business:company:update']">鏌ョ湅璇︽儏</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <pagination @size-change="handleSizeChange" @current-change="getList" :pagination="pagination" />
+    <TaskDetail v-if="isShowDetail" ref="DetailRef" />
+  </div>
+</template>
+
+<script>
+import Pagination from '@/components/common/Pagination'
+import QueryForm from '@/components/common/QueryForm'
+import TaskDetail from './taskDetail.vue'
+export default {
+  components: {
+    TaskDetail,
+    QueryForm,
+    Pagination
+  },
+  data () {
+    return {
+      isShowDetail: false,
+      activeTab: '0',
+      filters: {},
+      queryFormConfig: {
+        formItems: [
+          {
+            filed: 'taskType',
+            type: 'select',
+            label: '浠诲姟绫诲瀷',
+            options: []
+          },
+          {
+            filed: 'status',
+            type: 'daterange',
+            label: ''
+          }
+        ],
+        online: true
+      },
+      loading: false,
+      sorting: false,
+      searchForm: {
+        // type: 1
+      },
+      pagination: {
+        capacity: 10,
+        page: 1
+      },
+      list: [{}],
+      total: 0
+    }
+  },
+  methods: {
+    handleDetail () {
+      this.isShowDetail = true
+      this.$nextTick(() => {
+        this.$refs.DetailRef.isShowModal = true
+      })
+    },
+    getList (page) { },
+    clear () { },
+    handleSizeChange (capacity) {
+      this.pagination.capacity = capacity
+    }
+  }
+}
+</script>
+
+<style scoped lang="scss"></style>
diff --git a/admin/src/views/task/taskDetail.vue b/admin/src/views/task/taskDetail.vue
new file mode 100644
index 0000000..a3aea6c
--- /dev/null
+++ b/admin/src/views/task/taskDetail.vue
@@ -0,0 +1,308 @@
+<template>
+  <GlobalWindow
+    :title="title"
+    text="鍚屾剰"
+    backText="鎷掔粷"
+    :visible.sync="isShowModal"
+    @confirm="confirm"
+  >
+    <div class="modal_wrap">
+      <div class="modal_content">
+        <div class="header">
+          <div class="left">
+            <div class="h1">璁垮棰勭害</div>
+            <div class="time">鎻愪氦鏃堕棿锛�</div>
+          </div>
+          <div class="right">寰呭鏍�</div>
+        </div>
+        <div class="info">
+          <div class="title">璁垮棰勭害淇℃伅</div>
+          <div class="list">
+            <div class="item">
+              <div class="label">琚浜�</div>
+              <div class="value"></div>
+            </div>
+            <div class="item">
+              <div class="label">鏉ヨ鏃堕棿</div>
+              <div class="value"></div>
+            </div>
+            <div class="item">
+              <div class="label">鏉ヨ浜嬬敱</div>
+              <div class="value"></div>
+            </div>
+            <div class="item">
+              <div class="label">闅忚杞﹁締</div>
+              <div class="value"></div>
+            </div>
+            <div class="item">
+              <div class="label">鏂藉伐浜哄憳</div>
+              <div class="value"></div>
+            </div>
+            <div class="item">
+              <div class="label">鏂藉伐鍐呭</div>
+              <div class="value"></div>
+            </div>
+          </div>
+        </div>
+        <div class="table_info">
+          <div class="title">璁垮淇℃伅</div>
+          <el-table :data="detail.datalist" border fit>
+            <el-table-column label="濮撳悕" prop="" min-width="150">
+              <template slot-scope="{ row }">
+                <div class="name_wrap">
+                  <image src="" class="avatar" mode="" />
+                  <div class="content">
+                    <div class="line">
+                      <div class="name">鏉庝笢</div>
+                      <div class="tag">鐢宠浜�</div>
+                    </div>
+                    <div class="line placeholder9">1888888</div>
+                  </div>
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column label="鎬у埆" prop="" min-width="40" />
+            <el-table-column label="璇佷欢绫诲瀷" prop="" min-width="80" />
+            <el-table-column label="璇佷欢鍙风爜" prop="" min-width="120" />
+            <el-table-column label="鍏徃鍚嶇О" prop="" min-width="120" />
+            <el-table-column label="浜鸿劯鐓х墖" prop="" min-width="80" />
+          </el-table>
+        </div>
+      </div>
+      <div class="side">
+        <div class="side_title">瀹℃壒娴佺▼</div>
+        <div class="list">
+          <div class="item">
+            <div class="separate"></div>
+            <div class="info">
+              <i class="el-icon-success icon"></i>
+              <img src="" class="avatar" alt="" />
+              <div class="content">
+                <div class="line">
+                  <div class="name">鍒樻煇鍒樻煇</div>
+                  <div class="time">2020-02-02 12:20</div>
+                </div>
+                <div class="line">
+                  <div class="company">涓浗绉诲姩鏈夐檺鍏徃</div>
+                </div>
+              </div>
+            </div>
+          </div>
+          <div class="item">
+            <!-- <div v-if="" class="separate"></div> -->
+            <div class="info">
+              <i class="el-icon-success icon"></i>
+              <img src="" class="avatar" alt="" />
+              <div class="content">
+                <div class="line">
+                  <div class="name">鍒樻煇鍒樻煇</div>
+                  <div class="time">2020-02-02 12:20</div>
+                </div>
+                <div class="line">
+                  <div class="company">
+                    涓浗绉诲姩鏈夐檺鍏徃( <span class="status">宸插悓鎰�</span> )
+                  </div>
+                </div>
+              </div>
+            </div>
+            <div class="remark">鎻愪氦绾﹀ソ鐨�</div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </GlobalWindow>
+</template>
+
+<script>
+import GlobalWindow from '@/components/common/GlobalWindow'
+export default {
+  components: { GlobalWindow },
+  data() {
+    return {
+      title: '璁垮棰勭害璇︽儏',
+      isShowModal: false,
+      detail: {
+        datalist: [{}]
+      }
+    }
+  },
+  methods: {
+    confirm() {
+      console.log('--')
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.modal_wrap {
+  display: flex;
+  height: 100%;
+  .modal_content {
+    flex: 1;
+    padding: 0px 30px;
+    border-radius: 8px;
+    overflow: hidden;
+    height: 100%;
+
+    .title {
+      font-weight: 600;
+      font-size: 18px;
+      color: #333333;
+      margin-bottom: 20px;
+      margin-top: 30px;
+    }
+
+    .info {
+      .list {
+        display: flex;
+        flex-wrap: wrap;
+
+        .item {
+          display: flex;
+          width: 40%;
+          margin-bottom: 20px;
+          &:nth-of-type(2n) {
+            width: 60%;
+          }
+
+          .label {
+            color: #888888;
+            width: 68px;
+          }
+
+          .value {
+            color: #111111;
+          }
+        }
+      }
+    }
+
+    .header {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      padding: 20px 30px;
+      margin: 0 -30px;
+      border-radius: 8px 8px 0 0;
+      background: linear-gradient(to right, #f2f6fe, #cadffa);
+
+      .h1 {
+        font-weight: 600;
+        font-size: 22px;
+        color: #111111;
+        margin-bottom: 8px;
+      }
+
+      .time {
+        font-size: 14px;
+        color: #999999;
+      }
+
+      .right {
+        height: 40px;
+        font-size: 16px;
+        color: #ffffff;
+        line-height: 40px;
+        padding: 0 20px;
+        background: #207ff7;
+        box-shadow: 4px 4px 0px 0px rgba(32, 127, 247, 0.16);
+        border-radius: 16px 0px 16px 0px;
+      }
+    }
+    .table_info {
+      .name_wrap {
+        display: flex;
+        align-items: center;
+        .avatar {
+          width: 40px;
+          height: 40px;
+          border-radius: 50%;
+          margin-right: 12px;
+        }
+        .content {
+          .line {
+            display: flex;
+          }
+          .tag {
+            color: #b2cbf9;
+            border: 1px solid #b2cbf9;
+            padding: 0px 4px;
+            border-radius: 4px;
+            margin-left: 6px;
+          }
+        }
+      }
+    }
+  }
+
+  .side {
+    height: 100%;
+    width: 420px;
+    background: #ffffff;
+    border-left: 20px solid #f7f7f7;
+    .list {
+      .item {
+        padding: 8px 0;
+        position: relative;
+        .separate {
+          position: absolute;
+          border-left: 2px dashed #cccccc;
+          left: 51px;
+          height: calc(100% - 24px);
+          top: 46px;
+        }
+        .info {
+          display: flex;
+          align-items: center;
+          margin-left: 40px;
+          .icon {
+            position: relative;
+            z-index: 11;
+            color: #53b76f;
+            font-size: 24px;
+          }
+          .avatar {
+            width: 40px;
+            height: 40px;
+            border-radius: 50%;
+            margin: 0 12px 0 16px;
+            border: 1px solid;
+          }
+          .content {
+            flex: 1;
+            .line {
+              display: flex;
+              justify-content: space-between;
+              align-content: center;
+              margin-bottom: 6px;
+              .name {
+                font-weight: 600;
+                font-size: 16px;
+                color: #111111;
+              }
+              .time {
+                color: #888888;
+              }
+              .company {
+                font-size: 13px;
+                color: #888888;
+                .status {
+                  color: #00ba67;
+                }
+              }
+            }
+          }
+        }
+        .remark {
+          background: #f7f7f7;
+          border-radius: 4px;
+          padding: 13px 15px;
+          color: #666666;
+          margin-left: 120px;
+        }
+      }
+    }
+  }
+}
+</style>

--
Gitblit v1.9.3