Ver Fonte

市场部资源转交

wucl há 2 anos atrás
pai
commit
5bea18c704

+ 1 - 1
package.json

@@ -28,7 +28,7 @@
     "cross-env": "^7.0.2",
     "e-vue-contextmenu": "^0.1.3",
     "echarts": "^4.8.0",
-    "element-ui": "^2.13.2",
+    "element-ui": "^2.15.7",
     "format": "^0.2.2",
     "fuse.js": "^6.2.0",
     "html2canvas": "^1.0.0-rc.7",

+ 1 - 1
public/index.html

@@ -7,7 +7,7 @@
   <meta name="renderer" content="webkit">
   <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
   <link rel="shortcut icon" href="<%= BASE_URL %>dayou_favicon.ico">
-  <title><%= webpackConfig.name %></title>
+  <title>大友评估主营业务系统</title>
 </head>
 <body>
 <div id="app"></div>

+ 3 - 0
src/api/modules/business.js

@@ -23,4 +23,7 @@ export default {
    delete(params) {
      return request.delete(`businessOpportunity/${params}`)
    },
+   changeManager(params){
+    return request.put(`businessOpportunity/changeManager`, params)
+   }
 }

+ 3 - 0
src/api/modules/customer.js

@@ -23,4 +23,7 @@ export default {
    delete(params) {
      return request.delete(`customer/${params}`)
    },
+   changeManager(params){
+    return request.put(`customer/changeManager`, params)
+   }
 }

+ 3 - 0
src/api/modules/item.js

@@ -29,5 +29,8 @@ export default {
   },
   itemUser(params){
     return request.get(`itemUser/user`, { params: params })
+  },
+  changeManager(params){
+    return request.put(`item/changeManager`, params)
   }
 }

+ 26 - 0
src/api/modules/resourceTransfer.js

@@ -0,0 +1,26 @@
+import request from '@/utils/request'
+import { fileDown } from '../../utils/file'
+import md5 from 'js-md5'
+/*
+* 资源转交
+*/
+export default {
+  list(params) {
+    return request.get(`resourceTransfer`, { params: params })
+  },
+  detail(params) {
+    return request.get(`resourceTransfer/${params}`)
+  },
+  add(params) {
+    return request.post(`resourceTransfer`, params)
+  },
+  edit(params) {
+    return request.put(`resourceTransfer`, params)
+  },
+   delete(params) {
+     return request.delete(`resourceTransfer/${params}`)
+   },
+   history(params){
+    return request.get(`resourceTransfer/history`, { params: params })
+   }
+}

+ 3 - 0
src/api/modules/user.js

@@ -44,5 +44,8 @@ export default {
   },
   postUserVOList(params){
     return request.get(`user/list/${params}`)
+  },
+  usersByDepartment(params){
+    return request.get(`user/departmentName/${params}`)
   }
 }

+ 2 - 1
src/main.js

@@ -17,7 +17,8 @@ import 'normalize.css/normalize.css' // a modern alternative to CSS resets
 import settings from './settings'
 
 import Element from 'element-ui'
-import './styles/element-variables.scss'
+import 'element-ui/lib/theme-chalk/index.css'
+// import './styles/element-variables.scss'
 
 import '@/styles/index.scss' // global css
 

+ 1 - 1
src/router/permission.js

@@ -63,7 +63,7 @@ router.beforeEach(async (to, from, next) => {
   NProgress.start();
 
   // set page title
-  document.title = getPageTitle(to.meta.title);
+  // document.title = getPageTitle(to.meta.title);
 
   // determine whether the user has logged in
   const hasToken = getToken();

+ 366 - 369
src/views/item/list.vue

@@ -1,106 +1,45 @@
 <template>
   <div class="app-container">
     <div class="title-container">
-      <breadcrumb id="breadcrumb-container" class="breadcrumb-container"/>
+      <breadcrumb id="breadcrumb-container" class="breadcrumb-container" />
     </div>
-
     <y-page-list-layout :page-list="pageData" :page-para="listQuery" :get-page-list="getList">
       <template slot="left">
-        <PermissionButton
-          menu-code="_views_item_add"
-          class-name="filter-item"
-          type="primary"
-          size="mini"
-          :page-jump="true"
-          round
-          style="float: left"
-        />
-        <el-select
-          v-model="listQuery.state"
-          placeholder="状态"
-          clearable
-          filterable
-          style="margin-left: 20px;width: 100px;float: left;"
-          class="filter-item"
-        >
-          <el-option label="进行中" value="进行中"/>
-          <el-option label="已完成" value="已完成"/>
-          <el-option label="未开始" value="未开始"/>
+        <PermissionButton menu-code="_views_item_add" class-name="filter-item" type="primary" size="mini"
+          :page-jump="true" round style="float: left" />
+        <el-select v-model="listQuery.state" placeholder="状态" clearable filterable
+          style="margin-left: 20px;width: 100px;float: left;" class="filter-item">
+          <el-option label="进行中" value="进行中" />
+          <el-option label="已完成" value="已完成" />
+          <el-option label="未开始" value="未开始" />
         </el-select>
-        <el-select
-          v-model="listQuery.cate"
-          placeholder="项目类型"
-          clearable
-          filterable
-          style="margin-left: 20px;width: 100px;float: left;"
-          class="filter-item"
-        >
-          <el-option v-for="item in cateList" :key="item.id" :label="item.name" :value="item.id"/>
+        <el-select v-model="listQuery.cate" placeholder="项目类型" clearable filterable
+          style="margin-left: 20px;width: 100px;float: left;" class="filter-item">
+          <el-option v-for="item in cateList" :key="item.id" :label="item.name" :value="item.id" />
         </el-select>
-        <el-input
-          v-model="listQuery.name"
-          placeholder="项目名称"
-          clearable
-          style="margin-left: 20px;width: 320px;float: left;"
-        >
+        <el-input v-model="listQuery.name" placeholder="项目名称" clearable
+          style="margin-left: 20px;width: 320px;float: left;">
         </el-input>
-        <el-input
-          v-model="listQuery.businessNo"
-          placeholder="流水号"
-          clearable
-          style="margin-left: 20px;width: 320px;float: left;"
-        >
+        <el-input v-model="listQuery.businessNo" placeholder="流水号" clearable
+          style="margin-left: 20px;width: 320px;float: left;">
         </el-input>
-        <el-input
-          v-model="listQuery.clientManager"
-          placeholder="客户经理"
-          clearable
-          style="margin-left: 20px;width: 320px;float: left;"
-        >
+        <el-input v-model="listQuery.clientManager" placeholder="客户经理" clearable
+          style="margin-left: 20px;width: 320px;float: left;">
         </el-input>
-        <el-button
-          class="filter-item"
-          style="margin-left: 10px;float: left;"
-          type="primary"
-          @click="searchList"
-          round
-        >搜索
+        <el-button class="filter-item" style="margin-left: 10px;float: left;" type="primary" @click="searchList" round>搜索
         </el-button>
-        <el-button
-          class="filter-item"
-          style="float: left;"
-          round
-          type="warning"
-          @click="resetSearch()"
-        >重置
+        <el-button class="filter-item" style="float: left;" round type="warning" @click="resetSearch()">重置
         </el-button>
       </template>
       <template slot="right">
-        <PermissionButton
-          menu-code="_views_item_export"
-          class-name="filter-item"
-          round
-          type="primary"
-          name="导出"
-          @click="itemExport"
-        >
+        <PermissionButton menu-code="_views_item_export" class-name="filter-item" round type="primary" name="导出"
+          @click="itemExport">
         </PermissionButton>
-        <PermissionButton
-          menu-code="_views_item_mine_export"
-          class-name="filter-item"
-          round
-          type="primary"
-          name="导出"
-          @click="itemMineExport"
-        >
+        <PermissionButton menu-code="_views_item_mine_export" class-name="filter-item" round type="primary" name="导出"
+          @click="itemMineExport">
         </PermissionButton>
       </template>
-      <parentTable
-        v-loading="listLoading"
-        :data="pageData.records"
-        slot="table"
-        style="width: 100%;"
-      >
+      <parentTable v-loading="listLoading" :data="pageData.records" slot="table" style="width: 100%;">
         <el-table-column label="项目名称" align="center" width="200">
           <template slot-scope="{row}">
             <span>{{ row.name }}</span>
@@ -113,7 +52,7 @@
         </el-table-column>
         <el-table-column label="项目编号" align="center" width="180">
           <template slot-scope="{row}">
-            <span>{{row.belongTo}}{{ row.oaNo }}</span>
+            <span>{{ row.belongTo }}{{ row.oaNo }}</span>
           </template>
         </el-table-column>
         <el-table-column label="所属部门" align="center" width="130">
@@ -133,349 +72,407 @@
         </el-table-column>
         <el-table-column label="委托单位" align="center" width="130">
           <template slot-scope="{row}">
-            <span>{{ row.clientUnit}}</span>
+            <span>{{ row.clientUnit }}</span>
           </template>
         </el-table-column>
         <el-table-column label="客户名字" align="center" width="130">
           <template slot-scope="{row}">
-            <span>{{ row.clientName}}</span>
+            <span>{{ row.clientName }}</span>
           </template>
         </el-table-column>
         <el-table-column label="合同金额" align="center" width="100">
           <template slot-scope="{row}">
-            <span>{{ row.amount}}</span>
+            <span>{{ row.amount }}</span>
           </template>
         </el-table-column>
         <el-table-column label="客户经理" align="center" width="100">
           <template slot-scope="{row}">
-            <span>{{ row.clientManager}}</span>
+            <span>{{ row.clientManager }}</span>
           </template>
         </el-table-column>
         <el-table-column label="状态" align="center" width="100">
           <template slot-scope="{row}">
-            <el-tag>{{ row.itemStatus}}</el-tag>
+            <el-tag>{{ row.itemStatus }}</el-tag>
           </template>
         </el-table-column>
         <el-table-column label="当前阶段" align="center" width="200">
           <template slot-scope="{row}">
-            <el-tag>{{computedStageName(row.stageName)}}</el-tag>
+            <el-tag>{{ computedStageName(row.stageName) }}</el-tag>
           </template>
         </el-table-column>
         <el-table-column label="电子合同" align="center" width="100">
           <template slot-scope="{row}">
-            <el-button v-if="row.contractUrl" type="success" plain round @click="downloadContract(row.contractUrl)">下载</el-button>
+            <el-button v-if="row.contractUrl" type="success" plain round
+              @click="downloadContract(row.contractUrl)">下载</el-button>
             <el-button v-else plain round disabled>下载</el-button>
           </template>
         </el-table-column>
         <el-table-column label="操作" align="center" width="300" fixed="right">
           <template slot-scope="{row}">
-            <PermissionButton
-              menu-code="_views_item_plan"
-              class-name="filter-item"
-              name=""
-              type="primary"
-              :page-jump="true"
-              :page-query="{id: row.id,itemName: row.name,listQuery:listQuery}"
-              round
-              size="mini"
-            />
-            <PermissionButton
-              menu-code="_views_item_plan_list"
-              class-name="filter-item"
-              name=""
-              type="primary"
-              :page-jump="true"
-              :page-query="{id: row.id,itemName: row.name,listQuery:listQuery}"
-              round
-              size="mini"
-            />
-            <PermissionButton
-              menu-code="_view_item_log_write"
-              class-name="filter-item"
-              name=""
-              type="success"
-              :page-jump="true"
-              :page-query="{id: row.id,itemName:row.name,stageName:row.stageName,stageId:row.stageId,listQuery:listQuery}"
-              round
-              size="mini"
-            />
-            <PermissionButton
-              menu-code="_views_item_rate"
-              class-name="filter-item"
-              name="日志"
-              type="info"
-              :page-jump="true"
-              :page-query="{id: row.id,listQuery:listQuery}"
-              round
-              size="mini"
-            />
-            <PermissionButton
-              menu-code="_views_item_detail"
-              class-name="filter-item"
-              name=""
-              type="primary"
+            <PermissionButton menu-code="_views_item_plan" class-name="filter-item" name="" type="primary"
+              :page-jump="true" :page-query="{ id: row.id, itemName: row.name, listQuery: listQuery }" round
+              size="mini" />
+            <PermissionButton menu-code="_views_item_plan_list" class-name="filter-item" name="" type="primary"
+              :page-jump="true" :page-query="{ id: row.id, itemName: row.name, listQuery: listQuery }" round
+              size="mini" />
+            <PermissionButton menu-code="_view_item_log_write" class-name="filter-item" name="" type="success"
               :page-jump="true"
-              :page-query="{id: row.id,listQuery:listQuery}"
-              round
-              size="mini"
-            />
-            <PermissionButton
-              menu-code="_views_item_detail_readonly"
-              class-name="filter-item"
-              name=""
-              type="primary"
-              :page-jump="true"
-              :page-query="{id: row.id,listQuery:listQuery}"
-              round
-              size="mini"
-            />
-            <PermissionButton
-              menu-code="_views_item_remove"
-              class-name="filter-item"
-              name=""
-              type="danger"
-              round
-              size="mini"
-              @click="deleteInfo(row.id)"
-            />
+              :page-query="{ id: row.id, itemName: row.name, stageName: row.stageName, stageId: row.stageId, listQuery: listQuery }"
+              round size="mini" />
+            <PermissionButton menu-code="_views_item_rate" class-name="filter-item" name="日志" type="info"
+              :page-jump="true" :page-query="{ id: row.id, listQuery: listQuery }" round size="mini" />
+            <PermissionButton menu-code="_views_item_detail" class-name="filter-item" name="" type="primary"
+              :page-jump="true" :page-query="{ id: row.id, listQuery: listQuery }" round size="mini" />
+            <PermissionButton menu-code="_views_item_detail_readonly" class-name="filter-item" name="" type="primary"
+              :page-jump="true" :page-query="{ id: row.id, listQuery: listQuery }" round size="mini" />
+            <PermissionButton menu-code="_views_item_remove" class-name="filter-item" name="" type="danger" round
+              size="mini" @click="deleteInfo(row.id)" />
+            <PermissionButton menu-code="_views_item_transfer" class-name="filter-item" name="" type="success" round
+              size="mini" @click="transfer(row)" />
           </template>
         </el-table-column>
       </parentTable>
     </y-page-list-layout>
+    <el-dialog :visible.sync="dialogFormVisible" :close-on-click-modal="false" custom-class="tansferDialog">
+      <div class="detail">
+        <el-divider content-position="left">项目信息</el-divider>
+        <el-descriptions :column="4" size="lager" border>
+          <el-descriptions-item label="项目名称">{{ detail.name }}</el-descriptions-item>
+          <el-descriptions-item label="事业部流水号">{{ detail.businessNo }}</el-descriptions-item>
+          <el-descriptions-item label="项目编号">{{ detail.belongTo + detail.oaNo }}</el-descriptions-item>
+          <el-descriptions-item label="所属部门">{{ detail.departmentName }}</el-descriptions-item>
+          <el-descriptions-item label="项目类型">{{ detail.cateName }}</el-descriptions-item>
+          <el-descriptions-item label="业务来源">{{ detail.businessSourceName }}</el-descriptions-item>
+          <el-descriptions-item label="委托单位">{{ detail.clientUnit }}</el-descriptions-item>
+          <el-descriptions-item label="客户名称">{{ detail.clientName }}</el-descriptions-item>
+          <el-descriptions-item label="合同金额">{{ detail.amount }}</el-descriptions-item>
+          <el-descriptions-item label="客户经理">
+            <el-select v-model="detail.userId">
+              <el-option v-for="(item, index) in managers" :key="index" :label="item.name" :value="item.id"></el-option>
+            </el-select>
+            <el-tooltip class="item" effect="dark" content="点击转交" placement="bottom-start">
+            <el-button type="success" icon="el-icon-check" circle style="margin-left: 20px;" placeholder="转交"
+              @click="saveManager"></el-button>
+              </el-tooltip>
+          </el-descriptions-item>
+          <el-descriptions-item label="状态">{{ detail.itemStatus }}</el-descriptions-item>
+          <el-descriptions-item label="当前阶段">{{ computedStageName(detail.stageName) }}</el-descriptions-item>
+        </el-descriptions>
+      </div>
+      <div class="histroy">
+        <el-divider content-position="left">转交记录</el-divider>
+        <el-collapse v-model="activeNames">
+          <el-collapse-item name="1">
+            <el-timeline>
+              <el-timeline-item v-for="item in historys" :key="item.id" :timestamp="item.created" placement="top">
+                <el-card>
+                  <el-descriptions :column="3" border>
+                    <el-descriptions-item label="前客户经理"><el-tag type="info">{{ item.originalUserName
+                    }}</el-tag></el-descriptions-item>
+                    <el-descriptions-item label="后客户经理"><el-tag type="success">{{ item.currentUserName
+                    }}</el-tag></el-descriptions-item>
+                    <el-descriptions-item label="操作人"><el-tag>{{ item.operatorName }}</el-tag></el-descriptions-item>
+                  </el-descriptions>
+                </el-card>
+              </el-timeline-item>
+            </el-timeline>
+          </el-collapse-item>
+        </el-collapse>
+      </div>
+    </el-dialog>
   </div>
 </template>
 <script>
-  import YPageListLayout from '@/components/YPageListLayout'
-  import Breadcrumb from '@/components/Breadcrumb'
-  import PermissionButton from '@/components/PermissionButton/PermissionButton'
-  import { fileDown } from '../../utils/file'
+import YPageListLayout from '@/components/YPageListLayout'
+import Breadcrumb from '@/components/Breadcrumb'
+import PermissionButton from '@/components/PermissionButton/PermissionButton'
 
-  export default {
-    name: 'ViewsItemList',
-    components: {
-      Breadcrumb,
-      YPageListLayout,
-      PermissionButton,
+export default {
+  name: 'ViewsItemList',
+  components: {
+    Breadcrumb,
+    YPageListLayout,
+    PermissionButton,
+  },
+  filters: {
+    statusFilter(status) {
+      const statusMap = {
+        published: 'success',
+        draft: 'info',
+        deleted: 'danger',
+      }
+      return statusMap[status]
     },
-    filters: {
-      statusFilter(status) {
-        const statusMap = {
-          published: 'success',
-          draft: 'info',
-          deleted: 'danger',
-        }
-        return statusMap[status]
+  },
+  data() {
+    return {
+      isDisable: false,
+      tableKey: 0,
+      pageData: { records: [] },
+      listLoading: true,
+      listQuery: {
+        page: 1,
+        size: 10,
+        descs: 'id',
+        isCurYear: false,
       },
+      listQueryKey: 'keyword',
+      importLoading: false,
+      cateList: [],
+      dialogFormVisible: false,
+      detail: {},
+      activeNames: ['1'],
+      historys: [],
+      managers: [],
+    }
+  },
+  created() {
+    const that = this;
+    if (that.$route.query.state) {
+      that.listQuery.state = that.$route.query.state;
+    }
+    if (that.$route.query.isCurYear) {
+      that.listQuery.isCurYear = that.$route.query.isCurYear;
+    }
+    if (that.$route.query.name) {
+      that.listQuery.name = that.$route.query.name;
+    }
+    if (that.$route.query.current && !isNaN(that.$route.query.current)) {
+      that.listQuery.current = parseInt(that.$route.query.current);
+    }
+    if (that.$route.query.cate) {
+      that.listQuery.cate = parseInt(that.$route.query.cate);
+    }
+    if (that.$route.query.clientManager) {
+      that.listQuery.clientManager = that.$route.query.clientManager;
+    }
+    that.getList();
+    that.getCateList();
+  },
+  methods: {
+    itemExport() {
+      this.$utils.exportUtil(
+        "/item/export", this.listQuery,
+        "导出"
+      );
     },
-    data() {
-      return {
-        isDisable:false,
-        tableKey: 0,
-        pageData: { records: [] },
-        listLoading: true,
-        listQuery: {
-          page: 1,
-          size: 10,
-          descs: 'id',
-          isCurYear:false,
-        },
-        listQueryKey: 'keyword',
-        importLoading: false,
-        cateList:[],
-      }
+    itemMineExport() {
+      this.$utils.exportUtil(
+        "/item/mine/export", this.listQuery,
+        "导出"
+      );
     },
-    created() {
-      const that = this;
-      if (that.$route.query.state) {
-        that.listQuery.state = that.$route.query.state;
-      }
-      if (that.$route.query.isCurYear) {
-        that.listQuery.isCurYear = that.$route.query.isCurYear;
-      }
-      if (that.$route.query.name) {
-        that.listQuery.name = that.$route.query.name;
-      }
-      if (that.$route.query.current && !isNaN(that.$route.query.current)) {
-        that.listQuery.current = parseInt(that.$route.query.current);
-      }
-      if (that.$route.query.cate) {
-        that.listQuery.cate = parseInt(that.$route.query.cate);
+    getCateList() {
+      this.$api.dictData.simpleType("项目类型").then(res => {
+        this.cateList = res.data
+      })
+    },
+    downloadContract(url) {
+      var a = document.createElement('a');
+      var event = new MouseEvent('click');
+      a.download = url;
+      a.href = url;//路径前拼上前缀,完整路径
+      a.dispatchEvent(event);
+    },
+    resetSearch() {
+      this.$router.push({ query: {} });
+      this.listQuery = {
+        current: 1,
+        size: 10,
+        descs: 'id',
+        me: false,
       }
-      if (that.$route.query.clientManager) {
-        that.listQuery.clientManager = that.$route.query.clientManager;
+      this.getList()
+    },
+    computedStageName(val) {
+      if (val === null || val === undefined || val === '') {
+        return "无";
+      } else {
+        return val;
       }
-      that.getList();
-      that.getCateList();
     },
-    methods: {
-      itemExport(){
-        this.$utils.exportUtil(
-          "/item/export", this.listQuery,
-          "导出"
-        );
-      },
-      itemMineExport(){
-        this.$utils.exportUtil(
-          "/item/mine/export", this.listQuery,
-          "导出"
-        );
-      },
-      getCateList(){
-        this.$api.dictData.simpleType("项目类型").then(res => {
-          this.cateList = res.data
-        })
-      },
-      downloadContract(url){
-        var a = document.createElement('a');
-        var event = new MouseEvent('click');
-        a.download = url;
-        a.href = url;//路径前拼上前缀,完整路径
-        a.dispatchEvent(event);
-      },
-      resetSearch() {
-        this.$router.push({ query: {} });
-        this.listQuery = {
-          current: 1,
-          size: 10,
-          descs: 'id',
-          me: false,
-        }
-        this.getList()
-      },
-      computedStageName(val){
-        if (val===null || val===undefined || val === ''){
-          return "无";
-        }else {
-          return val;
-        }
-      },
-      removeHandle(row) {
-        // console.log(data)
-        const that = this
-        that
-          .$confirm('确认删除当前记录吗?', '警告', {
-            confirmButtonText: '确认',
-            cancelButtonText: '取消',
-            type: 'warning',
-          })
-          .then(async () => {
-            this.$api.term.delete(row.id).then((res) => {
-              if (res.code === 200) {
-                this.$message({
-                  type: 'success',
-                  message: '删除成功',
-                })
-                this.getList()
-              }
-            })
-          })
-          .catch((err) => {
-            console.error(err)
-          })
-      },
-      searchList() {
-        // 重置分页
-        this.listQuery.page = 1
-        this.listQuery.size = 10
-        this.getList()
-      },
-      getList() {
-        const that = this;
-        this.listLoading = true;
-        const key = {};
-        if (this.$router.currentRoute.path === '/item/list/mine'){
-          this.$api.item.mine(Object.assign({}, that.listQuery, key)).then((res) => {
-            that.pageData = res.data;
-            setTimeout(() => {
-              that.listLoading = false
-            }, 200)
-          })
-            .catch(() => {
-              that.listLoading = false
-            })
-        }else if(this.$router.currentRoute.path === '/item/list/me') {
-          this.$api.item.me(Object.assign({}, that.listQuery, key)).then((res) => {
-            that.pageData = res.data;
-            setTimeout(() => {
-              that.listLoading = false
-            }, 200)
-          })
-            .catch(() => {
-              that.listLoading = false
-            })
-        }else{
-          this.$api.item.list(Object.assign({}, that.listQuery, key)).then((res) => {
-            that.pageData = res.data
-            setTimeout(() => {
-              that.listLoading = false
-            }, 200)
-          })
-            .catch(() => {
-              that.listLoading = false
-            })
-        }
-      },
-      deleteInfo(id) {
-        const that = this
-        that.$confirm('请确认是否删除该数据?', '提示', {
-          confirmButtonText: '确定',
+    removeHandle(row) {
+      // console.log(data)
+      const that = this
+      that
+        .$confirm('确认删除当前记录吗?', '警告', {
+          confirmButtonText: '确认',
           cancelButtonText: '取消',
           type: 'warning',
-          center: true
-        }).then(() => {
-          that.$api.item.delete(id).then(data => {
-            that.loading = false
-            if (data.code === 200) {
-              that.getList()
-            } else {
+        })
+        .then(async () => {
+          this.$api.term.delete(row.id).then((res) => {
+            if (res.code === 200) {
               this.$message({
-                type: 'error',
-                message: data.msg
+                type: 'success',
+                message: '删除成功',
               })
+              this.getList()
             }
           })
-        }).catch(() => {
         })
+        .catch((err) => {
+          console.error(err)
+        })
+    },
+    searchList() {
+      // 重置分页
+      this.listQuery.page = 1
+      this.listQuery.size = 10
+      this.getList()
+    },
+    getList() {
+      const that = this;
+      this.listLoading = true;
+      const key = {};
+      if (this.$router.currentRoute.path === '/item/list/mine') {
+        this.$api.item.mine(Object.assign({}, that.listQuery, key)).then((res) => {
+          that.pageData = res.data;
+          setTimeout(() => {
+            that.listLoading = false
+          }, 200)
+        })
+          .catch(() => {
+            that.listLoading = false
+          })
+      } else if (this.$router.currentRoute.path === '/item/list/me') {
+        this.$api.item.me(Object.assign({}, that.listQuery, key)).then((res) => {
+          that.pageData = res.data;
+          setTimeout(() => {
+            that.listLoading = false
+          }, 200)
+        })
+          .catch(() => {
+            that.listLoading = false
+          })
+      } else {
+        this.$api.item.list(Object.assign({}, that.listQuery, key)).then((res) => {
+          that.pageData = res.data
+          setTimeout(() => {
+            that.listLoading = false
+          }, 200)
+        })
+          .catch(() => {
+            that.listLoading = false
+          })
       }
     },
-  }
+    deleteInfo(id) {
+      const that = this
+      that.$confirm('请确认是否删除该数据?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning',
+        center: true
+      }).then(() => {
+        that.$api.item.delete(id).then(data => {
+          that.loading = false
+          if (data.code === 200) {
+            that.getList()
+          } else {
+            this.$message({
+              type: 'error',
+              message: data.msg
+            })
+          }
+        })
+      }).catch(() => {
+      })
+    },
+    transfer(row) {
+      const originalUserId = row.userId;
+      this.dialogFormVisible = true;
+      this.detail = row;
+      this.detail.originalUserId = originalUserId;
+      this.getHistroyList(row.id);
+      this.getManagers();
+
+    },
+    getManagers() {
+      this.$api.user.usersByDepartment("市场部").then(res => {
+        this.managers = res.data
+      })
+    },
+    saveManager() {
+      if (this.detail.userId === this.detail.originalUserId){
+        this.$message({
+            type: 'error',
+            message: '抱歉,不能转交给本人。'
+          });
+          return ;
+      }
+      this.$api.item.changeManager(this.detail).then(res => {
+        if (res.code === 200 && res.data === true) {
+          this.$message({
+            type: 'success',
+            message: '转交成功'
+          });
+          this.getHistroyList(this.detail.id);
+        }
+      }
+      );
+    },
+
+    getHistroyList(id){
+      this.$api.resourceTransfer.history({"resourceType":"ITEM","resourceId":id}).then(res=>{
+        if (res.code === 200){
+          this.historys = res.data;
+        }
+      })
+    }
+  },
+}
 </script>
 <style lang="scss" scoped>
-  .right {
-    flex: 1;
+.right {
+  flex: 1;
 
-    .title {
-      font-size: 16px;
-      font-weight: 500;
-      color: rgba(51, 51, 51, 1);
-      line-height: 35px;
-      margin-bottom: 8px;
-    }
+  .title {
+    font-size: 16px;
+    font-weight: 500;
+    color: rgba(51, 51, 51, 1);
+    line-height: 35px;
+    margin-bottom: 8px;
+  }
 
-    .menu-2-box {
-      display: flex;
-      flex-wrap: wrap;
-      width: 100%;
-    }
+  .menu-2-box {
+    display: flex;
+    flex-wrap: wrap;
+    width: 100%;
+  }
 
-    .menu-2-item {
-      display: flex;
-      align-items: center;
-      color: #656565;
-      font-size: 12px;
-      width: 230px;
-      height: 101px;
-      background: rgb(255, 185, 129);
-      border-radius: 3px;
-      padding-left: 20px;
-      margin-right: 10px;
-      margin-bottom: 10px;
-      cursor: pointer;
-      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
+  .menu-2-item {
+    display: flex;
+    align-items: center;
+    color: #656565;
+    font-size: 12px;
+    width: 230px;
+    height: 101px;
+    background: rgb(255, 185, 129);
+    border-radius: 3px;
+    padding-left: 20px;
+    margin-right: 10px;
+    margin-bottom: 10px;
+    cursor: pointer;
+    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
 
-      .text {
-        margin-left: 16px;
-      }
+    .text {
+      margin-left: 16px;
     }
   }
+}
+
+/deep/ .tansferDialog {
+  width: 60%;
+  border-radius: 10px;
+}
+
+.el-dropdown-link {
+  cursor: pointer;
+  color: red;
+}
+
+.el-icon-arrow-down {
+  font-size: 12px;
+}
 </style>

+ 320 - 273
src/views/market/business/list.vue

@@ -1,61 +1,31 @@
 <template>
   <div class="app-container">
     <div class="title-container">
-      <breadcrumb id="breadcrumb-container" class="breadcrumb-container"/>
+      <breadcrumb id="breadcrumb-container" class="breadcrumb-container" />
     </div>
 
     <y-page-list-layout :page-list="pageData" :page-para="listQuery" :get-page-list="getList">
       <template slot="left">
-        <PermissionButton
-          menu-code="_views_market_business_add"
-          class-name="filter-item"
-          type="primary"
-          name
-          size="mini"
-          :page-jump="true"
-          round
-          style="float: left"
-        />
-        <el-input
-          v-model="listQuery.customerName"
-          placeholder="客户名字"
-          clearable
+        <PermissionButton menu-code="_views_market_business_add" class-name="filter-item" type="primary" name size="mini"
+          :page-jump="true" round style="float: left" />
+        <el-input v-model="listQuery.customerName" placeholder="客户名字" clearable
           style="margin-left: 20px;width: 320px;float: left;">
         </el-input>
-        <el-input
-          v-model="listQuery.opportunityName"
-          placeholder="商机名称"
-          clearable
+        <el-input v-model="listQuery.opportunityName" placeholder="商机名称" clearable
           style="margin-left: 20px;width: 320px;float: left;">
         </el-input>
-        <el-select clearable style="margin-left: 20px;width: 200px;float: left;" v-model="listQuery.state" placeholder="状态">
-          <el-option key="0" label="跟进中" value="跟进中"/>
-          <el-option key="1" label="签约" value="签约"/>
-          <el-option key="2" label="终止" value="终止"/>
+        <el-select clearable style="margin-left: 20px;width: 200px;float: left;" v-model="listQuery.state"
+          placeholder="状态">
+          <el-option key="0" label="跟进中" value="跟进中" />
+          <el-option key="1" label="签约" value="签约" />
+          <el-option key="2" label="终止" value="终止" />
         </el-select>
-        <el-button
-          class="filter-item"
-          style="margin-left: 10px;float: left;"
-          type="primary"
-          @click="searchList"
-          round
-        >搜索
+        <el-button class="filter-item" style="margin-left: 10px;float: left;" type="primary" @click="searchList" round>搜索
         </el-button>
-        <el-button
-          class="filter-item"
-          style="float: left;"
-          round
-          type="warning"
-          @click="resetSearch()"
-        >重置
+        <el-button class="filter-item" style="float: left;" round type="warning" @click="resetSearch()">重置
         </el-button>
       </template>
-      <parentTable
-        v-loading="listLoading"
-        :data="pageData.records"
-        slot="table"
-        style="width: 100%;"
-      >
+      <parentTable v-loading="listLoading" :data="pageData.records" slot="table" style="width: 100%;">
         <el-table-column label="客户名字" align="center" width="210">
           <template slot-scope="{row}">
             <span>{{ row.customerName }}</span>
@@ -96,59 +66,36 @@
             <span>{{ row.remark }}</span>
           </template>
         </el-table-column>
-        <el-table-column label="操作" align="center" width="210"  fixed="right">
+        <el-table-column label="操作" align="center" width="300" fixed="right">
           <template slot-scope="{row}">
-            <PermissionButton
-              menu-code="_views_market_business_detail"
-              class-name="filter-item"
-              name=""
-              type="primary"
-              :page-jump="true"
-              :page-query="{id: row.id,listQuery:listQuery}"
-              round
-              size="mini"
-            />
-            <PermissionButton
-              menu-code="_views_market_business_state"
-              class-name="filter-item"
-              name=""
-              type="danger"
-              round
-              size="mini"
-              @click="handleState(row.id,row.opportunityName,row.state,row.offReason)"
-            />
+            <PermissionButton menu-code="_views_market_business_detail" class-name="filter-item" name="" type="primary"
+              :page-jump="true" :page-query="{ id: row.id, listQuery: listQuery }" round size="mini" />
+            <PermissionButton menu-code="_views_market_business_state" class-name="filter-item" name="" type="danger"
+              round size="mini" @click="handleState(row.id, row.opportunityName, row.state, row.offReason)" />
+            <PermissionButton menu-code="_views_market_business_transfer" class-name="filter-item" name="" type="success"
+              round size="mini" @click="openTransferDialog(row)" />
           </template>
         </el-table-column>
       </parentTable>
     </y-page-list-layout>
-    <el-dialog
-      width="600px"
-      title="状态流转"
-      :visible.sync="dialogFormVisible"
-      :close-on-click-modal="false"
-    >
-      <el-form
-        ref="dataForm"
-        v-loading="dialogLoading"
-        :model="temp"
-        label-position="right"
-        label-width="110px"
-        style="width: 400px; margin-left:50px;"
-      >
+    <el-dialog width="600px" title="状态流转" :visible.sync="dialogFormVisible" :close-on-click-modal="false">
+      <el-form ref="dataForm" v-loading="dialogLoading" :model="temp" label-position="right" label-width="110px"
+        style="width: 400px; margin-left:50px;">
         <el-form-item label="商机名称:" prop="name">
-          <el-input v-model="temp.opportunityName" class="filter-item" readonly disabled/>
+          <el-input v-model="temp.opportunityName" class="filter-item" readonly disabled />
         </el-form-item>
 
         <el-form-item label="流转状态:" filterable prop="departmentId">
-          <el-select v-model="temp.state" filterable class="filter-item" style="float: left;width: 100%;" placeholder="请选择">
-            <el-option key="0" label="跟进中" value="跟进中"/>
-            <el-option key="1" label="签约" value="签约"/>
-            <el-option key="2" label="终止" value="终止"/>
+          <el-select v-model="temp.state" filterable class="filter-item" style="float: left;width: 100%;"
+            placeholder="请选择">
+            <el-option key="0" label="跟进中" value="跟进中" />
+            <el-option key="1" label="签约" value="签约" />
+            <el-option key="2" label="终止" value="终止" />
           </el-select>
         </el-form-item>
 
         <el-form-item label="终止原因:">
-          <el-input v-model="temp.offReason" class="filter-item" type="text"/>
+          <el-input v-model="temp.offReason" class="filter-item" type="text" />
         </el-form-item>
         <el-form-item label="">
           <el-button @click="dialogFormVisible = false">
@@ -160,103 +107,227 @@
         </el-form-item>
       </el-form>
     </el-dialog>
+    <el-dialog :visible.sync="dialogFormVisibleX" :close-on-click-modal="false" custom-class="tansferDialog">
+      <div class="detail">
+        <el-divider content-position="left">项目信息</el-divider>
+        <el-descriptions :column="4" size="lager" border>
+          <el-descriptions-item label="客户名字">{{ detail.customerName }}</el-descriptions-item>
+          <el-descriptions-item label="商机名称">{{ detail.opportunityName }}</el-descriptions-item>
+          <el-descriptions-item label="预计金额">{{ detail.estimateAmount }}</el-descriptions-item>
+          <el-descriptions-item label="预计开展日期">{{ detail.estimateDate }}</el-descriptions-item>
+          <el-descriptions-item label="状态">{{ detail.state }}</el-descriptions-item>
+          <el-descriptions-item label="客户经理">
+            <el-select v-model="detail.userId">
+              <el-option v-for="(item, index) in managers" :key="index" :label="item.name" :value="item.id"></el-option>
+            </el-select>
+            <el-tooltip class="item" effect="dark" content="点击转交" placement="bottom-start">
+              <el-button type="success" icon="el-icon-check" circle style="margin-left: 20px;" placeholder="转交"
+                @click="saveManager"></el-button>
+            </el-tooltip>
+          </el-descriptions-item>
+          <el-descriptions-item label="终止原因">{{ detail.offReason }}</el-descriptions-item>
+        </el-descriptions>
+      </div>
+      <div class="histroy">
+        <el-divider content-position="left">转交记录</el-divider>
+        <el-collapse v-model="activeNames">
+          <el-collapse-item name="1">
+            <el-timeline>
+              <el-timeline-item v-for="item in historys" :key="item.id" :timestamp="item.created" placement="top">
+                <el-card>
+                  <el-descriptions :column="3" border>
+                    <el-descriptions-item label="前客户经理"><el-tag type="info">{{ item.originalUserName
+                    }}</el-tag></el-descriptions-item>
+                    <el-descriptions-item label="后客户经理"><el-tag type="success">{{ item.currentUserName
+                    }}</el-tag></el-descriptions-item>
+                    <el-descriptions-item label="操作人"><el-tag>{{ item.operatorName }}</el-tag></el-descriptions-item>
+                  </el-descriptions>
+                </el-card>
+              </el-timeline-item>
+            </el-timeline>
+          </el-collapse-item>
+        </el-collapse>
+      </div>
+    </el-dialog>
   </div>
 </template>
 <script>
-  import YPageListLayout from '@/components/YPageListLayout'
-  import Breadcrumb from '@/components/Breadcrumb'
-  import PermissionButton from '@/components/PermissionButton/PermissionButton'
+import YPageListLayout from '@/components/YPageListLayout'
+import Breadcrumb from '@/components/Breadcrumb'
+import PermissionButton from '@/components/PermissionButton/PermissionButton'
 
-  export default {
-    name: 'ViewsMarketBusinessList',
-    components: {
-      Breadcrumb,
-      YPageListLayout,
-      PermissionButton,
+export default {
+  name: 'ViewsMarketBusinessList',
+  components: {
+    Breadcrumb,
+    YPageListLayout,
+    PermissionButton,
+  },
+  filters: {
+    statusFilter(status) {
+      const statusMap = {
+        published: 'success',
+        draft: 'info',
+        deleted: 'danger',
+      }
+      return statusMap[status]
     },
-    filters: {
-      statusFilter(status) {
-        const statusMap = {
-          published: 'success',
-          draft: 'info',
-          deleted: 'danger',
-        }
-        return statusMap[status]
+  },
+  data() {
+    return {
+      isDisable: false,
+      tableKey: 0,
+      pageData: { records: [] },
+      total: 20,
+      dialogLoading: false,
+      listLoading: true,
+      listQuery: {
+        page: 1,
+        size: 10,
+        descs: 'id',
       },
+      listQueryKey: 'keyword',
+      importLoading: false,
+      AllEnum: [],
+      dialogFormVisible: false,
+      temp: {
+        state: '',
+        offReason: ''
+      },
+      dialogFormVisibleX: false,
+      detail: {},
+      activeNames: ['1'],
+      historys: [],
+      managers: [],
+    }
+  },
+  created() {
+    const that = this;
+    if (that.$route.query.current && !isNaN(that.$route.query.current)) {
+      that.listQuery.current = parseInt(that.$route.query.current);
+    }
+    if (that.$route.query.customerName) {
+      that.listQuery.customerName = that.$route.query.customerName;
+    }
+    if (that.$route.query.opportunityName) {
+      that.listQuery.opportunityName = that.$route.query.opportunityName;
+    }
+    if (that.$route.query.state) {
+      that.listQuery.state = that.$route.query.state;
+    }
+    that.getAllEnum();
+    that.getList();
+  },
+  methods: {
+    handleState(businessId, businessName, state, offReason) {
+      const that = this;
+      that.temp.id = businessId;
+      that.temp.opportunityName = businessName;
+      that.temp.state = state;
+      that.temp.offReason = offReason;
+      that.dialogFormVisible = true;
     },
-    data() {
-      return {
-        isDisable:false,
-        tableKey: 0,
-        pageData: { records: [] },
-        total: 20,
-        dialogLoading: false,
-        listLoading: true,
-        listQuery: {
-          page: 1,
-          size: 10,
-          descs: 'id',
-        },
-        listQueryKey: 'keyword',
-        importLoading: false,
-        AllEnum:[],
-        dialogFormVisible:false,
-        temp:{
-          state:'',
-          offReason:''
-        }
+    updateState() {
+      if (this.temp.id) {
+        this.$api.business.edit(Object.assign({}, this.temp, {
+        })).then(res => {
+          if (res.code === 200) {
+            this.$notify({
+              title: '成功',
+              message: '状态流转成功',
+              type: 'success',
+              duration: 2000
+            });
+            this.dialogFormVisible = false;
+            this.getList();
+          }
+        }).catch(() => {
+          this.dialogFormVisible = false;
+        })
       }
     },
-    created() {
+    getAllEnum() {
       const that = this;
-      if (that.$route.query.current && !isNaN(that.$route.query.current)) {
-        that.listQuery.current = parseInt(that.$route.query.current);
-      }
-      if (that.$route.query.customerName) {
-        that.listQuery.customerName = that.$route.query.customerName;
-      }
-      if (that.$route.query.opportunityName) {
-        that.listQuery.opportunityName = that.$route.query.opportunityName;
-      }
-      if (that.$route.query.state) {
-        that.listQuery.state = that.$route.query.state;
+      that.$api.globalConfig.getAllEnum().then(data => {
+        if (data.code === 200) {
+          that.AllEnum = data.data
+        } else {
+          this.$message({
+            type: 'error',
+            message: data.msg
+          })
+        }
+      })
+    },
+    resetSearch() {
+      this.$router.push({ query: {} });
+      this.listQuery = {
+        current: 1,
+        size: 10,
+        descs: 'id',
       }
-      that.getAllEnum();
-      that.getList();
+      this.getList()
     },
-    methods: {
-      handleState(businessId, businessName, state, offReason) {
-        const that = this;
-        that.temp.id = businessId;
-        that.temp.opportunityName = businessName;
-        that.temp.state = state;
-        that.temp.offReason = offReason;
-        that.dialogFormVisible = true;
-      },
-      updateState(){
-        if (this.temp.id) {
-          this.$api.business.edit(Object.assign({}, this.temp, {
-          })).then(res => {
+    removeHandle(row) {
+      // console.log(data)
+      const that = this
+      that
+        .$confirm('确认删除当前记录吗?', '警告', {
+          confirmButtonText: '确认',
+          cancelButtonText: '取消',
+          type: 'warning',
+        })
+        .then(async () => {
+          this.$api.business.delete(row.id).then((res) => {
             if (res.code === 200) {
-              this.$notify({
-                title: '成功',
-                message: '状态流转成功',
+              this.$message({
                 type: 'success',
-                duration: 2000
-              });
-              this.dialogFormVisible = false;
-              this.getList();
+                message: '删除成功',
+              })
+              this.getList()
             }
-          }).catch(() => {
-            this.dialogFormVisible = false;
           })
-        }
-      },
-      getAllEnum() {
-        const that = this;
-        that.$api.globalConfig.getAllEnum().then(data => {
+        })
+        .catch((err) => {
+          console.error(err)
+        })
+    },
+    searchList() {
+      // 重置分页
+      this.listQuery.page = 1
+      this.listQuery.size = 10
+      this.getList()
+    },
+    getList() {
+      const that = this
+      this.listLoading = true
+      // console.log(that.listQuery)
+      const key = {}
+      key[this.listQueryKey] = this.listQuery.description
+      this.$api.business
+        .list(Object.assign({}, that.listQuery, key))
+        .then((res) => {
+          that.pageData = res.data
+          setTimeout(() => {
+            that.listLoading = false
+          }, 200)
+        })
+        .catch(() => {
+          that.listLoading = false
+        })
+    },
+    deleteInfo(id) {
+      const that = this
+      that.$confirm('请确认是否删除该数据?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning',
+        center: true
+      }).then(() => {
+        that.$api.business.delete(id).then(data => {
+          that.loading = false
           if (data.code === 200) {
-            that.AllEnum = data.data
+            that.getList()
           } else {
             this.$message({
               type: 'error',
@@ -264,125 +335,101 @@
             })
           }
         })
-      },
-      resetSearch() {
-        this.$router.push({ query: {} });
-        this.listQuery = {
-          current: 1,
-          size: 10,
-          descs: 'id',
+      }).catch(() => {
+      })
+    },
+    openTransferDialog(row) {
+      const originalUserId = row.userId;
+      this.dialogFormVisibleX = true;
+      this.detail = row;
+      this.detail.originalUserId = originalUserId;
+      this.getHistroyList(row.id);
+      this.getManagers();
+    },
+    getManagers() {
+      this.$api.user.usersByDepartment("市场部").then(res => {
+        this.managers = res.data
+      })
+    },
+    getHistroyList(id) {
+      this.$api.resourceTransfer.history({ "resourceType": "BUSINESS_OPPORTUNITY", "resourceId": id }).then(res => {
+        if (res.code === 200) {
+          this.historys = res.data;
+        }
+      })
+    },
+    saveManager() {
+      if (this.detail.userId === this.detail.originalUserId) {
+        this.$message({
+          type: 'error',
+          message: '抱歉,不能转交给本人。'
+        });
+        return;
+      }
+      this.$api.business.changeManager(this.detail).then(res => {
+        if (res.code === 200 && res.data === true) {
+          this.$message({
+            type: 'success',
+            message: '转交成功'
+          });
+          this.getHistroyList(this.detail.id);
         }
-        this.getList()
-      },
-      removeHandle(row) {
-        // console.log(data)
-        const that = this
-        that
-          .$confirm('确认删除当前记录吗?', '警告', {
-            confirmButtonText: '确认',
-            cancelButtonText: '取消',
-            type: 'warning',
-          })
-          .then(async () => {
-            this.$api.business.delete(row.id).then((res) => {
-              if (res.code === 200) {
-                this.$message({
-                  type: 'success',
-                  message: '删除成功',
-                })
-                this.getList()
-              }
-            })
-          })
-          .catch((err) => {
-            console.error(err)
-          })
-      },
-      searchList() {
-        // 重置分页
-        this.listQuery.page = 1
-        this.listQuery.size = 10
-        this.getList()
-      },
-      getList() {
-        const that = this
-        this.listLoading = true
-        // console.log(that.listQuery)
-        const key = {}
-        key[this.listQueryKey] = this.listQuery.description
-        this.$api.business
-          .list(Object.assign({}, that.listQuery, key))
-          .then((res) => {
-            that.pageData = res.data
-            setTimeout(() => {
-              that.listLoading = false
-            }, 200)
-          })
-          .catch(() => {
-            that.listLoading = false
-          })
-      },
-      deleteInfo(id) {
-        const that = this
-        that.$confirm('请确认是否删除该数据?', '提示', {
-          confirmButtonText: '确定',
-          cancelButtonText: '取消',
-          type: 'warning',
-          center: true
-        }).then(() => {
-          that.$api.business.delete(id).then(data => {
-            that.loading = false
-            if (data.code === 200) {
-              that.getList()
-            } else {
-              this.$message({
-                type: 'error',
-                message: data.msg
-              })
-            }
-          })
-        }).catch(() => {
-        })
       }
+      );
     },
-  }
+  },
+}
 </script>
 <style lang="scss" scoped>
-  .right {
-    flex: 1;
+.right {
+  flex: 1;
 
-    .title {
-      font-size: 16px;
-      font-weight: 500;
-      color: rgba(51, 51, 51, 1);
-      line-height: 35px;
-      margin-bottom: 8px;
-    }
+  .title {
+    font-size: 16px;
+    font-weight: 500;
+    color: rgba(51, 51, 51, 1);
+    line-height: 35px;
+    margin-bottom: 8px;
+  }
 
-    .menu-2-box {
-      display: flex;
-      flex-wrap: wrap;
-      width: 100%;
-    }
+  .menu-2-box {
+    display: flex;
+    flex-wrap: wrap;
+    width: 100%;
+  }
 
-    .menu-2-item {
-      display: flex;
-      align-items: center;
-      color: #656565;
-      font-size: 12px;
-      width: 230px;
-      height: 101px;
-      background: rgb(255, 185, 129);
-      border-radius: 3px;
-      padding-left: 20px;
-      margin-right: 10px;
-      margin-bottom: 10px;
-      cursor: pointer;
-      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
+  .menu-2-item {
+    display: flex;
+    align-items: center;
+    color: #656565;
+    font-size: 12px;
+    width: 230px;
+    height: 101px;
+    background: rgb(255, 185, 129);
+    border-radius: 3px;
+    padding-left: 20px;
+    margin-right: 10px;
+    margin-bottom: 10px;
+    cursor: pointer;
+    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
 
-      .text {
-        margin-left: 16px;
-      }
+    .text {
+      margin-left: 16px;
     }
   }
+}
+
+/deep/ .tansferDialog {
+  width: 60%;
+  border-radius: 10px;
+}
+
+.el-dropdown-link {
+  cursor: pointer;
+  color: red;
+}
+
+.el-icon-arrow-down {
+  font-size: 12px;
+}
 </style>

+ 304 - 263
src/views/market/customer/list.vue

@@ -1,94 +1,43 @@
 <template>
   <div class="app-container">
     <div class="title-container">
-      <breadcrumb id="breadcrumb-container" class="breadcrumb-container"/>
+      <breadcrumb id="breadcrumb-container" class="breadcrumb-container" />
     </div>
 
     <y-page-list-layout :page-list="pageData" :page-para="listQuery" :get-page-list="getList">
       <template slot="left">
-        <PermissionButton
-          menu-code="_views_market_customer_add"
-          class-name="filter-item"
-          type="primary"
-          name
-          size="mini"
-          :page-jump="true"
-          round
-          style="float: left"
-        />
-        <el-input
-          v-model="listQuery.name"
-          placeholder="客户名字"
-          clearable
+        <PermissionButton menu-code="_views_market_customer_add" class-name="filter-item" type="primary" name size="mini"
+          :page-jump="true" round style="float: left" />
+        <el-input v-model="listQuery.name" placeholder="客户名字" clearable
           style="margin-left: 20px;width: 320px;float: left;">
         </el-input>
-        <el-select clearable style="margin-left: 20px;width: 200px;float: left;" v-model="listQuery.level" placeholder="客户等级">
-          <el-option v-for="(item, index) in AllEnum['客户等级']" :key="index" :label="item" :value="item"/>
+        <el-select clearable style="margin-left: 20px;width: 200px;float: left;" v-model="listQuery.level"
+          placeholder="客户等级">
+          <el-option v-for="(item, index) in AllEnum['客户等级']" :key="index" :label="item" :value="item" />
         </el-select>
-        <el-button
-          class="filter-item"
-          style="margin-left: 10px;float: left;"
-          type="primary"
-          @click="searchList"
-          round
-        >搜索
+        <el-button class="filter-item" style="margin-left: 10px;float: left;" type="primary" @click="searchList" round>搜索
         </el-button>
-        <el-button
-          class="filter-item"
-          style="float: left;"
-          round
-          type="warning"
-          @click="resetSearch()"
-        >重置
+        <el-button class="filter-item" style="float: left;" round type="warning" @click="resetSearch()">重置
         </el-button>
       </template>
       <template slot="right">
-        <PermissionButton
-          menu-code="_views_customer_template"
-          class-name="filter-item"
-          round
-          icon="el-icon-download"
-          name="下载模板"
-          @click="handleDownload"
-        />
-        <PermissionButton
-          menu-code="_views_customer_import"
-          class-name="filter-item"
-          round
-          type="text"
-          name=""
-          style="padding: 0; margin-bottom: 10px"
-        >
-          <excelImport
-            ref="uploadControl"
-            flag="customer/importExcel"
-            :style-type="1"
-            title="导入"
-            @fath="getList"
-          />
+        <PermissionButton menu-code="_views_customer_template" class-name="filter-item" round icon="el-icon-download"
+          name="下载模板" @click="handleDownload" />
+        <PermissionButton menu-code="_views_customer_import" class-name="filter-item" round type="text" name=""
+          style="padding: 0; margin-bottom: 10px">
+          <excelImport ref="uploadControl" flag="customer/importExcel" :style-type="1" title="导入" @fath="getList" />
         </PermissionButton>
-        <PermissionButton
-          menu-code="_views_customer_export"
-          class-name="filter-item"
-          round
-          type="primary"
-          name="导出"
-          @click="customerExport"
-        >
+        <PermissionButton menu-code="_views_customer_export" class-name="filter-item" round type="primary" name="导出"
+          @click="customerExport">
         </PermissionButton>
       </template>
-      <parentTable
-        v-loading="listLoading"
-        :data="pageData.records"
-        slot="table"
-        style="width: 100%;"
-      >
+      <parentTable v-loading="listLoading" :data="pageData.records" slot="table" style="width: 100%;">
         <el-table-column label="客户名字" align="center" width="120">
           <template slot-scope="{row}">
             <span>{{ row.name }}</span>
           </template>
         </el-table-column>
-        <el-table-column label="市" align="center" width="150">
+        <el-table-column label="市/州" align="center" width="150">
           <template slot-scope="{row}">
             <span>{{ row.firstCity }}</span>
           </template>
@@ -130,9 +79,9 @@
         </el-table-column>
         <el-table-column label="客户等级" align="center" width="120">
           <template slot-scope="{row}">
-            <span v-if=" row.level==='重点客户' " style="color: red">{{row.level}}</span>
-            <span v-if=" row.level==='普通客户' " style="color: sandybrown">{{row.level}}</span>
-            <span v-if=" row.level==='一般客户' " style="color: green">{{row.level}}</span>
+            <span v-if="row.level === '重点客户'" style="color: red">{{ row.level }}</span>
+            <span v-if="row.level === '普通客户'" style="color: sandybrown">{{ row.level }}</span>
+            <span v-if="row.level === '一般客户'" style="color: green">{{ row.level }}</span>
           </template>
         </el-table-column>
         <el-table-column label="客户地址" align="center" width="200">
@@ -145,104 +94,219 @@
             <span>{{ row.userName }}</span>
           </template>
         </el-table-column>
-        <el-table-column label="操作" align="center" width="200"  fixed="right">
+        <el-table-column label="操作" align="center" width="300" fixed="right">
           <template slot-scope="{row}">
-            <PermissionButton
-              menu-code="_views_market_customer_detail"
-              class-name="filter-item"
-              name=""
-              type="primary"
-              :page-jump="true"
-              :page-query="{id: row.id,listQuery:listQuery}"
-              round
-              size="mini"
-            />
-            <PermissionButton
-              menu-code="_views_market_customer_remove"
-              class-name="filter-item"
-              name=""
-              type="danger"
-              round
-              size="mini"
-              @click="deleteInfo(row.id)"
-            />
+            <PermissionButton menu-code="_views_market_customer_detail" class-name="filter-item" name="" type="primary"
+              :page-jump="true" :page-query="{ id: row.id, listQuery: listQuery }" round size="mini" />
+            <PermissionButton menu-code="_views_market_customer_remove" class-name="filter-item" name="" type="danger"
+              round size="mini" @click="deleteInfo(row.id)" />
+            <PermissionButton menu-code="_views_customer_transfer" class-name="filter-item" name="" type="success" round
+              size="mini" @click="openTransferDialog(row)" />
           </template>
         </el-table-column>
       </parentTable>
     </y-page-list-layout>
+    <el-dialog :visible.sync="dialogFormVisible" :close-on-click-modal="false" custom-class="tansferDialog">
+      <div class="detail">
+        <el-divider content-position="left">项目信息</el-divider>
+        <el-descriptions :column="4" size="lager" border>
+          <el-descriptions-item label="客户名字">{{ detail.name }}</el-descriptions-item>
+          <el-descriptions-item label="市/州">{{ detail.firstCity }}</el-descriptions-item>
+          <el-descriptions-item label="区/县">{{ detail.secCity }}</el-descriptions-item>
+          <el-descriptions-item label="单位">{{ detail.department }}</el-descriptions-item>
+          <el-descriptions-item label="职位">{{ detail.position }}</el-descriptions-item>
+          <el-descriptions-item label="科室">{{ detail.section }}</el-descriptions-item>
+          <el-descriptions-item label="联系电话">{{ detail.mobile }}</el-descriptions-item>
+          <el-descriptions-item label="微信号">{{ detail.wechatNo }}</el-descriptions-item>
+          <el-descriptions-item label="QQ号">{{ detail.qq }}</el-descriptions-item>
+          <el-descriptions-item label="客户经理">
+            <el-select v-model="detail.userId">
+              <el-option v-for="(item, index) in managers" :key="index" :label="item.name" :value="item.id"></el-option>
+            </el-select>
+            <el-tooltip class="item" effect="dark" content="点击转交" placement="bottom-start">
+              <el-button type="success" icon="el-icon-check" circle style="margin-left: 20px;" placeholder="转交"
+                @click="saveManager"></el-button>
+            </el-tooltip>
+          </el-descriptions-item>
+          <el-descriptions-item label="客户等级">{{ detail.level }}</el-descriptions-item>
+        </el-descriptions>
+      </div>
+      <div class="histroy">
+        <el-divider content-position="left">转交记录</el-divider>
+        <el-collapse v-model="activeNames">
+          <el-collapse-item name="1">
+            <el-timeline>
+              <el-timeline-item v-for="item in historys" :key="item.id" :timestamp="item.created" placement="top">
+                <el-card>
+                  <el-descriptions :column="3" border>
+                    <el-descriptions-item label="前客户经理"><el-tag type="info">{{ item.originalUserName
+                    }}</el-tag></el-descriptions-item>
+                    <el-descriptions-item label="后客户经理"><el-tag type="success">{{ item.currentUserName
+                    }}</el-tag></el-descriptions-item>
+                    <el-descriptions-item label="操作人"><el-tag>{{ item.operatorName }}</el-tag></el-descriptions-item>
+                  </el-descriptions>
+                </el-card>
+              </el-timeline-item>
+            </el-timeline>
+          </el-collapse-item>
+        </el-collapse>
+      </div>
+    </el-dialog>
   </div>
 </template>
 <script>
-  import YPageListLayout from '@/components/YPageListLayout'
-  import Breadcrumb from '@/components/Breadcrumb'
-  import PermissionButton from '@/components/PermissionButton/PermissionButton'
+import YPageListLayout from '@/components/YPageListLayout'
+import Breadcrumb from '@/components/Breadcrumb'
+import PermissionButton from '@/components/PermissionButton/PermissionButton'
 
-  export default {
-    name: 'ViewsMarketCustomerList',
-    components: {
-      Breadcrumb,
-      YPageListLayout,
-      PermissionButton,
+export default {
+  name: 'ViewsMarketCustomerList',
+  components: {
+    Breadcrumb,
+    YPageListLayout,
+    PermissionButton,
+  },
+  filters: {
+    statusFilter(status) {
+      const statusMap = {
+        published: 'success',
+        draft: 'info',
+        deleted: 'danger',
+      }
+      return statusMap[status]
     },
-    filters: {
-      statusFilter(status) {
-        const statusMap = {
-          published: 'success',
-          draft: 'info',
-          deleted: 'danger',
-        }
-        return statusMap[status]
+  },
+  data() {
+    return {
+      isDisable: false,
+      tableKey: 0,
+      pageData: { records: [] },
+      total: 20,
+      listLoading: true,
+      listQuery: {
+        page: 1,
+        size: 10,
+        descs: 'id',
       },
+      listQueryKey: 'keyword',
+      importLoading: false,
+      name: null,
+      city: null,
+      county: null,
+      AllEnum: [],
+      dialogFormVisible: false,
+      detail: {},
+      activeNames: ['1'],
+      historys: [],
+      managers: [],
+    }
+  },
+  created() {
+    const that = this;
+    if (that.$route.query.current && !isNaN(that.$route.query.current)) {
+      that.listQuery.current = parseInt(that.$route.query.current);
+    }
+    if (that.$route.query.name) {
+      that.listQuery.name = that.$route.query.name;
+    }
+    if (that.$route.query.level) {
+      that.listQuery.level = that.$route.query.level;
+    }
+    that.getAllEnum();
+    that.getList();
+  },
+  methods: {
+    customerExport() {
+      this.$utils.exportUtil(
+        "/customer/export", this.listQuery,
+        "导出"
+      );
     },
-    data() {
-      return {
-        isDisable:false,
-        tableKey: 0,
-        pageData: { records: [] },
-        total: 20,
-        listLoading: true,
-        listQuery: {
-          page: 1,
-          size: 10,
-          descs: 'id',
-        },
-        listQueryKey: 'keyword',
-        importLoading: false,
-        name:null,
-        city:null,
-        county:null,
-        AllEnum:[],
-      }
+    handleDownload() {
+      this.$utils.exportUtil('/customer/download/importTemplate', {}, '模板下载')
     },
-    created() {
+    getAllEnum() {
       const that = this;
-      if (that.$route.query.current && !isNaN(that.$route.query.current)) {
-        that.listQuery.current = parseInt(that.$route.query.current);
-      }
-      if (that.$route.query.name) {
-        that.listQuery.name = that.$route.query.name;
-      }
-      if (that.$route.query.level) {
-        that.listQuery.level = that.$route.query.level;
+      that.$api.globalConfig.getAllEnum().then(data => {
+        if (data.code === 200) {
+          that.AllEnum = data.data
+        } else {
+          this.$message({
+            type: 'error',
+            message: data.msg
+          })
+        }
+      })
+    },
+    resetSearch() {
+      this.$router.push({ query: {} });
+      this.listQuery = {
+        current: 1,
+        size: 10,
+        descs: 'id',
       }
-      that.getAllEnum();
-      that.getList();
+      this.getList()
     },
-    methods: {
-      customerExport(){
-        this.$utils.exportUtil(
-          "/customer/export", this.listQuery,
-          "导出"
-        );
-      },
-      handleDownload() {
-        this.$utils.exportUtil('/customer/download/importTemplate', {}, '模板下载')
-      },
-      getAllEnum() {
-        const that = this;
-        that.$api.globalConfig.getAllEnum().then(data => {
+    removeHandle(row) {
+      // console.log(data)
+      const that = this
+      that
+        .$confirm('确认删除当前记录吗?', '警告', {
+          confirmButtonText: '确认',
+          cancelButtonText: '取消',
+          type: 'warning',
+        })
+        .then(async () => {
+          this.$api.customer.delete(row.id).then((res) => {
+            if (res.code === 200) {
+              this.$message({
+                type: 'success',
+                message: '删除成功',
+              })
+              this.getList()
+            }
+          })
+        })
+        .catch((err) => {
+          console.error(err)
+        })
+    },
+    searchList() {
+      // 重置分页
+      this.listQuery.page = 1
+      this.listQuery.size = 10
+      this.getList()
+    },
+    getList() {
+      const that = this
+      this.listLoading = true
+      // console.log(that.listQuery)
+      const key = {}
+      key[this.listQueryKey] = this.listQuery.description
+      this.$api.customer
+        .list(Object.assign({}, that.listQuery, key))
+        .then((res) => {
+          that.pageData = res.data
+          setTimeout(() => {
+            that.listLoading = false
+          }, 200)
+        })
+        .catch(() => {
+          that.listLoading = false
+        })
+    },
+    deleteInfo(id) {
+      const that = this
+      that.$confirm('请确认是否删除该数据?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning',
+        center: true
+      }).then(() => {
+        that.$api.customer.delete(id).then(data => {
+          that.loading = false
           if (data.code === 200) {
-            that.AllEnum = data.data
+            that.getList()
           } else {
             this.$message({
               type: 'error',
@@ -250,125 +314,102 @@
             })
           }
         })
-      },
-      resetSearch() {
-        this.$router.push({ query: {} });
-        this.listQuery = {
-          current: 1,
-          size: 10,
-          descs: 'id',
+      }).catch(() => {
+      })
+    },
+    openTransferDialog(row) {
+      const originalUserId = row.userId;
+      this.dialogFormVisible = true;
+      this.detail = row;
+      this.detail.originalUserId = originalUserId;
+      this.getHistroyList(row.id);
+      this.getManagers();
+    },
+    getManagers() {
+      this.$api.user.usersByDepartment("市场部").then(res => {
+        this.managers = res.data
+      })
+    },
+    getHistroyList(id) {
+      this.$api.resourceTransfer.history({ "resourceType": "CUSTOMER", "resourceId": id }).then(res => {
+        if (res.code === 200) {
+          this.historys = res.data;
         }
-        this.getList()
-      },
-      removeHandle(row) {
-        // console.log(data)
-        const that = this
-        that
-          .$confirm('确认删除当前记录吗?', '警告', {
-            confirmButtonText: '确认',
-            cancelButtonText: '取消',
-            type: 'warning',
-          })
-          .then(async () => {
-            this.$api.customer.delete(row.id).then((res) => {
-              if (res.code === 200) {
-                this.$message({
-                  type: 'success',
-                  message: '删除成功',
-                })
-                this.getList()
-              }
-            })
-          })
-          .catch((err) => {
-            console.error(err)
-          })
-      },
-      searchList() {
-        // 重置分页
-        this.listQuery.page = 1
-        this.listQuery.size = 10
-        this.getList()
-      },
-      getList() {
-        const that = this
-        this.listLoading = true
-        // console.log(that.listQuery)
-        const key = {}
-        key[this.listQueryKey] = this.listQuery.description
-        this.$api.customer
-          .list(Object.assign({}, that.listQuery, key))
-          .then((res) => {
-            that.pageData = res.data
-            setTimeout(() => {
-              that.listLoading = false
-            }, 200)
-          })
-          .catch(() => {
-            that.listLoading = false
-          })
-      },
-      deleteInfo(id) {
-        const that = this
-        that.$confirm('请确认是否删除该数据?', '提示', {
-          confirmButtonText: '确定',
-          cancelButtonText: '取消',
-          type: 'warning',
-          center: true
-        }).then(() => {
-          that.$api.customer.delete(id).then(data => {
-            that.loading = false
-            if (data.code === 200) {
-              that.getList()
-            } else {
-              this.$message({
-                type: 'error',
-                message: data.msg
-              })
-            }
-          })
-        }).catch(() => {
-        })
+      })
+    },
+    saveManager() {
+      if (this.detail.userId === this.detail.originalUserId){
+        this.$message({
+            type: 'error',
+            message: '抱歉,不能转交给本人。'
+          });
+          return ;
       }
+      this.$api.customer.changeManager(this.detail).then(res => {
+        if (res.code === 200 && res.data === true) {
+          this.$message({
+            type: 'success',
+            message: '转交成功'
+          });
+          this.getHistroyList(this.detail.id);
+        }
+      }
+      );
     },
-  }
+  },
+
+}
 </script>
 <style lang="scss" scoped>
-  .right {
-    flex: 1;
+.right {
+  flex: 1;
 
-    .title {
-      font-size: 16px;
-      font-weight: 500;
-      color: rgba(51, 51, 51, 1);
-      line-height: 35px;
-      margin-bottom: 8px;
-    }
+  .title {
+    font-size: 16px;
+    font-weight: 500;
+    color: rgba(51, 51, 51, 1);
+    line-height: 35px;
+    margin-bottom: 8px;
+  }
 
-    .menu-2-box {
-      display: flex;
-      flex-wrap: wrap;
-      width: 100%;
-    }
+  .menu-2-box {
+    display: flex;
+    flex-wrap: wrap;
+    width: 100%;
+  }
 
-    .menu-2-item {
-      display: flex;
-      align-items: center;
-      color: #656565;
-      font-size: 12px;
-      width: 230px;
-      height: 101px;
-      background: rgb(255, 185, 129);
-      border-radius: 3px;
-      padding-left: 20px;
-      margin-right: 10px;
-      margin-bottom: 10px;
-      cursor: pointer;
-      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
+  .menu-2-item {
+    display: flex;
+    align-items: center;
+    color: #656565;
+    font-size: 12px;
+    width: 230px;
+    height: 101px;
+    background: rgb(255, 185, 129);
+    border-radius: 3px;
+    padding-left: 20px;
+    margin-right: 10px;
+    margin-bottom: 10px;
+    cursor: pointer;
+    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
 
-      .text {
-        margin-left: 16px;
-      }
+    .text {
+      margin-left: 16px;
     }
   }
+}
+
+/deep/ .tansferDialog {
+  width: 60%;
+  border-radius: 10px;
+}
+
+.el-dropdown-link {
+  cursor: pointer;
+  color: red;
+}
+
+.el-icon-arrow-down {
+  font-size: 12px;
+}
 </style>

+ 3 - 1
src/views/market/index.vue

@@ -10,7 +10,9 @@
           <y-d-v-over-view style="width: 220px" title="本年已签约" :typeId="4" :ico="require('@/assets/statics/pg9.png')" :data="[{text:marketStaticsInfo.yearSaleDone,value:'元'}]" @click.native="toItemPage()"></y-d-v-over-view>
           <y-d-v-over-view style="width: 220px" title="本年已回款" :typeId="5" :ico="require('@/assets/statics/pg9.png')" :data="[{text:marketStaticsInfo.yearPaymentDone,value:'元'}]" @click.native="toPaymentPage('year')"></y-d-v-over-view>
           <y-d-v-over-view style="width: 220px" title="本月已回款" :typeId="6" :ico="require('@/assets/statics/pg9.png')" :data="[{text:marketStaticsInfo.monthPaymentDone,value:'元'}]" @click.native="toPaymentPage('month')"></y-d-v-over-view>
-          <el-progress  style=" margin-left:12px ;width: 91%" :text-inside="true" :stroke-width="24" :percentage="percentage" status="success" />
+          <el-tooltip class="item" effect="dark" content="年度回款目标完成率" placement="bottom">
+            <el-progress  style=" margin-left:12px ;width: 91%" :text-inside="true" :stroke-width="24" :percentage="percentage" status="success" />
+          </el-tooltip>
         </div>
       </y-data-view-module>
       <div class="calendar-class">

+ 2 - 1
vue.config.js

@@ -196,7 +196,8 @@ module.exports = {
             });
           config.optimization.runtimeChunk('single')
         }
-      )
+      );
+
   },
   css: {
     extract: false, //false表示开发环境,true表示生成环境