MrShi
2024-11-07 bf2338f5cc71890cda247d46edcffa42e21871f6
优化需求
已添加8个文件
已修改9个文件
956 ■■■■■ 文件已修改
company/.env.developmentCom 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/api/business/companyDepartment.js 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/api/business/customerService.js 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/api/system/role.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/api/system/user.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/components/business/OperaCompanyDepartmentWindow.vue 138 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/components/business/OperaCompanyDescWindow.vue 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/components/business/OperaCustomerServiceWindow.vue 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/components/business/allocateEnterprises.vue 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/components/business/modification.vue 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/components/system/role/Permissions.vue 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/components/system/user/OperaUserWindow.vue 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/views/business/company.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/views/business/companyDepartment.vue 162 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/views/business/customerService.vue 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/views/system/role.vue 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/views/system/user.vue 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/.env.developmentCom
@@ -9,6 +9,6 @@
#VUE_APP_API = 'https://dmtest.ahapp.net/yyb_web_api/'
VUE_APP_API = 'http://192.168.0.138:10031/'
VUE_APP_API = 'http://192.168.0.134:10031/'
# VUE_APP_API = 'https://www.yyb.red/yyb_web_api/'
company/src/api/business/companyDepartment.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,42 @@
import request from '../../utils/request'
// æŸ¥è¯¢
export function fetchList (data) {
  return request.post('/business/companyDepartment/page', data, {
    trim: true
  })
}
// åˆ›å»º
export function create (data) {
  return request.post('/business/companyDepartment/create', data)
}
// ä¿®æ”¹
export function updateById (data) {
  return request.post('/business/companyDepartment/updateById', data)
}
// åˆ é™¤
export function deleteById (id) {
  return request.get(`/business/companyDepartment/delete/${id}`)
}
// ç»„织树查询
export function tree () {
  return request.get(`/business/companyDepartment/tree`)
}
// æŽ’序
export function updateSort (data) {
  return request.post('/business/companyDepartment/updateSort', data)
}
// æ‰¹é‡åˆ é™¤
export function deleteByIdInBatch (ids) {
  return request.get('/business/companyDepartment/delete/batch', {
    params: {
      ids
    }
  })
}
company/src/api/business/customerService.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,33 @@
import request from '../../utils/request'
// æŸ¥è¯¢
export function fetchList (data) {
  return request.post('/business/customerService/page', data, {
    trim: true
  })
}
// åˆ›å»º
export function create (data) {
  return request.post('/business/customerService/create', data)
}
// ä¿®æ”¹
export function updateById (data) {
  return request.post('/business/customerService/updateById', data)
}
// åˆ é™¤
export function deleteById (id) {
  return request.get(`/business/customerService/delete/${id}`)
}
// æŽˆæƒä¼ä¸š
export function auth (data) {
  return request.post('/business/customerService/auth', data)
}
// æ ¹æ®ID查询
export function getById (id) {
  return request.get(`/business/customerService/${id}`)
}
company/src/api/system/role.js
@@ -47,3 +47,8 @@
export function createRoleMenu (data) {
  return request.post('/system/role/createRoleMenu', data)
}
// é…ç½®è§’色数据权限
export function createRoleDataPermission (data) {
  return request.post('/system/role/createRoleDataPermission', data)
}
company/src/api/system/user.js
@@ -47,3 +47,8 @@
export function updUserStatus (params) {
  return request.get('/system/user/updUserStatus', {params})
}
// è®¾ç½®æˆ–取消主管
export function updateHead (data) {
  return request.post('/system/user/updateHead', data)
}
company/src/components/business/OperaCompanyDepartmentWindow.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,138 @@
<template>
    <GlobalWindow
        :title="title"
        :visible.sync="visible"
        :confirm-working="isWorking"
        @confirm="confirm"
    >
        <el-form :model="form" ref="form" :rules="rules">{{form.type}}
            <el-form-item label="上级组织" prop="parentId">
                <el-cascader
                    :options="organization"
                    v-model="form.parentId"
                    :disabled="form.disabled"
                    placeholder="请选择上级组织"
                    :props="{ label: 'name', value: 'id', checkStrictly: true }"
                    clearable />
            </el-form-item>
            <el-form-item label="组织名称" prop="name">
                <el-input v-model="form.name" placeholder="请输入名称" v-trim/>
            </el-form-item>
        </el-form>
    </GlobalWindow>
</template>
<script>
  import BaseOpera from '@/components/base/BaseOpera'
  import GlobalWindow from '@/components/common/GlobalWindow'
  import { tree } from '@/api/business/companyDepartment'
  import { mapState } from 'vuex'
  export default {
    name: 'OperaCompanyDepartmentWindow',
    extends: BaseOpera,
    components: { GlobalWindow },
    computed: {
      ...mapState(['userInfo'])
    },
    data () {
      return {
        // è¡¨å•数据
        form: {
          id: null,
          name: '',
          parentId: [],
          type: '',
          disabled: false
        },
        // éªŒè¯è§„则
        rules: {
          name: [
            { required: true, message: '请输入组织名称' }
          ]
        },
        organization: []
      }
    },
    created () {
      this.config({
        api: '/business/companyDepartment',
        'field.id': 'id'
      })
    },
    methods: {
      __confirmCreate () {
        this.$refs.form.validate((valid) => {
          if (!valid) {
            return
          }
          let obj = JSON.parse(JSON.stringify(this.form))
          obj.parentId = obj.parentId && obj.parentId.length > 0 ? obj.parentId[0] : ''
          obj.type = this.userInfo.type
          // è°ƒç”¨æ–°å»ºæŽ¥å£
          this.isWorking = true
          this.api.create(obj)
            .then(() => {
              this.visible = false
              this.$tip.apiSuccess('新建成功')
              this.$emit('success')
            })
            .catch(e => {
              this.$tip.apiFailed(e)
            })
            .finally(() => {
              this.isWorking = false
            })
        })
      },
      __confirmEdit () {
        this.$refs.form.validate((valid) => {
          if (!valid) {
            return
          }
          // è°ƒç”¨æ–°å»ºæŽ¥å£
          let obj = JSON.parse(JSON.stringify(this.form))
          obj.parentId = obj.parentId && obj.parentId.length > 0 ? obj.parentId[0] : ''
          obj.type = this.userInfo.type
          this.isWorking = true
          this.api.updateById(obj)
            .then(() => {
              this.visible = false
              this.$tip.apiSuccess('修改成功')
              this.$emit('success')
            })
            .catch(e => {
              this.$tip.apiFailed(e)
            })
            .finally(() => {
              this.isWorking = false
            })
        })
      },
      open (title, target) {
        this.title = title
        this.visible = true
        this.getTree()
        // æ–°å»º
        if (target == null) {
          this.$nextTick(() => {
            this.$refs.form.resetFields()
            this.form[this.configData['field.id']] = null
          })
          return
        }
        // ç¼–辑
        this.$nextTick(() => {
          for (const key in this.form) {
            this.form[key] = target[key]
          }
        })
      },
      getTree() {
        tree()
          .then(records => {
            this.organization = records
          })
      }
    }
  }
</script>
company/src/components/business/OperaCompanyDescWindow.vue
@@ -98,6 +98,30 @@
                        <el-checkbox :true-label="1" :false-label="0" disabled v-model="row.canReduce">减保</el-checkbox>
                    </template>
                </el-table-column>
                <el-table-column
                    align="center"
                    label="签署状态">
                    <template slot-scope="{row}">
                        <template v-if="row.signStatus === 0">待签署</template>
                        <template v-else-if="row.signStatus === 1">已签署</template>
                    </template>
                </el-table-column>
                <el-table-column
                    prop="signDate"
                    align="center"
                    label="签署时间">
                </el-table-column>
                <el-table-column
                    prop="signUserName"
                    align="center"
                    label="签署人">
                </el-table-column>
                <el-table-column
                    label="操作">
                    <template slot-scope="{row}">
                        <el-button type="text" v-if="row.signStatus === 1" @click="openFile(row.fileSignUrl)">查看签署方案书</el-button>
                    </template>
                </el-table-column>
            </el-table>
            <div class="info_list" v-if="JSON.stringify(form) !== '{}'">
                <div class="info_list_item">
@@ -225,6 +249,9 @@
    })
  },
  methods: {
    openFile(url) {
      window.open(url)
    },
    close () {
      this.visiblePhone = false
      this.phone = ''
company/src/components/business/OperaCustomerServiceWindow.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,64 @@
<template>
    <GlobalWindow
        :title="title"
        :visible.sync="visible"
        :confirm-working="isWorking"
        @confirm="confirm"
    >
        <el-form :model="form" ref="form" :rules="rules">
            <el-form-item label="客服姓名" prop="name">
                <el-input v-model="form.name" placeholder="请输入名称" v-trim/>
            </el-form-item>
            <el-form-item label="手机号" prop="mobile">
                <el-input v-model="form.mobile" maxlength="11" show-word-limit placeholder="请输入手机号" v-trim/>
            </el-form-item>
            <el-form-item label="备注" prop="remark">
                <el-input v-model="form.remark" type="textarea" placeholder="请输入备注" v-trim/>
            </el-form-item>
        </el-form>
    </GlobalWindow>
</template>
<script>
  import BaseOpera from '@/components/base/BaseOpera'
  import GlobalWindow from '@/components/common/GlobalWindow'
  export default {
    name: 'OperaCustomerServiceWindow',
    extends: BaseOpera,
    components: { GlobalWindow },
    data () {
      const validatorMobile = (rule, value, callback) => {
        if (value === '') {
          callback(new Error('请输入手机号'));
        } else if (!/^1[3-9]\d{9}$/.test(value)) {
          callback(new Error('手机号不合法'));
        }
        callback()
      };
      return {
        // è¡¨å•数据
        form: {
          id: null,
          remark: '',
          name: '',
          mobile: ''
        },
        // éªŒè¯è§„则
        rules: {
          name: [
            { required: true, message: '请输入客服姓名' }
          ],
          mobile: [
            { required: true, validator: validatorMobile }
          ]
        }
      }
    },
    created () {
      this.config({
        api: '/business/customerService',
        'field.id': 'id'
      })
    }
  }
</script>
company/src/components/business/allocateEnterprises.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,109 @@
<template>
    <GlobalWindow
        class="menu-config-dialog"
        :visible.sync="visible"
        :confirm-working="isWorking"
        width="576px"
        title="分配服务企业"
        @confirm="confirm"
    >
        <p class="tip">为用户 <em>{{form.name || ''}}</em> åˆ†é…ä¼ä¸š</p>
        <el-transfer
            :titles="['未分配企业', '已分配企业']"
            v-model="form.companyIds"
            :data="enterprise" />
    </GlobalWindow>
</template>
<script>
  import GlobalWindow from '@/components/common/GlobalWindow'
  import { allForFp } from '@/api/business/company'
  import { auth, getById } from '@/api/business/customerService'
  import { mapState } from 'vuex'
  export default {
    name: 'allocateEnterprises',
    components: { GlobalWindow },
    computed: {
      ...mapState(['userInfo'])
    },
    data () {
      return {
        visible: false,
        isWorking: false,
        form: {
          id: null,
          name: '',
          companyIds: []
        },
        enterprise: []
      }
    },
    methods: {
      open (title, id) {
        this.title = title
        this.visible = true
        this.getCompany()
        for (const key in this.form) {
          this.form[key] = ''
        }
        getById(id)
          .then(res => {
            this.form.id = res.id
            this.form.name = res.name
            this.form.companyIds = res.customerCompanyList.map(item => item.companyId)
          })
      },
      getCompany() {
        allForFp({ type: this.userInfo.type })
          .then(res => {
            this.enterprise = res.map(item => {
              return {
                key: item.id,
                label: item.name
              }
            })
          })
      },
      confirm() {
        let obj = {
          id: this.form.id,
          customerCompanyList: []
        }
        if (this.form.companyIds.length > 0) {
          obj.customerCompanyList = this.form.companyIds.map(item => {
            return {
              companyId: item
            }
          })
        }
        this.isWorking = true
        auth(obj)
          .then(() => {
            this.visible = false
            this.$tip.apiSuccess('操作成功')
            this.$emit('success')
          })
          .catch(e => {
            this.$tip.apiFailed(e)
          })
          .finally(() => {
            this.isWorking = false
          })
      }
    }
  }
</script>
<style scoped lang="scss">
    @import "@/assets/style/variables.scss";
    .global-window {
        .tip {
            margin-bottom: 12px;
            em {
                font-style: normal;
                color: $primary-color;
                font-weight: bold;
            }
        }
    }
</style>
company/src/components/business/modification.vue
@@ -24,7 +24,7 @@
                label="保险方案">
                <template slot-scope="scope">
<!--                    :value="{ id:item.id, baseId: item.baseId }"-->
                    <el-select v-model="scope.row.solution.id" @change="changeSolution($event, scope.$index)" placeholder="请选择">
                    <el-select v-model="scope.row.solution.id" filterable @change="changeSolution($event, scope.$index)" placeholder="请选择">
                        <el-option
                            v-for="item in programme"
                            :key="item.id"
@@ -57,11 +57,19 @@
                </template>
            </el-table-column>
            <el-table-column
                align="center"
                label="签署状态">
                <template slot-scope="{row}">
                    <template v-if="row.signStatus === 0">待签章</template>
                    <template v-if="row.signStatus === 1">已签章</template>
                </template>
            </el-table-column>
            <el-table-column
                label="操作"
                align="center"
                width="100">
                <template slot-scope="scope">
                    <el-button type="text" size="small" style="color: red;" @click="dele(scope.$index)">删除</el-button>
                    <el-button type="text" size="small" style="color: red;" @click="dele(scope.$index)" v-if="scope.row.signStatus === 0 || !scope.row.signStatus">删除</el-button>
                </template>
            </el-table-column>
        </el-table>
company/src/components/system/role/Permissions.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,125 @@
<template>
    <GlobalWindow
        :title="title"
        :visible.sync="visible"
        :confirm-working="isWorking"
        @confirm="confirm"
    >
        <el-form :model="form" ref="form" :rules="rules">
            <el-form-item label="权限类型" prop="type">
                <el-select v-model="form.type" @change="form.customData === []" placeholder="请选择">
                    <el-option
                        v-for="item in options"
                        :key="item.value"
                        :label="item.label"
                        :value="item.value">
                    </el-option>
                </el-select>
            </el-form-item>
            <el-form-item label="自定义部门" prop="customData" v-if="form.type === 4">
                <el-cascader
                    :options="organization"
                    v-model="form.customData"
                    placeholder="请选择上级组织"
                    :props="{ label: 'name', value: 'id', multiple: true, checkStrictly: true }"
                    clearable />
            </el-form-item>
        </el-form>
    </GlobalWindow>
</template>
<script>
  import BaseOpera from '@/components/base/BaseOpera'
  import GlobalWindow from '@/components/common/GlobalWindow'
  import { tree } from '@/api/business/companyDepartment'
  import { createRoleDataPermission } from '@/api/system/role'
  export default {
    name: 'Permissions',
    extends: BaseOpera,
    components: { GlobalWindow },
    data () {
      return {
        // è¡¨å•数据
        form: {
          roleId: null,
          type: '',
          customData: []
        },
        // éªŒè¯è§„则
        rules: {
          type: [
            { required: true, message: '请选择权限类型' }
          ],
          customData: [
            { required: true, message: '请选择部门' }
          ]
        },
        organization: [],
        options: [
          { label: '全部', value: 0 },
          { label: '所属部门及下属部门', value: 1 },
          { label: '所属部门及其子孙部门', value: 2 },
          { label: '仅所属部门', value: 3 },
          { label: '自定义部门', value: 4 },
          { label: '仅自己', value: -1 }
        ]
      }
    },
    methods: {
      confirm () {
        this.$refs.form.validate((valid) => {
          if (!valid) {
            return
          }
          this.isWorking = true
          let obj = JSON.parse(JSON.stringify(this.form))
          if (obj.customData.length > 0) {
            obj.customData = obj.customData.flat().join(',')
          }
          createRoleDataPermission(obj)
            .then(() => {
              this.visible = false
              this.$tip.apiSuccess('操作成功')
              this.$emit('success')
            })
            .catch(e => {
              this.$tip.apiFailed(e)
            })
            .finally(() => {
              this.isWorking = false
            })
        })
      },
      getTree() {
        tree()
          .then(records => {
            this.organization = records
          })
      },
      open (title, target) {
        this.title = title
        this.visible = true
        this.getTree()
        // æ–°å»º
        if (target == null) {
          this.$nextTick(() => {
            this.$refs.form.resetFields()
            this.form[this.configData['field.id']] = null
          })
          return
        }
        // ç¼–辑
        this.$nextTick(() => {
          for (const key in this.form) {
            this.form[key] = target[key]
          }
        })
      }
    },
    created () {
      this.config({
        api: '/system/role'
      })
    }
  }
</script>
company/src/components/system/user/OperaUserWindow.vue
@@ -23,6 +23,14 @@
          <el-button type="primary" style="flex-shrink: 0; margin-left: 15px;" v-else>{{num}}s</el-button>
        </div>
      </el-form-item>
      <el-form-item label="部门" prop="departmentId">
        <el-cascader
          :options="organization"
          v-model="form.departmentId"
          placeholder="请选择"
          :props="{ label: 'name', value: 'id', checkStrictly: true }"
          clearable />
      </el-form-item>
      <el-form-item label="抄送文件邮箱" prop="email">
        <el-input v-model="form.email" placeholder="请输入" v-trim />
      </el-form-item>
@@ -37,7 +45,7 @@
import PositionSelect from '@/components/common/PositionSelect'
import { checkMobile, checkEmail } from '@/utils/form'
import { sendSms } from '@/api/business/smsEmail'
import { tree } from '@/api/business/companyDepartment'
export default {
  name: 'OperaUserWindow',
  extends: BaseOpera,
@@ -51,10 +59,12 @@
        realname: '', // å§“名
        mobile: '', // æ‰‹æœºå·ç 
        email: '',
        captcha: ''
        captcha: '',
        departmentId: ''
      },
      num: 0,
      timer: null,
      organization: [],
      // éªŒè¯è§„则
      rules: {
        username: [
@@ -66,6 +76,9 @@
        mobile: [
          { required: true, validator: checkMobile }
        ],
        departmentId: [
          { required: true, message: '请选择部门' }
        ],
        email: [
          { required: true, message: '请输入邮箱' }
        ]
@@ -73,6 +86,52 @@
    }
  },
  methods: {
    __confirmCreate () {
      this.$refs.form.validate((valid) => {
        if (!valid) {
          return
        }
        let obj = JSON.parse(JSON.stringify(this.form))
        obj.departmentId = obj.departmentId[0]
        // è°ƒç”¨æ–°å»ºæŽ¥å£
        this.isWorking = true
        this.api.create(obj)
          .then(() => {
            this.visible = false
            this.$tip.apiSuccess('新建成功')
            this.$emit('success')
          })
          .catch(e => {
            this.$tip.apiFailed(e)
          })
          .finally(() => {
            this.isWorking = false
          })
      })
    },
    __confirmEdit () {
      this.$refs.form.validate((valid) => {
        if (!valid) {
          return
        }
        let obj = JSON.parse(JSON.stringify(this.form))
        obj.departmentId = obj.departmentId[0]
        // è°ƒç”¨æ–°å»ºæŽ¥å£
        this.isWorking = true
        this.api.updateById(obj)
          .then(() => {
            this.visible = false
            this.$tip.apiSuccess('修改成功')
            this.$emit('success')
          })
          .catch(e => {
            this.$tip.apiFailed(e)
          })
          .finally(() => {
            this.isWorking = false
          })
      })
    },
    send() {
      if (!this.form.mobile) {
        this.$message.warning('请输入手机号')
@@ -82,6 +141,12 @@
        .then(res => {
          this.num = 60
          this.setTime()
        })
    },
    getTree() {
      tree()
        .then(records => {
          this.organization = records
        })
    },
    setTime() {
@@ -100,6 +165,7 @@
    open (title, target) {
      this.title = title
      this.visible = true
      this.getTree()
      clearInterval(this.timer)
      this.num = 0
      // æ–°å»º
@@ -107,8 +173,8 @@
        this.$nextTick(() => {
          this.$refs.form.resetFields()
          this.form.id = null
          this.form.departmentId = null
          this.form.positionIds = []
          // this.form.departmentId = null
          // this.form.positionIds = []
        })
        return
      }
@@ -117,8 +183,8 @@
        for (const key in this.form) {
          this.form[key] = target[key]
        }
        this.form.departmentId = target.department == null ? null : target.department.id
        this.form.positionIds = target.positions == null ? [] : target.positions.map(p => p.id)
        // this.form.departmentId = target.department == null ? null : target.department.id
        // this.form.positionIds = target.positions == null ? [] : target.positions.map(p => p.id)
      })
    }
  },
company/src/views/business/company.vue
@@ -23,6 +23,7 @@
                :data="tableData.list"
                stripe
            >
                <el-table-column prop="username" label="登录账号" min-width="150px" fixed  align="center"></el-table-column>
                <el-table-column prop="name" label="企业名称" min-width="150px" fixed  align="center"></el-table-column>
                <el-table-column prop="code" label="统一信用代码" min-width="150px" fixed     align="center"></el-table-column>
              <el-table-column prop="phone" label="绑定手机号" min-width="100px" fixed     align="center"></el-table-column>
company/src/views/business/companyDepartment.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,162 @@
<template>
    <TableLayout :permissions="['business:companydepartment:query']">
        <!-- è¡¨æ ¼å’Œåˆ†é¡µ -->
        <template v-slot:table-wrap>
            <ul class="toolbar" v-permissions="['business:companydepartment:create']">
                <li><el-button type="primary" @click="$refs.operaCompanyDepartmentWindow.open('新建组织', { disabled: false })" icon="el-icon-plus" v-permissions="['business:companydepartment:create']">新建</el-button></li>
                <li><el-button @click="deleteByIdInBatch" icon="el-icon-delete" v-permissions="['system:menu:delete']">删除</el-button></li>
                <li><el-button @click="sort('top')" :loading="isWorking.sort" icon="el-icon-sort-up" v-permissions="['system:menu:sort']">上移</el-button></li>
                <li><el-button @click="sort('bottom')" :loading="isWorking.sort" icon="el-icon-sort-down" v-permissions="['system:menu:sort']">下移</el-button></li>
            </ul>
            <el-table
                ref="table"
                v-loading="isWorking.search"
                :data="tableData.list"
                :tree-props="{children: 'childList', hasChildren: 'hasChildren'}"
                row-key="id"
                stripe
                :default-expand-all="false"
                @selection-change="handleSelectionChange"
            >
                <el-table-column type="selection" width="55" fixed="left"></el-table-column>
                <el-table-column prop="name" label="组织名称" min-width="100px"></el-table-column>
                <el-table-column prop="name" label="组织类型" min-width="100px"></el-table-column>
                <el-table-column prop="editorName" label="操作人" min-width="100px"></el-table-column>
                <el-table-column prop="editDate" label="操作时间" min-width="100px"></el-table-column>
                <el-table-column
                    v-if="containPermissions(['business:companydepartment:update', 'business:companydepartment:delete'])"
                    label="操作"
                    min-width="140"
                    fixed="right"
                >
                    <template slot-scope="{row}">
                        <el-button type="text" @click="$refs.operaCompanyDepartmentWindow.open('编辑组织', {...row, parentId: [row.id], disabled: true})" icon="el-icon-edit" v-permissions="['business:companydepartment:update']">编辑</el-button>
                        <el-button type="text" icon="el-icon-plus" @click="$refs.operaCompanyDepartmentWindow.open('新建子组织', {...row, id: null, parentId: [row.id], disabled: true})">新建子组织</el-button>
                        <el-button type="text" @click="deleteById(row)" icon="el-icon-delete" v-permissions="['business:companydepartment:delete']">删除</el-button>
                    </template>
                </el-table-column>
            </el-table>
        </template>
        <!-- æ–°å»º/修改 -->
        <OperaCompanyDepartmentWindow ref="operaCompanyDepartmentWindow" @success="handlePageChange"/>
    </TableLayout>
</template>
<script>
  import BaseTable from '@/components/base/BaseTable'
  import TableLayout from '@/layouts/TableLayout'
  import Pagination from '@/components/common/Pagination'
  import OperaCompanyDepartmentWindow from '@/components/business/OperaCompanyDepartmentWindow'
  import { tree, updateSort } from '@/api/business/companyDepartment'
  export default {
    name: 'CompanyDepartment',
    extends: BaseTable,
    components: { TableLayout, Pagination, OperaCompanyDepartmentWindow },
    data () {
      return {
        // æœç´¢
        searchForm: {
        },
        isWorking: {
          sort: false
        }
      }
    },
    created () {
      this.config({
        module: '企业信息表',
        api: '/business/companyDepartment',
        'field.id': 'id',
        'field.main': 'id'
      })
      this.search()
    },
    methods: {
      // æŸ¥è¯¢æ•°æ®
      handlePageChange () {
        this.isWorking.search = true
        tree()
          .then(records => {
            this.tableData.list = records
          })
          .catch(e => {
            this.$tip.apiFailed(e)
          })
          .finally(() => {
            this.isWorking.search = false
          })
      },
      // æŽ’序
      sort (direction) {
        if (this.isWorking.sort) {
          return
        }
        if (this.tableData.selectedRows.length === 0) {
          this.$tip.warning('请选择一条数据')
          return
        }
        if (this.tableData.selectedRows.length > 1) {
          this.$tip.warning('排序时仅允许选择一条数据')
          return
        }
        const menuId = this.tableData.selectedRows[0].id
        // æ‰¾åˆ°èœå•范围
        let menuPool
        for (const rootMenu of this.tableData.list) {
          const parent = this.__findParent(menuId, rootMenu)
          if (parent != null) {
            menuPool = parent.children
          }
        }
        menuPool = menuPool || this.tableData.list
        const menuIndex = menuPool.findIndex(menu => menu.id === menuId)
        // ä¸Šç§»æ ¡éªŒ
        if (direction === 'top' && menuIndex === 0) {
          this.$tip.warning('菜单已到顶部')
          return
        }
        // ä¸‹ç§»æ ¡éªŒ
        if (direction === 'bottom' && menuIndex === menuPool.length - 1) {
          this.$tip.warning('菜单已到底部')
          return
        }
        this.isWorking.sort = true
        updateSort({
          id: this.tableData.selectedRows[0].id,
          direction
        })
          .then(() => {
            if (direction === 'top') {
              menuPool.splice(menuIndex, 0, menuPool.splice(menuIndex - 1, 1)[0])
            } else {
              menuPool.splice(menuIndex, 0, menuPool.splice(menuIndex + 1, 1)[0])
            }
          })
          .catch(e => {
            this.$tip.apiFailed(e)
          })
          .finally(() => {
            this.isWorking.sort = false
          })
      },
      // æŸ¥è¯¢çˆ¶èŠ‚ç‚¹
      __findParent (id, parent) {
        if (parent.childList === 0) {
          return
        }
        for (const menu of parent.childList) {
          if (menu.id === id) {
            return parent
          }
          if (menu.childList.length > 0) {
            const m = this.__findParent(id, menu)
            if (m != null) {
              return m
            }
          }
        }
        return null
      }
    }
  }
</script>
company/src/views/business/customerService.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,93 @@
<template>
    <TableLayout :permissions="['business:customerservice:query']">
        <!-- æœç´¢è¡¨å• -->
        <el-form ref="searchForm" slot="search-form" :model="searchForm" label-width="100px" inline>
            <el-form-item label="名称" prop="name">
                <el-input v-model="searchForm.name" placeholder="请输入名称" @keypress.enter.native="search"></el-input>
            </el-form-item>
            <el-form-item label="手机号" prop="mobile">
                <el-input v-model="searchForm.mobile" placeholder="请输入手机号" @keypress.enter.native="search"></el-input>
            </el-form-item>
            <section>
                <el-button type="primary" @click="search">搜索</el-button>
                <el-button @click="reset">重置</el-button>
            </section>
        </el-form>
        <!-- è¡¨æ ¼å’Œåˆ†é¡µ -->
        <template v-slot:table-wrap>
            <ul class="toolbar" v-permissions="['business:customerservice:create']">
                <li><el-button type="primary" @click="$refs.operaCustomerServiceWindow.open('新增账号')" icon="el-icon-plus" v-permissions="['business:customerservice:create']">新建</el-button></li>
            </ul>
            <el-table
                v-loading="isWorking.search"
                :data="tableData.list"
                stripe
            >
                <el-table-column label="序号" width="80px">
                    <template slot-scope="scope">
                        <span>{{scope.$index + 1}}</span>
                    </template>
                </el-table-column>
                <el-table-column prop="name" label="客服姓名" min-width="100px"></el-table-column>
                <el-table-column prop="mobile" label="手机号" min-width="100px"></el-table-column>
                <el-table-column prop="companyNum" label="服务企业数" min-width="100px"></el-table-column>
                <el-table-column prop="remark" label="备注" min-width="100px"></el-table-column>
                <el-table-column prop="createDate" label="创建时间" min-width="100px"></el-table-column>
                <el-table-column prop="createUserName" label="创建人" min-width="100px"></el-table-column>
                <el-table-column
                    v-if="containPermissions(['business:customerservice:update', 'business:customerservice:delete'])"
                    label="操作"
                    min-width="180"
                    fixed="right"
                >
                    <template slot-scope="{row}">
                        <el-button type="text" @click="$refs.operaCustomerServiceWindow.open('编辑账号', row)" icon="el-icon-edit" v-permissions="['business:customerservice:update']">编辑</el-button>
                        <el-button type="text" @click="$refs.allocateEnterprises.open('分配服务企业', row.id)" icon="el-icon-connection">企业授权</el-button>
                        <el-button type="text" @click="deleteById(row)" icon="el-icon-delete" v-permissions="['business:customerservice:delete']">删除</el-button>
                    </template>
                </el-table-column>
            </el-table>
            <pagination
                @size-change="handleSizeChange"
                @current-change="handlePageChange"
                :pagination="tableData.pagination"
            >
            </pagination>
        </template>
        <!-- æ–°å»º/修改 -->
        <OperaCustomerServiceWindow ref="operaCustomerServiceWindow" @success="handlePageChange"/>
        <!--    åˆ†é…ä¼ä¸š    -->
        <allocateEnterprises ref="allocateEnterprises" @success="handlePageChange"/>
    </TableLayout>
</template>
<script>
  import BaseTable from '@/components/base/BaseTable'
  import TableLayout from '@/layouts/TableLayout'
  import Pagination from '@/components/common/Pagination'
  import OperaCustomerServiceWindow from '@/components/business/OperaCustomerServiceWindow'
  import allocateEnterprises from '@/components/business/allocateEnterprises'
  export default {
    name: 'CustomerService',
    extends: BaseTable,
    components: { TableLayout, Pagination, OperaCustomerServiceWindow, allocateEnterprises },
    data () {
      return {
        // æœç´¢
        searchForm: {
          name: '',
          mobile: ''
        }
      }
    },
    created () {
      this.config({
        module: '客服信息表',
        api: '/business/customerService',
        'field.id': 'id',
        'field.main': 'id'
      })
      this.search()
    }
  }
</script>
company/src/views/system/role.vue
@@ -42,12 +42,12 @@
        <el-table-column
          v-if="containPermissions(['system:role:update', 'system:role:createRolePermission', 'system:role:createRoleMenu', 'system:role:delete'])"
          label="操作"
          min-width="270"
          min-width="330"
          fixed="right"
        >
<!--          v-if="isAdmin || (row.code !== adminCode && userInfo.roles.findIndex(code => code === row.code) === -1)"-->
          <template slot-scope="{row}">
            <el-button type="text" @click="$refs.operaRoleWindow.open('编辑角色', row)" icon="el-icon-edit" v-permissions="['system:role:update']">编辑</el-button>
            <el-button type="text" @click="openRole(row.systemDataPermission)">数据权限</el-button>
            <el-button type="text" @click="$refs.permissionConfigWindow.open(row)" v-permissions="['system:role:createRolePermission']">配置权限</el-button>
            <el-button type="text" @click="$refs.menuConfigWindow.open(row)" icon="el-icon-menu" v-permissions="['system:role:createRoleMenu']">授权菜单</el-button>
            <el-button v-if="!row.fixed" type="text" @click="deleteById(row)" icon="el-icon-delete" v-permissions="['system:role:delete']">删除</el-button>
@@ -66,6 +66,8 @@
    <PermissionConfigWindow ref="permissionConfigWindow" @success="handlePageChange(tableData.pagination.pageIndex)"/>
    <!-- æŽˆæƒèœå• -->
    <MenuConfigWindow ref="menuConfigWindow" @success="handlePageChange(tableData.pagination.pageIndex)"/>
    <!--  æ•°æ®æƒé™  -->
    <Permissions ref="permissions" @success="handlePageChange(tableData.pagination.pageIndex)"/>
  </TableLayout>
</template>
@@ -76,10 +78,11 @@
import OperaRoleWindow from '@/components/system/role/OperaRoleWindow'
import PermissionConfigWindow from '@/components/system/role/PermissionConfigWindow'
import MenuConfigWindow from '@/components/system/role/MenuConfigWindow'
import Permissions from '@/components/system/role/Permissions'
export default {
  name: 'SystemRole',
  extends: BaseTable,
  components: { MenuConfigWindow, PermissionConfigWindow, OperaRoleWindow, TableLayout, Pagination },
  components: { MenuConfigWindow, PermissionConfigWindow, OperaRoleWindow, TableLayout, Pagination, Permissions },
  data () {
    return {
      // æœç´¢
@@ -100,6 +103,15 @@
      }]
    })
    this.search()
  },
  methods: {
    openRole(row) {
      let customData = []
      row.customData.split(',').forEach(item => {
        customData.push([item])
      })
      this.$refs.permissions.open('数据权限', { ...row, customData })
    }
  }
}
</script>
company/src/views/system/user.vue
@@ -2,21 +2,12 @@
  <TableLayout :permissions="['system:user:query']">
    <!-- æœç´¢è¡¨å• -->
    <el-form ref="searchForm" slot="search-form" :model="searchForm" label-width="80px" inline>
<!--      <el-form-item label="用户名" prop="username">-->
<!--        <el-input v-model="searchForm.username" v-trim placeholder="请输入用户名" @keypress.enter.native="search"/>-->
<!--      </el-form-item>-->
      <el-form-item label="姓名" prop="realname">
        <el-input v-model="searchForm.realname" v-trim placeholder="请输入" @keypress.enter.native="search"/>
      </el-form-item>
<!--      <el-form-item label="手机号码" prop="mobile">-->
<!--        <el-input v-model="searchForm.mobile" v-trim placeholder="请输入手机号码" @keypress.enter.native="search"/>-->
<!--      </el-form-item>-->
<!--            <el-form-item label="所属部门" prop="rootDeptId">-->
<!--        <DepartmentSelect v-model="searchForm.rootDeptId" placeholder="请选择所属部门" clearable/>-->
<!--      </el-form-item>-->
<!--      <el-form-item label="岗位" prop="positionId">-->
<!--        <PositionSelect v-model="searchForm.positionId" placeholder="请选择岗位" clearable/>-->
<!--      </el-form-item>-->
      <el-form-item label="所属部门" prop="companyDepartmentPathName">
        <el-input v-model="searchForm.companyDepartmentPathName" v-trim placeholder="请输入" @keypress.enter.native="search"/>
      </el-form-item>
      <section>
        <el-button type="primary" icon="el-icon-search" @click="search">搜索</el-button>
        <el-button @click="reset">重置</el-button>
@@ -44,6 +35,19 @@
        <el-table-column prop="username" label="账号" min-width="120px"></el-table-column>
        <el-table-column prop="realname" label="姓名" min-width="100px"></el-table-column>
        <el-table-column prop="mobile" label="联系方式" min-width="100px"></el-table-column>
        <el-table-column label="主管" min-width="100px">
            <template slot-scope="{ row }">
                <el-switch
                    v-model="row.headStatus"
                    @change="setHeadStatus($event, row)"
                    active-color="#13ce66"
                    inactive-color="#ff4949"
                    :active-value="1"
                    :inactive-value="0">
                </el-switch>
            </template>
        </el-table-column>
        <el-table-column prop="companyDepartmentPathName" label="所在部门" min-width="100px"></el-table-column>
        <el-table-column prop="roles" label="角色" min-width="160px" class-name="table-column-strings">
          <template slot-scope="{row}">
            <ul>
@@ -72,7 +76,7 @@
        >
<!--          row.id !== userInfo.id &&-->
          <template v-if="isAdmin || (row.roles.findIndex(r => r.code === adminCode) === -1)" slot-scope="{row}">
            <el-button type="text" icon="el-icon-edit" @click="$refs.operaUserWindow.open('编辑用户', row)" v-permissions="['system:user:update']">编辑</el-button>
            <el-button type="text" icon="el-icon-edit" @click="$refs.operaUserWindow.open('编辑用户', {...row, departmentId: [row.departmentId]})" v-permissions="['system:user:update']">编辑</el-button>
            <el-button type="text" @click="$refs.allocationEnterprises.open('分配企业', row)" v-if="userInfo.type !== 1">分配企业</el-button>
            <el-button type="text" icon="el-icon-s-custom" @click="$refs.roleConfigWindow.open(row)" v-permissions="['system:user:createUserRole']">配置角色</el-button>
            <el-button type="text" @click="$refs.resetPwdWindow.open(row)" v-permissions="['system:user:resetPwd']">重置密码</el-button>
@@ -107,7 +111,7 @@
import ResetPwdWindow from '@/components/system/user/ResetPwdWindow'
import DepartmentSelect from '@/components/common/DepartmentSelect'
import PositionSelect from '@/components/common/PositionSelect'
import { updUserStatus } from '@/api/system/user'
import { updUserStatus, updateHead } from '@/api/system/user'
export default {
  name: 'SystemUser',
@@ -121,7 +125,8 @@
        realname: '', // å§“名
        rootDeptId: null, // éƒ¨é—¨ID
        positionId: null, // å²—位ID
        mobile: '' // æ‰‹æœºå·ç 
        mobile: '', // æ‰‹æœºå·ç 
        companyDepartmentPathName: ''   // éƒ¨é—¨åç§°
      }
    }
  },
@@ -138,6 +143,13 @@
    this.search()
  },
  methods: {
    // è®¾ç½®å–消主管
    setHeadStatus(e, row) {
      updateHead({ id: row.id, headStatus: row.headStatus })
        .then(res => {
          this.search()
        })
    },
    changeStatus(status, row) {
      updUserStatus({
        id: row.id,