瀏覽代碼

营销商机功能优化;商机阶段分析增加路由调整页面时缓存;

001295 1 年之前
父節點
當前提交
3d7732a7e8

+ 565 - 0
src/views/business/spd/bo/basic/bobehaviorList.vue

@@ -0,0 +1,565 @@
+<template>
+  <div class="app-container">
+    <div class="btn_grooup" v-if="bo.winningState == 0 && '0-1'.includes(boAuthority.post)">
+      <el-button
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+        >新增</el-button>
+    </div>
+    <el-table size="mini" v-loading="loading" :data="behaviorList">
+      <el-table-column label="序号" align="center" type="index" width="50" fixed/>
+      <el-table-column label="负责人" align="center" prop="staffName" />
+      <el-table-column label="行动日期" align="center" prop="time" />
+      <el-form-item label="行动日期" prop="time">
+        <el-date-picker clearable
+          v-model="form.time"
+          type="date"
+          value-format="yyyy-MM-dd"
+          placeholder="请选择行动日期">
+        </el-date-picker>
+      </el-form-item>
+      <el-table-column label="联系人" align="center" prop="linkmanName" />
+      <el-table-column label="拜访效果" align="center" prop="result" >
+        <template slot-scope="scope">
+          <dict-tag :options="dict.type.mk_bo_behavior_res" :value="scope.row.result"/>
+        </template>
+      </el-table-column>
+      <el-table-column label="是否上级协助" align="center" prop="assist" >
+        <template slot-scope="scope">
+          <dict-tag :options="dict.type.sys_yes_no" :value="scope.row.assist"/>
+        </template>
+      </el-table-column>
+      <el-table-column show-overflow-tooltip label="协助内容" align="center" prop="assistContent" />
+      <el-table-column show-overflow-tooltip label="洽谈内容" align="center" prop="content" />
+      <el-table-column label="行动类型" align="center" prop="type">
+        <template slot-scope="scope">
+          <dict-tag :options="dict.type.mk_bo_behavior_type" :value="scope.row.type"/>
+        </template>
+      </el-table-column>
+      <el-table-column label="拜访目的" align="center" prop="purpose">
+        <template slot-scope="scope">
+            <dict-tag :options="dict.type.mk_bo_behavior_goal" :value="scope.row.purpose"/>
+        </template>
+      </el-table-column>
+      <el-table-column show-overflow-tooltip label="销售组织" align="center" prop="salesOrgName"/>
+      <el-table-column show-overflow-tooltip label="部门" align="center" prop="deptName"/>
+      <el-table-column label="操作" fixed="right" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-view"
+            @click="handleBrowse(scope.row)"
+          >查看</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改行动对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="1000px" append-to-body>
+      <el-form size="mini" ref="form" :model="form" :rules="rules" label-width="80px" :disabled="this.operatingState == 'Browse'">
+        <el-divider content-position="left">
+          <dev style="width: 50px; height: 40px; font-size: 18px">基本信息</dev>
+        </el-divider>
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="商机名称" prop="type">
+              <el-input v-model="form.boName" readonly/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="行动类型" prop="type">
+              <el-input :value="dict.label" v-for="dict in dict.type.mk_bo_behavior_type" v-if="dict.value == form.type" readonly/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="行动日期" prop="time">
+              <el-date-picker clearable
+                v-model="form.time"
+                type="date"
+                value-format="yyyy-MM-dd"
+                placeholder="">
+              </el-date-picker>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="客户" prop="customerName">
+              <el-input v-model="form.customerName" readonly/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="联系人" prop="linkmanName">
+              <dr-popover-select v-model="form.linkmanName" title="联系人" type="LINKMAN_PARAM" :dataMapping="{
+                  linkman: 'id',
+                  linkmanName: 'name',
+                }" :source.sync="form"
+                :queryParams="additionalCondition"
+              >
+              </dr-popover-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="拜访目的" prop="purpose">
+              <el-select v-model="form.purpose" placeholder="">
+                <el-option
+                  v-for="dict in dict.type.mk_bo_behavior_goal"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col  :span="8">
+            <el-form-item label="拜访效果" prop="result">
+              <el-select v-model="form.result" placeholder="">
+                <el-option
+                  v-for="dict in dict.type.mk_bo_behavior_res"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col  :span="8">
+            <el-form-item label="是否上级协助" prop="assist">
+              <el-select v-model="form.assist" placeholder="">
+                <el-option
+                  v-for="dict in dict.type.sys_yes_no"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col  :span="8">
+            <el-form-item label="协助内容" prop="assistContent" v-show="form.assist == 'Y'" :rules="form.assist == 'Y' ? rules.assistContent : [{require: false}]">
+              <el-input v-model="form.assistContent" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="销售区域" prop="marketingAreaName">
+              <dr-popover-select v-model="form.marketingAreaName" title="销售区域" type="MK_SALESAREA_PARAM" :dataMapping="{
+                  marketingArea: 'id',
+                  marketingAreaName: 'name',
+                }" :source.sync="form"
+              >
+              </dr-popover-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col  :span="8">
+            <el-form-item label="销售组织" prop="salesOrgName">
+              <el-input v-model="form.salesOrgName" readonly/>
+            </el-form-item>
+          </el-col>
+          <el-col  :span="8">
+             <el-form-item label="部门" prop="deptName">
+              <el-input v-model="form.deptName" readonly/>
+            </el-form-item>
+          </el-col>
+          <el-col  :span="8">
+            <el-form-item label="负责人" prop="staffName">
+              <el-input v-model="form.staffName" readonly/>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-divider content-position="left">
+          <dev style="width: 50px; height: 40px; font-size: 18px">跟进内容</dev>
+        </el-divider>
+        <el-form-item label="内容" prop="content" >
+          <el-input
+            type="textarea"
+            :rows="2"
+            maxlength=900
+            placeholder="填写提示:今天拜访了谁,收集了什么述求,达成了什么结果,下一步计划。"
+            autosize
+            v-model="form.content">
+          </el-input>
+        </el-form-item>
+        <el-divider content-position="left">
+          <dev style="width: 50px; height: 40px; font-size: 18px">照片信息</dev>
+        </el-divider>
+
+        <el-upload
+          action="actionUrl"
+          list-type="picture-card"
+          :on-change="uploadPic"
+          :on-preview="handlePictureCardPreview"
+          :on-remove="handleRemove"
+          :auto-upload="false"
+          :file-list="fileList"
+          >
+          <i class="el-icon-plus"></i>
+        </el-upload>
+        <el-dialog :visible.sync="dialogVisible">
+          <img width="100%" :src="dialogImageUrl" alt="">
+        </el-dialog>
+
+        <div class="md-auditInfo">
+          <el-divider content-position="left">
+            <dev style="width: 50px; height: 40px; font-size: 18px">其它信息</dev>
+          </el-divider>
+          <el-row>
+            <el-col :span="6">
+              <el-form-item label="创建人">
+                <el-input v-model="form.createByName" readonly></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="6">
+              <el-form-item label="创建时间">
+                <el-input v-model="form.createTime" readonly></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="6">
+              <el-form-item label="修改人">
+                <el-input v-model="form.updateByName" readonly></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="6">
+              <el-form-item label="修改时间">
+                <el-input v-model="form.updateTime" readonly></el-input>
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </div>
+      </el-form>
+      <div slot="footer">
+        <el-button size="mini" type="primary" @click="submitForm" v-if="this.operatingState != 'Browse'" :disabled="submitButtonEditStatus">确 定</el-button>
+        <el-button size="mini" @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { listBehavior, getBehavior, addBehavior, updateBehavior } from "@/api/business/spd/bo/behavior";
+import ContactRef from '@/views/business/spd/bo/refer/contact/index.vue';
+import SaleaeaRef from '@/views/business/spd/bo/refer/saleaea/index.vue';
+
+export default {
+  name: "bobehaviorList",
+  props:["bo","boAuthority"],
+  dicts: ['mk_bo_behavior_res','mk_bo_behavior_type','sys_yes_no','mk_bo_behavior_goal'],
+  components: {ContactRef,SaleaeaRef},
+  data() {
+    return {
+      dialogImageUrl: '',
+      dialogVisible: false,
+      disabled: false,
+      actionUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址,
+      fileList: [],
+      // 遮罩层
+      loading: true,
+      // 总条数
+      total: 0,
+      // 行动表格数据
+      behaviorList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        bo: null,
+        boStage: null,
+        boName: null,
+        task: null,
+        taskCode: null,
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        type: [
+          { required: true, message: "行动类型不能为空", trigger: "blur" }
+        ],
+        time: [
+          { required: true, message: "行动日期不能为空", trigger: "blur" }
+        ],
+        customerName: [
+          { required: true, message: "客户不能为空", trigger: "blur" }
+        ],
+        linkmanName: [
+          { required: true, message: "联系人不能为空", trigger: "blur" }
+        ],
+        purpose: [
+          { required: true, message: "拜访目的不能为空", trigger: "blur" }
+        ],
+        assist: [
+          { required: true, message: "是否需要上级协助不能为空", trigger: "blur" }
+        ],
+        assistContent: [
+          { required: true, message: "协助内容不能为空", trigger: "blur" }
+        ],
+        staffName: [
+          { required: true, message: "负责人不能为空", trigger: "blur" }
+        ],
+        content: [
+          { required: true, message: "洽谈内容不能为空", trigger: "blur" }
+        ],
+        result: [
+          { required: true, message: "拜访效果不能为空", trigger: "blur" }
+        ],
+      },
+      //当前操作状态
+      operatingState: '',
+      //确定按钮是否可点
+      submitButtonEditStatus:false,
+    };
+  },
+  created() {
+    //组件创建时初始化查询参数
+    this.queryParams.bo = this.bo.id;
+    let params = {"post":this.boAuthority.post};
+    this.queryParams.params = params;
+    //查询
+    this.getList();
+  },
+  methods: {
+    uploadPic(file, fileList) {
+      this.fileList = fileList
+    },
+    handleRemove(file) {
+      this.fileList = this.fileList.filter(item => item.uid !== file.uid)
+    },
+    handlePictureCardPreview(file) {
+      this.dialogImageUrl = file.url;
+      this.dialogVisible = true;
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        console.log(this.form.photos.split(','));
+      });
+    },
+    /** 查询行动列表 */
+    getList() {
+      this.loading = true;
+      listBehavior(this.queryParams).then(response => {
+        this.behaviorList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        bo: null,
+        boName: null,
+        task: null,
+        taskCode: null,
+        type: null,
+        time: null,
+        customer: null,
+        customerName: null,
+        linkman: null,
+        linkmanName: null,
+        purpose: null,
+        result: null,
+        assist: null,
+        assistContent: null,
+        marketingArea: null,
+        marketingAreaName: null,
+        salesOrg: null,
+        salesOrgName: null,
+        dept: null,
+        deptName: null,
+        staff: null,
+        staffName: null,
+        content: null,
+        tenantId: null,
+        revision: null,
+        createBy: null,
+        createTime: null,
+        updateBy: null,
+        updateTime: null,
+        delFlag: null
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length!==1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.fileList = [];
+      this.reset();
+      this.operatingState = "Insert";
+      this.form.bo = this.bo.id;
+      this.form.boName = this.bo.boName;
+      this.form.boStage = this.bo.boStage;
+      this.form.customer = this.bo.customer;
+      this.form.customerName = this.bo.customerName;
+      this.form.type = '0';
+      this.form.staff = this.$store.state.user.id;
+      this.form.staffName = this.$store.state.user.nickName;
+      this.form.dept = this.$store.state.user.deptId;
+      this.form.deptName = this.$store.state.user.deptName;
+      this.form.salesOrg = this.$store.state.user.orgId;
+      this.form.salesOrgName = this.$store.state.user.orgName;
+      this.form.time = new Date();
+      this.open = true;
+      this.title = "商机跟进";
+    },
+    /** 查看按钮操作 */
+    handleBrowse(row) {
+      this.reset();
+      const id = row.id || this.ids
+      getBehavior(id).then(response => {
+        this.form = response.data;
+        this.fileList = this.form.behaviorPs;
+        this.open = true;
+        this.operatingState = "Browse";
+        this.title = "行动内容";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.submitButtonEditStatus = true;
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          let formData = new FormData();
+          formData.append("behavior", new Blob([JSON.stringify(this.form)], {type: "application/json"}));
+          if(this.fileList.length < 1){
+            formData.append('files', null);
+          }else{
+            this.fileList.forEach(el => {
+              formData.append('files', el.raw);
+            })
+          }
+          if (this.form.id != null) {
+            updateBehavior(formData).then(response => {
+              this.$modal.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+              this.submitButtonEditStatus = false;
+            });
+          } else {
+            addBehavior(formData).then(response => {
+              this.$modal.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+              this.submitButtonEditStatus = false;
+            });
+          }
+        }else{
+          this.submitButtonEditStatus = false;
+        }
+      });
+    },
+    additionalCondition(){
+      return {
+        parame:{
+          customer: this.form.customer ? this.form.customer : 'xxx'
+        }
+      }
+    },
+  }
+};
+</script>
+
+
+
+<style scoped>
+.md-content >>> .el-form-item {
+  margin-bottom: 10px;
+}
+
+.md-content >>> .el-tabs--border-card > .el-tabs__content {
+  padding-bottom: 8px;
+}
+
+.md-content .md-auditInfo >>> .el-form-item {
+  margin-bottom: 0px;
+}
+
+.md-main >>> .el-form-item,
+.md-vice >>> .el-form-item {
+  width: 100%;
+  box-sizing: border-box;
+}
+
+.md-main >>> .el-form-item__label,
+.md-vice >>> .el-form-item__label {
+  width: 40%;
+}
+
+.md-main >>> .el-form-item__content,
+.md-md-vice >>> .el-form-item__content {
+  width: 60%;
+}
+
+.md-content >>> .el-form-item__label {
+  font-weight: normal;
+  /* text-align: left;
+  width: 28%; */
+  white-space: nowrap;
+  /* IE6 需要定义宽度 */
+  overflow: hidden;
+
+  -o-text-overflow: ellipsis;
+  /* Opera */
+  text-overflow: ellipsis;
+  /* IE, Safari (WebKit) */
+  /* -moz-binding: url('ellipsis.xml#ellipsis'); */
+  /* Firefox */
+}
+
+.md-main >>> .material-table {
+  height: 100%;
+}
+
+.md-vice >>> .material-table {
+  height: 140px;
+  overflow-y: auto;
+  overflow-x: auto;
+}
+
+.btn_grooup {
+  margin-bottom: 10px;
+  display: flex;
+  justify-content: flex-end;
+}
+</style>

+ 591 - 0
src/views/business/spd/bo/basic/bocontactList.vue

@@ -0,0 +1,591 @@
+<template>
+  <div class="app-container">
+    <div class="btn_grooup" v-if="bo.winningState == 0 && '0-1'.includes(boAuthority.post)">
+      <el-button
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+        >新增</el-button>
+    </div>
+    <el-table size="mini" v-loading="loading" :data="contactList">
+      <el-table-column label="序号" align="center" type="index" width="50" fixed/>
+      <el-table-column label="编号" align="center" prop="code" width="250"/>
+      <el-table-column label="姓名" align="center" prop="name" />
+      <el-table-column label="性别" align="center" prop="gander" >
+        <template slot-scope="scope">
+          <dict-tag :options="dict.type.sys_user_sex" :value="scope.row.gander"/>
+        </template>
+      </el-table-column>
+      <el-table-column label="联系电话" align="center" prop="telephone" show-overflow-tooltip/>
+      <el-table-column label="所属客户" align="center" prop="customerName" show-overflow-tooltip/>
+      <el-table-column label="职务" align="center" prop="position" >
+        <template slot-scope="scope">
+          <dict-tag :options="dict.type.mk_bo_position" :value="scope.row.position"/>
+        </template>
+      </el-table-column>
+      <el-table-column label="决策力" align="center" prop="power" >
+        <template slot-scope="scope">
+          <dict-tag :options="dict.type.mk_bo_power" :value="scope.row.power"/>
+        </template>
+      </el-table-column>
+      <el-table-column width="200" show-overflow-tooltip label="兴趣爱好" align="center" prop="hobby" />
+      <el-table-column width="200" show-overflow-tooltip label="家庭地址" align="center" prop="address" />
+      <el-table-column label="状态" align="center" prop="state" >
+        <template slot-scope="scope">
+          <dict-tag :options="dict.type.mk_bo_contact_state" :value="scope.row.state"/>
+        </template>
+      </el-table-column>
+      <el-table-column width="200" label="操作" fixed="right" align="center" class-name="small-padding fixed-width" >
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-if="'0-1'.includes(boAuthority.post) && scope.row.createBy == $store.state.user.name"
+          >修改</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-view"
+            @click="handleBrowse(scope.row)"
+          >查看</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-if="'0-1'.includes(boAuthority.post) && scope.row.createBy == $store.state.user.name"
+          >删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改联系人管理对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="1100px" append-to-body>
+      <el-form size="mini" ref="form" :model="form" :rules="rules" label-width="80px" :disabled="this.operatingState == 'Browse'">
+        <el-divider content-position="left">
+          <dev style="width: 50px; height: 40px; font-size: 18px">基本信息</dev>
+        </el-divider>
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="编码" prop="code">
+              <el-input v-model="form.code" placeholder="系统自动生成编码" readonly/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="姓名" prop="name">
+              <el-input v-model="form.name" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="性别" prop="gander">
+              <el-select v-model="form.gander" placeholder="">
+                <el-option
+                  v-for="dict in dict.type.sys_user_sex"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="所属客户" prop="customerName">
+              <el-input v-model="form.customerName" readonly/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="联系人分类" prop="contactClassification">
+              <el-select v-model="form.contactClassification" placeholder="">
+                <el-option
+                  v-for="dict in dict.type.mk_bo_contact_type"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="生日" prop="birthday">
+              <el-date-picker clearable
+                v-model="form.birthday"
+                type="date"
+                value-format="yyyy-MM-dd"
+              >
+              </el-date-picker>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="籍贯" prop="birthplace">
+              <el-input v-model="form.birthplace" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="兴趣爱好" prop="hobby">
+              <el-input v-model="form.hobby" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="状态" prop="state">
+              <el-select v-model="form.state" placeholder="">
+                <el-option
+                  v-for="dict in dict.type.mk_bo_contact_state"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-divider content-position="left">
+          <dev style="width: 50px; height: 40px; font-size: 18px">工作信息</dev>
+        </el-divider>
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="上级联系人" prop="superiorContactName">
+              <dr-popover-select v-model="form.superiorContactName" title="上级联系人" type="LINKMAN_PARAM" :dataMapping="{
+                  superiorContact: 'id',
+                  superiorContactName: 'name',
+                }" :source.sync="form"
+                :queryParams="additionalCondition"
+              >
+              </dr-popover-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="任职科室" prop="section">
+              <el-popover-select-v2 v-model="form.sectionName" title="科室" valueKey="name" referName="MkCustomersDepartmentRule"
+                :dataMapping="{ section: 'id', sectionName: 'name'}" :source.sync="form" :queryParams="additionalCondition" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="职务" prop="position">
+              <el-select v-model="form.position" placeholder="">
+                <el-option
+                  v-for="dict in dict.type.mk_bo_position"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="职称" prop="jobTitle">
+              <el-select v-model="form.jobTitle" placeholder="">
+                <el-option
+                  v-for="dict in dict.type.mk_bo_job_title"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="决策力" prop="power">
+              <el-select v-model="form.power" placeholder="">
+                <el-option
+                  v-for="dict in dict.type.mk_bo_power"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="支持度" prop="support">
+              <el-select v-model="form.support" placeholder="">
+                <el-option
+                  v-for="dict in dict.type.mk_bo_support"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="擅长领域" prop="fieldExpertise">
+              <el-select v-model="form.fieldExpertise" placeholder="">
+                <el-option
+                  v-for="dict in dict.type.mk_bo_field_expertise"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="关键决策人" prop="decisionMaker">
+              <el-select v-model="form.decisionMaker" placeholder="">
+                <el-option
+                  v-for="dict in dict.type.sys_yes_no"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+          </el-col>
+        </el-row>
+        <el-divider content-position="left">
+          <dev style="width: 50px; height: 40px; font-size: 18px">联系信息</dev>
+        </el-divider>
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="联系电话" prop="telephone">
+              <el-input v-model="form.telephone" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="微信" prop="mail">
+              <el-input v-model="form.mail" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="家庭地址" prop="address">
+              <el-input v-model="form.address" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="最佳拜访时间" prop="visitTime">
+              <el-input v-model="form.visitTime" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="最佳拜访地点" prop="visitPlace">
+              <el-input v-model="form.visitPlace" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+          </el-col>
+        </el-row>
+        <el-tabs v-model="activeName" v-if="this.operatingState != 'Insert'">
+          <el-tab-pane label="学历信息" name="first">
+            <EducationList  :key="timer" :supForm="this.form" />
+          </el-tab-pane>
+          <el-tab-pane label="社会关系" name="second">
+            <RelationshipList :key="timer" :supForm="this.form" />
+          </el-tab-pane>
+        </el-tabs>
+        <div class="md-auditInfo">
+          <el-divider content-position="left">
+            <dev style="width: 50px; height: 40px; font-size: 18px">其它信息</dev>
+          </el-divider>
+          <el-row>
+            <el-col :span="6">
+              <el-form-item label="创建人">
+                <el-input v-model="form.createByName" readonly></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="6">
+              <el-form-item label="创建时间">
+                <el-input v-model="form.createTime" readonly></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="6">
+              <el-form-item label="修改人">
+                <el-input v-model="form.updateByName" readonly></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="6">
+              <el-form-item label="修改时间">
+                <el-input v-model="form.updateTime" readonly></el-input>
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </div>
+      </el-form>
+      <div slot="footer">
+        <el-button size="mini" type="primary" @click="submitForm" v-if="this.operatingState != 'Browse'" :disabled="submitButtonEditStatus">确 定</el-button>
+        <el-button size="mini" @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {getContact, delContact, addContact, updateContact } from "@/api/business/spd/bo/contact";
+import {listContact} from "@/api/business/spd/bo/basic";
+import EducationList from '../education/educationList.vue';
+import RelationshipList from '../relationship/relationshipList.vue';
+
+export default {
+  name: "contactList",
+  props:["source","bo","boAuthority"],
+  dicts: ['sys_user_sex','mk_bo_contact_state','mk_bo_section','mk_bo_position','mk_bo_job_title','mk_bo_power','mk_bo_support','mk_bo_field_expertise','sys_yes_no','mk_bo_contact_type'],
+  components: {
+    EducationList,
+    RelationshipList,
+    ElPopoverSelectV2: () =>import("@/components/popover-select-v2")
+  },
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 联系人管理表格数据
+      contactList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        boId: null,
+        name: null,
+        code: null,
+        customer: null,
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        name: [
+          { required: true, message: "姓名不能为空", trigger: "blur" }
+        ],
+        gander: [
+          { required: true, message: "性别不能为空", trigger: "blur" }
+        ],
+        customerName: [
+          { required: true, message: "所属客户名称不能为空", trigger: "blur" }
+        ],
+        state: [
+          { required: true, message: "状态不能为空", trigger: "blur" }
+        ],
+        section: [
+          { required: true, message: "任职科室不能为空", trigger: "blur" }
+        ],
+        position: [
+          { required: true, message: "职务不能为空", trigger: "blur" }
+        ],
+        jobTitle: [
+          { required: true, message: "职称不能为空", trigger: "blur" }
+        ],
+        power: [
+          { required: true, message: "决策力不能为空", trigger: "blur" }
+        ],
+        decisionMaker: [
+          { required: true, message: "关键决策人不能为空", trigger: "blur" }
+        ],
+        telephone: [
+          { required: true, message: "联系电话不能为空", trigger: "blur" },
+          {
+            validator: function(rule, value, callback) {
+              if (/^1[34578]\d{9}$/.test(value) == false) {
+                callback(new Error("手机号格式错误"));
+              } else {
+                callback();
+              }
+            },
+            trigger: "blur"
+          }
+        ],
+      },
+      //重新加载子组件参数
+      timer: '',
+      //当前操作状态
+      operatingState: '',
+      //
+      activeName: 'first',
+      //确定按钮是否可点
+      submitButtonEditStatus:false,
+    };
+  },
+  created() {
+    this.queryParams.customer = this.bo.customer;
+    let params = {"post":this.boAuthority.post};
+    this.queryParams.params = params;
+    this.getList();
+  },
+  methods: {
+    /** 查询联系人管理列表 */
+    getList() {
+      this.loading = true;
+      listContact(this.queryParams).then(response => {
+        this.contactList = response.rows;
+        console.log('this.contactList',this.contactList);
+        for (var i = 0; i < this.contactList.length; i++) {
+          if( this.contactList[i].telephone){
+            this.contactList[i].telephone = this.contactList[i].telephone.substring(0,3) + '******' + this.contactList[i].telephone.substring(this.contactList[i].telephone.length - 4,this.contactList[i].telephone.length);
+          }
+          this.contactList[i].customerName = this.contactList[i].customerName.substring(0,2) + '******' + this.contactList[i].customerName.substring(this.contactList[i].customerName.length - 2,this.contactList[i].customerName.length);
+          const start = new Array(this.contactList[i].name.length).join('*');
+          this.contactList[i].name = start + this.contactList[i].name.slice(-1);
+        }
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        boId: null,
+        delFlag: null,
+        updateTime: null,
+        updateBy: null,
+        createDate: null,
+        createBy: null,
+        departmentName: null,
+        departmentCode: null,
+        area: null,
+        organization: null,
+        visitPlace: null,
+        visitTime: null,
+        address: null,
+        mail: null,
+        telephone: null,
+        decisionMaker: null,
+        fieldExpertise: null,
+        support: null,
+        power: null,
+        jobTitle: null,
+        position: null,
+        section: null,
+        superiorContact: null,
+        superiorContactName: null,
+        state: null,
+        hobby: null,
+        birthplace: null,
+        birthday: null,
+        contactClassification: null,
+        customerName: null,
+        customerCode: null,
+        gander: null,
+        name: null,
+        code: null,
+        id: null
+      };
+      this.resetForm("form");
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.operatingState = "Insert";
+      this.reset();
+      this.form.boId = this.bo.id;
+      this.form.customer = this.bo.customer;
+      this.form.customerName = this.bo.customerName;
+      this.form.state = '1';
+      this.open = true;
+      this.title = "添加联系人";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.operatingState = "Update";
+      this.reset();
+      const id = row.id || this.ids
+      getContact(id).then(response => {
+        this.form = response.data;
+        this.open = true;
+        this.title = "修改联系人";
+        this.timer = new Date().getTime();
+      });
+    },
+    /** 查看按钮操作 */
+    handleBrowse(row) {
+      this.reset();
+      const id = row.id || this.ids
+      getContact(id).then(response => {
+        this.form = response.data;
+        this.open = true;
+        this.operatingState = "Browse";
+        this.title = "基础信息";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.submitButtonEditStatus = true;
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.id != null) {
+            updateContact(this.form).then(response => {
+              this.$modal.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+              this.submitButtonEditStatus = false;
+            });
+          } else {
+            addContact(this.form).then(response => {
+              this.$modal.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+              this.submitButtonEditStatus = false;
+            });
+          }
+        }else{
+          this.submitButtonEditStatus = false;
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$modal.confirm('是否确认删除联系人管理编号为"' + ids + '"的数据项?').then(function() {
+        return delContact(ids);
+      }).then(() => {
+        this.getList();
+        this.$modal.msgSuccess("删除成功");
+      }).catch(() => {});
+    },
+    additionalCondition(){
+      return {
+        parame:{
+          customer: this.form.customer ? this.form.customer : 'xxx'
+        }
+      }
+    },
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+.btn_grooup {
+  margin-bottom: 10px;
+  display: flex;
+  justify-content: flex-end;
+}
+</style>

+ 302 - 0
src/views/business/spd/bo/basic/bopojpsnList.vue

@@ -0,0 +1,302 @@
+<template>
+  <div class="app-container">
+    <div class="btn_grooup">
+      <el-button
+        type="primary"
+        plain
+        icon="el-icon-plus"
+        size="mini"
+        @click="handleAdd"
+        v-if="bo.winningState == 0 && bo.principal == $store.state.user.name"
+        >新增</el-button>
+    </div>
+    <el-table size="mini" v-loading="loading" :data="pojpsnList" @selection-change="handleSelectionChange">
+      <el-table-column type="index" label="序号" width="55" align="center"/>
+      <el-table-column label="员工名称" align="center" prop="staffName" />
+      <el-table-column label="项目岗位" align="center" prop="post">
+        <template slot-scope="scope">
+          <dict-tag
+            :options="dict.type.mk_bo_pojpsn_post"
+            :value="scope.row.post"
+          />
+        </template>
+      </el-table-column>
+      <el-table-column label="职责" align="center" prop="jobs" width="400">
+        <template slot-scope="scope">
+          <el-select v-model="scope.row.jobs" multiple disabled size="medium">
+            <el-option
+              v-for="item in mk_bo_pojpsn_job"
+              :key="item.code"
+              :label="item.name"
+              :value="item.code"
+            >
+            </el-option>
+          </el-select>
+        </template>
+      </el-table-column>
+      <el-table-column
+        label="操作"
+        fixed="right"
+        align="center"
+        class-name="small-padding fixed-width"
+      >
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-if="bo.winningState == 0 && bo.principal == $store.state.user.name"
+            >修改</el-button
+          >
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-if="bo.winningState == 0 && bo.principal == $store.state.user.name"
+            >删除</el-button
+          >
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total > 0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改项目成员对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+        <el-popover-select-v2 
+          size="mini" 
+          v-model="form.staffName" 
+          title="员工" 
+          valueKey="name"
+          referName="CONTACTS_PARAM" 
+          :dataMapping="{staff:'id',staffName: 'name'}"
+          :source.sync="form"
+        >
+        </el-popover-select-v2>
+        <el-form-item label="项目岗位" prop="post">
+          <el-select v-model="form.post" placeholder="请选择项目岗位" disabled>
+            <el-option
+              v-for="dict in dict.type.mk_bo_pojpsn_post"
+              :key="dict.value"
+              :label="dict.label"
+              :value="dict.value"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="职责" prop="jobs">
+          <el-select v-model="form.jobs" multiple placeholder="请选择职责">
+            <el-option
+              v-for="item in mk_bo_pojpsn_job"
+              :key="item.code"
+              :label="item.name"
+              :value="item.code"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+      </el-form>
+      <div slot="footer">
+        <el-button type="primary" @click="submitForm" :disabled="submitButtonEditStatus">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {listPojpsn,getPojpsn,delPojpsn,addPojpsn,updatePojpsn,} from "@/api/business/spd/bo/pojpsn";
+import StaffRef from "@/views/business/spd/bo/refer/staff/index.vue";
+import { getBoJobListByType } from "@/api/business/spd/bo/boJob";
+
+export default {
+  name: "pojpsnList",
+  props: ["source", "bo","boAuthority"],
+  dicts: ["mk_bo_pojpsn_post",],
+  components: { StaffRef },
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 项目成员表格数据
+      pojpsnList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        bo: null,
+        boName: null,
+        staffName: null,
+        post: null,
+        job: null,
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        staffName: [
+          { required: true, message: "员工不能为空", trigger: "blur" },
+        ],
+        post: [{ required: true, message: "岗位不能为空", trigger: "blur" }],
+        jobs: [{ required: true, message: "职责不能为空", trigger: "blur" }],
+      },
+      //当前操作状态
+      operatingState: "",
+      //职责列表
+      mk_bo_pojpsn_job:[],
+      //确定按钮是否可点
+      submitButtonEditStatus:false,
+    };
+  },
+  created() {
+    this.queryParams.bo = this.bo.id;
+    getBoJobListByType(this.bo.boType).then((response) => {
+      this.mk_bo_pojpsn_job = response.rows;
+      this.getList();
+    });
+  },
+  methods: {
+    /** 查询项目成员列表 */
+    getList() {
+      this.loading = true;
+      listPojpsn(this.queryParams).then((response) => {
+        this.pojpsnList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+      this.jobs = [];
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        bo: null,
+        boName: null,
+        staff: null,
+        staffName: null,
+        post: null,
+        job: null,
+        tenantId: null,
+        revision: null,
+        createBy: null,
+        createTime: null,
+        updateBy: null,
+        updateTime: null,
+        delFlag: null,
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map((item) => item.id);
+      this.single = selection.length !== 1;
+      this.multiple = !selection.length;
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.operatingState = "Insert";
+      this.reset();
+      this.form.bo = this.bo.id;
+      this.form.boName = this.bo.boName;
+      this.form.post = "1";
+      this.open = true;
+      this.title = "添加项目成员";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.operatingState = "Update";
+      this.reset();
+      const id = row.id || this.ids;
+      getPojpsn(id).then((response) => {
+        this.form = response.data;
+        this.open = true;
+        this.title = "修改项目成员";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.submitButtonEditStatus = true;
+      this.$refs["form"].validate((valid) => {
+        if (valid) {
+          if (this.form.id != null) {
+            updatePojpsn(this.form).then((response) => {
+              this.$modal.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+              this.submitButtonEditStatus = false;
+            });
+          } else {
+            addPojpsn(this.form).then((response) => {
+              this.$modal.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+              this.submitButtonEditStatus = false;
+            });
+          }
+        }else{
+          this.submitButtonEditStatus = false;
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$modal
+        .confirm('是否确认删除项目成员编号为"' + ids + '"的数据项?')
+        .then(function () {
+          return delPojpsn(ids);
+        })
+        .then(() => {
+          this.getList();
+          this.$modal.msgSuccess("删除成功");
+        })
+        .catch(() => {});
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.btn_grooup {
+  margin-bottom: 10px;
+  display: flex;
+  justify-content: flex-end;
+}
+</style>