Explorar o código

Merge branch 'develop' of http://code.dashoo.cn/chengjian/opms_frontend into develop

liuyaqi %!s(int64=3) %!d(string=hai) anos
pai
achega
fae9de6416

+ 14 - 0
src/api/base/productAuth.js

@@ -0,0 +1,14 @@
+import micro_request from '@/utils/micro_request'
+const basePath = process.env.VUE_APP_AdminPath
+export default {
+  // 用户列表
+  getList(query) {
+    return micro_request.postRequest(basePath, 'BaseProductAuth', 'GetProductLineUsers', query)
+  },
+  getDetail(query) {
+    return micro_request.postRequest(basePath, 'BaseProductAuth', 'GetList', query)
+  },
+  authorize(query) {
+    return micro_request.postRequest(basePath, 'BaseProductAuth', 'Save', query)
+  },
+}

+ 24 - 0
src/api/base/regionAuth.js

@@ -0,0 +1,24 @@
+/*
+ * @Author: wanglj 471442253@qq.com
+ * @Date: 2023-02-14 11:17:19
+ * @LastEditors: wanglj
+ * @LastEditTime: 2023-02-14 14:44:34
+ * @Description: file content
+ * @FilePath: \opms_frontend\src\api\base\regionAuth.js
+ */
+import micro_request from '@/utils/micro_request'
+const basePath = process.env.VUE_APP_AdminPath
+export default {
+  // 用户列表
+  getList(query) {
+    return micro_request.postRequest(basePath, 'BaseRegionAuth', 'GetRegionUsers', query)
+  },
+  // 授权
+  saveRegion(query) {
+    return micro_request.postRequest(basePath, 'BaseRegionAuth', 'Save', query)
+  },
+  // 区域/个人授权详情
+  getDetail(query) {
+    return micro_request.postRequest(basePath, 'BaseRegionAuth', 'GetList', query)
+  },
+}

+ 3 - 0
src/vab/components/VabQueryForm/index.vue

@@ -21,6 +21,9 @@
     margin: 0 0 0 0;
     > .el-button {
       margin: 0 10px $base-margin/2 0 !important;
+      &:last-child {
+        margin-right: 0 !important;
+      }
     }
   }
 

+ 21 - 4
src/vab/styles/default.scss

@@ -4049,7 +4049,7 @@ $--background-color-base: $base-color-background;
     align-items: center;
     font-size: 14px;
     padding-right: 8px;
-    span:first-child {
+    >span:first-child {
       flex: 1;
       overflow: hidden;
       text-overflow: ellipsis;
@@ -4084,11 +4084,28 @@ $--background-color-base: $base-color-background;
   display: flex;
   width: 100%;
   .tree-side {
-    flex: 0 0 210px;
-    margin-right: 10px;
+    // flex: 1 1 210px;
+    width: 210px;
+    border-right: 6px solid #f6f8f9;
+    display: flex;
+    flex-direction: column;
+    background: #fff; 
+    .el-tree {
+      flex:1;
+      overflow: auto;
+    }
+    footer {
+      flex:0 0 32px;
+      display: flex;
+      .el-button {
+        flex:1;
+      }
+    }
   }
   .tree-table {
-    width: calc(100% - 220px);
+    width: calc(100% - 216px);
+    padding:0 6px;
+    background: #fff;
   }
   .info-side {
     flex: 0 0 400px;

+ 224 - 0
src/views/base/productAuth/index.vue

@@ -0,0 +1,224 @@
+<!--
+ * @Author: wanglj 471442253@qq.com
+ * @Date: 2023-02-13 11:50:01
+ * @LastEditors: wanglj
+ * @LastEditTime: 2023-02-14 09:32:28
+ * @Description: file content
+ * @FilePath: \opms_frontend\src\views\base\productAuth\index.vue
+-->
+<template>
+  <div class="product-auth-container">
+    <vab-query-form>
+      <vab-query-form-left-panel>
+        <el-form :inline="true" :model="queryForm" @submit.native.prevent>
+          <el-form-item>
+            <el-input v-model="queryForm.keyWords" placeholder="姓名" />
+          </el-form-item>
+          <el-form-item>
+            <el-button icon="el-icon-search" type="primary" @click="handleSearch">查询</el-button>
+            <el-button icon="el-icon-refresh-right" @click="reset">重置</el-button>
+          </el-form-item>
+        </el-form>
+      </vab-query-form-left-panel>
+      <vab-query-form-right-panel :span="12">
+        <table-tool :check-list.sync="checkList" :columns="columns" />
+      </vab-query-form-right-panel>
+    </vab-query-form>
+    <el-table v-loading="listLoading" border :data="list" :height="$baseTableHeight(1)">
+      <el-table-column
+        v-for="(item, index) in finallyColumns"
+        :key="index"
+        align="center"
+        :label="item.label"
+        :prop="item.prop"
+        show-overflow-tooltip
+        :sortable="item.sortable"
+        :width="item.width">
+        <template #default="{ row }">
+          <span>{{ row[item.prop] }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column align="center" label="操作" width="120px">
+        <template #default="{ row }">
+          <el-button type="text" @click="handleAuth(row)">授权</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <el-pagination
+      background
+      :current-page="queryForm.pageNum"
+      :layout="layout"
+      :page-size="queryForm.pageSize"
+      :page-sizes="[5, 10]"
+      :total="total"
+      @current-change="handleCurrentChange"
+      @size-change="handleSizeChange" />
+    <!-- 授权弹窗 -->
+    <el-dialog title="产品线授权" :visible.sync="visible" width="500px" @close="handleClose">
+      <el-form ref="form" :model="form">
+        <el-form-item prop="productLine">
+          <el-checkbox-group v-model="form.productLine" @change="$forceUpdate()">
+            <el-checkbox v-for="item in productList" :key="item.productCode" :label="item.productCode">
+              {{ item.productName }}
+            </el-checkbox>
+          </el-checkbox-group>
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button @click="visible = false">取 消</el-button>
+        <el-button type="primary" @click="save">确 定</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+<script>
+  import proAuthApi from '@/api/base/productAuth'
+  import TableTool from '@/components/table/TableTool'
+  import to from 'await-to-js'
+  export default {
+    name: 'ProductAuthorize',
+    components: {
+      TableTool,
+    },
+    data() {
+      return {
+        total: 0,
+        queryForm: {
+          pageNum: 1,
+          pageSize: 5,
+          keyWords: '',
+          deptId: 2,
+        },
+        layout: 'total, sizes, prev, pager, next, jumper',
+        listLoading: false,
+        list: [],
+        checkList: [],
+        columns: [
+          {
+            label: '姓名',
+            width: '120px',
+            prop: 'userName',
+            sortable: false,
+            disableCheck: true,
+          },
+          {
+            label: '岗位',
+            width: '120px',
+            prop: 'userPost',
+            sortable: false,
+            disableCheck: false,
+          },
+          {
+            label: '电话',
+            width: '120px',
+            prop: 'userPhone',
+            sortable: false,
+            disableCheck: false,
+          },
+          {
+            label: '授权产品线',
+            width: 'auto',
+            prop: 'productName',
+            sortable: false,
+            disableCheck: true,
+          },
+        ],
+        visible: false,
+        productList: [],
+        form: {
+          userId: 0,
+          userName: '',
+          userPost: '',
+          userPhone: '',
+          productLine: [],
+        },
+      }
+    },
+    computed: {
+      finallyColumns() {
+        return this.columns.filter((item) => this.checkList.includes(item.label))
+      },
+    },
+    mounted() {
+      this.getProducts()
+      this.fetchData()
+    },
+    methods: {
+      async fetchData() {
+        const [err, res] = await to(proAuthApi.getList(this.queryForm))
+        if (err) return
+        this.list = res.data.list || []
+        this.total = res.data.total
+      },
+      handleSearch() {
+        this.queryForm.pageNum = 1
+        this.fetchData()
+      },
+      getProducts() {
+        this.getDicts('sys_product_line').then((response) => {
+          let arr = response.data.values || []
+          for (const item of arr) {
+            this.productList.push({
+              productCode: item.key,
+              productName: item.value,
+              remark: item.remark,
+            })
+          }
+        })
+      },
+      reset() {
+        this.queryForm = {
+          pageNum: 1,
+          pageSize: 10,
+          keyWords: '',
+          deptId: 2,
+        }
+        this.fetchData()
+      },
+      handleSizeChange(val) {
+        this.queryForm.pageSize = val
+        this.fetchData()
+      },
+      handleCurrentChange(val) {
+        this.queryForm.pageNum = val
+        this.fetchData()
+      },
+      // 授权
+      async handleAuth(row) {
+        this.form = { ...row }
+        this.form.productLine = row.productCode ? row.productCode.split(',') : []
+        this.visible = true
+      },
+      handleClose() {
+        this.form = {
+          userId: 0,
+          userName: '',
+          userPost: '',
+          userPhone: '',
+          productLine: [],
+        }
+        this.$refs.form.clearValidate()
+      },
+      // 确认授权
+      async save() {
+        let arr = []
+        for (const key of this.form.productLine) {
+          const obj = this.productList.find((item) => item.productCode == key)
+          if (obj) arr.push(obj)
+        }
+        const params = { ...this.form }
+        params.lines = arr
+        const [err, res] = await to(proAuthApi.authorize(params))
+        if (err) return
+        this.$message.success(res.msg)
+        this.visible = false
+        this.fetchData()
+      },
+    },
+  }
+</script>
+<style lang="scss" scoped>
+  .el-checkbox {
+    width: 100%;
+  }
+</style>

+ 429 - 0
src/views/base/regionAuth/index.vue

@@ -0,0 +1,429 @@
+<!--
+ * @Author: wanglj 471442253@qq.com
+ * @Date: 2023-02-13 13:51:45
+ * @LastEditors: wanglj
+ * @LastEditTime: 2023-02-14 18:05:38
+ * @Description: file content
+ * @FilePath: \opms_frontend\src\views\base\regionAuth\index.vue
+-->
+<template>
+  <div class="region-auth-container">
+    <vab-query-form>
+      <el-form>
+        <vab-query-form-left-panel>
+          <el-form-item>
+            <el-input v-model="queryForm.keyWords" placeholder="姓名" />
+          </el-form-item>
+          <el-form-item>
+            <el-button icon="el-icon-search" type="primary" @click="handleSearch">查询</el-button>
+            <el-button icon="el-icon-refresh-right" @click="reset">重置</el-button>
+          </el-form-item>
+        </vab-query-form-left-panel>
+        <vab-query-form-right-panel>
+          <el-button icon="el-icon-circle-check" type="primary" @click="handleAuth">授权</el-button>
+          <table-tool :check-list.sync="checkList" :columns="columns" />
+        </vab-query-form-right-panel>
+      </el-form>
+    </vab-query-form>
+    <el-row :gutter="10">
+      <el-col :span="12">
+        <el-table
+          v-loading="listLoading"
+          border
+          :data="list"
+          :height="$baseTableHeight(1)"
+          style="width: 100%"
+          @row-click="handleRowClick">
+          <el-table-column
+            v-for="(item, index) in finallyColumns"
+            :key="index"
+            align="center"
+            :label="item.label"
+            :prop="item.prop"
+            show-overflow-tooltip
+            :sortable="item.sortable"
+            :width="item.width">
+            <template #default="{ row }">
+              <span>{{ row[item.prop] }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column align="center" label="选择" width="80">
+            <template #default="{ row }">
+              <i v-if="form.userId == row.userId" class="el-icon-check"></i>
+            </template>
+          </el-table-column>
+          <template #empty>
+            <el-image class="vab-data-empty" :src="require('@/assets/empty_images/data_empty.png')" />
+          </template>
+        </el-table>
+        <el-pagination
+          background
+          :current-page="queryForm.pageNum"
+          :layout="layout"
+          :page-size="queryForm.pageSize"
+          :total="total"
+          @current-change="handleCurrentChange"
+          @size-change="handleSizeChange" />
+      </el-col>
+      <el-col :span="12">
+        <el-table v-loading="listLoading" border :data="regionList" :height="$baseTableHeight(0)" style="width: 100%">
+          <el-table-column align="center" label="销售区域" prop="saleRegionName" />
+          <el-table-column align="center" label="省" prop="provinceName" />
+          <el-table-column align="center" label="市" prop="cityName" />
+        </el-table>
+      </el-col>
+    </el-row>
+
+    <el-dialog title="授权区域" top="5vh" :visible.sync="visible" width="80%" @close="handleClose">
+      <div v-loading="dialogLoading" class="side-layout">
+        <div class="tree-side">
+          <el-tree
+            ref="tree"
+            class="filter-tree"
+            :data="deptOptions"
+            default-expand-all
+            :default-expanded-keys="[1]"
+            :filter-node-method="filterNode"
+            highlight-current
+            node-key="id"
+            :props="defaultProps"
+            @node-click="handleNodeClick">
+            <span slot-scope="{ node }" class="custom-tree-node">
+              <span>{{ node.label }}</span>
+              <span><i class="el-icon-more"></i></span>
+            </span>
+          </el-tree>
+        </div>
+        <div class="tree-table">
+          <el-checkbox v-model="checkAll" :indeterminate="isIndeterminate" @change="handleCheckAllChange">
+            全选
+          </el-checkbox>
+          <div v-for="item in options" :key="item.custProvinceId" class="province" :label="item.custProvince">
+            <h3>{{ item.custProvince }}</h3>
+            <div class="check-container">
+              <el-checkbox
+                v-model="item.checkAll"
+                :indeterminate="item.isIndeterminate"
+                @change="(val) => handleSndCheckAllChange(val, item)">
+                全选
+              </el-checkbox>
+              <el-checkbox-group v-model="form.checkList" @change="(val) => handleChange(val, item)">
+                <el-checkbox v-for="city in item.children" :key="city.id" :label="city.custCityId">
+                  {{ city.custCity }}
+                  <span v-if="city.allocator.length">({{ city.allocator.join() }})</span>
+                </el-checkbox>
+              </el-checkbox-group>
+            </div>
+          </div>
+        </div>
+      </div>
+      <template #footer>
+        <el-button @click="visible = false">取 消</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+  import to from 'await-to-js'
+  import regionApi from '@/api/base/region'
+  import regAuthApi from '@/api/base/regionAuth'
+  import TableTool from '@/components/table/TableTool'
+  export default {
+    name: 'RegionAuth',
+    components: {
+      TableTool,
+    },
+    data() {
+      return {
+        queryForm: {
+          pageNum: 1,
+          pageSize: 10,
+          keyWords: '',
+          deptId: 2,
+        },
+        layout: 'total, sizes, prev, pager, next, jumper',
+        listLoading: false,
+        total: 0,
+        list: [],
+        regionList: [],
+        checkList: [],
+        columns: [
+          {
+            label: '姓名',
+            width: '120px',
+            prop: 'userName',
+            sortable: false,
+            disableCheck: true,
+          },
+          {
+            label: '岗位',
+            width: 'auto',
+            prop: 'userPost',
+            sortable: false,
+            disableCheck: false,
+          },
+          {
+            label: '电话',
+            width: 'auto',
+            prop: 'userPhone',
+            sortable: false,
+            disableCheck: false,
+          },
+        ],
+        checkAll: false,
+        isIndeterminate: false,
+        form: {
+          userId: 0,
+          checkList: [],
+        },
+        regionId: 0,
+        saleRegionName: '',
+        visible: false,
+        deptOptions: [],
+        defaultProps: {
+          id: 'id',
+          regionCode: 'regionCode',
+          label: 'regionDesc',
+        },
+        options: [], //区域选项
+        flatOptions: [], //扁平化区域
+        dialogLoading: false,
+        allocated: [], //已被分配的城市
+      }
+    },
+    computed: {
+      finallyColumns() {
+        return this.columns.filter((item) => this.checkList.includes(item.label))
+      },
+    },
+    mounted() {
+      this.fetchData()
+    },
+    methods: {
+      async fetchData() {
+        const [err, res] = await to(regAuthApi.getList(this.queryForm))
+        if (err) return
+        this.list = res.data.list || []
+        this.total = res.data.total
+        this.form = {
+          userId: 0,
+          checkList: [],
+        }
+        this.regionList = []
+      },
+      handleRowClick(row) {
+        this.form.userId = row.userId
+        this.form.userName = row.userName
+        this.form.userPost = row.userPost
+        this.form.userPhone = row.userPhone
+        this.getSndList()
+      },
+      async getSndList() {
+        const [err, res] = await to(
+          regAuthApi.getDetail({
+            userId: this.form.userId,
+          })
+        )
+        if (err) return
+        this.regionList = res.data.list || []
+      },
+      handleSearch() {
+        this.queryForm.pageNum = 1
+        this.fetchData()
+      },
+      reset() {
+        this.queryForm = {
+          pageNum: 1,
+          pageSize: 10,
+          keyWords: '',
+          deptId: 2,
+        }
+        this.fetchData()
+      },
+      handleSizeChange(val) {
+        this.queryForm.pageSize = val
+        this.fetchData()
+      },
+      handleCurrentChange(val) {
+        this.queryForm.pageNum = val
+        this.fetchData()
+      },
+      async handleAuth() {
+        if (!this.form.userId) return this.$message.warning('请选择用户')
+        this.visible = true
+        this.getRegionList()
+      },
+      async getRegionList() {
+        const { data: data } = await regionApi.getRegionList()
+        this.deptOptions = data.list
+        this.regionId = data.list[0].id
+        this.saleRegionName = data.list[0].regionDesc
+        //默认第一选中
+        this.$nextTick(() => {
+          this.$refs.tree.setCurrentKey(this.regionId)
+          this.handleNodeClick({ id: this.regionId, regionDesc: this.saleRegionName })
+        })
+      },
+      async handleDetail() {
+        this.form.checkList = []
+        this.allocated = []
+        const [err, res] = await to(
+          regAuthApi.getDetail({
+            // userId: this.form.userId,
+            saleRegionId: this.regionId,
+          })
+        )
+        if (err) return
+        const list = res.data.list || []
+        for (const item of list) {
+          if (item.userId == this.form.userId) this.form.checkList.push(item.cityId)
+          else this.allocated.push(item)
+        }
+      },
+      async handleNodeClick(data) {
+        this.checkAll = false
+        this.isIndeterminate = false
+        this.regionId = data.id
+        this.saleRegionName = data.regionDesc
+        await this.handleDetail()
+        const [err, res] = await to(regionApi.getRegionDetailList({ regionId: data.id }))
+        if (err) return
+        this.flatOptions = res.data.list || []
+        this.flatOptions.forEach((item) => (item.saleRegionName = data.regionDesc))
+        let obj = []
+        for (const item of this.flatOptions) {
+          const target = obj.findIndex((each) => each.custProvinceId == item.custProvinceId)
+          const newItem = { ...item, allocator: [] }
+          const allocator = this.allocated.find((each) => each.cityId == item.custCityId)
+          if (allocator) {
+            newItem.allocator.push(allocator.userName)
+          }
+          if (target > -1) {
+            obj[target].children.push(newItem)
+          } else {
+            obj.push({
+              checkAll: false,
+              isIndeterminate: false,
+              custProvinceId: item.custProvinceId,
+              custProvince: item.custProvince,
+              children: [newItem],
+            })
+          }
+        }
+        this.options = obj
+        this.handleChange(this.form.checkList)
+      },
+      // 筛选节点
+      filterNode(value, data) {
+        if (!value) return true
+        return data[this.defaultProps.label].indexOf(value) !== -1
+      },
+      handleClose() {
+        // this.form = {
+        //   userId: 0,
+        //   checkList: [],
+        // }
+        this.getSndList()
+      },
+      handleCheckAllChange(val) {
+        this.form.checkList = val ? this.flatOptions.map((item) => item.custCityId) : []
+        this.options.forEach((item) => {
+          item.checkAll = val
+        })
+        this.isIndeterminate = false
+        this.$forceUpdate()
+        this.save()
+      },
+      handleSndCheckAllChange(val, item) {
+        item.isIndeterminate = false
+        for (let i = 0; i < item.children.length; i++) {
+          const index = this.form.checkList.findIndex((each) => each == item.children[i].custCityId)
+          if (index > -1) {
+            this.form.checkList.splice(index, 1)
+            i--
+          }
+        }
+        const arr = item.children.map((each) => each.custCityId)
+        if (val) this.form.checkList = [...this.form.checkList, ...arr]
+        this.$forceUpdate()
+        this.save()
+      },
+      handleChange(val, item) {
+        if (item) {
+          let count = 0
+          for (const child of item.children) {
+            console.log(child, child.custCityId, this.form.checkList, '---')
+            if (this.form.checkList.includes(child.custCityId)) count++
+          }
+          item.checkAll = count == item.children.length
+          item.isIndeterminate = count > 0 && count < item.children.length
+          this.save()
+        } else {
+          for (const pro of this.options) {
+            let count = 0
+            pro.children.forEach((city) => {
+              if (this.form.checkList.includes(city.custCityId)) count++
+            })
+            pro.checkAll = count == pro.children.length
+            pro.isIndeterminate = count > 0 && count < pro.children.length
+          }
+        }
+        this.$forceUpdate()
+        this.isIndeterminate = val.length > 0 && val.length < this.flatOptions.length
+        this.checkAll = val.length == this.flatOptions.length && val.length > 0
+      },
+      async save() {
+        this.dialogLoading = true
+        let params = { ...this.form }
+        params.saleRegionId = this.regionId
+        params.saleRegionName = this.saleRegionName
+        let arr = []
+        for (const item of params.checkList) {
+          const obj = this.flatOptions.find((each) => each.id == item)
+          if (obj)
+            arr.push({
+              saleRegionId: obj.regionId,
+              saleRegionName: obj.saleRegionName,
+              provinceId: obj.custProvinceId,
+              provinceName: obj.custProvince,
+              cityId: obj.custCityId,
+              cityName: obj.custCity,
+            })
+        }
+        params.regions = arr
+        const [err, res] = await to(regAuthApi.saveRegion(params))
+        if (err) return (this.dialogLoading = false)
+        this.$message.success(res.msg)
+        this.dialogLoading = false
+      },
+    },
+  }
+</script>
+
+<style lang="scss" scoped>
+  .side-layout {
+    height: 600px;
+  }
+  .el-icon-check {
+    font-size: 18px;
+    color: #67c23a;
+    font-weight: bold;
+  }
+  .vab-theme-blue-black .side-layout .tree-table {
+    padding: 10px 20px;
+    .province {
+      margin: 20px 0;
+      line-height: 24px;
+      h3 {
+        padding: 10px;
+        border-radius: 5px;
+        background: #eee;
+      }
+      .check-container {
+        padding-left: 8px;
+        line-height: 30px;
+      }
+    }
+  }
+</style>

+ 38 - 29
src/views/plat/task/components/TaskAdd.vue

@@ -15,7 +15,7 @@
             </el-select>
           </el-form-item>
         </el-col>
-        <el-col :span="12">
+        <!-- <el-col :span="12">
           <el-form-item label="开始时间" prop="taskStartDate">
             <el-date-picker
               v-model="form.taskStartDate"
@@ -24,20 +24,35 @@
               type="date"
               value-format="yyyy-MM-dd HH:mm:ss" />
           </el-form-item>
-        </el-col>
+        </el-col> -->
         <el-col :span="12">
-          <el-form-item label="结束时间" prop="taskEndDate">
+          <el-form-item label="要求完成时间" prop="taskEndDate">
             <el-date-picker
               v-model="form.taskEndDate"
-              placeholder="请选择结束时间"
+              placeholder="请选择要求完成时间"
               style="width: 100%"
               type="date"
               value-format="yyyy-MM-dd HH:mm:ss" />
           </el-form-item>
         </el-col>
+        <el-col :span="12">
+          <el-form-item label="督办事项来源" prop="source">
+            <el-input v-model="form.source" placeholder="请输入督办事项来源" />
+          </el-form-item>
+        </el-col>
         <el-col :span="24">
-          <el-form-item label="说明" prop="taskDesc">
-            <el-input v-model="form.taskDesc" placeholder="请输入说明" type="textarea" />
+          <el-form-item label="督办内容" prop="taskDesc">
+            <el-input v-model="form.taskDesc" placeholder="请输入督办内容" type="textarea" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="负责人" prop="mainUserId">
+            <!-- <el-select v-model="form.mainUserId" placeholder="请选择负责人" style="width: 100%">
+              <el-option v-for="item in users" :key="item.id" :label="item.userName" :value="item.id" />
+            </el-select> -->
+            <el-input v-model="form.mainUserName" placeholder="负责人" readonly>
+              <el-button slot="append" icon="el-icon-search" @click="choose(false, 'mainUserId', 'mainUserName')" />
+            </el-input>
           </el-form-item>
         </el-col>
         <el-col :span="12">
@@ -54,36 +69,26 @@
           </el-form-item>
         </el-col>
         <el-col :span="12">
-          <el-form-item label="监办人" prop="watchUserId">
-            <!-- <el-select v-model="form.watchUserId" clear placeholder="请选择监办人" style="width: 100%">
+          <el-form-item label="协办人" prop="teamNames">
+            <!-- <el-select v-model="teamIds" clear multiple placeholder="请选择协办人" style="width: 100%">
               <el-option v-for="item in users" :key="item.id" :label="item.userName" :value="item.id" />
             </el-select> -->
-            <el-input v-model="form.watchUserName" placeholder="监办人" readonly>
-              <el-button slot="append" icon="el-icon-search" @click="choose(false, 'watchUserId', 'watchUserName')" />
-            </el-input>
-          </el-form-item>
-        </el-col>
-        <el-col :span="12">
-          <el-form-item label="负责人" prop="mainUserId">
-            <!-- <el-select v-model="form.mainUserId" placeholder="请选择负责人" style="width: 100%">
-              <el-option v-for="item in users" :key="item.id" :label="item.userName" :value="item.id" />
-            </el-select> -->
-            <el-input v-model="form.mainUserName" placeholder="负责人" readonly>
-              <el-button slot="append" icon="el-icon-search" @click="choose(false, 'mainUserId', 'mainUserName')" />
+            <el-input v-model="form.teamNames" placeholder="协办人" readonly>
+              <el-button slot="append" icon="el-icon-search" @click="choose(true, 'teamIds', 'teamNames')" />
             </el-input>
           </el-form-item>
         </el-col>
         <el-col :span="12">
-          <el-form-item label="团队成员">
-            <!-- <el-select v-model="teamIds" clear multiple placeholder="请选择团队成员" style="width: 100%">
+          <el-form-item label="监办人" prop="watchUserId">
+            <!-- <el-select v-model="form.watchUserId" clear placeholder="请选择监办人" style="width: 100%">
               <el-option v-for="item in users" :key="item.id" :label="item.userName" :value="item.id" />
             </el-select> -->
-            <el-input v-model="form.teamNames" placeholder="团队成员" readonly>
-              <el-button slot="append" icon="el-icon-search" @click="choose(true, 'teamIds', 'teamNames')" />
+            <el-input v-model="form.watchUserName" placeholder="监办人" readonly>
+              <el-button slot="append" icon="el-icon-search" @click="choose(false, 'watchUserId', 'watchUserName')" />
             </el-input>
           </el-form-item>
         </el-col>
-        <el-col :span="12">
+        <!-- <el-col :span="12">
           <el-form-item label="关联类型" prop="targetType">
             <el-select
               v-model="form.targetType"
@@ -113,7 +118,7 @@
           <el-form-item label="备注" prop="remark">
             <el-input v-model="form.remark" placeholder="请输入备注" type="textarea" />
           </el-form-item>
-        </el-col>
+        </el-col> -->
       </el-row>
     </el-form>
     <template #footer>
@@ -171,7 +176,7 @@
         // 回款
         payments: [],
         selfVisible: false,
-        // 团队成员
+        // 协办人
         teamIds: [],
         // 客户数据
         customers: [],
@@ -185,6 +190,7 @@
           isOverdue: '10',
           taskStartDate: '',
           taskEndDate: '',
+          source: '',
           taskDesc: '',
           supervisorUserId: '',
           watchUserId: '',
@@ -205,10 +211,12 @@
         rules: {
           taskTitle: [{ required: true, message: '标题不能为空', trigger: 'blur' }],
           taskType: [{ required: true, message: '类型不能为空', trigger: 'blur' }],
-          taskStartDate: [{ required: true, message: '开始时间不能为空', trigger: 'blur' }],
-          taskEndDate: [{ required: true, message: '结束时间不能为空', trigger: 'blur' }],
+          // taskStartDate: [{ required: true, message: '开始时间不能为空', trigger: 'blur' }],
+          taskEndDate: [{ required: true, message: '要求完成时间不能为空', trigger: 'blur' }],
           supervisorUserId: [{ required: true, message: '督办人不能为空', trigger: 'change' }],
           mainUserId: [{ required: true, message: '负责人不能为空', trigger: 'change' }],
+          teamNames: [{ required: true, message: '协办人不能为空', trigger: 'change' }],
+          watchUserId: [{ required: true, message: '监办人不能为空', trigger: 'change' }],
         },
         multiple: false,
         property: '',
@@ -347,6 +355,7 @@
         this.form.isOverdue = '10'
         this.form.taskStartDate = ''
         this.form.taskEndDate = ''
+        this.form.source = ''
         this.form.taskDesc = ''
         this.form.supervisorUserId = ''
         this.form.watchUserId = ''

+ 19 - 13
src/views/plat/task/components/TaskDetail.vue

@@ -7,9 +7,9 @@
           <span style="font-size: 18px; margin-right: 10px">
             {{ theTask.taskTitle }}
           </span>
-          <el-button v-show="theTask.isOverdue === '10'" type="primary" @click="changeStatus('IsOverdue', '20')">
+          <!-- <el-button v-show="theTask.isOverdue === '10'" type="primary" @click="changeStatus('IsOverdue', '20')">
             超期
-          </el-button>
+          </el-button> -->
           <el-button v-show="theTask.taskStatus === '10'" type="primary" @click="changeStatus('TaskStatus', '20')">
             关闭
           </el-button>
@@ -17,25 +17,27 @@
           <el-row :gutter="20" style="margin-top: 10px">
             <el-col :span="8">督办类型:{{ typeMap[theTask.taskType] }}</el-col>
             <el-col :span="8">状态:{{ theTask.taskStatus === '10' ? '进行中' : '关闭' }}</el-col>
-            <el-col :span="8">超期:{{ theTask.isOverdue === '10' ? '否' : '是' }}</el-col>
-            <el-col :span="8">开始时间:{{ parseTime(theTask.taskStartDate) }}</el-col>
-            <el-col :span="8">结束时间:{{ parseTime(theTask.taskEndDate) }}</el-col>
-            <el-col :span="24">说明:{{ theTask.taskDesc }}</el-col>
+            <el-col :span="8">
+              超期:{{ isNotOverdue(parseTime(theTask.taskEndDate, '{y}-{m}-{d} 23:59:59')) ? '否' : '是' }}
+            </el-col>
+            <el-col :span="8">发布时间:{{ parseTime(theTask.taskStartDate) }}</el-col>
+            <el-col :span="8">要求完成时间:{{ parseTime(theTask.taskEndDate) }}</el-col>
+            <el-col :span="24">督办内容:{{ theTask.taskDesc }}</el-col>
             <el-col :span="8">督办人:{{ userMap[theTask.supervisorUserId] }}</el-col>
             <el-col :span="8">监办人:{{ userMap[theTask.watchUserId] }}</el-col>
             <el-col :span="8">负责人:{{ userMap[theTask.mainUserId] }}</el-col>
-            <el-col :span="16">团队成员:{{ teamNames }}</el-col>
-            <el-col :span="8">
+            <el-col :span="16">协办人:{{ teamNames }}</el-col>
+            <!-- <el-col :span="8">
               关联类型:
               <span v-show="theTask.targetType == '10'">客户</span>
               <span v-show="theTask.targetType == '20'">项目</span>
               <span v-show="theTask.targetType == '30'">合同</span>
               <span v-show="theTask.targetType == '40'">回款</span>
-            </el-col>
-            <el-col :span="8">关联对象:{{ theTask.targetName }}</el-col>
+            </el-col> -->
+            <!-- <el-col :span="8">关联对象:{{ theTask.targetName }}</el-col> -->
             <el-col :span="8">创建人:{{ theTask.createdName }}</el-col>
-            <el-col :span="8">创建时间:{{ parseTime(theTask.createdTime) }}</el-col>
-            <el-col :span="24">备注:{{ theTask.remark }}</el-col>
+            <!-- <el-col :span="8">创建时间:{{ parseTime(theTask.createdTime) }}</el-col> -->
+            <!-- <el-col :span="24">备注:{{ theTask.remark }}</el-col> -->
             <el-button v-show="theTask.taskStatus === '10'" type="primary" @click="addProgress">添加进展</el-button>
             <el-table border :data="progressList" height="440">
               <el-table-column align="center" label="进展说明" prop="progDesc" />
@@ -138,7 +140,7 @@
       return {
         // 进展新增弹窗
         progressAddDialogVisible: false,
-        // 团队成员
+        // 协办人
         teamNames: '',
         // 评论新增弹窗
         commentAddDialogVisible: false,
@@ -158,6 +160,10 @@
       },
     },
     methods: {
+      // 判断是否没有超期
+      isNotOverdue(date) {
+        return new Date() <= new Date(date)
+      },
       // 改变督办状态
       changeStatus(type, status) {
         this.$confirm('确定修改督办状态?', '提示', {

+ 20 - 16
src/views/plat/task/detail.vue

@@ -28,39 +28,39 @@
               <span v-else-if="theTask.taskStatus === '30'">流程完成</span>
             </el-descriptions-item>
             <el-descriptions-item content-class-name="my-content" label="超期" label-class-name="my-label">
-              {{ theTask.isOverdue === '10' ? '否' : '是' }}
+              {{ isNotOverdue(parseTime(theTask.taskEndDate, '{y}-{m}-{d} 23:59:59')) ? '否' : '是' }}
             </el-descriptions-item>
-            <el-descriptions-item content-class-name="my-content" label="开始时间" label-class-name="my-label">
-              {{ parseTime(theTask.taskStartDate) }}
+            <el-descriptions-item content-class-name="my-content" label="发布时间" label-class-name="my-label">
+              {{ parseTime(theTask.taskStartDate, '{y}-{m}-{d}') }}
             </el-descriptions-item>
-            <el-descriptions-item content-class-name="my-content" label="结束时间" label-class-name="my-label">
-              {{ parseTime(theTask.taskEndDate) }}
+            <el-descriptions-item content-class-name="my-content" label="要求完成时间" label-class-name="my-label">
+              {{ parseTime(theTask.taskEndDate, '{y}-{m}-{d}') }}
             </el-descriptions-item>
-            <el-descriptions-item content-class-name="my-content" label="说明" label-class-name="my-label">
+            <el-descriptions-item content-class-name="my-content" label="督办内容" label-class-name="my-label">
               {{ theTask.taskDesc }}
             </el-descriptions-item>
           </el-descriptions>
           <el-descriptions :colon="false" :column="6" direction="vertical">
+            <el-descriptions-item content-class-name="my-content" label="负责人" label-class-name="my-label">
+              {{ userMap[theTask.mainUserId] }}
+            </el-descriptions-item>
+            <el-descriptions-item content-class-name="my-content" label="协办人" label-class-name="my-label">
+              {{ teamNames }}
+            </el-descriptions-item>
             <el-descriptions-item content-class-name="my-content" label="督办人" label-class-name="my-label">
               {{ userMap[theTask.supervisorUserId] }}
             </el-descriptions-item>
             <el-descriptions-item content-class-name="my-content" label="监办人" label-class-name="my-label">
               {{ userMap[theTask.watchUserId] }}
             </el-descriptions-item>
-            <el-descriptions-item content-class-name="my-content" label="负责人" label-class-name="my-label">
-              {{ userMap[theTask.mainUserId] }}
-            </el-descriptions-item>
-            <el-descriptions-item content-class-name="my-content" label="团队成员" label-class-name="my-label">
-              {{ teamNames }}
-            </el-descriptions-item>
-            <el-descriptions-item content-class-name="my-content" label="关联类型" label-class-name="my-label">
+            <!-- <el-descriptions-item content-class-name="my-content" label="关联类型" label-class-name="my-label">
               <span v-show="theTask.targetType == '10'">客户</span>
               <span v-show="theTask.targetType == '20'">项目</span>
               <span v-show="theTask.targetType == '30'">合同</span>
               <span v-show="theTask.targetType == '40'">回款</span>
-            </el-descriptions-item>
-            <el-descriptions-item content-class-name="my-content" label="关联对象" label-class-name="my-label">
-              {{ theTask.targetName }}
+            </el-descriptions-item> -->
+            <el-descriptions-item content-class-name="my-content" label="督办事项来源" label-class-name="my-label">
+              {{ theTask.source }}
             </el-descriptions-item>
           </el-descriptions>
         </header>
@@ -219,6 +219,10 @@
       this.open()
     },
     methods: {
+      // 判断是否没有超期
+      isNotOverdue(date) {
+        return new Date() <= new Date(date)
+      },
       // 打开弹窗
       open() {
         // 获取数据信息

+ 27 - 17
src/views/plat/task/index.vue

@@ -96,7 +96,7 @@
                 <span v-if="row.taskStatus === '30'">流程完成</span>
               </span>
               <span v-else-if="item.prop === 'isOverdue'">
-                {{ row.isOverdue === '10' ? '否' : '是' }}
+                {{ isNotOverdue(parseTime(row['taskEndDate'], '{y}-{m}-{d} 23:59:59')) ? '否' : '是' }}
               </span>
               <span v-else-if="item.prop === 'mainUserId' || item.prop === 'supervisorUserId'">
                 {{ userMap[row[item.prop]] }}
@@ -204,23 +204,29 @@
             sortable: false,
           },
           {
-            label: '超期',
+            label: '督办事项来源',
             width: '120px',
-            prop: 'isOverdue',
+            prop: 'source',
             sortable: false,
           },
           {
-            label: '督办说明',
+            label: '超期',
             width: '120px',
-            prop: 'taskDesc',
+            prop: 'isOverdue',
             sortable: false,
           },
           {
-            label: '关联对象',
+            label: '督办内容',
             width: '120px',
-            prop: 'targetName',
+            prop: 'taskDesc',
             sortable: false,
           },
+          // {
+          //   label: '关联对象',
+          //   width: '120px',
+          //   prop: 'targetName',
+          //   sortable: false,
+          // },
           {
             label: '负责人',
             width: '120px',
@@ -228,7 +234,7 @@
             sortable: false,
           },
           {
-            label: '团队成员',
+            label: '协办人',
             width: '180px',
             prop: 'ownerUserId',
             sortable: false,
@@ -240,23 +246,23 @@
             sortable: false,
           },
           {
-            label: '开始时间',
+            label: '发布时间',
             width: '160px',
             prop: 'taskStartDate',
             sortable: false,
           },
           {
-            label: '结束时间',
+            label: '要求完成时间',
             width: '160px',
             prop: 'taskEndDate',
             sortable: false,
           },
-          {
-            label: '创建时间',
-            width: '160px',
-            prop: 'createdTime',
-            sortable: false,
-          },
+          // {
+          //   label: '创建时间',
+          //   width: '160px',
+          //   prop: 'createdTime',
+          //   sortable: false,
+          // },
         ],
       }
     },
@@ -272,6 +278,10 @@
       this.fetchData()
     },
     methods: {
+      // 判断是否没有超期
+      isNotOverdue(date) {
+        return new Date() <= new Date(date)
+      },
       // 刷新表数据和数量统计
       doRefresh() {
         this.fetchData()
@@ -403,7 +413,7 @@
             console.error(err)
           })
       },
-      // 团队成员
+      // 协办人
       generateTeamMembers(ids) {
         if (!ids) {
           return ''