lizhenhao пре 2 година
родитељ
комит
55ed6787a1

+ 75 - 0
src/api/position/JobPositionService.js

@@ -0,0 +1,75 @@
+import request from '@/utils/httpRequest'
+
+export default class JobPositionService {
+  list (params) {
+    return request({
+      url: '/job/job_position/list',
+      method: 'get',
+      params: params
+    })
+  }
+  save (inputForm) {
+    return request({
+      url: `/job/job_position/save`,
+      method: 'post',
+      data: inputForm
+    })
+  }
+  delete (ids) {
+    return request({
+      url: '/job/job_position/delete',
+      method: 'delete',
+      params: {ids: ids}
+    })
+  }
+  queryById (id) {
+    return request({
+      url: '/job/job_position/queryById',
+      method: 'get',
+      params: {id: id}
+    })
+  }
+  queryAllPosition () {
+    return request({
+      url: '/job/job_position/queryAllPosition',
+      method: 'get',
+      params: {}
+    })
+  }
+  queryAllOffice () {
+    return request({
+      url: '/job/job_position/queryAllOffice',
+      method: 'get',
+      params: {}
+    })
+  }
+  changeUseFlag (ids, useFlag) {
+    return request({
+      url: '/job/job_position/changeUseFlag/' + useFlag,
+      method: 'post',
+      params: {ids: ids}
+    })
+  }
+  importExcel (data) {
+    return request({
+      url: '/job/job_position/import',
+      method: 'post',
+      data: data
+    })
+  }
+  exportTemplate () {
+    return request({
+      url: '/job/job_position/import/template',
+      method: 'get',
+      responseType: 'blob'
+    })
+  }
+  exportExcel (params) {
+    return request({
+      url: '/job/job_position/export',
+      method: 'get',
+      params: params,
+      responseType: 'blob'
+    })
+  }
+}

+ 32 - 0
src/api/position/PositionCategoryService.js

@@ -0,0 +1,32 @@
+import request from '@/utils/httpRequest'
+
+export default class PositionCategoryService {
+  list (params) {
+    return request({
+      url: '/job/position_category/list',
+      method: 'get',
+      params: params
+    })
+  }
+  queryById (id) {
+    return request({
+      url: '/job/position_category/queryById',
+      method: 'get',
+      params: {id: id}
+    })
+  }
+  save (inputForm) {
+    return request({
+      url: `/job/position_category/save`,
+      method: 'post',
+      data: inputForm
+    })
+  }
+  delete (ids) {
+    return request({
+      url: '/job/position_category/delete',
+      method: 'delete',
+      params: {ids: ids}
+    })
+  }
+}

+ 39 - 0
src/api/position/PositionService.js

@@ -0,0 +1,39 @@
+import request from '@/utils/httpRequest'
+
+export default class PositionService {
+  list (params) {
+    return request({
+      url: '/job/position/list',
+      method: 'get',
+      params: params
+    })
+  }
+  queryById (id) {
+    return request({
+      url: '/job/position/queryById',
+      method: 'get',
+      params: {id: id}
+    })
+  }
+  queryAllCategory () {
+    return request({
+      url: '/job/position/queryAllCategory',
+      method: 'get',
+      params: {}
+    })
+  }
+  save (inputForm) {
+    return request({
+      url: `/job/position/save`,
+      method: 'post',
+      data: inputForm
+    })
+  }
+  delete (ids) {
+    return request({
+      url: '/job/position/delete',
+      method: 'delete',
+      params: {ids: ids}
+    })
+  }
+}

+ 48 - 0
src/views/modules/position/Position.vue

@@ -0,0 +1,48 @@
+<template>
+  <div class="el-scrollbar__wrap wrap-white padding-20">
+    <el-tabs v-model="activeName" @tab-click="handleClick">
+      <el-tab-pane label="职务分类" name="positionCategory"style="height: calc(100vh - 210px)" lazy>
+        <position-category
+          i="positionCategory"
+          :index="activeName"
+        />
+      </el-tab-pane>
+      <el-tab-pane label="职务" name="position" style="height: calc(100vh - 210px)" lazy>
+        <position
+          i="position"
+          :index="activeName"
+        />
+      </el-tab-pane>
+      <el-tab-pane label="职位" name="jobPosition" style="height: calc(100vh - 210px)" lazy>
+        <job-position
+          i="jobPosition"
+          :index="activeName"
+        />
+      </el-tab-pane>
+    </el-tabs>
+  </div>
+</template>
+<script>
+  import positionCategory from './tabs/PositionCategoryList'
+  import jobPosition from './tabs/JobPositionList'
+  import position from './tabs/PositionList'
+  export default {
+    components: {
+      positionCategory,
+      jobPosition,
+      position
+    },
+    data () {
+      return {
+        activeName: 'jobPosition'
+      }
+    },
+    created () {
+      if (this.$route.query.activeName) {
+        this.activeName = this.$route.query.activeName
+      }
+    },
+    methods: {
+    }
+  }
+</script>

+ 176 - 0
src/views/modules/position/tabs/JobPositionForm.vue

@@ -0,0 +1,176 @@
+<template>
+  <div>
+    <el-dialog
+      :title="title"
+      :close-on-click-modal="false"
+      v-dialogDrag
+      width="500px"
+      @close="close"
+      @keyup.enter.native="doSubmit"
+      :visible.sync="visible">
+      <el-form size="middle" :model="inputForm" ref="inputForm" v-loading="loading" :class="method==='view'?'readonly':''"  :disabled="method==='view'"
+               label-width="100px" @submit.native.prevent>
+        <el-row  :gutter="15">
+          <el-col :span="21">
+            <el-form-item label="职位" prop="name"
+                          :rules="[
+                          {required: true, message:'职位不能为空', trigger:'blur'}
+                 ]">
+              <el-input v-model="inputForm.name" placeholder="请填写职位"     ></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="21">
+            <el-form-item label="职位编码" prop="no"
+                          :rules="[
+                 ]">
+              <el-input v-model="inputForm.no" placeholder="请填写职位编码"     ></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="21">
+            <el-form-item label="所属部门" prop="officeId" :rules="[
+                          {required: true, message:'部门不能为空', trigger:'blur'}
+                 ]">
+              <el-select v-model="inputForm.officeId" placeholder="请选择"  style="width: 100%;">
+                <el-option
+                  v-for="item in this.officeList"
+                  :key="item.id"
+                  :label="item.name"
+                  :value="item.id">
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="21">
+            <el-form-item label="编制人数" prop="staffNum"
+                          :rules="[
+                 ]">
+              <el-input v-model="inputForm.staffNum" placeholder="请填写编制人数"     ></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="21">
+            <el-form-item label="对应职务" prop="positionId">
+              <el-select v-model="inputForm.positionId" placeholder="请选择"  style="width: 100%;">
+                <el-option
+                  v-for="item in this.positionList"
+                  :key="item.id"
+                  :label="item.name"
+                  :value="item.id">
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="21">
+            <el-form-item label="任职资格" prop="qualification"
+                          :rules="[
+                 ]">
+              <el-input type="textarea" maxlength="1000" v-model="inputForm.qualification" placeholder="请填写任职资格"  show-word-limit   ></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="21">
+            <el-form-item label="责任描述" prop="obligation"
+                          :rules="[
+                 ]">
+              <el-input type="textarea" maxlength="1000" v-model="inputForm.obligation" placeholder="请填写责任描述"  show-word-limit   ></el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+      <el-button size="small" @click="close()" icon="el-icon-circle-close">关闭</el-button>
+      <el-button size="small" type="primary" v-if="method != 'view'" @click="doSubmit()" icon="el-icon-circle-check" v-noMoreClick>确定</el-button>
+    </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+  import JobPositionService from '@/api/position/JobPositionService'
+  export default {
+    data () {
+      return {
+        title: '',
+        method: '',
+        visible: false,
+        loading: false,
+        inputForm: {
+          name: '',
+          no: '',
+          officeId: '',
+          staffNum: '',
+          positionId: '',
+          qualification: '',
+          obligation: '',
+          useFlag: ''
+        },
+        officeList: [],
+        positionList: []
+      }
+    },
+    jobPositionService: null,
+    created () {
+      this.jobPositionService = new JobPositionService()
+    },
+    methods: {
+      init (method, id) {
+        this.method = method
+        this.inputForm = {
+          name: '',
+          no: '',
+          officeId: '',
+          staffNum: '',
+          positionId: '',
+          qualification: '',
+          obligation: '',
+          useFlag: ''
+        }
+        this.inputForm.id = id
+        this.jobPositionService.queryAllOffice().then(({data}) => {
+          this.officeList = data
+        })
+        this.jobPositionService.queryAllPosition().then(({data}) => {
+          this.positionList = data
+        })
+        if (method === 'add') {
+          this.title = `新建职位`
+        } else if (method === 'edit') {
+          this.title = '修改职位'
+        } else if (method === 'view') {
+          this.title = '查看职位'
+        }
+        this.visible = true
+        this.loading = false
+        this.$nextTick(() => {
+          this.$refs.inputForm.resetFields()
+          if (method === 'edit' || method === 'view') { // 修改或者查看
+            this.loading = true
+            this.jobPositionService.queryById(this.inputForm.id).then(({data}) => {
+              this.inputForm = this.recover(this.inputForm, data)
+              this.inputForm = JSON.parse(JSON.stringify(this.inputForm))
+              this.loading = false
+            })
+          }
+        })
+      },
+      // 表单提交
+      doSubmit () {
+        this.$refs['inputForm'].validate((valid) => {
+          if (valid) {
+            this.loading = true
+            this.jobPositionService.save(this.inputForm).then(({data}) => {
+              this.close()
+              this.$message.success(data)
+              this.$emit('refreshDataList')
+              this.loading = false
+            }).catch(() => {
+              this.loading = false
+            })
+          }
+        })
+      },
+      close () {
+        this.$refs.inputForm.resetFields()
+        this.visible = false
+      }
+    }
+  }
+</script>

+ 295 - 0
src/views/modules/position/tabs/JobPositionList.vue

@@ -0,0 +1,295 @@
+<template>
+  <div class="page">
+    <el-form size="small" :inline="true" class="query-form" ref="searchForm" :model="searchForm" @keyup.enter.native="refreshList()" @submit.native.prevent>
+      <!-- 搜索框-->
+      <el-form-item prop="name">
+        <el-input size="small" v-model="searchForm.name" placeholder="职位名称" clearable></el-input>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" @click="refreshList()" size="small" icon="el-icon-search">查询</el-button>
+        <el-button @click="resetSearch()" size="small" icon="el-icon-refresh-right">重置</el-button>
+      </el-form-item>
+
+    </el-form>
+
+    <div class="bg-white top" style="">
+      <vxe-toolbar :refresh="{query: refreshList}" import export custom>
+        <template #buttons>
+          <el-button v-if="hasPermission('job:job_position:add')" type="primary" size="small" icon="el-icon-plus" @click="add()">新建</el-button>
+          <el-button v-if="hasPermission('job:job_position:del')" type="danger"   size="small" icon="el-icon-delete" @click="del()" :disabled="$refs.jobPositionTable && $refs.jobPositionTable.getCheckboxRecords().length === 0" plain>删除</el-button>
+          <el-button v-if="hasPermission('job:job_position:add','job:job_position:edit','job:job_position:del')" type="primary"   size="small" icon="el-icon-check" @click="change(null,'1')" :disabled="$refs.jobPositionTable && $refs.jobPositionTable.getCheckboxRecords().length === 0" plain>启用</el-button>
+          <el-button v-if="hasPermission('job:job_position:add','job:job_position:edit','job:job_position:del')" type="primary"   size="small" icon="el-icon-close" @click="change(null,'2')" :disabled="$refs.jobPositionTable && $refs.jobPositionTable.getCheckboxRecords().length === 0" plain>停用</el-button>
+          <el-button style="margin-right: 50px" v-if="hasPermission('job:job_position:import')"  type="default" @click="downloadTpl()" size="small">下载模板</el-button>
+          <el-switch
+            @change="switchChange"
+            v-model="switchBlock"
+            active-text="展示停用职位"
+            inactive-text="不展示停用职位">
+          </el-switch>
+        </template>
+      </vxe-toolbar>
+      <div style="height: calc(100% - 80px)">
+        <vxe-table
+          border="inner"
+          auto-resize
+          resizable
+          height="auto"
+          :loading="loading"
+          size="small"
+          ref="jobPositionTable"
+          show-header-overflow
+          show-overflow
+          highlight-hover-row
+          :menu-config="{}"
+          :export-config="{
+                    remote: true,
+                    filename: `职位数据${moment(new Date()).format('YYYY-MM-DD')}`,
+                    sheetName: '职位数据',
+                    exportMethod: exportMethod,
+                    types: ['xlsx'],
+                    modes: ['current', 'all']
+                  }"
+          :import-config="{
+                    importMethod: importMethod,
+                    types: ['xls', 'xlsx'],
+                    remote: true}"
+          @sort-change="sortChangeHandle"
+          :sort-config="{remote:true}"
+          :data="dataList"
+          :checkbox-config="{}">
+          <vxe-column type="seq" width="40"></vxe-column>
+          <vxe-column type="checkbox" width="40" ></vxe-column>
+          <vxe-column  title="职位名称" field="name">
+            <template slot-scope="scope">
+              <el-link  type="primary" :underline="false" v-if="hasPermission('sys:project:view','sys:project:edit','sys:project:add')" @click="view(scope.row.id)">{{scope.row.name}}</el-link>
+              <span v-else>{{scope.row.name}}</span>
+            </template>
+          </vxe-column>
+          <vxe-column width="150" title="职位编码" field="no"></vxe-column>
+          <vxe-column width="180" title="所属部门" field="officeId"></vxe-column>
+          <vxe-column width="150" title="对应职务" field="positionId"></vxe-column>
+          <vxe-column width="130" title="编制人数" field="staffNum"></vxe-column>
+          <vxe-column width="130" title="状态" field="useFlag">
+            <template slot-scope="scope">
+              {{ $dictUtils.getDictLabel("use_flag", scope.row.useFlag, '-') }}
+            </template>
+          </vxe-column>
+          <vxe-column title="操作" width="180" fixed="right" align="center">
+            <template  slot-scope="scope">
+              <el-button v-if="hasPermission('job:job_position:view')" type="text" icon="el-icon-view" size="small" @click="view(scope.row.id)">查看</el-button>
+              <el-button v-if="hasPermission('job:job_position:edit')" type="text" icon="el-icon-edit" size="small" @click="edit(scope.row.id)">修改</el-button>
+              <el-button v-if="hasPermission('job:job_position:del')" type="text"  icon="el-icon-delete" size="small" @click="del(scope.row.id)">删除</el-button>
+            </template>
+          </vxe-column>
+        </vxe-table>
+        <vxe-pager
+          background
+          size="small"
+          :current-page="tablePage.currentPage"
+          :page-size="tablePage.pageSize"
+          :total="tablePage.total"
+          :page-sizes="[10, 20, 100, 1000, {label: '全量数据', value: 1000000}]"
+          :layouts="['PrevPage', 'JumpNumber', 'NextPage', 'FullJump', 'Sizes', 'Total']"
+          @page-change="currentChangeHandle">
+        </vxe-pager>
+      </div>
+    </div>
+    <JobPositionForm  ref="jobPositionForm" @refreshDataList="refreshList"></JobPositionForm>
+  </div>
+</template>
+
+<script>
+  import JobPositionForm from './JobPositionForm'
+  import JobPositionService from '@/api/position/JobPositionService'
+  export default {
+    props: {
+      index: {
+        type: String,
+        default: ''
+      },
+      i: {
+        type: String,
+        default: ''
+      }
+    },
+    data () {
+      return {
+        switchBlock: true,
+        searchForm: {
+        },
+        dataList: [],
+        tablePage: {
+          total: 0,
+          currentPage: 1,
+          pageSize: 10,
+          orders: []
+        },
+        loading: false
+      }
+    },
+    jobPositionService: null,
+    created () {
+      this.jobPositionService = new JobPositionService()
+    },
+    watch: {
+      index (index) {
+        if (index === this.i) {
+          this.refreshList()
+        }
+      }
+    },
+    components: {
+      JobPositionForm
+    },
+    activated () {
+      this.refreshList()
+    },
+
+    methods: {
+      // 新增
+      add () {
+        this.$refs.jobPositionForm.init('add', '')
+      },
+      // 修改
+      edit (id) {
+        id = id || this.$refs.jobPositionTable.getCheckboxRecords().map(item => {
+          return item.id
+        })[0]
+        this.$refs.jobPositionForm.init('edit', id)
+      },
+      // 查看
+      view (id) {
+        this.$refs.jobPositionForm.init('view', id)
+      },
+      change (id, useFlag) {
+        let ids = id || this.$refs.jobPositionTable.getCheckboxRecords().map(item => {
+          return item.id
+        }).join(',')
+        this.$confirm(`确定改变所选数据的状态吗?`, '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+          this.loading = true
+          this.jobPositionService.changeUseFlag(ids, useFlag).then(({data}) => {
+            this.$message.success(data)
+            this.refreshList()
+            this.loading = false
+          })
+        })
+      },
+      // 获取数据列表
+      refreshList () {
+        this.loading = true
+        this.jobPositionService.list({
+          'current': this.tablePage.currentPage,
+          'size': this.tablePage.pageSize,
+          'orders': this.tablePage.orders,
+          ...this.searchForm
+        }).then(({data}) => {
+          this.dataList = data.records
+          this.tablePage.total = data.total
+          this.loading = false
+        })
+      },
+      // 当前页
+      currentChangeHandle ({ currentPage, pageSize }) {
+        this.tablePage.currentPage = currentPage
+        this.tablePage.pageSize = pageSize
+        this.refreshList()
+      },
+      // 排序
+      sortChangeHandle (column) {
+        this.tablePage.orders = []
+        if (column.order != null) {
+          this.tablePage.orders.push({column: this.$utils.toLine(column.property), asc: column.order === 'asc'})
+        }
+        this.refreshList()
+      },
+      // 删除
+      del (id) {
+        let ids = id || this.$refs.jobPositionTable.getCheckboxRecords().map(item => {
+          return item.id
+        }).join(',')
+        this.$confirm(`确定删除所选项吗?`, '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+          this.loading = true
+          this.jobPositionService.delete(ids).then(({data}) => {
+            this.$message.success(data)
+            this.refreshList()
+            this.loading = false
+          })
+        })
+      },
+      resetSearch () {
+        this.$refs.searchForm.resetFields()
+        this.refreshList()
+      },
+      switchChange () {
+        if (this.switchBlock === false) {
+          this.searchForm.useFlag = '1'
+        } else {
+          this.searchForm.useFlag = ''
+        }
+        this.refreshList()
+      },
+      // 下载模板
+      downloadTpl () {
+        // this.$utils.downloadExcel('/sys/project/import/template')
+        this.loading = true
+        this.jobPositionService.exportTemplate().then((res) => {
+          // 将二进制流文件写入excel表,以下为重要步骤
+          this.$utils.downloadExcel(res.data, '职位导入模板')
+          this.loading = false
+        }).catch(function (err) {
+          this.loading = false
+          if (err.response) {
+            console.log(err.response)
+          }
+        })
+      },
+      importMethod ({ file }) {
+        // 处理表单
+        const formBody = new FormData()
+        formBody.append('file', file)
+        this.loading = true
+        this.jobPositionService.importExcel(formBody).then(result => {
+          this.$message.success(result.data)
+          this.refreshList()
+          this.loading = false
+        }).catch(() => {
+          this.refreshList()
+          this.loading = false
+        })
+      },
+      // 自定义服务端导出
+      exportMethod ({ options }) {
+        // 传给服务端的参数
+        const params = {
+          'current': this.tablePage.currentPage,
+          'size': this.tablePage.pageSize,
+          'orders': this.tablePage.orders,
+          ...this.searchForm,
+          filename: options.filename,
+          sheetName: options.sheetName,
+          isHeader: options.isHeader,
+          original: options.original,
+          mode: options.mode,
+          selectIds: options.mode === 'selected' ? options.data.map(item => item.id) : [],
+          exportFields: options.columns.map(column => column.property)
+        }
+        return this.jobPositionService.exportExcel(params).then((res) => {
+          // 将二进制流文件写入excel表,以下为重要步骤
+          this.$utils.downloadExcel(res.data, options.filename)
+        }).catch(function (err) {
+          if (err.response) {
+            console.log(err.response)
+          }
+        })
+      }
+    }
+  }
+</script>

+ 101 - 0
src/views/modules/position/tabs/PositionCategoryForm.vue

@@ -0,0 +1,101 @@
+<template>
+  <div>
+    <el-dialog
+      :title="title"
+      :close-on-click-modal="false"
+      v-dialogDrag
+      width="500px"
+      @close="close"
+      @keyup.enter.native="doSubmit"
+      :visible.sync="visible">
+      <el-form size="middle" :model="inputForm" ref="inputForm" v-loading="loading" :class="method==='view'?'readonly':''"  :disabled="method==='view'"
+               label-width="100px" @submit.native.prevent>
+        <el-row  :gutter="15">
+          <el-col :span="21">
+            <el-form-item label="职务分类" prop="name"
+                          :rules="[
+                 ]">
+              <el-input v-model="inputForm.name" placeholder="请填写职务分类"     ></el-input>
+            </el-form-item>
+          </el-col>
+
+
+        </el-row>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+      <el-button size="small" @click="close()" icon="el-icon-circle-close">关闭</el-button>
+      <el-button size="small" type="primary" v-if="method != 'view'" @click="doSubmit()" icon="el-icon-circle-check" v-noMoreClick>确定</el-button>
+    </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+  import PositionCategoryService from '@/api/position/PositionCategoryService'
+  export default {
+    data () {
+      return {
+        title: '',
+        method: '',
+        visible: false,
+        loading: false,
+        inputForm: {
+          name: ''
+        }
+      }
+    },
+    positionCategoryService: null,
+    created () {
+      this.positionCategoryService = new PositionCategoryService()
+    },
+    methods: {
+      init (method, id) {
+        this.method = method
+        this.inputForm = {
+          name: ''
+        }
+        this.inputForm.id = id
+        if (method === 'add') {
+          this.title = `新建职务分类`
+        } else if (method === 'edit') {
+          this.title = '修改职务分类'
+        } else if (method === 'view') {
+          this.title = '查看职务分类'
+        }
+        this.visible = true
+        this.loading = false
+        this.$nextTick(() => {
+          this.$refs.inputForm.resetFields()
+          if (method === 'edit' || method === 'view') { // 修改或者查看
+            this.loading = true
+            this.positionCategoryService.queryById(this.inputForm.id).then(({data}) => {
+              this.inputForm = this.recover(this.inputForm, data)
+              this.inputForm = JSON.parse(JSON.stringify(this.inputForm))
+              this.loading = false
+            })
+          }
+        })
+      },
+      // 表单提交
+      doSubmit () {
+        this.$refs['inputForm'].validate((valid) => {
+          if (valid) {
+            this.loading = true
+            this.positionCategoryService.save(this.inputForm).then(({data}) => {
+              this.close()
+              this.$message.success(data)
+              this.$emit('refreshDataList')
+              this.loading = false
+            }).catch(() => {
+              this.loading = false
+            })
+          }
+        })
+      },
+      close () {
+        this.$refs.inputForm.resetFields()
+        this.visible = false
+      }
+    }
+  }
+</script>

+ 177 - 0
src/views/modules/position/tabs/PositionCategoryList.vue

@@ -0,0 +1,177 @@
+<template>
+  <div class="page">
+    <el-form size="small" :inline="true" class="query-form" ref="searchForm" :model="searchForm" @keyup.enter.native="refreshList()" @submit.native.prevent>
+      <!-- 搜索框-->
+      <el-form-item prop="name">
+        <el-input size="small" v-model="searchForm.name" placeholder="职务分类名称" clearable></el-input>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" @click="refreshList()" size="small" icon="el-icon-search">查询</el-button>
+        <el-button @click="resetSearch()" size="small" icon="el-icon-refresh-right">重置</el-button>
+      </el-form-item>
+    </el-form>
+    <div class="bg-white top" style="">
+      <vxe-toolbar :refresh="{query: refreshList}" custom>
+        <template #buttons>
+          <el-button v-if="hasPermission('job:position_category:add')" type="primary" size="small" icon="el-icon-plus" @click="add()">新建</el-button>
+          <el-button v-if="hasPermission('job:position_category:del')" type="danger"   size="small" icon="el-icon-delete" @click="del()" :disabled="$refs.positionCategoryTable && $refs.positionCategoryTable.getCheckboxRecords().length === 0" plain>删除</el-button>
+        </template>
+      </vxe-toolbar>
+      <div style="height: calc(100% - 80px)">
+        <vxe-table
+          border="inner"
+          auto-resize
+          resizable
+          height="auto"
+          :loading="loading"
+          size="small"
+          ref="positionCategoryTable"
+          show-header-overflow
+          show-overflow
+          highlight-hover-row
+          :menu-config="{}"
+          @sort-change="sortChangeHandle"
+          :sort-config="{remote:true}"
+          :data="dataList"
+          :checkbox-config="{}">
+          <vxe-column type="seq" width="40"></vxe-column>
+          <vxe-column type="checkbox" width="40" ></vxe-column>
+          <vxe-column title="职务分类名称" field="name"></vxe-column>
+          <vxe-column title="操作" width="200px" fixed="right" align="center">
+            <template  slot-scope="scope">
+              <el-button v-if="hasPermission('job:position_category:edit')" type="text" icon="el-icon-edit" size="small" @click="edit(scope.row.id)">修改</el-button>
+              <el-button v-if="hasPermission('job:position_category:del')" type="text"  icon="el-icon-delete" size="small" @click="del(scope.row.id)">删除</el-button>
+            </template>
+          </vxe-column>
+        </vxe-table>
+        <vxe-pager
+          background
+          size="small"
+          :current-page="tablePage.currentPage"
+          :page-size="tablePage.pageSize"
+          :total="tablePage.total"
+          :page-sizes="[10, 20, 100, 1000, {label: '全量数据', value: 1000000}]"
+          :layouts="['PrevPage', 'JumpNumber', 'NextPage', 'FullJump', 'Sizes', 'Total']"
+          @page-change="currentChangeHandle">
+        </vxe-pager>
+      </div>
+    </div>
+    <PositionCategoryForm  ref="positionCategoryForm" @refreshDataList="refreshList"></PositionCategoryForm>
+  </div>
+</template>
+
+<script>
+  import PositionCategoryForm from './PositionCategoryForm'
+  import PositionCategoryService from '@/api/position/PositionCategoryService'
+  export default {
+    props: {
+      index: {
+        type: String,
+        default: ''
+      },
+      i: {
+        type: String,
+        default: ''
+      }
+    },
+    data () {
+      return {
+        searchForm: {
+        },
+        dataList: [],
+        tablePage: {
+          total: 0,
+          currentPage: 1,
+          pageSize: 10,
+          orders: []
+        },
+        loading: false
+      }
+    },
+    positionCategoryService: null,
+    created () {
+      this.positionCategoryService = new PositionCategoryService()
+    },
+    watch: {
+      index (index) {
+        if (index === this.i) {
+          this.refreshList()
+        }
+      }
+    },
+    components: {
+      PositionCategoryForm
+    },
+    activated () {
+      this.refreshList()
+    },
+
+    methods: {
+      // 新增
+      add () {
+        this.$refs.positionCategoryForm.init('add', '')
+      },
+      // 修改
+      edit (id) {
+        id = id || this.$refs.positionCategoryTable.getCheckboxRecords().map(item => {
+          return item.id
+        })[0]
+        this.$refs.positionCategoryForm.init('edit', id)
+      },
+      // 查看
+      view (id) {
+        this.$refs.positionCategoryForm.init('view', id)
+      },
+      // 获取数据列表
+      refreshList () {
+        this.loading = true
+        this.positionCategoryService.list({
+          'current': this.tablePage.currentPage,
+          'size': this.tablePage.pageSize,
+          'orders': this.tablePage.orders,
+          ...this.searchForm
+        }).then(({data}) => {
+          this.dataList = data.records
+          this.tablePage.total = data.total
+          this.loading = false
+        })
+      },
+      // 当前页
+      currentChangeHandle ({ currentPage, pageSize }) {
+        this.tablePage.currentPage = currentPage
+        this.tablePage.pageSize = pageSize
+        this.refreshList()
+      },
+      // 排序
+      sortChangeHandle (column) {
+        this.tablePage.orders = []
+        if (column.order != null) {
+          this.tablePage.orders.push({column: this.$utils.toLine(column.property), asc: column.order === 'asc'})
+        }
+        this.refreshList()
+      },
+      // 删除
+      del (id) {
+        let ids = id || this.$refs.positionCategoryTable.getCheckboxRecords().map(item => {
+          return item.id
+        }).join(',')
+        this.$confirm(`确定删除所选项吗?`, '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+          this.loading = true
+          this.positionCategoryService.delete(ids).then(({data}) => {
+            this.$message.success(data)
+            this.refreshList()
+            this.loading = false
+          })
+        })
+      },
+      resetSearch () {
+        this.$refs.searchForm.resetFields()
+        this.refreshList()
+      }
+    }
+  }
+</script>

+ 127 - 0
src/views/modules/position/tabs/PositionForm.vue

@@ -0,0 +1,127 @@
+<template>
+  <div>
+    <el-dialog
+      :title="title"
+      :close-on-click-modal="false"
+      v-dialogDrag
+      width="500px"
+      @close="close"
+      @keyup.enter.native="doSubmit"
+      :visible.sync="visible">
+      <el-form size="middle" :model="inputForm" ref="inputForm" v-loading="loading" :class="method==='view'?'readonly':''"  :disabled="method==='view'"
+               label-width="100px" @submit.native.prevent>
+        <el-row  :gutter="15">
+          <el-col :span="21">
+            <el-form-item label="职务" prop="name"
+                          :rules="[
+                          {required: true, message:'职务不能为空', trigger:'blur'}
+                 ]">
+              <el-input v-model="inputForm.name" placeholder="请填写职务"     ></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="21">
+            <el-form-item label="职务分类" prop="categoryId">
+              <el-select v-model="inputForm.categoryId" placeholder="请选择"  style="width: 100%;">
+                <el-option
+                  v-for="item in this.categoryList"
+                  :key="item.id"
+                  :label="item.name"
+                  :value="item.id">
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="21">
+            <el-form-item label="描述" prop="description"
+                          :rules="[
+                 ]">
+              <el-input type="textarea" maxlength="200" v-model="inputForm.description" placeholder="请填写描述"  show-word-limit   ></el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+      <el-button size="small" @click="close()" icon="el-icon-circle-close">关闭</el-button>
+      <el-button size="small" type="primary" v-if="method != 'view'" @click="doSubmit()" icon="el-icon-circle-check" v-noMoreClick>确定</el-button>
+    </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+  import PositionService from '@/api/position/PositionService'
+  export default {
+    data () {
+      return {
+        title: '',
+        method: '',
+        visible: false,
+        loading: false,
+        inputForm: {
+          name: '',
+          categoryId: '',
+          description: ''
+        },
+        categoryList: []
+      }
+    },
+    positionService: null,
+    created () {
+      this.positionService = new PositionService()
+    },
+    methods: {
+      init (method, id) {
+        this.method = method
+        this.inputForm = {
+          name: '',
+          categoryId: '',
+          description: ''
+        }
+        this.inputForm.id = id
+        this.positionService.queryAllCategory().then(({data}) => {
+          this.categoryList = data
+        })
+        if (method === 'add') {
+          this.title = `新建职务`
+        } else if (method === 'edit') {
+          this.title = '修改职务'
+        } else if (method === 'view') {
+          this.title = '查看职务'
+        }
+        this.visible = true
+        this.loading = false
+        this.$nextTick(() => {
+          this.$refs.inputForm.resetFields()
+          if (method === 'edit' || method === 'view') { // 修改或者查看
+            this.loading = true
+            this.positionService.queryById(this.inputForm.id).then(({data}) => {
+              this.inputForm = this.recover(this.inputForm, data)
+              this.inputForm = JSON.parse(JSON.stringify(this.inputForm))
+              this.loading = false
+            })
+          }
+        })
+      },
+      // 表单提交
+      doSubmit () {
+        this.$refs['inputForm'].validate((valid) => {
+          if (valid) {
+            this.loading = true
+            this.positionService.save(this.inputForm).then(({data}) => {
+              this.close()
+              this.$message.success(data)
+              this.$emit('refreshDataList')
+              this.loading = false
+            }).catch(() => {
+              this.loading = false
+            })
+          }
+        })
+      },
+      close () {
+        this.$refs.inputForm.resetFields()
+        this.visible = false
+      }
+    }
+  }
+</script>

+ 178 - 0
src/views/modules/position/tabs/PositionList.vue

@@ -0,0 +1,178 @@
+<template>
+  <div class="page">
+    <el-form size="small" :inline="true" class="query-form" ref="searchForm" :model="searchForm" @keyup.enter.native="refreshList()" @submit.native.prevent>
+      <!-- 搜索框-->
+      <el-form-item prop="name">
+        <el-input size="small" v-model="searchForm.name" placeholder="职务名称" clearable></el-input>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" @click="refreshList()" size="small" icon="el-icon-search">查询</el-button>
+        <el-button @click="resetSearch()" size="small" icon="el-icon-refresh-right">重置</el-button>
+      </el-form-item>
+    </el-form>
+    <div class="bg-white top" style="">
+      <vxe-toolbar :refresh="{query: refreshList}" custom>
+        <template #buttons>
+          <el-button v-if="hasPermission('job:position:add')" type="primary" size="small" icon="el-icon-plus" @click="add()">新建</el-button>
+          <el-button v-if="hasPermission('job:position:del')" type="danger"   size="small" icon="el-icon-delete" @click="del()" :disabled="$refs.positionTable && $refs.positionTable.getCheckboxRecords().length === 0" plain>删除</el-button>
+        </template>
+      </vxe-toolbar>
+      <div style="height: calc(100% - 80px)">
+        <vxe-table
+          border="inner"
+          auto-resize
+          resizable
+          height="auto"
+          :loading="loading"
+          size="small"
+          ref="positionTable"
+          show-header-overflow
+          show-overflow
+          highlight-hover-row
+          :menu-config="{}"
+          @sort-change="sortChangeHandle"
+          :sort-config="{remote:true}"
+          :data="dataList"
+          :checkbox-config="{}">
+          <vxe-column type="seq" width="40"></vxe-column>
+          <vxe-column type="checkbox" width="40" ></vxe-column>
+          <vxe-column width="180" title="职务名称" field="name"></vxe-column>
+          <vxe-column width="180" title="职务分类" field="categoryId"></vxe-column>
+          <vxe-column title="描述" field="description"></vxe-column>
+          <vxe-column title="操作" width="200px" fixed="right" align="center">
+            <template  slot-scope="scope">
+              <el-button v-if="hasPermission('job:position:edit')" type="text" icon="el-icon-edit" size="small" @click="edit(scope.row.id)">修改</el-button>
+              <el-button v-if="hasPermission('job:position:del')" type="text"  icon="el-icon-delete" size="small" @click="del(scope.row.id)">删除</el-button>
+            </template>
+          </vxe-column>
+        </vxe-table>
+        <vxe-pager
+          background
+          size="small"
+          :current-page="tablePage.currentPage"
+          :page-size="tablePage.pageSize"
+          :total="tablePage.total"
+          :page-sizes="[10, 20, 100, 1000, {label: '全量数据', value: 1000000}]"
+          :layouts="['PrevPage', 'JumpNumber', 'NextPage', 'FullJump', 'Sizes', 'Total']"
+          @page-change="currentChangeHandle">
+        </vxe-pager>
+      </div>
+    </div>
+    <PositionForm  ref="positionForm" @refreshDataList="refreshList"></PositionForm>
+  </div>
+</template>
+
+<script>
+  import PositionForm from './PositionForm'
+  import PositionService from '@/api/position/PositionService'
+  export default {
+    props: {
+      index: {
+        type: String,
+        default: ''
+      },
+      i: {
+        type: String,
+        default: ''
+      }
+    },
+    data () {
+      return {
+        searchForm: {
+        },
+        dataList: [],
+        tablePage: {
+          total: 0,
+          currentPage: 1,
+          pageSize: 10,
+          orders: []
+        },
+        loading: false
+      }
+    },
+    positionService: null,
+    created () {
+      this.positionService = new PositionService()
+    },
+    components: {
+      PositionForm
+    },
+    activated () {
+      this.refreshList()
+    },
+    watch: {
+      index (index) {
+        if (index === this.i) {
+          this.refreshList()
+        }
+      }
+    },
+    methods: {
+      // 新增
+      add () {
+        this.$refs.positionForm.init('add', '')
+      },
+      // 修改
+      edit (id) {
+        id = id || this.$refs.positionTable.getCheckboxRecords().map(item => {
+          return item.id
+        })[0]
+        this.$refs.positionForm.init('edit', id)
+      },
+      // 查看
+      view (id) {
+        this.$refs.positionForm.init('view', id)
+      },
+      // 获取数据列表
+      refreshList () {
+        this.loading = true
+        this.positionService.list({
+          'current': this.tablePage.currentPage,
+          'size': this.tablePage.pageSize,
+          'orders': this.tablePage.orders,
+          ...this.searchForm
+        }).then(({data}) => {
+          this.dataList = data.records
+          this.tablePage.total = data.total
+          this.loading = false
+        })
+      },
+      // 当前页
+      currentChangeHandle ({ currentPage, pageSize }) {
+        this.tablePage.currentPage = currentPage
+        this.tablePage.pageSize = pageSize
+        this.refreshList()
+      },
+      // 排序
+      sortChangeHandle (column) {
+        this.tablePage.orders = []
+        if (column.order != null) {
+          this.tablePage.orders.push({column: this.$utils.toLine(column.property), asc: column.order === 'asc'})
+        }
+        this.refreshList()
+      },
+      // 删除
+      del (id) {
+        let ids = id || this.$refs.positionTable.getCheckboxRecords().map(item => {
+          return item.id
+        }).join(',')
+        this.$confirm(`确定删除所选项吗?`, '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+          this.loading = true
+          this.positionService.delete(ids).then(({data}) => {
+            this.$message.success(data)
+            this.refreshList()
+            this.loading = false
+          })
+        })
+      },
+      resetSearch () {
+        this.$refs.searchForm.resetFields()
+        this.refreshList()
+      }
+    }
+  }
+</script>