Browse Source

添加配置中心

qinzhipeng_v@didiglobal.com 4 năm trước cách đây
mục cha
commit
7d15e7abeb

+ 143 - 0
src/api/toConfigure.js

@@ -0,0 +1,143 @@
+// 项目详情页
+import request from '@/utils/request'
+import { TeamManagement } from '@/apiConfig/api'
+
+// 获取业务线list
+export function settingGetBizList(data) {
+  return request({
+    url: TeamManagement + `/setting/getBizList`,
+    method: 'post',
+    data
+  })
+}
+
+// 保存业务线配置
+export function settingUpdateBiz(data) {
+  return request({
+    url: TeamManagement + `/setting/updateBiz`,
+    method: 'post',
+    data
+  })
+}
+
+// 查询当前用户在当前业务线下的团队信息
+export function teamQueryTeamListByName(bizId) {
+  return request({
+    url: TeamManagement + `/team/queryTeamListByName?bizId=${bizId}`,
+    method: 'get'
+  })
+}
+
+// 新建团队
+export function teamCreateTeam(data) {
+  return request({
+    url: TeamManagement + `/team/createTeam`,
+    method: 'post',
+    data
+  })
+}
+
+// 编辑团队名称
+export function teamModifyTeam(data) {
+  return request({
+    url: TeamManagement + `/team/modifyTeam`,
+    method: 'post',
+    data
+  })
+}
+
+// 删除团队
+export function teamDeleteTeam(bizId) {
+  return request({
+    url: TeamManagement + `/team/deleteTeam?teamId=${bizId}`,
+    method: 'get'
+  })
+}
+
+// 获取团队信息
+export function teamQueryTeamInfo(data) {
+  return request({
+    url: TeamManagement + `/team/queryTeamInfo`,
+    method: 'post',
+    data
+  })
+}
+
+// 获取业务线下的所有成员
+export function settingGetMembersBelowBiz(data) {
+  return request({
+    url: TeamManagement + `/setting/getMembersBelowBiz`,
+    method: 'post',
+    data
+  })
+}
+
+// 获取业务线下未加入团队的成员
+export function settingGetMembersWithoutTeam(data) {
+  return request({
+    url: TeamManagement + `/setting/getMembersWithoutTeam`,
+    method: 'post',
+    data
+  })
+}
+
+// 编辑当前团队的成员
+export function teamUpdateTeamMember(data) {
+  return request({
+    url: TeamManagement + `/team/updateTeamMember`,
+    method: 'post',
+    data
+  })
+}
+
+// 删除当前团队的成员
+export function teamDeleteTeamMember(data) {
+  return request({
+    url: TeamManagement + `/team/deleteTeamMember?id=${data}`,
+    method: 'get'
+  })
+}
+
+// 删除业务线成员
+export function settingDeleteMemberBelowBiz(data) {
+  return request({
+    url: TeamManagement + `/setting/deleteMemberBelowBiz`,
+    method: 'post',
+    data
+  })
+}
+
+// 获取当前业务线下所有团队
+export function teamQueryTeamListBelowBiz(data) {
+  return request({
+    url: TeamManagement + `/team/queryTeamListBelowBiz?bizId=${data}`,
+    method: 'get'
+  })
+}
+
+// 编辑业务线下成员
+export function settingEditMember(data) {
+  return request({
+    url: TeamManagement + `/setting/editMember`,
+    method: 'post',
+    data
+  })
+}
+
+// 业务线下添加成员
+export function settingAddMembersToBiz(data) {
+  return request({
+    url: TeamManagement + `/setting/addMembersToBiz`,
+    method: 'post',
+    data
+  })
+}
+
+// 团队下添加成员
+export function teamAddMemberToGroup(data) {
+  return request({
+    url: TeamManagement + `/team/addMemberToGroup`,
+    method: 'post',
+    data
+  })
+}

+ 12 - 0
src/router/index.js

@@ -700,6 +700,18 @@ export const constantRoutes = [{
     component: (resolve) => require(['@/views/ToConfigure/configure'], resolve),
     meta: { title: '配置' }
   }]
+},
+{
+  path: '/Platform/setUp',
+  component: Layout,
+  name: '配置',
+  meta: { title: '配置', icon: '组织配置' },
+  children: [{
+    path: 'index',
+    name: '配置中心',
+    component: (resolve) => require(['@/views/ToConfigure/index'], resolve),
+    meta: { title: '配置中心' }
+  }]
 }
 ]
 

+ 164 - 0
src/views/ToConfigure/components/AddTeamMembers.vue

@@ -0,0 +1,164 @@
+<template>
+  <el-dialog title="添加团队成员" :visible.sync="dialogTeamVisible" class="public_task" width="50%" :close-on-click-modal="false" :destroy-on-close="true" @close="teamClose">
+    <div class="blueStripe" />
+    <div class="team_title"><span class="el-icon-warning" /> 每位用户在业务线的角色唯一</div>
+    <div style="padding: 0 20px;">
+      <el-select v-model="teamData" remote filterable reserve-keyword :remote-method="remoteMethod" size="medium" placeholder="请输入姓名或邮箱前缀" style="width: 100%;" :loading="loading">
+        <el-option v-for="item in options" :key="item.memberIDAP" :label="item.memberName" :value="item.memberIDAP" @click.native="teamChange(item)">
+          <div class="item-style">
+            <div class="item-detail">{{ item.memberName }}</div>
+            <div style="min-width:80px">{{ item.memberName }}</div>
+            <div class="item-detail">{{ item.memberIDAP }}</div>
+          </div>
+        </el-option>
+      </el-select>
+      <div class="team_cont">
+        <div v-for="item in teamMemberList" :key="item.memberIDAP" style="display: flex; justify-content: space-between; margin: 20px;">
+          <div style="display: flex; justify-content: flex-start; width: 200px;">
+            <el-avatar :src="item.phoneUrl" />
+            <span style="margin: 0 10px;">
+              <span class="team_name">{{ item.memberName }}</span><br>
+              <span class="team_name1">{{ item.memberIDAP }}</span>
+            </span>
+          </div>
+          <div class="team_code team_role" align="center">
+            <span v-if="item.roleName">{{ item.roleName }}</span>
+            <el-dropdown v-else placement="bottom" trigger="click">
+              <span class="el-dropdown-link">
+                {{ "设置角色" }}
+              </span>
+              <el-dropdown-menu slot="dropdown">
+                <el-dropdown-item @click.native="setRole(item, 3, 'PM')">PM</el-dropdown-item>
+                <el-dropdown-item @click.native="setRole(item, 3, 'RD')">RD</el-dropdown-item>
+                <el-dropdown-item @click.native="setRole(item, 4, 'QA')">QA</el-dropdown-item>
+              </el-dropdown-menu>
+            </el-dropdown>
+          </div>
+          <div class="el-icon-delete team_code" @click="team_dele(item)" />
+        </div>
+      </div>
+    </div>
+    <div slot="footer" class="dialog-footer">
+      <el-button @click="teamClose">取 消</el-button>
+      <el-button type="primary" @click="team_select">确 定</el-button>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+import { mapGetters } from 'vuex'
+import '@/styles/PublicStyle/index.scss'
+import { settingGetMembersBelowBiz, teamAddMemberToGroup } from '@/api/toConfigure'
+export default {
+  props: {
+    data: { type: Object, required: true }
+  },
+  data() {
+    return {
+      dialogTeamVisible: true,
+      teamMemberList: [],
+      options: [],
+      loading: false,
+      titleName: '',
+      teamData: null,
+      type: {},
+      form: {}
+    }
+  },
+  computed: {
+    ...mapGetters(['bizId'])
+  },
+  watch: {
+    data: {
+      handler(newV) {
+        if (newV) {
+          this.type = newV
+        }
+      },
+      deep: true,
+      immediate: true
+    }
+  },
+  methods: {
+    async teamChange(val) {
+      this.teamMemberList.push(val)
+      this.teamData = null
+      this.options = []
+    },
+    async remoteMethod(query) {
+      if (query !== '') {
+        this.loading = true
+        const res = await settingGetMembersBelowBiz({ bizId: this.bizId, people: query })
+        if (res.code === 200) {
+          this.loading = false
+          this.options = res.data
+        }
+      } else {
+        this.options = []
+      }
+    },
+    async team_select() {
+      const res = await teamAddMemberToGroup({ bizId: this.bizId, teamMemberRelateInfoRequests: this.teamMemberList, teamId: this.type.code })
+      if (res.code === 200) {
+        this.teamClose()
+      }
+    },
+    team_dele(val) { // 删除成员
+      this.teamMemberList = this.teamMemberList.filter(item => val.memberIDAP !== item.memberIDAP)
+    },
+    setRole(data, e, name) {
+      data.role = e
+      data.roleName = name
+    },
+    teamClose() {
+      this.dialogTeamVisible = false
+      this.$emit('update')
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+  .team_title {
+    position: absolute;
+    top: 23px;
+    left: 132PX;
+    color: #EC5A4B;
+  }
+  .team_cont {
+    border: 1px dashed #E5E5E5;
+    height: 350px;
+    margin-top: 30px;
+    overflow-y: auto;
+  }
+  .team_name {
+    font-size: 14px;
+    font-family: PingFang SC;
+    font-weight: 400;
+    color: #444;
+  }
+  .team_name1 {
+    font-size: 12px;
+    font-family: PingFang SC;
+    font-weight: 400;
+    color: #666;
+  }
+  .team_code {
+    line-height: 39px;
+    cursor: pointer;
+  }
+  .team_role {
+    min-width: 100px;
+
+  }
+  .item-style {
+  display: flex;
+  justify-content: flex-start;
+  .item-detail {
+    min-width:100px;
+    color: #8492a6;
+    font-size: 13px;
+    overflow:hidden
+  }
+}
+</style>

+ 207 - 0
src/views/ToConfigure/components/BusinessDirection.vue

@@ -0,0 +1,207 @@
+<template>
+  <div>
+    <div class="spacing">
+      <el-button size="small" type="primary" icon="el-icon-plus" @click="handlerModule('add')"> 新增一级方向 </el-button>
+    </div>
+    <el-table ref="moduleTable" :data="moduleData" style="width: 100%;margin-bottom: 20px;" row-key="id" border :tree-props="{children: 'childRqmtOrnts', hasChildren: 'hasChildren'}" header-align="center" size="mini" :header-cell-style="{ background: '#F2F3F6' }" fit>
+      <el-table-column v-if="false" prop="id" label="ID" width="180" align="center" />
+      <el-table-column prop="rqmtOrntName" label="需求方向名称" />
+      <el-table-column prop="creator" label="创建人" width="150" align="center" />
+      <el-table-column prop="gmtCreate" label="创建时间" width="150" align="center" />
+      <el-table-column label="操作" width="240" align="center">
+        <template slot-scope="scope">
+          <el-button size="mini" plain @click="handlerModule('add', scope.row, scope.$index)">添加</el-button>
+          <el-button size="mini" plain type="primary" @click="handlerModule('edit', scope.row, scope.$index)">编辑</el-button>
+          <el-button size="mini" plain type="danger" @click="handlerModule('delete', scope.row, scope.$index)">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <el-dialog :title="moduleTitle" :visible.sync="moduleDialog" class="public_task" width="30%" :before-close="() => {moduleDialog = false}">
+      <div class="blueStripe" />
+      <el-form ref="moduleForm" :model="moduleForm">
+        <template v-if="curcentModule === 'add'">
+          <el-form-item label="父方向:" :label-width="formLabelWidth">
+            <el-col :span="18">{{ curcentParent }}</el-col>
+          </el-form-item>
+          <el-form-item
+            v-for="(moduleName, index) in moduleForm.rqmtOrntNames"
+            :key="index"
+            label="方向名称:"
+            :label-width="formLabelWidth"
+            :prop="'rqmtOrntNames.' + index"
+            :rules="[
+              { required: true, message: '请输入方向名称', trigger: 'blur' },
+              { max: 20, message: '方向名称过长', trigger: 'blur' }
+            ]"
+          >
+            <el-col :span="20">
+              <el-input v-model="moduleForm.rqmtOrntNames[index]" style="width: 100%;" autocomplete="off" placeholder="不超过20个字符" />
+            </el-col>
+            <el-col v-show="index === moduleForm.rqmtOrntNames.length-1" :span="2" :offset="1">
+              <i class="el-icon-circle-plus-outline" @click="addModuleForm()" />
+            </el-col>
+          </el-form-item>
+        </template>
+        <template v-if="curcentModule === 'edit'">
+          <el-form-item label="父方向:" :label-width="formLabelWidth">
+            <el-col :span="18">{{ curcentParent }}</el-col>
+          </el-form-item>
+          <el-form-item label="方向名称:" :label-width="formLabelWidth">
+            <el-input v-model="moduleForm.rqmtOrntNames[0]" style="width: 100%;" autocomplete="off" placeholder="不超过20个字符" />
+          </el-form-item>
+        </template>
+        <div v-if="curcentModule === 'delete'" align="center">
+          是否要删除需求方向:<span style="color: #E6A23C">{{ moduleForm.rqmtOrntNames[0] }}</span>
+        </div>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+        <el-button size="mini" @click="moduleDialog = false">取 消</el-button>
+        <el-button type="primary" size="mini" @click="confirmModule('moduleForm')">确 定</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { settingQueryBizRqmtOrntList, settingDeleteBizRqmtOrnt, settingAddBizRqmtOrnt, settingUpdateBizRqmtOrnt, queryBizModuleList } from '@/api/configure'
+import '@/styles/PublicStyle/index.scss'
+import { mapGetters } from 'vuex'
+export default {
+  data() {
+    return {
+      moduleData: [],
+      moduleDialog: false,
+      formLabelWidth: '120px',
+      curcentModule: '', // 当前方向类型
+      moduleForm: { bizId: null, rqmtOrntNames: [null], parentId: null, id: null }, // 添加方向form
+      moduleTitle: '',
+      codeName: '', // 编辑失败还原之前的名字
+      bizIds: this.$store.state.data.bizId
+    }
+  },
+  computed: {
+    ...mapGetters(['bizId'])
+  },
+  watch: {
+    bizId: {
+      handler(newV) {
+        if (newV === -1) return
+        this.settingQueryBizRqmtOrntList()
+      },
+      immediate: true
+    }
+  },
+  created() {
+    this.getQueryBizModuleList()
+  },
+  methods: {
+    async getQueryBizModuleList() { // 获取结构化模块列表
+      const res = await queryBizModuleList(this.bizId)
+      this.data = this.handleData(res.data)
+    },
+    handleData(arr) {
+      if (arr.length === 0) return
+      const newArr = arr.filter(item => {
+        return item.isDelete !== 1
+      })
+      for (let i = 0; i < newArr.length; i++) {
+        newArr[i].childModules = this.handleData(newArr[i].childModules)
+      }
+      return newArr
+    },
+    async settingQueryBizRqmtOrntList() {
+      const res = await settingQueryBizRqmtOrntList(this.bizIds)
+      this.moduleData = res.data
+    },
+    handlerModule(type, data, index) { // 方向处理
+      this.curcentModule = type
+      this.moduleForm = { bizId: this.bizId, rqmtOrntNames: [null], parentId: -1, id: null }// 初始化
+      this.curcentParent = '无'
+      this.moduleTitle = '新增方向'
+      if (data && type === 'add') {
+        this.moduleDialog = true
+        this.moduleTitle = '新增方向'
+        this.curcentParent = data.rqmtOrntName
+        this.moduleForm.parentId = data.id
+      } else if (data && type === 'edit') {
+        this.moduleDialog = true
+        this.moduleTitle = '编辑方向'
+        this.moduleForm.id = data.id
+        this.curcentParent = data.parentId === -1 ? '无' : data.parentRqmtOrntName
+        this.moduleForm.parentId = data.parentId
+        this.moduleForm.rqmtOrntNames[0] = data.rqmtOrntName
+        this.codeName = data.rqmtOrntName
+      } else if (data && type === 'delete') {
+        if (data.childRqmtOrnts && data.childRqmtOrnts.length > 0) {
+          this.$message({ message: '该方向下存在子方向,不允许删除', type: 'error' })
+        } else {
+          this.moduleDialog = true
+          this.moduleTitle = '删除确认'
+          this.moduleForm.id = data.id
+          this.moduleForm.rqmtOrntNames[0] = data.rqmtOrntName
+        }
+      } else {
+        this.moduleDialog = true
+      }
+    },
+    addModuleForm() {
+      if (this.moduleForm.rqmtOrntNames.length <= 4) {
+        this.moduleForm.rqmtOrntNames.push(null)
+      }
+    },
+    async confirmModule(formName) { // 方向操作确认
+      if (this.curcentModule === 'add') {
+        this.$refs[formName].validate((valid) => {
+          if (valid) {
+            settingAddBizRqmtOrnt(this.moduleForm).then(res => {
+              if (res.code === 200) {
+                this.moduleDialog = false
+                this.settingQueryBizRqmtOrntList()
+                this.$message({ message: '已新增需求方向', type: 'success' })
+              }
+            })
+          } else {
+            this.$message({ message: '填写格式不正确', type: 'error' })
+            return false
+          }
+        })
+      } else if (this.curcentModule === 'edit') {
+        this.$refs[formName].validate((valid) => {
+          if (valid) {
+            let data = {}
+            data = this.moduleForm
+            data.rqmtOrntName = this.moduleForm.rqmtOrntNames.toString()
+            settingUpdateBizRqmtOrnt(data).then(res => {
+              if (res.code === 200) {
+                this.moduleDialog = false
+                this.settingQueryBizRqmtOrntList()
+                this.$message({ message: '已修改需求方向', type: 'success' })
+              } else {
+                this.$set(this.moduleForm, 'rqmtOrntNames[0]', this.codeName)
+              }
+            })
+          } else {
+            this.$message({ message: '填写格式不正确', type: 'error' })
+            return false
+          }
+        })
+      } else if (this.curcentModule === 'delete') {
+        const res = await settingDeleteBizRqmtOrnt(this.moduleForm)
+        if (res.code === 200) {
+          this.moduleDialog = false
+          this.settingQueryBizRqmtOrntList()
+          this.$message({ message: '删除成功', type: 'success' })
+        }
+      }
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.spacing {
+  margin: 0 0 20px;
+  text-align: right;
+}
+</style>

+ 211 - 0
src/views/ToConfigure/components/MemberDetails.vue

@@ -0,0 +1,211 @@
+<template>
+  <el-container>
+    <el-header>
+      <div class="team_space_between">
+        <div class="team_title">团队-{{ titleName }}</div>
+        <el-button v-if="titleName === '全部成员' || titleName === '未加入团队的成员'" type="primary" size="mini" icon="el-icon-plus" @click="setMember({}, '添加成员')">添加成员</el-button>
+        <el-button v-else type="primary" size="mini" icon="el-icon-plus" @click="setTeamMember">添加团队成员</el-button>
+      </div>
+    </el-header>
+    <el-main>
+      <el-table :data="AllMember" style="width: 100%">
+        <el-table-column prop="date" label="姓名" min-width="110">
+          <template slot-scope="scope">
+            <div style="display: flex; justify-content: flex-start;">
+              <el-avatar :src="scope.row.phoneUrl" />
+              <span style="margin: 0 10px;">
+                {{ scope.row.memberName }} <span v-if="scope.row.isLeader === 1" class="team_fzr"><span class="team_fname">负责人</span></span><br>
+                {{ scope.row.memberIDAP }}
+              </span>
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="date" label="角色" min-width="80">
+          <template slot-scope="scope">
+            {{ scope.row.roleName || '' }}
+          </template>
+        </el-table-column>
+        <el-table-column prop="date" label="所在团队" min-width="300">
+          <template slot-scope="scope">
+            {{ scope.row.teamNames ? scope.row.teamNames.join(" | ") : '' }}
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" width="150" align="center">
+          <template slot-scope="scope">
+            <el-dropdown placement="bottom" trigger="click">
+              <span class="el-dropdown-link">
+                ···
+              </span>
+              <el-dropdown-menu slot="dropdown">
+                <div v-if="titleName === '全部成员' || titleName === '未加入团队的成员'">
+                  <el-dropdown-item @click.native="setMember(scope.row, '编辑成员')">编辑成员</el-dropdown-item>
+                  <el-dropdown-item @click.native="setMember(scope.row, '删除成员')">删除成员</el-dropdown-item>
+                </div>
+                <div v-else>
+                  <el-dropdown-item v-if="scope.row.isLeader === 0" @click.native="setMember(scope.row, '设置负责人')">设置为负责人</el-dropdown-item>
+                  <el-dropdown-item v-else @click.native="setMember(scope.row, '取消负责人')">取消负责人</el-dropdown-item>
+                  <el-dropdown-item @click.native="setMember(scope.row, '移除成员')">从团队移出</el-dropdown-item>
+                </div>
+              </el-dropdown-menu>
+            </el-dropdown>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-main>
+    <el-footer style="text-align: right;">
+      <el-pagination :current-page.sync="currentPage" :page-size="10" layout="total, prev, pager, next" :total="total" background @size-change="handleSizeChange" @current-change="handleCurrentChange" />
+    </el-footer>
+    <memberSetup v-if="memberSetupShow" :data="member_information" @update="settingGetMembersBelowBiz" />
+    <teamMember v-if="teamMemberSetupShow" :data="type" @update="settingGetMembersBelowBiz" />
+  </el-container>
+</template>
+
+<script>
+import { mapGetters } from 'vuex'
+import { teamQueryTeamInfo, settingGetMembersBelowBiz, settingGetMembersWithoutTeam } from '@/api/toConfigure.js'
+import memberSetup from './memberSetup.vue'
+import teamMember from './AddTeamMembers.vue'
+
+export default {
+  components: {
+    memberSetup,
+    teamMember
+  },
+  props: {
+    data: { type: [String, Object], required: true }
+  },
+  data() {
+    return {
+      currentPage: 1,
+      pageSize: 10,
+      curIndex: 1,
+      type: '',
+      total: 0,
+      memberSetupShow: false, // 团队成员移除。取消负责人。设置负责人
+      teamMemberSetupShow: false, // 添加团队成员loading
+      member_information: {},
+      titleName: '全部成员',
+      AllMember: [] // 全部成员
+    }
+  },
+  computed: {
+    ...mapGetters(['bizId'])
+  },
+  watch: {
+    bizId: {
+      handler(newV) {
+        this.settingGetMembersBelowBiz()
+      }
+    },
+    data: {
+      handler(newV) {
+        if (newV) {
+          this.type = newV
+          this.pageSize = 10
+          this.curIndex = 1
+          this.settingGetMembersBelowBiz()
+        }
+      },
+      deep: true,
+      immediate: true
+    }
+  },
+  methods: {
+    async settingGetMembersBelowBiz() {
+      if (this.bizId === -1) return
+      if (this.type === 'all') {
+        this.titleName = '全部成员'
+        const res = await settingGetMembersBelowBiz({ bizId: this.bizId, pageSize: this.pageSize, curIndex: this.curIndex })
+        if (res.code === 200) {
+          this.AllMember = res.data
+          this.total = res.total
+        }
+      }
+      if (this.type === 'not') {
+        this.titleName = '未加入团队的成员'
+        const res = await settingGetMembersWithoutTeam({ bizId: this.bizId, pageSize: this.pageSize, curIndex: this.curIndex })
+        if (res.code === 200) {
+          this.AllMember = res.data
+          this.total = res.total
+        }
+      }
+      if (this.type.num === 'myTeam') {
+        this.titleName = this.type.name
+        const res = await teamQueryTeamInfo({ teamId: this.type.code, pageSize: this.pageSize, curIndex: this.curIndex })
+        if (res.code === 200) {
+          this.AllMember = res.data.teamLeaderRelateInfoResponseList.concat(res.data.teamMemberRelateInfoResponseList)
+          this.total = res.total
+        }
+      }
+      this.memberSetupShow = false
+      this.teamMemberSetupShow = false
+    },
+    setMember(data, name) { // 团队成员移除。取消负责人。设置负责人
+      data.teamName = this.titleName
+      this.member_information = {
+        data: data,
+        name: name
+      }
+      this.memberSetupShow = true
+    },
+    setTeamMember() { // 添加团队成员
+      this.teamMemberSetupShow = true
+    },
+    handleSizeChange(val) {
+      this.pageSize = val
+      this.settingGetMembersBelowBiz()
+    },
+    handleCurrentChange(val) {
+      this.curIndex = val
+      this.settingGetMembersBelowBiz()
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.team_space_between {
+  margin: 20px 0;
+  display: flex;
+  justify-content: space-between;
+}
+.team_title {
+  font-size: 16px;
+  font-family: PingFang SC;
+  font-weight: 500;
+  line-height: 22px;
+  color: #444444;
+}
+// .team_main {
+//   min-height: calc(100vh - 356px);
+// }
+.el-dropdown-link {
+    cursor: pointer;
+  }
+  .el-icon-arrow-down {
+    font-size: 12px;
+  }
+  .el-avatar {
+    background: #FFF;
+  }
+  >>>.el-avatar>img {
+    margin: 0 auto;
+}
+.team_fzr {
+  width: 80px;
+  height: 18px;
+  background: #E5F2FF;
+  border: 1px solid #409EFF;
+  opacity: 1;
+  border-radius: 9px;
+}
+.team_fname {
+  padding: 0 10px;
+  font-size: 10px;
+  font-family: Microsoft Sans Serif;
+  font-weight: 400;
+  line-height: 35px;
+  color: #409EFF;
+  opacity: 1;
+}
+</style>

+ 72 - 0
src/views/ToConfigure/components/bizConfigure.vue

@@ -0,0 +1,72 @@
+<template>
+  <div>
+    <p class="biz_property">业务线属性</p>
+    <el-radio-group v-model="radio" :disabled="Prohibit" class="biz_radio">
+      <el-radio label="0"> 公开 </el-radio>
+      <el-radio label="1"> 私密(仅成员可见)</el-radio>
+    </el-radio-group><br>
+    <el-button v-if="Prohibit" size="small" class="biz_buttom" type="primary" @click="Prohibit = false"> 编辑 </el-button>
+    <el-button v-if="!Prohibit" size="small" class="biz_buttom" @click="cancel"> 取消 </el-button>
+    <el-button v-if="!Prohibit" size="small" class="biz_buttom" type="primary" @click="preservation"> 保存 </el-button>
+  </div>
+</template>
+
+<script>
+import { mapGetters } from 'vuex'
+import { settingGetBizList, settingUpdateBiz } from '@/api/toConfigure.js'
+export default {
+  data() {
+    return {
+      radio: '1',
+      Prohibit: true,
+      bizObj: {}
+    }
+  },
+  computed: {
+    ...mapGetters(['bizId'])
+  },
+  watch: {
+    bizId: {
+      handler(newV) {
+        if (newV === -1) return
+        this.getBizIdList()
+      },
+      immediate: true
+    }
+  },
+  methods: {
+    async getBizIdList() { // 获取业务线属性
+      const res = await settingGetBizList({ id: this.bizId })
+      if (res.code === 200) {
+        this.bizObj = res.data[0]
+        this.radio = JSON.stringify(this.bizObj.isSecret)
+      }
+    },
+    async preservation() { // 保存业务线配置
+      const res = await settingUpdateBiz({ id: this.bizId, isSecret: Number(this.radio), bizName: this.bizObj.name })
+      if (res.code === 200) {
+        this.Prohibit = true
+        this.$message({ message: '修改成功', type: 'success', duration: 1000, offset: 150 })
+      }
+    },
+    cancel() {
+      this.Prohibit = true
+      this.radio = JSON.stringify(this.bizObj.isSecret)
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.biz_property {
+  font-size: 16px;
+  line-height: 22px;
+  color: #444444;
+}
+.biz_buttom {
+  width: 70px;
+}
+.biz_radio {
+  margin: 30px 0;
+}
+</style>

+ 276 - 0
src/views/ToConfigure/components/businessTechnology.vue

@@ -0,0 +1,276 @@
+<template>
+  <div>
+    <div class="spacing">
+      <el-button size="small" type="primary" icon="el-icon-plus" @click="handlerModule('add')"> 新增一级模块 </el-button>
+    </div>
+    <el-table
+      ref="moduleTable"
+      :data="moduleData"
+      style="width: 100%;margin-bottom: 20px;"
+      row-key="id"
+      border
+      :tree-props="{children: 'childModules', hasChildren: 'hasChildren'}"
+      header-align="center"
+      size="mini"
+      :header-cell-style="{ background: '#F2F3F6' }"
+      fit
+    >
+      <el-table-column v-if="false" prop="id" label="ID" width="180" align="center" />
+      <el-table-column prop="moduleName" label="模块名称" />
+      <el-table-column prop="creator" label="创建人" width="150" align="center" />
+      <el-table-column prop="createTime" label="创建时间" width="150" align="center" />
+      <el-table-column label="操作" width="240" align="center">
+        <template slot-scope="scope">
+          <el-button size="mini" plain @click="handlerModule('add', scope.row, scope.$index)">添加</el-button>
+          <el-button size="mini" plain type="primary" @click="handlerModule('edit', scope.row, scope.$index)">编辑</el-button>
+          <el-button size="mini" plain type="danger" @click="handlerModule('delete', scope.row, scope.$index)">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <normal-dialog :show-dialog="moduleDialog" :title="moduleTitle" :width="'30%'" @confirm="confirmModule('moduleForm')" @cancel="moduleDialog=false">
+      <el-form ref="moduleForm" :model="moduleForm">
+        <template v-if="curcentModule === 'add'">
+          <el-form-item label="父模块:" :label-width="formLabelWidth">
+            <el-col :span="11">{{ curcentParent }}</el-col>
+          </el-form-item>
+          <el-form-item
+            v-for="(moduleName, index) in moduleForm.moduleNames"
+            :key="index"
+            label="模块名称:"
+            :label-width="formLabelWidth"
+            :prop="'moduleNames.' + index"
+            :rules="[
+              { required: true, message: '请输入模块名称', trigger: 'blur' },
+              { min: 1, max: 20, message: '模块名称过长', trigger: 'blur' }
+            ]"
+          >
+            <el-col :span="20">
+              <el-input v-model="moduleForm.moduleNames[index]" autocomplete="off" placeholder="不超过20个字符" />
+            </el-col>
+            <el-col v-show="index === moduleForm.moduleNames.length-1" :span="2" :offset="1">
+              <i class="el-icon-circle-plus-outline" @click="addModuleForm()" />
+            </el-col>
+          </el-form-item>
+        </template>
+        <template v-if="curcentModule === 'edit'">
+          <el-form-item label="父模块:" :label-width="formLabelWidth">
+            <el-col :span="11">{{ curcentParent }}</el-col>
+          </el-form-item>
+          <el-form-item label="模块名称:" :label-width="formLabelWidth">
+            <el-col :span="20">
+              <el-input v-model="moduleForm.moduleNames[0]" autocomplete="off" placeholder="不超过20个字符" />
+            </el-col>
+          </el-form-item>
+        </template>
+        <el-col v-if="curcentModule === 'delete'" :span="11">
+          是否要删除模块:<span style="color: #E6A23C">{{ moduleForm.moduleNames[0] }}</span>
+        </el-col>
+      </el-form>
+    </normal-dialog>
+  </div>
+</template>
+
+<script>
+import { mapGetters } from 'vuex'
+import { queryBizModuleList, updateBizModule, deleteBizModule, addModule } from '@/api/configure'
+import normalDialog from '@/components/dialog/normalDialog'
+export default {
+  components: {
+    normalDialog
+  },
+  data() {
+    return {
+      userInformation: localStorage.getItem('username'),
+      dialogFormVisible: false,
+      dialogFormVisibleQuery: false,
+      activeName: 'second',
+      title_name: '',
+      currentPage1: 1,
+      gridData: [],
+      arr_team: [],
+      rules: {
+        teamName: [{ required: true, message: '团队名称不能为空', trigger: 'change' }, { max: 20, message: '团队名称,不得超过20个汉字', trigger: 'blur' }],
+        teamAttribute: [{ required: true, message: '团队属性不能为空', trigger: 'change' }],
+        dates: [{ required: true, message: '团队成员不能为空', trigger: ['blur', 'change'] }]
+      },
+      teamRoleEnum: [],
+      teamMemberRelateInfos: [],
+      form: {},
+      tableData: [],
+      table_Data: [],
+      options: [],
+      lerader: [],
+      tates: [],
+      depid: [],
+      loading: false,
+      test: {},
+      arry: [],
+      arr: [],
+      total: 0,
+      total1: 0,
+      curIndex: 1,
+      pageSize: 15,
+      activeIndex: '0',
+      businessCode: '0',
+      isAdmin: false, // 是否管理员
+      treeData: [],
+      curcentTreeData: { id: null, label: null },
+      showDialog: false,
+      dialogTitle: '', // 对话框title
+      curcentDialog: '', // 当前业务线窗口的类型
+      nodeForm: { id: null, name: null }, // 添加节点form
+      formLabelWidth: '120px',
+      nodeRules: {
+        name: [
+          { required: true, message: '请输入业务线名称', trigger: 'blur' },
+          { min: 1, max: 10, message: '业务线名称过长', trigger: 'blur' }
+        ],
+        id: [
+          { required: true, message: 'id不能为空' },
+          { type: 'number', message: 'id必须为数字值' }
+        ]
+      },
+      moduleData: [], // 模块数据
+      moduleDialog: false, // 模块操作对话框
+      moduleTitle: '', // 模块对话框title
+      curcentModule: '', // 当前模块类型
+      curcentParent: '', // 当前模块父模块
+      curcentParentId: '', // 当前模块父模块ID
+      moduleForm: { bizId: null, moduleNames: [null], parentId: null, id: null }, // 添加模块form
+      teamType: 0 // 0 我的 1 团队
+    }
+  },
+  computed: {
+    ...mapGetters(['bizId'])
+  },
+  watch: {
+    bizId: {
+      handler(newV) {
+        if (newV === -1) return
+        this.getQueryBizModuleList()
+      },
+      immediate: true
+    }
+  },
+  methods: {
+    async getQueryBizModuleList() { // 获取结构化模块列表
+      const res = await queryBizModuleList(this.bizId)
+      this.moduleData = this.handleData(res.data)
+    },
+    handleData(arr) {
+      if (arr.length === 0) return
+      const newArr = arr.filter(item => {
+        return item.isDelete !== 1
+      })
+      for (let i = 0; i < newArr.length; i++) {
+        newArr[i].childModules = this.handleData(newArr[i].childModules)
+      }
+      return newArr
+    },
+    addModuleForm() {
+      if (this.moduleForm.moduleNames.length <= 4) {
+        this.moduleForm.moduleNames.push(null)
+      }
+    },
+    handlerModule(type, data, index) { // 模块处理
+      this.curcentModule = type
+      this.moduleForm = { bizId: null, moduleNames: [null], parentId: -1, id: null }// 初始化
+      this.curcentParent = '无'
+      this.moduleTitle = '新增模块'
+      if (data && type === 'add') {
+        this.moduleDialog = true
+        this.moduleTitle = '新增模块'
+        this.curcentParent = data.moduleName
+        this.moduleForm.parentId = data.id
+      } else if (data && type === 'edit') {
+        this.moduleDialog = true
+        this.moduleTitle = '编辑模块'
+        this.moduleForm.id = data.id
+        this.curcentParent = data.parentId === -1 ? '无' : data.parentModuleName
+        this.moduleForm.parentId = data.parentId
+        this.moduleForm.moduleNames[0] = data.moduleName
+      } else if (data && type === 'delete') {
+        if (data.childModules && data.childModules.length > 0) {
+          this.$message({ message: '该模块下存在子模块,不允许删除', type: 'error' })
+        } else {
+          this.moduleDialog = true
+          this.moduleTitle = '删除确认'
+          this.moduleForm.id = data.id
+          this.moduleForm.moduleNames[0] = data.moduleName
+        }
+      } else {
+        this.moduleDialog = true
+      }
+    },
+    confirmModule(formName) { // 模块操作确认
+      if (this.curcentModule === 'add') {
+        this.$refs[formName].validate((valid) => {
+          if (valid) {
+            this.addModule(this.moduleForm)
+          } else {
+            this.$message({ message: '填写格式不正确', type: 'error' })
+            return false
+          }
+        })
+      } else if (this.curcentModule === 'edit') {
+        this.$refs[formName].validate((valid) => {
+          if (valid) {
+            this.updataModule(this.moduleForm)
+          } else {
+            this.$message({ message: '填写格式不正确', type: 'error' })
+            return false
+          }
+        })
+      } else if (this.curcentModule === 'delete') {
+        this.deleteModule(this.moduleForm)
+      }
+    },
+    async addModule(moduleForm) { // 添加模块
+      const form = {
+        bizId: this.bizId,
+        moduleNames: moduleForm.moduleNames,
+        parentId: moduleForm.parentId || -1
+      }
+      const res = await addModule(form)
+      if (res.code === 200) {
+        this.$message({ message: '添加成功', type: 'success' })
+        this.getQueryBizModuleList(this.bizId)// 重新获取模块列表
+        this.moduleDialog = false
+      }
+    },
+    async updataModule(moduleForm) { // 更新模块
+      const form = {
+        id: moduleForm.id,
+        bizId: this.bizId,
+        moduleName: moduleForm.moduleNames[0],
+        parentId: moduleForm.parentId || -1
+      }
+      const res = await updateBizModule(form)
+      if (res.code === 200) {
+        this.$message({ message: '更新成功', type: 'success' })
+        this.getQueryBizModuleList(this.bizId)// 重新获取模块列表
+        this.moduleDialog = false
+      }
+    },
+    async deleteModule(moduleForm) { // 删除模块
+      const form = {
+        id: moduleForm.id
+      }
+      const res = await deleteBizModule(form)
+      if (res.code === 200) {
+        this.$message({ message: '删除成功', type: 'success' })
+        this.moduleData = []// 初始化
+        this.getQueryBizModuleList(this.bizId)// 重新获取模块列表
+        this.moduleDialog = false
+      }
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.spacing {
+  margin: 0 0 20px;
+  text-align: right;
+}
+</style>

+ 154 - 0
src/views/ToConfigure/components/memberConfiguration.vue

@@ -0,0 +1,154 @@
+<template>
+  <el-container>
+    <el-main class="member_main">
+      <div class="member_title">成员</div>
+      <div class="member_all" @click="memberAll('all')">全部成员</div>
+      <div class="member_all member_margin" @click="memberAll('not')">未加入团队的成员</div>
+      <div class="member_title">团队</div>
+      <div class="member_team">我的团队</div>
+      <div v-for="item in memberList[0]" :key="item.code">
+        <div class="member_all member_space_between">
+          <span class="navList" @click="myTeam(item)">{{ item.name }}</span>
+          <el-dropdown placement="bottom" trigger="click">
+            <span class="el-dropdown-link">
+              ···
+            </span>
+            <el-dropdown-menu slot="dropdown">
+              <el-dropdown-item @click.native="operationTeam('编辑团队名称', item)">修改团队名称</el-dropdown-item>
+              <el-dropdown-item @click.native="operationTeam('删除团队', item)">删除团队</el-dropdown-item>
+            </el-dropdown-menu>
+          </el-dropdown>
+        </div>
+      </div>
+      <div class="member_team" style="margin-top: 25px;">其他团队</div>
+      <div v-for="item in memberList[1]" :key="item.code">
+        <div class="member_all member_space_between">
+          <span class="navList" @click="myTeam(item)">{{ item.name }}</span>
+          <el-dropdown placement="bottom" trigger="click">
+            <span class="el-dropdown-link">
+              ···
+            </span>
+            <el-dropdown-menu slot="dropdown">
+              <el-dropdown-item @click.native="operationTeam('编辑团队名称', item)">修改团队名称</el-dropdown-item>
+              <el-dropdown-item @click.native="operationTeam('删除团队', item)">删除团队</el-dropdown-item>
+            </el-dropdown-menu>
+          </el-dropdown>
+        </div>
+      </div>
+    </el-main>
+    <el-footer class="member_footer">
+      <el-button type="primary" plain size="mini" icon="el-icon-plus" @click="operationTeam('新建团队')">新建团队</el-button>
+    </el-footer>
+    <team-dialog v-if="teamDialog" :title="titltName" @update="updateTeam" />
+  </el-container>
+</template>
+
+<script>
+import { mapGetters } from 'vuex'
+import { teamQueryTeamListByName } from '@/api/toConfigure.js'
+import teamDialog from './teamSetup.vue'
+export default {
+  components: {
+    teamDialog
+  },
+  data() {
+    return {
+      memberList: [],
+      titltName: {
+        name: '',
+        data: {}
+      },
+      teamDialog: false // 团队(新建/编辑/删除)
+    }
+  },
+  computed: {
+    ...mapGetters(['bizId'])
+  },
+  watch: {
+    bizId: {
+      handler(newV) {
+        if (newV === -1) return
+        this.teamQueryTeamListByName()
+      },
+      immediate: true
+    }
+  },
+  methods: {
+    async teamQueryTeamListByName() { // 获取团队及成员
+      const res = await teamQueryTeamListByName(this.bizId)
+      if (res.code === 200) {
+        this.memberList = res.data
+      }
+    },
+    operationTeam(name, data) { // 新建/编辑/删除 团队
+      this.teamDialog = true
+      this.titltName = { name: name, data: data }
+    },
+    updateTeam() { // 更新成员信息
+      this.teamDialog = false
+      this.teamQueryTeamListByName()
+    },
+    memberAll(val) {
+      this.$emit('details', val)
+    },
+    myTeam(item) {
+      item.num = 'myTeam'
+      this.$emit('details', item)
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.member_title {
+  font-size: 16px;
+  font-family: PingFang SC;
+  font-weight: 500;
+  line-height: 22px;
+  color: #444444;
+  margin-bottom: 20px;
+}
+.member_all {
+  font-size: 14px;
+  font-family: PingFangSC-Regular;
+  line-height: 24px;
+  color: #333333;
+}
+.member_all:hover {
+  cursor: pointer;
+  color: #409EFF;
+}
+.member_team {
+  font-size: 14px;
+  font-family: PingFangSC-Regular;
+  line-height: 24px;
+  color: #999999;
+}
+.member_margin {
+  margin-bottom: 32px;
+}
+.member_main {
+  min-height: calc(100vh - 296px);
+}
+.member_footer {
+  text-align: center;
+}
+.member_space_between {
+  display: flex;
+  justify-content: space-between;
+}
+.el-dropdown-link {
+  cursor: pointer;
+}
+.el-icon-arrow-down {
+  font-size: 12px;
+}
+.navList {
+  width: 130px;
+  white-space: nowrap;
+  overflow: hidden;
+  /* 	显示省略符号(...)来代表被修剪的文本 */
+  text-overflow: ellipsis;
+  display: inline-block;
+}
+</style>

+ 150 - 0
src/views/ToConfigure/components/memberSetup.vue

@@ -0,0 +1,150 @@
+<template>
+  <el-dialog :title="titleName" :visible.sync="dialogFormVisible" class="public_task" width="30%" :close-on-click-modal="false" :destroy-on-close="true" @close="teamClose">
+    <div class="blueStripe" />
+    <el-form v-if="titleName === '添加成员' || titleName === '编辑成员'" ref="form" :model="teamData" style="padding: 0 30px;">
+      <el-form-item v-if="titleName === '添加成员'" label="姓名" prop="createMember" :rules="[{ required: true, message: '姓名不可为空', trigger: 'change'}]" :label-width="formLabelWidth">
+        <searchPeople :value.sync="teamData.createMember" :multiple="true" :size="'medium'" style="width: 100%;" />
+      </el-form-item>
+      <el-form-item v-else label="姓名" :label-width="formLabelWidth">
+        {{ teamData.memberName }}
+      </el-form-item>
+      <el-form-item label="角色" :label-width="formLabelWidth">
+        <el-select v-model="teamData.role" clearable placeholder="请选择" style="width: 100%;">
+          <el-option v-for="(item,index) in role" :key="item.name + index" :label="item.name" :value="item.code" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="团队" :label-width="formLabelWidth">
+        <el-select v-model="teamData.teamIds" multiple clearable placeholder="请选择" style="width: 100%;">
+          <el-option v-for="(item,index) in teamOption" :key="item.name + index" :label="item.name" :value="item.code" />
+        </el-select>
+      </el-form-item>
+    </el-form>
+    <div align="center">
+      <div v-if="titleName === '取消负责人'">是否取消 <span style="color: #E6A23C">{{ teamData.memberName }}</span> 在团队 <span style="color: #E6A23C">{{ teamData.teamName }}</span> 的负责人角色?</div>
+      <div v-if="titleName === '设置负责人'">是否设置 <span style="color: #E6A23C">{{ teamData.memberName }}</span> 为团队 <span style="color: #E6A23C">{{ teamData.teamName }}</span> 的负责人?</div>
+      <div v-if="titleName === '移除成员'">是否将 <span style="color: #E6A23C">{{ teamData.memberName }}</span> 从团队 <span style="color: #E6A23C">{{ teamData.teamName }}</span> 中移除?</div>
+      <div v-if="titleName === '删除成员'">是否将 <span style="color: #E6A23C">{{ teamData.memberName }}</span> 从业务线移除?</div>
+    </div>
+    <div slot="footer" class="dialog-footer">
+      <el-button @click="teamClose, dialogFormVisible = false">取 消</el-button>
+      <el-button type="primary" @click="team_select">确 定</el-button>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+import { mapGetters } from 'vuex'
+import '@/styles/PublicStyle/index.scss'
+import searchPeople from '@/components/select/searchPeople' // 人员select
+import { teamUpdateTeamMember, teamDeleteTeamMember, settingDeleteMemberBelowBiz, teamQueryTeamListBelowBiz, settingEditMember, settingAddMembersToBiz } from '@/api/toConfigure.js'
+export default {
+  components: {
+    searchPeople
+  },
+  props: {
+    data: { type: Object, required: true }
+  },
+  data() {
+    return {
+      role: [{ code: 2, name: 'PM' }, { code: 3, name: 'RD' }, { code: 4, name: 'QA' }],
+      formLabelWidth: '60px',
+      dialogFormVisible: true,
+      teamOption: [], // 所有团队
+      titleName: '',
+      teamData: {
+        createMember: []
+      },
+      type: {},
+      form: {}
+    }
+  },
+  computed: {
+    ...mapGetters(['bizId'])
+  },
+  watch: {
+    data: {
+      handler(newV) {
+        if (newV) {
+          this.type = newV
+          this.teamModifyTeam()
+        }
+      },
+      deep: true,
+      immediate: true
+    }
+  },
+  methods: {
+    async teamModifyTeam() {
+      this.titleName = this.type.name
+      this.type.name === '添加成员' ? '' : this.teamData = this.type.data
+      const res = await teamQueryTeamListBelowBiz(this.bizId)
+      if (res.code === 200) {
+        this.teamOption = res.data
+      }
+    },
+    teamClose() {
+      this.dialogFormVisible = false
+      this.$emit('update')
+    },
+    async team_select() {
+      if (this.type.name === '设置负责人' || this.type.name === '取消负责人') {
+        const isLeader = this.type.name === '设置负责人' ? 1 : 0
+        const res = await teamUpdateTeamMember({ id: this.teamData.id, isLeader: isLeader })
+        if (res.code === 200) {
+          this.teamClose()
+          this.$message({ message: '负责人变更成功', type: 'success', duration: 1000, offset: 150 })
+        }
+      }
+      if (this.type.name === '移除成员') {
+        const res = await teamDeleteTeamMember(this.teamData.id)
+        if (res.code === 200) {
+          this.teamClose()
+          this.$message({ message: '删除成功', type: 'success', duration: 1000, offset: 150 })
+        }
+      }
+      if (this.type.name === '删除成员') {
+        const res = await settingDeleteMemberBelowBiz({ bizId: this.bizId, memberNames: [this.teamData.memberIDAP] })
+        if (res.code === 200) {
+          this.teamClose()
+          this.$message({ message: '删除成功', type: 'success', duration: 1000, offset: 150 })
+        }
+      }
+      if (this.type.name === '编辑成员') {
+        const BizTeamMemberRequest = {
+          bizId: this.bizId,
+          memberNames: [this.teamData.memberIDAP],
+          role: this.teamData.role,
+          teamIds: this.teamData.teamIds
+        }
+        const res = await settingEditMember(BizTeamMemberRequest)
+        if (res.code === 200) {
+          this.teamClose()
+          this.$message({ message: '修改成员成功', type: 'success', duration: 1000, offset: 150 })
+        }
+      }
+      if (this.type.name === '添加成员') {
+        if (!this.teamData.createMember[0]) {
+          this.$message({ message: '姓名不可为空', type: 'error', duration: 1000, offset: 150 })
+          return false
+        }
+        const BizTeamMemberRequest = {
+          bizId: this.bizId,
+          memberNames: this.teamData.createMember,
+          role: this.teamData.role,
+          teamIds: this.teamData.teamIds
+        }
+        const res = await settingAddMembersToBiz(BizTeamMemberRequest)
+        if (res.code === 200) {
+          this.teamClose()
+          this.$message({ message: '修改成员成功', type: 'success', duration: 1000, offset: 150 })
+        }
+      }
+    }
+  }
+
+}
+</script>
+
+<style>
+
+</style>

+ 5 - 7
src/views/ToConfigure/components/noticeConfig.vue

@@ -132,19 +132,13 @@ import {
   deleteBizNoticeSetting,
   enableBizNoticeSetting
 } from '@/api/configure'
+import { mapGetters } from 'vuex'
 import modifyNotice from './modifyNotice'
 import requireImg from '@/assets/detailPage/需求@2x.png'
 import taskImg from '@/assets/detailPage/任务@2x.png'
 import normalDialog from '@/components/dialog/normalDialog'
 export default {
   components: { modifyNotice, normalDialog },
-  props: {
-    bizId: {
-      type: Number,
-      default: NaN,
-      required: true
-    }
-  },
   data() {
     return {
       activeTab: 1,
@@ -166,6 +160,9 @@ export default {
       controlType: 0 // 0 删除 1停用
     }
   },
+  computed: {
+    ...mapGetters(['bizId'])
+  },
   watch: {
     activeTab: {
       handler(newV) {
@@ -174,6 +171,7 @@ export default {
     },
     bizId: {
       handler(newV) {
+        if (newV === -1) return
         this.getBizNoticeSettingList()
       },
       immediate: true

+ 131 - 0
src/views/ToConfigure/components/teamSetup.vue

@@ -0,0 +1,131 @@
+<template>
+  <el-dialog :title="titleName" :visible.sync="dialogFormVisible" class="public_task" width="30%" :close-on-click-modal="false" :destroy-on-close="true" @close="teamClose">
+    <div class="blueStripe" />
+    <el-form v-if="titleName === '新建团队'" ref="form" :model="form" style="padding: 0 30px;">
+      <el-form-item label="团队名称" prop="title" :rules="[{ required: true, message: '请输入团队名称', trigger: ['blur', 'change']}]" :label-width="formLabelWidth">
+        <el-input v-model="form.title" size="medium" placeholder="请输入团队名称" />
+      </el-form-item>
+      <el-form-item label="负责人" :label-width="formLabelWidth">
+        <searchPeople :value.sync="form.creator" :multiple="true" :size="'medium'" style="width: 100%;" />
+      </el-form-item>
+      <el-form-item label="团队成员" :label-width="formLabelWidth">
+        <searchPeople :value.sync="form.teamList" :multiple="true" :size="'medium'" style="width: 100%;" />
+      </el-form-item>
+    </el-form>
+    <el-form v-if="titleName === '编辑团队名称'" ref="teamData" :model="teamData" style="padding: 0 30px;">
+      <el-form-item prop="name" :rules="[{ required: true, message: '请输入团队名称', trigger: ['blur', 'change']}]">
+        <el-input v-model="teamData.name" size="medium" placeholder="请输入团队名称" />
+      </el-form-item>
+    </el-form>
+    <div v-if="titleName === '删除团队'" class="team_del">
+      <div>是否删除团队 <span style="color: #E6A23C">{{ teamData.name }} </span>?
+        <div>仅删除团队信息,团队成员依然保留在业务线成员中</div>
+      </div>
+    </div>
+    <div slot="footer" class="dialog-footer">
+      <el-button @click="teamClose, dialogFormVisible = false">取 消</el-button>
+      <el-button type="primary" @click="team_select">确 定</el-button>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+import { mapGetters } from 'vuex'
+import '@/styles/PublicStyle/index.scss'
+import searchPeople from '@/components/select/searchPeople' // 人员select
+import { teamCreateTeam, teamDeleteTeam, teamModifyTeam } from '@/api/toConfigure.js'
+
+export default {
+  components: {
+    searchPeople
+  },
+  props: {
+    title: { type: Object, required: true }
+  },
+  data() {
+    return {
+      titleName: '',
+      teamData: {},
+      dialogFormVisible: true,
+      form: { },
+      formLabelWidth: '80px'
+    }
+  },
+  computed: {
+    ...mapGetters(['bizId'])
+  },
+  watch: {
+    title: {
+      handler(newV) {
+        if (newV) {
+          this.titleName = newV.name
+          this.teamData = newV.data
+        }
+      },
+      immediate: true
+    }
+  },
+  methods: {
+    async team_select() {
+      if (this.titleName === '新建团队') {
+        this.$refs.form.validate(async(valid) => {
+          if (valid) {
+            const creator = []
+            const teamList = []
+            const result = []
+            const obj = {}
+            this.form.creator ? this.form.creator.map(item => creator.push({ isLeader: 1, memberIDAP: item })) : ''
+            this.form.teamList ? this.form.teamList.map(item => teamList.push({ isLeader: 0, memberIDAP: item })) : ''
+            const arr = creator.concat(teamList)
+            for (var i = 0; i < arr.length; i++) {
+              if (!obj[arr[i].memberIDAP]) {
+                result.push(arr[i])
+                obj[arr[i].memberIDAP] = true
+              }
+            }
+            const data = { bizId: this.bizId, teamName: this.form.title, teamMemberRelateInfoRequests: result }
+            alert()
+            const res = await teamCreateTeam(data)
+            if (res.code === 200) {
+              this.teamClose()
+              this.$message({ message: '保存团队成功', type: 'success', duration: 1000, offset: 150 })
+            }
+          }
+        })
+      }
+      if (this.titleName === '删除团队') {
+        const res = await teamDeleteTeam(this.teamData.code)
+        if (res.code === 200) {
+          this.teamClose()
+          this.$message({ message: '删除成功', type: 'success', duration: 1000, offset: 150 })
+        }
+      }
+      if (this.titleName === '编辑团队名称') {
+        this.$refs.teamData.validate(async(valid) => {
+          if (valid) {
+            const res = await teamModifyTeam({ teamName: this.teamData.name, teamId: this.teamData.code })
+            if (res.code === 200) {
+              this.teamClose()
+              this.$message({ message: '修改成功', type: 'success', duration: 1000, offset: 150 })
+            }
+          }
+        })
+      }
+    },
+    teamClose() {
+      this.dialogFormVisible = false
+      this.$emit('update')
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.el-form-item {
+  margin-bottom: 15px;
+}
+.team_del {
+  display: flex;
+  justify-content: center;
+}
+</style>

+ 128 - 0
src/views/ToConfigure/index.vue

@@ -0,0 +1,128 @@
+<template>
+  <el-container class="configure_Background">
+    <el-header style="height: auto;" class="configure_header">
+      <div class="configure_title">配置中心</div>
+      <el-divider />
+      <el-tabs v-model="activeName" @tab-click="handleClick">
+        <el-tab-pane label="成员配置" name="first" />
+        <el-tab-pane label="需求方向配置" name="second" />
+        <el-tab-pane label="技术模块配置" name="third" />
+        <el-tab-pane label="通知配置" name="fourth" />
+        <el-tab-pane label="业务线配置" name="fourths" />
+      </el-tabs>
+    </el-header>
+    <el-container>
+      <el-main :class="{ 'configure_Main1': tabIndex === '0', 'configure_Main': tabIndex !== '0' }">
+        <div v-if="tabIndex === '0'">
+          <div class="member_demo">
+            <div class="member_left">
+              <member-configuration @details="detailslist" />
+            </div>
+            <div style="width: -webkit-fill-available; overflow-x: hidden;">
+              <Member-details :data="childName" />
+            </div>
+          </div>
+        </div>
+        <div v-if="tabIndex === '1'">
+          <Business />
+        </div>
+        <div v-if="tabIndex === '2'">
+          <Technology />
+        </div>
+        <div v-if="tabIndex === '3'">
+          <notice-config />
+        </div>
+        <div v-if="tabIndex === '4'">
+          <biz-configure />
+        </div>
+      </el-main>
+    </el-container>
+  </el-container>
+</template>
+
+<script>
+import bizConfigure from './components/bizConfigure.vue'
+import Business from './components/BusinessDirection.vue'
+import Technology from './components/businessTechnology.vue'
+import noticeConfig from './components/noticeConfig.vue'
+import memberConfiguration from './components/memberConfiguration.vue'
+import MemberDetails from './components/MemberDetails.vue'
+
+export default {
+  components: {
+    bizConfigure,
+    Business,
+    Technology,
+    noticeConfig,
+    memberConfiguration,
+    MemberDetails
+  },
+  data() {
+    return {
+      activeName: 'first',
+      tabIndex: '0',
+      childName: 'all'
+    }
+  },
+  methods: {
+    handleClick(tab, event) {
+      this.tabIndex = tab.index
+    },
+    detailslist(val) {
+      this.childName = val
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+  .configure_Background {
+    background: #F2F3F6;
+    >>>.el-tabs__nav-wrap::after {
+    display: none;
+    }
+    >>>.el-tabs__active-bar {
+      display: none;
+    }
+    >>>.el-tabs__header {
+    margin: 0 0 20px !important;
+    }
+    >>>.el-tabs__item {
+    color: #333;
+    }
+  }
+  .configure_header {
+    margin: 0 10px;
+    background: #FFF;
+  }
+  .configure_Main {
+    padding: 20px;
+    margin: 10px;
+    background: #FFF;
+    min-height: calc(100vh - 236px);
+  }
+  .configure_Main1 {
+    margin: 10px;
+    background: #FFF;
+    padding: 0px;
+    min-height: calc(100vh - 236px);
+  }
+  .configure_title {
+    font-size: 22px;
+    font-weight: 800;
+    color: #444;
+    padding-top: 20px;
+    display: table-cell;
+    vertical-align: middle;
+  }
+  .member_demo {
+  display: flex;
+  justify-content: flex-start;
+  }
+.member_left {
+  width: 220px;
+  border-right: 1px solid #EEEEEE;
+  min-height: calc(100vh - 236px);
+  padding: 0 !important;
+}
+</style>