Selaa lähdekoodia

feature:增加合作伙伴模块

liuzl 2 vuotta sitten
vanhempi
commit
a5baf1d3b0

+ 42 - 0
src/api/base/partner.js

@@ -0,0 +1,42 @@
+import micro_request from '@/utils/micro_request'
+
+const basePath = process.env.VUE_APP_ParentPath
+export default {
+  getCompanyList(query) {
+    return micro_request.postRequest(basePath, 'PartnerCompany', 'List', query)
+  },
+  addCompany(query) {
+    return micro_request.postRequest(basePath, 'PartnerCompany', 'Add', query)
+  },
+  updateCompany(query) {
+    return micro_request.postRequest(basePath, 'PartnerCompany', 'Update', query)
+  },
+  deleteCompany(query) {
+    return micro_request.postRequest(basePath, 'PartnerCompany', 'Delete', query)
+  },
+  getCompany(query) {
+    return micro_request.postRequest(basePath, 'PartnerCompany', 'Get', query)
+  },
+
+  getCompanyConcatList(query) {
+    return micro_request.postRequest(basePath, 'PartnerCompanyContact', 'List', query)
+  },
+  addCompanyConcat(query) {
+    return micro_request.postRequest(basePath, 'PartnerCompanyContact', 'Add', query)
+  },
+  updateCompanyConcat(query) {
+    return micro_request.postRequest(basePath, 'PartnerCompanyContact', 'Update', query)
+  },
+  deleteCompanyConcat(query) {
+    return micro_request.postRequest(basePath, 'PartnerCompanyContact', 'Delete', query)
+  },
+  getCompanyConcat(query) {
+    return micro_request.postRequest(basePath, 'PartnerCompanyContact', 'Get', query)
+  },
+  downloadFile(query) {
+    return micro_request.postRequest(basePath, 'PartnerCompanyContact', 'ExcelTemplate', query)
+  },
+  exportFile(query) {
+    return micro_request.postRequest(basePath, 'PartnerCompanyContact', 'ExcelUpload', query)
+  },
+}

+ 110 - 0
src/views/base/partners/components/PartnerEdit.vue

@@ -0,0 +1,110 @@
+<template>
+  <el-dialog append-to-body :title="title" :visible.sync="dialogFormVisible" @close="close">
+    <el-form ref="form" :model="form" :rules="rules">
+      <el-row :gutter="20">
+        <el-col :span="12">
+          <el-form-item label="姓名" prop="name">
+            <el-input v-model="form.name" placeholder="请输入姓名" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="电话" prop="contactWay">
+            <el-input v-model="form.contactWay" maxlength="11" placeholder="请输入电话" />
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row :gutter="20">
+        <el-col :span="12">
+          <el-form-item label="岗位" prop="post">
+            <el-input v-model="form.post" placeholder="请输入岗位" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="负责区域" prop="territory">
+            <el-input v-model="form.territory" placeholder="请输入负责区域" />
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row :gutter="20">
+        <el-col :span="24">
+          <el-form-item label="备注" prop="remark">
+            <el-input v-model="form.remark" placeholder="请输入备注" type="textarea" />
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </el-form>
+    <span slot="footer">
+      <el-button @click="close">取 消</el-button>
+      <el-button type="primary" @click="save">确 定</el-button>
+    </span>
+  </el-dialog>
+</template>
+<script>
+  import partnerApi from '@/api/base/partner'
+  export default {
+    name: 'UserEdit',
+    data() {
+      return {
+        form: {
+          contactWay: '',
+          name: '',
+          partnerId: null,
+          post: '',
+          remark: '',
+          territory: '',
+          id: null,
+        },
+        rules: {
+          name: [{ required: true, trigger: 'blur', message: '请输入姓名' }],
+          territory: [{ required: true, trigger: 'blur', message: '请输入负责区域' }],
+        },
+        //省份
+        title: '',
+        dialogFormVisible: false,
+      }
+    },
+    mounted() {},
+    methods: {
+      open(row) {
+        console.log(isNaN(row))
+        if (isNaN(row)) {
+          this.title = '编辑'
+          this.form = Object.assign({ ...row })
+        } else {
+          this.title = '新建'
+          this.form.partnerId = row
+        }
+        this.dialogFormVisible = true
+      },
+      close() {
+        this.$refs['form'].resetFields()
+        this.form = {
+          contactWay: '',
+          name: '',
+          partnerId: null,
+          post: '',
+          remark: '',
+          territory: '',
+          id: null,
+        }
+        this.dialogFormVisible = false
+      },
+      save() {
+        this.$refs['form'].validate(async (valid) => {
+          if (valid) {
+            let params = { ...this.form }
+            if (!this.form.id) {
+              const { msg } = await partnerApi.addCompanyConcat(params)
+              this.$baseMessage(msg, 'success', 'vab-hey-message-success')
+            } else {
+              const { msg } = await partnerApi.updateCompanyConcat(params)
+              this.$baseMessage(msg, 'success', 'vab-hey-message-success')
+            }
+            this.$emit('fetch-data')
+            this.close()
+          }
+        })
+      },
+    },
+  }
+</script>

+ 512 - 0
src/views/base/partners/detail.vue

@@ -0,0 +1,512 @@
+<!--
+ * @Author: wanglj 471442253@qq.com
+ * @Date: 2022-12-26 09:30:47
+ * @LastEditors: liuzhenlin
+ * @LastEditTime: 2023-06-30 18:22:00
+ * @Description: file content
+ * @FilePath: \订单全流程管理系统\src\views\base\partners\detail.vue
+-->
+<template>
+  <div class="detail">
+    <div class="side-layout">
+      <div>
+        <div class="title">
+          <p>合作伙伴</p>
+          <h3>
+            <div>{{ detail.title }}</div>
+            <el-button @click="handleFollow">添加跟进</el-button>
+          </h3>
+        </div>
+        <header>
+          <el-descriptions :colon="false" :column="7" direction="vertical">
+            <el-descriptions-item content-class-name="my-content" label="负责区域" label-class-name="my-label">
+              {{ detail.territory }}
+            </el-descriptions-item>
+            <el-descriptions-item content-class-name="my-content" label="联系人" label-class-name="my-label">
+              {{ detail.name }}
+            </el-descriptions-item>
+            <el-descriptions-item content-class-name="my-content" label="联系方式" label-class-name="my-label">
+              {{ detail.contactWay }}
+            </el-descriptions-item>
+            <el-descriptions-item content-class-name="my-content" label="岗位" label-class-name="my-label">
+              {{ detail.post }}
+            </el-descriptions-item>
+            <el-descriptions-item content-class-name="my-content" label="备注" label-class-name="my-label">
+              {{ detail.remark }}
+            </el-descriptions-item>
+          </el-descriptions>
+        </header>
+        <el-tabs v-model="activeName">
+          <el-tab-pane label="跟进记录" name="follow">
+            <ul v-if="followList.length" class="follow">
+              <li v-for="(date, index) in followList" :key="index">
+                <div class="date">
+                  <h2>{{ date.followDay.split('-')[2] }}</h2>
+                  <h3>
+                    {{ date.followDay.split('-').splice(0, 2).join('.') }}
+                  </h3>
+                </div>
+                <ul class="content">
+                  <li v-for="(item, idx) in date.followupList" :key="idx">
+                    <!-- <el-avatar class="user-avatar"
+              :src="avatar" />-->
+                    <div class="text-container">
+                      <vab-icon class="user-avatar" icon="account-circle-fill" />
+                      <div class="text">
+                        <p class="action">
+                          <span>{{ item.createdName }} 跟进({{ formatType(item.followType) }})</span>
+                          <span>
+                            <vab-icon icon="time-line" />
+                            {{ item.followDate }}
+                          </span>
+                        </p>
+                        <p>{{ item.followContent }}</p>
+                        <div class="footer">
+                          <p></p>
+                          <div>
+                            <el-button icon="el-icon-edit" size="mini" @click="postComments(item)">发表评论</el-button>
+                            <el-button size="mini" @click="showDetail(item)">
+                              <vab-icon icon="arrow-right-circle-fill" />
+                              详情
+                            </el-button>
+                            <el-button size="mini" @click="showComment(item)">评论({{ item.commentNumber }})</el-button>
+                          </div>
+                        </div>
+                      </div>
+                    </div>
+                    <transition name="height">
+                      <ul v-if="item.showComment" class="comments">
+                        <li v-for="comment in item.comments" :key="comment.id">
+                          <vab-icon class="user-avatar" icon="account-circle-fill" />
+                          <div class="text">
+                            <p>{{ comment.createdName }}</p>
+                            <p>{{ comment.content }}</p>
+                            <p>{{ comment.createdTime }}</p>
+                          </div>
+                        </li>
+                      </ul>
+                    </transition>
+                  </li>
+                </ul>
+              </li>
+            </ul>
+            <div v-else class="no-follow">暂无跟进记录</div>
+          </el-tab-pane>
+        </el-tabs>
+      </div>
+    </div>
+    <!-- 跟进详情 -->
+    <FollowDetail ref="followDetail" />
+    <!-- 添加跟进记录 -->
+    <follow-add ref="follow-add" @fetch-data="getFollowList" />
+  </div>
+</template>
+
+<script>
+  import follow from '@/api/customer/follow'
+  import to from 'await-to-js'
+  import FollowDetail from '../components/FollowDetail'
+  import partnerApi from '@/api/base/partner'
+  import FollowAdd from '@/views/proj/business/components/FollowAdd'
+
+  export default {
+    name: 'CustomerDetail',
+    components: {
+      FollowDetail,
+      FollowAdd,
+    },
+    data() {
+      return {
+        id: '',
+        detail: {
+          custCode: '', //客户编码
+          abbrName: '', //助记名
+          level: '', //客户级别
+          indusTry: '', //客户类型
+          custStatus: '', //客户状态
+          followUpDate: '', //最后跟进时间
+        },
+        activeName: 'follow',
+        followList: [],
+        bidInfoTypeOptions: {},
+      }
+    },
+    mounted() {
+      this.id = this.$route.query.id
+      this.init()
+      this.getFollowList()
+    },
+    methods: {
+      // 添加跟进记录
+      handleFollow() {
+        this.followup = {
+          targetId: this.detail.id,
+          targetType: '70',
+          targetName: this.detail.name,
+          custId: '',
+          custName: '',
+        }
+        this.$refs['follow-add'].showEdit(this.followup)
+      },
+      async getFollowList() {
+        let params = {
+          targetId: '' + this.id,
+          targetType: '70',
+          DaysBeforeToday: 99999,
+        }
+        const [err, res] = await to(follow.getListByDay(params))
+        if (err) return
+        this.followList = res.data.list || []
+      },
+      // 发表评论
+      postComments(row) {
+        this.$PostComment({ form: row, visible: true })
+          .then(() => {
+            this.getFollowList()
+          })
+          .catch(() => {})
+      },
+      async init() {
+        const [err, res] = await to(partnerApi.getCompanyConcat({ id: parseInt(this.id) }))
+        if (err) return
+        if (res.code == 200) {
+          this.detail = res.data
+        }
+      },
+
+      formatType(val) {
+        let str = ''
+        if (val == 10) str = '电话'
+        else if (val == 20) str = '邮件'
+        else if (val == 30) str = '拜访'
+        return str
+      },
+      // 跟进记录详情
+      showDetail(row) {
+        this.$refs.followDetail.init({ ...row })
+      },
+      // 展开评论
+      showComment(row) {
+        if (!row.comments.length) return this.$message.warning('暂无评论')
+        row.showComment = !row.showComment
+        this.$forceUpdate()
+      },
+    },
+  }
+</script>
+
+<style lang="scss" scoped>
+  $base: '.detail';
+  #{$base} {
+    height: calc(100vh - 60px - 12px * 2 - 40px);
+    display: flex;
+    padding: 20px 40px;
+
+    > .el-row {
+      flex: 1;
+      width: 100%;
+
+      > .el-col {
+        height: 100%;
+      }
+    }
+
+    .title {
+      p,
+      h3 {
+        margin: 0;
+      }
+
+      p {
+        font-size: 14px;
+        font-weight: 400;
+        line-height: 22px;
+      }
+
+      h3 {
+        font-size: 24px;
+        font-weight: 500;
+        line-height: 36px;
+        color: #333;
+        display: flex;
+        justify-content: space-between;
+      }
+    }
+
+    header {
+      height: 74px;
+      background: rgba(196, 196, 196, 0.5);
+      border-radius: 4px;
+      display: flex;
+      align-items: center;
+      padding: 0 20px;
+      margin-top: 16px;
+
+      ::v-deep .el-descriptions__body {
+        background: transparent;
+      }
+
+      ::v-deep .my-label {
+        font-size: 14px;
+        font-weight: 600;
+        color: #1d66dc;
+      }
+
+      ::v-deep .my-content {
+        font-size: 14px;
+        font-weight: 600;
+        color: #333;
+        white-space: nowrap;
+        overflow: hidden;
+        text-overflow: ellipsis;
+      }
+    }
+
+    .el-tabs {
+      height: calc(100% - 148px);
+      display: flex;
+      flex-direction: column;
+
+      ::v-deep .el-tabs__content {
+        flex: 1;
+
+        .el-tab-pane {
+          height: 100%;
+
+          .el-descriptions {
+            table-layout: fixed;
+
+            .is-bordered {
+              table-layout: fixed;
+            }
+          }
+        }
+      }
+    }
+
+    .buttons {
+      padding-top: 28px;
+      text-align: right;
+    }
+
+    .records {
+      margin: 0;
+      padding: 10px 20px;
+      list-style: none;
+      height: calc(100% - 60px);
+      overflow-y: auto;
+
+      > li {
+        display: flex;
+
+        & + li {
+          margin-top: 10px;
+        }
+      }
+
+      .date {
+        width: 100px;
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+
+        h2,
+        h3 {
+          margin: 0;
+        }
+
+        h2 {
+          font-size: 26px;
+          line-height: 32px;
+        }
+      }
+
+      .content {
+        flex: 1;
+        list-style: none;
+
+        li {
+          display: flex;
+
+          & + li {
+            margin-top: 10px;
+          }
+        }
+
+        .user-avatar {
+          font-size: 40px;
+        }
+
+        .text {
+          flex: 1;
+          padding-left: 20px;
+
+          p {
+            font-weight: 500;
+            margin: 0;
+            line-height: 20px;
+
+            span {
+              color: #1d66dc;
+            }
+          }
+
+          p:nth-child(2) {
+            margin-bottom: 10px;
+          }
+
+          .action {
+            font-weight: bold;
+            color: #333;
+          }
+        }
+      }
+    }
+
+    .follow {
+      height: 100%;
+      padding: 10px 20px;
+      overflow: auto;
+
+      > li {
+        display: flex;
+
+        + li {
+          margin-top: 10px;
+        }
+      }
+
+      .date {
+        width: 100px;
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+
+        h2,
+        h3 {
+          margin: 0;
+        }
+
+        h2 {
+          font-size: 26px;
+          line-height: 32px;
+        }
+      }
+
+      .content {
+        flex: 1;
+        list-style: none;
+
+        > li {
+          border: 1px solid rgb(215, 232, 244);
+          background: rgb(247, 251, 254);
+          border-radius: 4px;
+          padding: 8px;
+          overflow: hidden;
+
+          .text-container {
+            display: flex;
+          }
+
+          .comments {
+            padding-left: 60px;
+            margin-top: 10px;
+            max-height: 190px;
+            overflow: auto;
+
+            li {
+              display: flex;
+              border-top: 1px solid #e3e5e7;
+
+              .text {
+                flex: 1;
+                padding: 0 10px;
+
+                p {
+                  font-weight: 500;
+                  margin: 0;
+                  line-height: 32px;
+                }
+
+                p:first-child {
+                  line-height: 30px;
+                  font-weight: bold;
+                }
+
+                p:last-child {
+                  font-size: 12px;
+                  color: #9499a0;
+                  text-align: right;
+                }
+              }
+            }
+          }
+
+          + li {
+            margin-top: 10px;
+          }
+        }
+
+        .user-avatar {
+          font-size: 40px;
+        }
+
+        .text {
+          flex: 1;
+          padding-left: 20px;
+          padding-right: 10px;
+
+          p {
+            font-weight: 500;
+            margin: 0;
+            line-height: 32px;
+
+            span {
+              color: #1d66dc;
+            }
+          }
+
+          .action {
+            display: flex;
+            justify-content: space-between;
+
+            span:first-child {
+              font-weight: bold;
+              color: #333;
+            }
+          }
+
+          .footer {
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+          }
+        }
+      }
+    }
+
+    .no-follow {
+      height: 100%;
+      width: 100%;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      font-size: 12px;
+      color: rgba(0, 0, 0, 0.65);
+    }
+  }
+
+  .height-enter-active,
+  .height-leave-active {
+    transition: all 0.5s;
+  }
+
+  .height-enter-to,
+  .height-leave {
+    height: 190px;
+  }
+
+  .height-enter, .height-leave-to /* .fade-leave-active below version 2.1.8 */ {
+    height: 0;
+  }
+</style>

+ 438 - 0
src/views/base/partners/index.vue

@@ -0,0 +1,438 @@
+<template>
+  <div class="user-management-container">
+    <div class="side-layout">
+      <div class="tree-side">
+        <div class="head-container">
+          <el-row style="padding-right: 10px" type="flex">
+            <el-col><span style="font-size: 25px">公司</span></el-col>
+            <el-button type="text" @click="addCompany()">新增</el-button>
+          </el-row>
+        </div>
+        <el-tree
+          ref="tree"
+          class="filter-tree"
+          :data="companyList"
+          default-expand-all
+          :default-expanded-keys="[1]"
+          highlight-current
+          node-key="id"
+          :props="defaultProps"
+          @node-click="handleNodeClick">
+          <span slot-scope="{ node }" class="custom-tree-node">
+            <span>
+              <span>{{ node.label }}</span>
+            </span>
+            <span>
+              <!-- <el-button icon="el-icon-more" type="text" /> -->
+              <el-dropdown @command="(command) => treeHandle(command, node)">
+                <span class="el-dropdown-link">
+                  <i class="el-icon-more"></i>
+                  <!-- <i class="el-icon-arrow-down el-icon--right"></i> -->
+                </span>
+                <el-dropdown-menu slot="dropdown">
+                  <el-dropdown-item v-permissions="['base:region:edit']" command="edit">编辑</el-dropdown-item>
+                  <el-dropdown-item v-permissions="['base:region:delete']" command="del">删除</el-dropdown-item>
+                </el-dropdown-menu>
+              </el-dropdown>
+            </span>
+          </span>
+        </el-tree>
+      </div>
+      <div class="tree-table">
+        <vab-query-form>
+          <vab-query-form-top-panel>
+            <el-form :inline="true" :model="queryForm" @submit.native.prevent>
+              <el-form-item>
+                <el-input
+                  v-model.trim="queryForm.name"
+                  clearable
+                  placeholder="联系人"
+                  @keyup.enter.native="queryData" />
+              </el-form-item>
+              <el-form-item>
+                <el-button icon="el-icon-search" type="primary" @click="queryData">查询</el-button>
+                <el-button icon="el-icon-refresh-right" @click="reset">重置</el-button>
+              </el-form-item>
+            </el-form>
+          </vab-query-form-top-panel>
+          <vab-query-form-left-panel>
+            <el-button
+              v-permissions="['base:product:add']"
+              icon="el-icon-plus"
+              type="primary"
+              @click="$refs.edit.open(queryForm.partnerId)">
+              添加
+            </el-button>
+            <el-button icon="el-icon-download" type="primary" @click="downloadTemplate">下载模板</el-button>
+            <el-upload
+              ref="uploadRef"
+              action="#"
+              :before-upload="
+                (file) => {
+                  return beforeAvatarUpload(file)
+                }
+              "
+              :file-list="fileList"
+              :http-request="uploadrequest"
+              :show-file-list="false"
+              style="margin: 0 10px 10px 0 !important">
+              <el-button icon="el-icon-upload2" type="primary">导入</el-button>
+            </el-upload>
+          </vab-query-form-left-panel>
+          <vab-query-form-right-panel>
+            <table-tool :columns="columns" :show-columns.sync="showColumns" table-type="productTable" />
+          </vab-query-form-right-panel>
+        </vab-query-form>
+
+        <el-table ref="table" v-loading="listLoading" border :data="list" :height="$baseTableHeight(2)">
+          <el-table-column align="center" label="序号" show-overflow-tooltip width="80">
+            <template #default="{ $index }">
+              {{ $index + 1 }}
+            </template>
+          </el-table-column>
+          <el-table-column
+            v-for="(item, index) in showColumns"
+            :key="index"
+            align="center"
+            :label="item.label"
+            :min-width="item.minWidth"
+            :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" fixed="right" label="操作" show-overflow-tooltip width="120">
+            <template #default="{ row }">
+              <el-button type="text" @click="$refs.edit.open(row)">编辑</el-button>
+              <el-button type="text" @click="handleDetail(row)">详情</el-button>
+              <el-button type="text" @click="handleDelete(row)">删除</el-button>
+            </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" />
+      </div>
+    </div>
+    <partner-edit ref="edit" @fetch-data="fetchData" />
+  </div>
+</template>
+
+<script>
+  import partnerApi from '@/api/base/partner'
+  import TableTool from '@/components/table/TableTool'
+  import PartnerEdit from './components/PartnerEdit'
+  import downloadFileByByte from '@/utils/base64ToFile'
+  import to from 'await-to-js'
+  import axios from 'axios'
+  import asyncUploadFile from '@/utils/uploadajax'
+  export default {
+    name: 'Product',
+    components: { TableTool, PartnerEdit },
+    data() {
+      return {
+        list: [],
+        listLoading: true,
+        layout: 'total, sizes, prev, pager, next, jumper',
+        total: 0,
+        queryForm: {
+          pageNum: 1,
+          pageSize: 10,
+          name: '',
+          partnerId: null,
+        },
+        showColumns: [],
+        columns: [
+          {
+            label: '负责区域',
+            width: 'auto',
+            prop: 'territory',
+            sortable: false,
+            disableCheck: true,
+          },
+          {
+            label: '联系人',
+            prop: 'name',
+            width: '160px',
+            sortable: false,
+            disableCheck: true,
+          },
+          {
+            label: '联系方式',
+            width: '160px',
+            prop: 'contactWay',
+            sortable: false,
+          },
+
+          {
+            label: '岗位',
+            width: '160px',
+            prop: 'post',
+            sortable: false,
+          },
+          {
+            label: '备注',
+            width: 'auto',
+            prop: 'remark',
+            sortable: false,
+          },
+        ],
+        defaultProps: {
+          key: 'id',
+          label: 'partnerName',
+        },
+        fileList: [],
+        fileSettings: {
+          // 文件配置信息
+          fileSize: 52428800,
+          fileTypes: '.doc,.docx,.zip,.xls,.xlsx,.rar,.jpg,.jpeg,.gif,.png,.jfif,.txt',
+          pictureSize: 52428800,
+          pictureTypes: '.jpg,.jpeg,.gif,.png,.jfif,.txt',
+          types: '.doc,.docx,.zip,.xls,.xlsx,.rar,.jpg,.jpeg,.gif,.png,.jfif,.mp4,.txt',
+          videoSize: 104857600,
+          videoType: '.mp4',
+        },
+        companyList: [], //产品分类
+      }
+    },
+    watch: {
+      showColumns: function () {
+        this.$nextTick(() => this.$refs.table.doLayout())
+      },
+    },
+    created() {
+      this.getCompanyList()
+    },
+    methods: {
+      async treeHandle(command, node) {
+        console.log(command, node, '111111111')
+        if (command == 'edit') {
+          this.addCompany(node)
+        } else if (command == 'del') {
+          this.$confirm(`确认删除销售区域 ${node.label}?`, '提示', {
+            confirmButtonText: '确定',
+            cancelButtonText: '取消',
+            type: 'warning',
+          })
+            .then(async () => {
+              const [err, res] = await to(partnerApi.deleteCompany({ id: [node.data.id] }))
+              if (err) return
+              if (res.code == 200) {
+                this.$baseMessage(res.msg, 'success', 'vab-hey-message-success')
+                this.getCompanyList()
+              }
+            })
+            .catch(() => {
+              this.$message({
+                type: 'info',
+                message: '已取消删除',
+              })
+            })
+        }
+      },
+      async getCompanyList() {
+        const [err, res] = await to(partnerApi.getCompanyList({}))
+        if (err) return
+        if (res.code == 200 && res.data.list.length > 0) {
+          this.companyList = res.data.list || []
+          //默认第一选中
+          this.$nextTick(() => {
+            this.$refs.tree.setCurrentKey(res.data.list[0].id)
+            this.queryForm.partnerId = res.data.list[0].id
+            this.fetchData()
+          })
+        }
+      },
+      async fetchData() {
+        this.listLoading = true
+        const {
+          data: { list, total },
+        } = await partnerApi.getCompanyConcatList(this.queryForm)
+        this.list = list
+        this.total = total
+        this.listLoading = false
+      },
+
+      addCompany(node) {
+        console.log(node)
+        let defVal = ''
+        if (node) {
+          defVal = node.label
+        }
+        this.$prompt('请输入公司名称', '提示', {
+          inputValue: defVal, // 设置默认值
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          inputPattern: /\S+/,
+          inputErrorMessage: '公司名称不能为空',
+        })
+          .then(async ({ value }) => {
+            if (node) {
+              const params = {
+                id: node.data.id,
+                partnerName: value,
+              }
+              const [err, res] = await to(partnerApi.updateCompany(params))
+              if (err) return
+              if (res.code == 200) {
+                this.$baseMessage(res.msg, 'success', 'vab-hey-message-success')
+                this.getCompanyList()
+              }
+            } else {
+              const [err, res] = await to(partnerApi.addCompany({ partnerName: value }))
+              if (err) return
+              if (res.code == 200) {
+                this.$baseMessage(res.msg, 'success', 'vab-hey-message-success')
+                this.getCompanyList()
+              }
+            }
+            // 当用户点击确定按钮时,执行的逻辑
+          })
+          .catch(() => {
+            // 当用户点击取消按钮时,执行的逻辑
+            console.log('取消输入')
+          })
+      },
+      // 节点单击事件
+      handleNodeClick(data) {
+        console.log(data)
+        this.queryForm.partnerId = data.id
+        this.fetchData()
+      },
+      reset() {
+        this.queryForm = {
+          pageNum: 1,
+          pageSize: 10,
+          partnerId: null,
+          name: '',
+        }
+        this.fetchData()
+      },
+
+      //详情
+      handleDetail(row) {
+        this.$router.push({
+          name: 'PartnersDetail',
+          query: {
+            id: row.id,
+          },
+        })
+      },
+
+      handleDelete(row) {
+        this.$baseConfirm('你确定要删除当前项吗', null, async () => {
+          const { msg } = await partnerApi.deleteCompanyConcat({ id: [row.id] })
+          this.$baseMessage(msg, 'success', 'vab-hey-message-success')
+          await this.fetchData()
+        })
+      },
+      handleSizeChange(val) {
+        this.queryForm.pageSize = val
+        this.fetchData()
+      },
+      handleCurrentChange(val) {
+        this.queryForm.pageNum = val
+        this.fetchData()
+      },
+      queryData() {
+        this.queryForm.pageNum = 1
+        this.fetchData()
+      },
+      downloadTemplate() {
+        partnerApi
+          .downloadFile({})
+          .then((res) => {
+            if (res.code == 200) {
+              downloadFileByByte(res.data, '合作伙伴导入模板.xlsx')
+            }
+          })
+          .catch((err) => {
+            console.error(err)
+          })
+      },
+
+      // 上传图片
+      beforeAvatarUpload(file) {
+        let flag1 = file.size < this.fileSettings.fileSize
+        if (!flag1) {
+          this.$message.warning('文件过大,请重新选择!')
+          return false
+        }
+        let flag2 = this.fileSettings.fileTypes.split(',').includes('.' + file.name.split('.').pop())
+        if (!flag2) {
+          this.$message.warning('文件类型不符合,请重新选择!')
+          return false
+        }
+        return true
+      },
+      // 上传
+      uploadrequest(option) {
+        let _this = this
+        let url = process.env.VUE_APP_UPLOAD_WEED
+        axios
+          .post(url)
+          .then((res) => {
+            if (res.data && res.data.fid && res.data.fid !== '') {
+              option.action = `${process.env.VUE_APP_PROTOCOL}${res.data.publicUrl}/${res.data.fid}`
+              // let file_name = option.file.name
+              // let index = file_name.lastIndexOf('.')
+              // let file_extend = ''
+              // if (index > 0) {
+              //   // 截取名称中的扩展名
+              //   file_extend = file_name.substr(index + 1)
+              // }
+              // let uploadform = {
+              //   fileName: file_name, // 资料名称
+              //
+              //   size: option.file.size.toString(), // 资料大小
+              //   fileType: file_extend, // 资料文件类型
+              // }
+              let fileUrl = `${process.env.VUE_APP_PROTOCOL}${res.data.publicUrl}/${res.data.fid}` // 资料存储url
+              asyncUploadFile(option).then(async () => {
+                const params = {
+                  excelUrl: fileUrl,
+                  partnerId: this.queryForm.partnerId,
+                }
+                const [err, res] = await to(partnerApi.exportFile(params))
+                if (err) return
+                if (res.code == 200) {
+                  _this.$message({
+                    type: 'success',
+                    message: '上传成功',
+                  })
+                  this.fetchData()
+                }
+              })
+            } else {
+              _this.$message({
+                type: 'warning',
+                message: '未上传成功!请刷新界面重新上传!',
+              })
+            }
+          })
+          .catch(function () {
+            _this.$message({
+              type: 'warning',
+              message: '未上传成功!请重新上传!',
+            })
+          })
+      },
+    },
+  }
+</script>
+<style>
+  .el-form-item--small {
+    margin: 0 0 10px 0 !important;
+  }
+</style>

+ 18 - 6
src/views/proj/business/components/FollowAdd.vue

@@ -110,6 +110,8 @@
       :query-params="queryContact"
       :title="distrTitle"
       @save="selectContact" />
+
+    <select-user ref="selectUser" :query-params="queryContact" @save="selectContact" />
   </el-dialog>
 </template>
 
@@ -119,6 +121,7 @@
   import followApi from '@/api/customer/follow'
   import SelectContact from '@/components/select/SelectCustomerContact'
   import SelectDistributor from '@/components/select/SelectDistributorContact'
+  import SelectUser from '@/components/select/SelectUser'
   import asyncUploadFile from '@/utils/uploadajax'
 
   export default {
@@ -126,6 +129,7 @@
     components: {
       SelectContact,
       SelectDistributor,
+      SelectUser,
     },
     data() {
       return {
@@ -142,8 +146,8 @@
           targetId: '',
           targetName: '',
           targetType: '',
-          custId: 0,
-          custName: '',
+          custId: null,
+          custName: null,
           contactsId: '',
           contactsName: '',
           reminders: '',
@@ -189,9 +193,7 @@
       }
     },
     watch: {},
-    created() {
-      this.getOptions()
-    },
+    created() {},
     methods: {
       getOptions() {
         Promise.all([this.getDicts('plat_follow_type'), this.getDicts('plat_follow_content_type')]).then(
@@ -205,6 +207,9 @@
         console.log(this.form.targetType)
         if (this.form.targetType == '50') {
           this.$refs.selectDistributor.open()
+        }
+        if (this.form.targetType == '70') {
+          this.$refs.selectUser.open()
         } else {
           if (!this.queryContact.custId) {
             this.$message.warning('请先选择客户')
@@ -217,6 +222,8 @@
         if (val && val.length > 0) {
           if (this.form.targetType == '50') {
             this.form.contactsName = val.map((item) => item.name).join()
+          } else if (this.form.targetType == '70') {
+            this.form.contactsName = val.map((item) => item.nickName).join()
           } else {
             this.form.contactsName = val.map((item) => item.cuctName).join()
           }
@@ -225,6 +232,7 @@
         console.log(this.form)
       },
       showEdit(row, title = null) {
+        this.getOptions()
         this.title = '添加跟进记录'
         this.form = Object.assign(this.form, row)
         console.log(this.form)
@@ -236,6 +244,10 @@
           }
         } else if (this.form.targetType == '50') {
           this.queryContact.distId = this.form.targetId
+        } else if (this.form.targetType == '70') {
+          this.queryContact.distId = this.form.targetId
+          this.form.custId = null
+          this.form.custName = null
         }
         this.distrTitle = title
         this.dialogFormVisible = true
@@ -252,12 +264,12 @@
           if (valid) {
             this.loading = true
             const [err, res] = await to(followApi.addFollowUp(this.form))
+            this.loading = false
             if (err) {
               this.$baseMessage(res.msg, 'error')
             } else {
               this.$baseMessage(res.msg, 'success')
             }
-            this.loading = false
             this.$emit('fetch-data')
             this.close()
           } else {