From bf2338f5cc71890cda247d46edcffa42e21871f6 Mon Sep 17 00:00:00 2001
From: MrShi <1878285526@qq.com>
Date: 星期四, 07 十一月 2024 09:44:42 +0800
Subject: [PATCH] 优化需求

---
 company/src/components/business/OperaCompanyDescWindow.vue       |   27 +
 company/src/api/business/companyDepartment.js                    |   42 ++
 company/src/components/business/modification.vue                 |   12 
 company/.env.developmentCom                                      |    2 
 company/src/views/system/user.vue                                |   42 +
 company/src/api/system/role.js                                   |    5 
 company/src/components/system/user/OperaUserWindow.vue           |   78 ++++
 company/src/api/business/customerService.js                      |   33 ++
 company/src/views/business/company.vue                           |    1 
 company/src/components/business/allocateEnterprises.vue          |  109 ++++++
 company/src/views/business/customerService.vue                   |   93 +++++
 company/src/components/business/OperaCustomerServiceWindow.vue   |   64 ++++
 company/src/views/system/role.vue                                |   18 
 company/src/views/business/companyDepartment.vue                 |  162 ++++++++++
 company/src/components/business/OperaCompanyDepartmentWindow.vue |  138 ++++++++
 company/src/components/system/role/Permissions.vue               |  125 +++++++
 company/src/api/system/user.js                                   |    5 
 17 files changed, 929 insertions(+), 27 deletions(-)

diff --git a/company/.env.developmentCom b/company/.env.developmentCom
index b2dc706..821575c 100644
--- a/company/.env.developmentCom
+++ b/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/'
diff --git a/company/src/api/business/companyDepartment.js b/company/src/api/business/companyDepartment.js
new file mode 100644
index 0000000..cb9f259
--- /dev/null
+++ b/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
+    }
+  })
+}
diff --git a/company/src/api/business/customerService.js b/company/src/api/business/customerService.js
new file mode 100644
index 0000000..3bacb6c
--- /dev/null
+++ b/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}`)
+}
diff --git a/company/src/api/system/role.js b/company/src/api/system/role.js
index 5d9e34b..8f9093f 100644
--- a/company/src/api/system/role.js
+++ b/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)
+}
diff --git a/company/src/api/system/user.js b/company/src/api/system/user.js
index 6473428..6cbfe6b 100644
--- a/company/src/api/system/user.js
+++ b/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)
+}
diff --git a/company/src/components/business/OperaCompanyDepartmentWindow.vue b/company/src/components/business/OperaCompanyDepartmentWindow.vue
new file mode 100644
index 0000000..4cd780c
--- /dev/null
+++ b/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>
diff --git a/company/src/components/business/OperaCompanyDescWindow.vue b/company/src/components/business/OperaCompanyDescWindow.vue
index b10e676..fde348f 100644
--- a/company/src/components/business/OperaCompanyDescWindow.vue
+++ b/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 = ''
diff --git a/company/src/components/business/OperaCustomerServiceWindow.vue b/company/src/components/business/OperaCustomerServiceWindow.vue
new file mode 100644
index 0000000..b2775b6
--- /dev/null
+++ b/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>
diff --git a/company/src/components/business/allocateEnterprises.vue b/company/src/components/business/allocateEnterprises.vue
new file mode 100644
index 0000000..d67e1cb
--- /dev/null
+++ b/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>
diff --git a/company/src/components/business/modification.vue b/company/src/components/business/modification.vue
index 53e9d17..6bcff4c 100644
--- a/company/src/components/business/modification.vue
+++ b/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>
diff --git a/company/src/components/system/role/Permissions.vue b/company/src/components/system/role/Permissions.vue
new file mode 100644
index 0000000..5ec691e
--- /dev/null
+++ b/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>
diff --git a/company/src/components/system/user/OperaUserWindow.vue b/company/src/components/system/user/OperaUserWindow.vue
index a64d417..46df45a 100644
--- a/company/src/components/system/user/OperaUserWindow.vue
+++ b/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)
       })
     }
   },
diff --git a/company/src/views/business/company.vue b/company/src/views/business/company.vue
index 87a5ea1..ea58a9e 100644
--- a/company/src/views/business/company.vue
+++ b/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="缁熶竴淇$敤浠g爜" min-width="150px" fixed     align="center"></el-table-column>
               <el-table-column prop="phone" label="缁戝畾鎵嬫満鍙�" min-width="100px" fixed     align="center"></el-table-column>
diff --git a/company/src/views/business/companyDepartment.vue b/company/src/views/business/companyDepartment.vue
new file mode 100644
index 0000000..ca9b260
--- /dev/null
+++ b/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>
diff --git a/company/src/views/business/customerService.vue b/company/src/views/business/customerService.vue
new file mode 100644
index 0000000..a5a33c6
--- /dev/null
+++ b/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>
diff --git a/company/src/views/system/role.vue b/company/src/views/system/role.vue
index 45cab31..fcaf19b 100644
--- a/company/src/views/system/role.vue
+++ b/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>
diff --git a/company/src/views/system/user.vue b/company/src/views/system/user.vue
index e43e158..d6acebf 100644
--- a/company/src/views/system/user.vue
+++ b/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,

--
Gitblit v1.9.3