Browse Source

人员管理

jz.kai 4 years ago
parent
commit
235f7be873

+ 1 - 1
package.json

@@ -12,7 +12,7 @@
     "axios": "^0.19.0",
     "core-js": "^3.6.5",
     "echarts": "^4.5.0",
-    "element-ui": "^2.4.5",
+    "element-ui": "^2.15.1",
     "hls.js": "^0.14.15",
     "js-cookie": "^2.2.1",
     "nprogress": "0.2.0",

+ 1 - 1
public/index.html

@@ -6,7 +6,7 @@
     <meta name="viewport" content="width=device-width,initial-scale=1.0">
     <link rel="icon" href="<%= BASE_URL %>favicon.ico">
     <script type="text/javascript" src="./static/tinymce/tinymce.min.js"></script>
-    <title>荆州市企业联合会</title>
+    <title>荆州市政府督查办公平台</title>
   </head>
   <body>
     <noscript>

+ 54 - 0
src/api/base/incident.js

@@ -0,0 +1,54 @@
+import request from '@/utils/request'
+import constant from '@/constant'
+
+function pageList(formData){
+  return request.post(constant.serverUrl + "/base/incident/pageList", formData);
+}
+
+function create(){
+  return request.get(constant.serverUrl + "/base/incident/create");
+}
+
+function edit(id){
+  return request.get(constant.serverUrl + "/base/incident/edit/" + id);
+}
+
+function add(formModel){
+  return request.post(constant.serverUrl + "/base/incident/add", formModel,{
+    headers: {
+      "Content-Type": "application/json"
+    }
+  });
+}
+
+function update(formModel){  
+  return request.post(constant.serverUrl + "/base/incident/update", formModel,{
+    headers: {
+      "Content-Type": "application/json"
+    }
+  });
+}
+
+function remove(id){
+  return request.post(constant.serverUrl + "/base/incident/delete/" + id);
+}
+
+function batchRemove(idList){
+  return request.post(constant.serverUrl + "/base/incident/batchDelete",idList,{
+    headers: {
+      "Content-Type": "application/json"
+    }
+  });
+}
+
+function nextStep(formModel){  
+  return request.post(constant.serverUrl + "/base/incident/nextStep", formModel,{
+    headers: {
+      "Content-Type": "application/json"
+    }
+  });
+}
+
+export default {
+  pageList,create,edit,add,update,remove,batchRemove,nextStep
+}

+ 50 - 0
src/api/base/organization.js

@@ -0,0 +1,50 @@
+import request from '@/utils/request'
+import constant from '@/constant'
+
+function pageList(formData){
+  return request.post(constant.serverUrl + "/base/organization/pageList", formData);
+}
+
+function create(){
+  return request.get(constant.serverUrl + "/base/organization/create");
+}
+
+function edit(id){
+  return request.get(constant.serverUrl + "/base/organization/edit/" + id);
+}
+
+function add(formModel){
+  return request.post(constant.serverUrl + "/base/organization/add", formModel,{
+    headers: {
+      "Content-Type": "application/json"
+    }
+  });
+}
+
+function update(formModel){  
+  return request.post(constant.serverUrl + "/base/organization/update", formModel,{
+    headers: {
+      "Content-Type": "application/json"
+    }
+  });
+}
+
+function remove(id){
+  return request.post(constant.serverUrl + "/base/organization/delete/" + id);
+}
+
+function batchRemove(idList){
+  return request.post(constant.serverUrl + "/base/organization/batchDelete",idList,{
+    headers: {
+      "Content-Type": "application/json"
+    }
+  });
+}
+
+function query(formData){
+  return request.post(constant.serverUrl + "/base/organization/query", formData);
+}
+
+export default {
+  pageList,create,edit,add,update,remove,batchRemove,query
+}

+ 46 - 0
src/api/base/person.js

@@ -0,0 +1,46 @@
+import request from '@/utils/request'
+import constant from '@/constant'
+
+function pageList(formData){
+  return request.post(constant.serverUrl + "/base/person/pageList", formData);
+}
+
+function create(){
+  return request.get(constant.serverUrl + "/base/person/create");
+}
+
+function edit(id){
+  return request.get(constant.serverUrl + "/base/person/edit/" + id);
+}
+
+function add(formModel){
+  return request.post(constant.serverUrl + "/base/person/add", formModel,{
+    headers: {
+      "Content-Type": "application/json"
+    }
+  });
+}
+
+function update(formModel){  
+  return request.post(constant.serverUrl + "/base/person/update", formModel,{
+    headers: {
+      "Content-Type": "application/json"
+    }
+  });
+}
+
+function remove(id){
+  return request.post(constant.serverUrl + "/base/person/delete/" + id);
+}
+
+function batchRemove(idList){
+  return request.post(constant.serverUrl + "/base/person/batchDelete",idList,{
+    headers: {
+      "Content-Type": "application/json"
+    }
+  });
+}
+
+export default {
+  pageList,create,edit,add,update,remove,batchRemove
+}

+ 27 - 1
src/routers/modules/base.js

@@ -1,5 +1,31 @@
 var routers = [
-        
+    {
+        path: '/base/organization/list',
+        name: 'BaseOrganizationList',
+        component: () => import('@/views/base/organization-list.vue'),
+        meta: {
+                roles: ["admin"],
+                title: '组织机构管理'
+        }
+    },
+    {
+        path: '/base/incident/list',
+        name: 'BaseIncidentList',
+        component: () => import('@/views/base/incident-list.vue'),
+        meta: {
+                roles: ["admin"],
+                title: '督查督办管理'
+        }
+    },
+    {
+        path: '/base/person/list',
+        name: 'BasePersonList',
+        component: () => import('@/views/base/person-list.vue'),
+        meta: {
+                roles: ["admin"],
+                title: '人员管理'
+        }
+    },
 ]
 
 export default routers;

+ 456 - 0
src/views/base/incident-detail.vue

@@ -0,0 +1,456 @@
+
+<style scoped>
+.user-panel {
+  margin: 10px auto;
+}
+</style>
+<template>
+  <el-dialog
+    :visible.sync="showDialog"
+    :title="title"
+    :modal-append-to-body="false"
+    style="text-align: left"
+    @close="closeDialog"
+    :close-on-click-modal="false"
+  >
+    <div class="user-panel" v-loading="loading">
+      <el-form
+        ref="form"
+        :model="formModel"
+        :rules="ruleValidate"
+        :label-width="'100px'"
+      >
+        <el-form-item label="督办类型" prop="caseType">
+          <el-select
+            v-model="formModel.caseType"
+            filterable
+            placeholder="请选择"
+            style="width: 300px"
+          >
+            <el-option
+              v-for="caseType in caseTypeResult"
+              :key="caseType.value"
+              :label="caseType.name"
+              :value="caseType.value"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-row v-if="ldps">
+          <el-col :span="12">
+            <el-form-item label="领导批示类型" prop="instructionsType">
+              <el-select
+                v-model="formModel.instructionsType"
+                filterable
+                placeholder="请选择"
+                style="width: 300px"
+              >
+                <el-option
+                  v-for="instructionsType in instructionsTypeResult"
+                  :key="instructionsType.value"
+                  :label="instructionsType.name"
+                  :value="instructionsType.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="批示时间" prop="instructionsTime">
+              <el-date-picker
+                v-model="formModel.instructionsTime"
+                value-format="yyyy-MM-dd"
+                type="date"
+                style="width: 300px"
+                placeholder="请选择批示时间"
+              >
+              </el-date-picker>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="领导批示" prop="instructions">
+              <el-input
+                v-model="formModel.instructions"
+                placeholder="请输入领导批示"
+                style="width: 95%"
+              ></el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-form-item label="标题" prop="title">
+          <el-input
+            v-model="formModel.title"
+            placeholder="请输入标题"
+            style="width: 95%"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="内容" prop="content">
+          <mce-editor
+            ref="editor"
+            uploadName="upfile"
+            v-model="formModel.content"
+            :url="uploadUrl"
+            :config="editorConfig"
+          ></mce-editor>
+        </el-form-item>
+        <el-form-item label="附件" prop="attList">
+          <el-upload
+            class="avatar-uploader"
+            name="photoFile"
+            :action="uploadImgUrl"
+            :headers="headers"
+            :data="uploadData"
+            :on-success="fileHandleAvatarSuccess"
+            :before-upload="fileBeforeAvatarUpload"
+            :before-remove="fileHandleRemove"
+            :on-preview="fileHandleDownload"
+            :file-list="formModel.attList"
+            :auto-upload="true"
+            accept="application/msword,application/vnd.ms-excel,application/vnd.ms-powerpoint,application/pdf"
+            >
+            <el-button size="small" type="primary">点击上传</el-button>
+          </el-upload>
+        </el-form-item>
+        <el-form-item label="图片" prop="picList">
+          <el-upload
+            class="avatar-uploader"
+            name="photoFile"
+            :action="uploadImgUrl"
+            :headers="headers"
+            :data="uploadData"
+            :on-success="picHandleAvatarSuccess"
+            :before-upload="picBeforeAvatarUpload"
+            :file-list="formModel.picList"
+            :auto-upload="true"
+            accept="image/png,image/jpeg"
+            list-type="picture-card"
+            >
+              <i slot="default" class="el-icon-plus"></i>
+              <div slot="file" slot-scope="{file}">
+                <img
+                  class="el-upload-list__item-thumbnail"
+                  :src="file.url" alt=""
+                >
+                <span class="el-upload-list__item-actions">
+                  <span
+                    class="el-upload-list__item-preview"
+                    @click="picHandlePictureCardPreview(file)"
+                  >
+                    <i class="el-icon-zoom-in"></i>
+                  </span>
+                  <span
+                    v-if="!picDisabled"
+                    class="el-upload-list__item-delete"
+                    @click="picHandleRemove(file)"
+                  >
+                    <i class="el-icon-delete"></i>
+                  </span>
+                </span>
+              </div>
+          </el-upload>
+          <el-dialog :visible.sync="picDialogVisible"
+                      title="查看图片"
+                      :modal-append-to-body="false"
+                      :append-to-body="true"
+          >
+            <img width="100%" :src="picDialogImageUrl" alt="">
+          </el-dialog>
+        </el-form-item>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="责任单位" prop="stepOrgId">
+              <el-select-tree
+                :props="props"
+                :options="queryOrgResult"
+                v-model="formModel.stepOrgId"
+                style="width:300px;"
+                size="mediumn"
+                height="200"
+              ></el-select-tree>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="提醒时间" prop="stepWarnTime">
+              <el-date-picker
+                v-model="formModel.stepWarnTime"
+                value-format="yyyy-MM-dd"
+                type="date"
+                style="width: 300px"
+                placeholder="请选择提醒时间"
+              >
+              </el-date-picker>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <!-------------->
+      </el-form>
+    </div>
+    <span slot="footer" class="dialog-footer">
+      <el-button @click="closeDialog">取 消</el-button>
+      <el-button type="primary" @click="handleSubmit" :loading="submitting">确 定</el-button>
+    </span>
+  </el-dialog>
+</template>
+<script>
+import Constant from "@/constant";
+import incidentApi from "@/api/base/incident";
+import dataDictionaryApi from "@/api/sys/dataDictionary";
+import organizationApi from "@/api/base/organization";
+import SelectTree from "@/components/SelectTree";
+import MceEditor from "@/components/Tinymce";
+import { getToken } from "@/utils/auth";
+
+export default {
+  props: ["businessKey", "title"],
+  components: {
+    "mce-editor": MceEditor,
+    "el-select-tree": SelectTree
+  },
+  data() {
+    return {
+      formModel: {},
+      ruleValidate: {
+        title: [{ required: true, message: "标题不能为空", trigger: "blur" }],
+        content: [{ required: true, message: "内容不能为空", trigger: "blur" }],
+        caseType: [
+          { required: true, message: "督办类型不能为空", trigger: "blur" },
+        ],
+        stepOrgId: [{ required: true, message: "责任单位不能为空", trigger: "blur" }],
+        stepWarnTime: [{ required: true, message: "提醒时间不能为空", trigger: "blur" }],
+      },
+      showDialog: true,
+      loading: false,
+      submitting: false,
+      caseTypeResult: [],
+      instructionsTypeResult: [],
+      ldps: false,
+      editorConfig: {
+        height: 200,
+        width: "95%",
+      },
+      uploadUrl: Constant.serverUrl + "/tinymce/upload?token=" + getToken(),
+      //上传图片start
+      uploadImgUrl: Constant.serverUrl + "/uploadPicture",
+      uploadData: {
+        subFolder: "supervision",
+      },
+      headers: {
+        Authorization: getToken(),
+      },
+      picDialogImageUrl: '',
+      picDialogVisible: false,
+      picDisabled: false,
+      //上传图片end
+      queryOrgResult: [],
+      props: {
+        // 配置项(必选)
+        value: "id",
+        label: "name"
+      }
+    };
+  },
+  created() {
+    var self = this;
+
+    dataDictionaryApi
+      .findByCatalogName({
+        catalogName: "督办类型",
+      })
+      .then((response) => {
+        var jsonData = response.data;
+        this.caseTypeResult = jsonData.data;
+      });
+
+    dataDictionaryApi
+      .findByCatalogName({
+        catalogName: "领导批示类型",
+      })
+      .then((response) => {
+        var jsonData = response.data;
+        this.instructionsTypeResult = jsonData.data;
+      });
+  },
+  methods: {
+    picHandleRemove(file) {
+      var self = this;
+      self.$confirm("是否确认删除?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+      .then(() => {
+        var index = self.formModel.picList.findIndex(item => {
+          if ( item.url == file.url) {
+            return true;
+          }
+        })
+        self.formModel.picList.splice(index,1);
+      });
+    },
+    picHandlePictureCardPreview(file) {
+      this.picDialogImageUrl = file.url;
+      this.picDialogVisible = true;
+    },
+    picHandleAvatarSuccess(res, file) {
+      this.loading = false;
+      var self = this;
+      
+      var attachmentDTO = {
+        name: res.data.fileName,
+        url: res.data.fileUrl,
+      }
+      self.formModel.picList.push(attachmentDTO);
+    },
+    picBeforeAvatarUpload(file) {
+      this.loading = true;
+      const isLt2M = file.size / 1024 / 1024 < 2;
+
+      if (!isLt2M) {
+        this.$message.error("上传图片大小不能超过 2MB!");
+        this.loading = false;
+      }
+      return isLt2M;
+    },
+    fileHandleDownload(file){
+      return false;
+    },
+    fileHandleRemove(file) {
+      var self = this;
+      self.$confirm("是否确认删除?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+      .then(() => {
+        var index = self.formModel.attList.findIndex(item => {
+          if ( item.url == file.url) {
+            return true;
+          }
+        })
+        self.formModel.attList.splice(index,1);
+      })
+      .catch(() => {
+      });
+      return false;
+    },
+    fileHandleAvatarSuccess(res, file) {
+      this.loading = false;
+      var self = this;
+
+      var attachmentDTO = {
+        name: res.data.fileName,
+        url: res.data.fileUrl,
+      }
+      self.formModel.attList.push(attachmentDTO);
+    },
+    fileBeforeAvatarUpload(file) {
+      this.loading = true;
+      const isLt2M = file.size / 1024 / 1024 < 4;
+
+      if (!isLt2M) {
+        this.$message.error("上传附件大小不能超过 4MB!");
+        this.loading = false;
+      }
+      return isLt2M;
+    },
+    closeDialog() {
+      this.$emit("close", false);
+    },
+    handleReset(name) {
+      this.queryMenu();
+    },
+    handleSubmit() {
+      var self = this;
+      self.loading = true;
+      this.$refs["form"].validate((valid) => {
+        if (valid) {
+          (function () {
+            var id = self.formModel.id;
+
+            self.formModel.content = self.$refs.editor.getContent();
+            if (id == null || id.length == 0) {
+              return incidentApi.add(self.formModel);
+            } else {
+              return incidentApi.update(self.formModel);
+            }
+          })().then(function (response) {
+            self.loading = false;
+            var jsonData = response.data;
+
+            if (jsonData.result) {
+              self.$message({
+                message: "保存成功!",
+                type: "success",
+              });
+
+              self.$emit("close", true);
+            } else {
+              self.$message({
+                message: jsonData.message + "",
+                type: "warning",
+              });
+
+              self.$emit("close", false);
+            }
+          });
+        }
+      });
+    },
+    queryMenu(keywords) {
+      var formData = new FormData();
+      formData.append("keywords",keywords);
+
+      return organizationApi.query(formData).then(response=>{
+        var jsonData = response.data;
+
+        if(jsonData.result){
+          this.queryOrgResult = jsonData.data;
+        }
+        else{
+          this.$message.error(jsonData.message + "");
+        }
+      });
+    },
+  },
+  mounted: function () {
+    this.queryMenu("");
+    var self = this;
+
+    (function () {
+      if (self.businessKey.length == 0) {
+        return incidentApi.create();
+      } else {
+        return incidentApi.edit(self.businessKey);
+      }
+    })()
+      .then((response) => {
+        var jsonData = response.data;
+        self.loading = false;
+
+        if (jsonData.result) {
+          self.formModel = jsonData.data;
+          if (self.formModel.content != null) {
+            self.$refs.editor.setContent(self.formModel.content);
+          }
+        } else {
+          self.$message.error(jsonData.message + "");
+        }
+      })
+      .catch((error) => {
+        self.$message.error(error + "");
+      });
+  },
+  watch: {
+    "formModel.caseType": function (newVal, oldVal) {
+      if (newVal != null) {
+        switch (newVal) {
+          case "1":
+            this.ldps = true;
+            break;
+          default:
+            this.ldps = false;
+            break;
+        }
+      }
+    },
+  },
+};
+</script>

+ 380 - 0
src/views/base/incident-doc.vue

@@ -0,0 +1,380 @@
+
+<style scoped>
+.user-panel {
+  margin: 10px auto;
+}
+.table-doc {
+  width: 100%;
+}
+.table-doc table {
+  border-right: 1px solid #bbb;
+  border-bottom: 1px solid #bbb;
+  padding: 0px;
+  width: 95%;
+}
+.table-doc table td {
+  border-left: 1px solid #bbb;
+  border-top: 1px solid #bbb;
+  padding: 5px;
+  height: 38px;
+  line-height: 25px;
+}
+.td-left-column {
+  text-align: center;
+  width: 11%;
+}
+.td-right-column {
+  text-align: center;
+}
+.td-left-column1 {
+  text-align: center;
+  width: 16%;
+}
+.td-right-column1 {
+  text-align: center;
+}
+.el-col a:link,
+a:visited,
+a:hover,
+a:active {
+  color: #606266;
+  text-decoration: none;
+}
+.title {
+  color: rgba(16, 16, 16, 100);
+  font-size: 16px;
+  text-align: left;
+  line-height: 50px;
+}
+</style>
+<template>
+  <el-dialog
+    :visible.sync="showDialog"
+    :title="title"
+    :modal-append-to-body="false"
+    style="text-align: left"
+    @close="closeDialog"
+    :close-on-click-modal="false"
+  >
+    <div class="user-panel" v-loading="loading">
+      <el-form
+        ref="form"
+        :model="formModel"
+        :rules="ruleValidate"
+        :label-width="'100px'"
+      >
+        <el-row class="title"> 督办信息 </el-row>
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="督办类型">
+              <b>{{ formModel.caseTypeName }}</b>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="登记时间">
+              <b>{{ formModel.createTime }}</b>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="提醒时间">
+              <b>{{ formModel.stepWarnTime }}</b>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row class="table-doc">
+          <table border="0" cellspacing="0" cellpadding="0" align="center">
+            <tr>
+              <td class="td-left-column">标题</td>
+              <td>
+                {{ formModel.title }}
+              </td>
+            </tr>
+            <tr>
+              <td class="td-left-column">交办单位</td>
+              <td>
+                {{ formModel.stepOrgName }}
+              </td>
+            </tr>
+            <tr>
+              <td class="td-left-column">正文</td>
+              <td v-html="formModel.content">
+                {{ formModel.content }}
+              </td>
+            </tr>
+            <tr>
+              <td class="td-left-column">相关附件</td>
+              <td>
+                <el-col
+                  v-for="attList in formModel.attList"
+                  :key="attList.url"
+                  class="el-col"
+                >
+                  <a target="_black" :href="attList.url">{{ attList.name }}</a>
+                </el-col>
+              </td>
+            </tr>
+            <tr>
+              <td class="td-left-column">相关图片</td>
+              <td class="td-right-column" align="center">
+                <el-col
+                  :span="4"
+                  v-for="picUrl in formModel.picUrlList"
+                  :key="picUrl"
+                >
+                  <el-card
+                    :body-style="{ padding: '5px' }"
+                    style="width: 110px; height: 110px"
+                  >
+                    <el-image
+                      :src="picUrl"
+                      style="width: 100px; height: 100px"
+                      :preview-src-list="formModel.picUrlList"
+                      fit="cover"
+                      :z-index="3000"
+                    ></el-image>
+                  </el-card>
+                </el-col>
+              </td>
+            </tr>
+            <tr v-if="formModel.instructions != null">
+              <td class="td-left-column">领导批示</td>
+              <td>
+                {{ formModel.instructionsName }}:{{ formModel.instructions }}
+              </td>
+            </tr>
+            <tr v-if="formModel.instructions != null">
+              <td class="td-left-column">批示时间</td>
+              <td>
+                {{ formModel.instructionsTime }}
+              </td>
+            </tr>
+          </table>
+        </el-row>
+        <el-row class="title"> 督办处置记录 </el-row>
+        <el-row class="table-doc">
+          <table border="0" cellspacing="0" cellpadding="0" align="center">
+            <tr>
+              <td class="td-left-column1"><b>交办时间</b></td>
+              <td class="td-left-column1"><b>处置单位</b></td>
+              <td class="td-left-column1"><b>处置时间</b></td>
+              <td class="td-right-column1"><b>处置记录</b></td>
+            </tr>
+            <tr v-for="list in formModel.incidentStepList" :key="list.id">
+              <td class="td-left-column1">{{ list.createTime }}</td>
+              <td class="td-right-column1">{{ list.orgName }}</td>
+              <td class="td-left-column1">{{ list.updateTime }}</td>
+              <td class="td-right-column1">{{ list.content }}</td>
+            </tr>
+          </table>
+        </el-row>
+        <el-row class="title"> 督办处置 </el-row>
+        <el-row>
+          <el-form-item label="处置方式" prop="subWayType">
+            <el-select
+              v-model="formModel.subWayType"
+              filterable
+              placeholder="请选择处置方式"
+              style="width: 300px"
+            >
+              <el-option
+                v-for="subWayType in wayTypeResult"
+                :key="subWayType.value"
+                :label="subWayType.name"
+                :value="subWayType.value"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="处置内容" prop="subContent">
+            <el-input
+              v-model="formModel.subContent"
+              type="textarea"
+              :autosize="{ minRows: 2 }"
+              placeholder="请输入处置内容"
+              style="width: 95%"
+            ></el-input>
+          </el-form-item>
+        </el-row>
+        <el-row v-if="czfx">
+          <el-col :span="12">
+            <el-form-item label="责任单位" prop="subOrgId">
+              <el-select-tree
+                :props="props"
+                :options="orgResult"
+                v-model="formModel.subOrgId"
+                style="width: 300px"
+                size="mediumn"
+                height="200"
+              ></el-select-tree>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="提醒时间" prop="subWarnTime">
+              <el-date-picker
+                v-model="formModel.subWarnTime"
+                value-format="yyyy-MM-dd"
+                type="date"
+                style="width: 300px"
+                placeholder="请选择批示时间"
+              >
+              </el-date-picker>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+    </div>
+    <span slot="footer" class="dialog-footer">
+      <el-button @click="closeDialog">关 闭</el-button>
+      <el-button type="primary" @click="handleSubmit" :loading="submitting"
+        >确 定</el-button
+      >
+    </span>
+  </el-dialog>
+</template>
+<script>
+import Constant from "@/constant";
+import incidentApi from "@/api/base/incident";
+import dataDictionaryApi from "@/api/sys/dataDictionary";
+import organizationApi from "@/api/base/organization";
+import SelectTree from "@/components/SelectTree";
+import { getToken } from "@/utils/auth";
+
+export default {
+  props: ["businessKey", "title"],
+  components: {
+    "el-select-tree": SelectTree,
+  },
+  data() {
+    return {
+      ruleValidate: {
+        subWayType: [
+          { required: true, message: "处置方式不能为空", trigger: "blur" },
+        ],
+        subContent: [
+          { required: true, message: "处置内容不能为空", trigger: "blur" },
+        ],
+      },
+      formModel: {},
+      showDialog: true,
+      loading: false,
+      submitting: false,
+      picDialogImageUrl: "",
+      picDialogVisible: false,
+      czfx: false,
+      wayTypeResult: [],
+      subWayType: {
+        name: "",
+        value: "",
+      },
+      orgResult: [],
+      props: {
+        value: "id",
+        label: "name"
+      }
+    };
+  },
+  created() {
+    var self = this;
+
+    dataDictionaryApi
+      .findByCatalogName({
+        catalogName: "督办处置类型",
+      })
+      .then((response) => {
+        var jsonData = response.data;
+        this.wayTypeResult = jsonData.data;
+      });
+  },
+  methods: {
+    closeDialog() {
+      this.$emit("close", false);
+    },
+    handleReset(name) {
+      this.queryMenu();
+    },
+    handleSubmit() {
+      var self = this;
+
+      this.$refs["form"].validate((valid) => {
+        if (valid) {
+          (function () {
+            self.loading = true;
+            return incidentApi.nextStep(self.formModel);
+          })().then(function (response) {
+            self.loading = false;
+            var jsonData = response.data;
+
+            if (jsonData.result) {
+              self.$message({
+                message: "保存成功!",
+                type: "success",
+              });
+
+              self.$emit("close", true);
+            } else {
+              self.$message({
+                message: jsonData.message + "",
+                type: "warning",
+              });
+
+              self.$emit("close", false);
+            }
+          });
+        }
+      });
+    },
+    queryMenu(keywords) {
+      var formData = new FormData();
+      formData.append("keywords", keywords);
+
+      return organizationApi.query(formData).then((response) => {
+        var jsonData = response.data;
+
+        if (jsonData.result) {
+          this.orgResult = jsonData.data;
+        } else {
+          this.$message.error(jsonData.message + "");
+        }
+      });
+    },
+  },
+  mounted: function () {
+    this.queryMenu("");
+    var self = this;
+
+    (function () {
+      if (self.businessKey.length == 0) {
+        return incidentApi.create();
+      } else {
+        return incidentApi.edit(self.businessKey);
+      }
+    })()
+      .then((response) => {
+        var jsonData = response.data;
+        self.loading = false;
+
+        if (jsonData.result) {
+          self.formModel = jsonData.data;
+        } else {
+          self.$message.error(jsonData.message + "");
+        }
+      })
+      .catch((error) => {
+        self.$message.error(error + "");
+      });
+  },
+  watch: {
+    "formModel.subWayType": function (newVal, oldVal) {
+      if (newVal != null) {
+        switch (newVal) {
+          case "1":
+            this.czfx = true;
+            break;
+          default:
+            this.czfx = false;
+            break;
+        }
+      }
+    },
+  },
+};
+</script>

+ 225 - 0
src/views/base/incident-info.vue

@@ -0,0 +1,225 @@
+
+<style scoped>
+.user-panel {
+  margin: 10px auto;
+}
+.table-doc {
+  width: 100%;
+}
+.table-doc table {
+  border-right: 1px solid #bbb;
+  border-bottom: 1px solid #bbb;
+  padding: 0px;
+  width: 95%;
+}
+.table-doc table td {
+  border-left: 1px solid #bbb;
+  border-top: 1px solid #bbb;
+  padding: 5px;
+  height: 38px;
+  line-height: 25px;
+}
+.td-left-column {
+  text-align: center;
+  width: 11%;
+}
+.td-right-column {
+  text-align: center;
+}
+.td-left-column1 {
+  text-align: center;
+  width: 16%;
+}
+.td-right-column1 {
+  text-align: center;
+}
+.el-col a:link,
+a:visited,
+a:hover,
+a:active {
+  color: #606266;
+  text-decoration: none;
+}
+.title {
+  color: rgba(16, 16, 16, 100);
+  font-size: 16px;
+  text-align: left;
+  line-height: 50px;
+}
+</style>
+<template>
+  <el-dialog
+    :visible.sync="showDialog"
+    :title="title"
+    :modal-append-to-body="false"
+    style="text-align: left"
+    @close="closeDialog"
+    :close-on-click-modal="false"
+  >
+    <div class="user-panel">
+      <el-form
+        ref="form"
+        :model="formModel"
+        :rules="ruleValidate"
+        :label-width="'100px'"
+      >
+        <el-row class="title"> 督办信息 </el-row>
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="督办类型">
+              <b>{{ formModel.caseTypeName }}</b>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="登记时间">
+              <b>{{ formModel.createTime }}</b>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="提醒时间">
+              <b>{{ formModel.stepWarnTime }}</b>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row class="table-doc">
+          <table border="0" cellspacing="0" cellpadding="0" align="center">
+            <tr>
+              <td class="td-left-column">标题</td>
+              <td>
+                {{ formModel.title }}
+              </td>
+            </tr>
+            <tr>
+              <td class="td-left-column">交办单位</td>
+              <td>
+                {{ formModel.stepOrgName }}
+              </td>
+            </tr>
+            <tr>
+              <td class="td-left-column">正文</td>
+              <td v-html="formModel.content">
+                {{ formModel.content }}
+              </td>
+            </tr>
+            <tr>
+              <td class="td-left-column">相关附件</td>
+              <td>
+                <el-col
+                  v-for="attList in formModel.attList"
+                  :key="attList.url"
+                  class="el-col"
+                >
+                  <a target="_black" :href="attList.url">{{ attList.name }}</a>
+                </el-col>
+              </td>
+            </tr>
+            <tr>
+              <td class="td-left-column">相关图片</td>
+              <td class="td-right-column" align="center">
+                <el-col
+                  :span="4"
+                  v-for="picUrl in formModel.picUrlList"
+                  :key="picUrl"
+                >
+                  <el-card
+                    :body-style="{ padding: '5px' }"
+                    style="width: 110px; height: 110px"
+                  >
+                    <el-image
+                      :src="picUrl"
+                      style="width: 100px; height: 100px"
+                      :preview-src-list="formModel.picUrlList"
+                      fit="cover"
+                      :z-index="3000"
+                    ></el-image>
+                  </el-card>
+                </el-col>
+              </td>
+            </tr>
+            <tr v-if="formModel.instructions != null">
+              <td class="td-left-column">领导批示</td>
+              <td>
+                {{ formModel.instructionsName }}:{{ formModel.instructions }}
+              </td>
+            </tr>
+            <tr v-if="formModel.instructions != null">
+              <td class="td-left-column">批示时间</td>
+              <td>
+                {{ formModel.instructionsTime }}
+              </td>
+            </tr>
+          </table>
+        </el-row>
+        <el-row class="title"> 督办处置记录 </el-row>
+        <el-row class="table-doc">
+          <table border="0" cellspacing="0" cellpadding="0" align="center">
+            <tr>
+              <td class="td-left-column1"><b>交办时间</b></td>
+              <td class="td-left-column1"><b>处置单位</b></td>
+              <td class="td-left-column1"><b>处置时间</b></td>
+              <td class="td-right-column1"><b>处置记录</b></td>
+            </tr>
+            <tr v-for="list in formModel.incidentStepList" :key="list.id">
+              <td class="td-left-column1">{{ list.createTime }}</td>
+              <td class="td-right-column1">{{ list.orgName }}</td>
+              <td class="td-left-column1">{{ list.updateTime }}</td>
+              <td class="td-right-column1">{{ list.content }}</td>
+            </tr>
+          </table>
+        </el-row>
+      </el-form>
+    </div>
+    <span slot="footer" class="dialog-footer">
+      <el-button @click="closeDialog">关 闭</el-button>
+    </span>
+  </el-dialog>
+</template>
+<script>
+import incidentApi from "@/api/base/incident";
+
+export default {
+  props: ["businessKey", "title"],
+  data() {
+    return {
+      ruleValidate: {
+        subWayType: [
+          { required: true, message: "处置方式不能为空", trigger: "blur" },
+        ],
+        subContent: [
+          { required: true, message: "处置内容不能为空", trigger: "blur" },
+        ],
+      },
+      formModel: {},
+      showDialog: true,
+    };
+  },
+  methods: {
+    closeDialog() {
+      this.$emit("close", false);
+    },
+  },
+  mounted: function () {
+    var self = this;
+
+    (function () {
+      if (self.businessKey.length == 0) {
+        return incidentApi.create();
+      } else {
+        return incidentApi.edit(self.businessKey);
+      }
+    })()
+      .then((response) => {
+        var jsonData = response.data;
+
+        if (jsonData.result) {
+          self.formModel = jsonData.data;
+        } else {
+          self.$message.error(jsonData.message + "");
+        }
+      })
+      .catch((error) => {
+        self.$message.error(error + "");
+      });
+  },
+};
+</script>

+ 387 - 0
src/views/base/incident-list.vue

@@ -0,0 +1,387 @@
+<template>
+  <div>
+    <el-breadcrumb separator=">">
+      <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
+      <el-breadcrumb-item>
+        <a href="#">系统管理</a>
+      </el-breadcrumb-item>
+      <el-breadcrumb-item>
+        <a href="/base/incident">督查督办管理</a>
+      </el-breadcrumb-item>
+    </el-breadcrumb>
+    <el-divider></el-divider>
+    <!--
+      要resetFields起作用,必须配置:model和prop
+    -->
+    <el-form
+      ref="queryForm"
+      :model="queryModel"
+      inline
+      class="demo-form-inline"
+    >
+      <el-form-item label="督办类型" prop="caseType">
+        <el-select
+          v-model="queryModel.caseType"
+          filterable
+          placeholder="请选择"
+          size="mini"
+        >
+          <el-option
+            v-for="caseType in caseTypeResult"
+            :key="caseType.value"
+            :label="caseType.name"
+            :value="caseType.value"
+          ></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="标题" prop="title">
+        <el-input type="text" size="mini" v-model="queryModel.title"></el-input>
+      </el-form-item>
+      <el-form-item label="进度" prop="isFinished">
+        <el-select
+          v-model="queryModel.isFinished"
+          filterable
+          placeholder="请选择"
+          size="mini"
+        >
+          <el-option
+            v-for="isFinished in isFinishedResult"
+            :key="isFinished.value"
+            :label="isFinished.name"
+            :value="isFinished.value"
+          ></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-button
+          type="primary"
+          size="mini"
+          icon="ios-search"
+          @click="changePage(1)"
+          :loading="loading"
+          >查询</el-button
+        >&nbsp;
+        <el-button
+          type="info"
+          size="mini"
+          style="margin-left: 8px"
+          @click="handleReset('queryForm')"
+          >重置</el-button
+        >&nbsp;
+      </el-form-item>
+    </el-form>
+    <el-divider></el-divider>
+    <el-row class="button-group">
+      <el-button
+        type="primary"
+        size="small"
+        plain
+        icon="el-icon-circle-plus"
+        @click="handleAdd"
+        >新增</el-button
+      >
+      <el-button
+        type="primary"
+        size="small"
+        plain
+        icon="el-icon-circle-plus"
+        :disabled="multipleSelection.length == 0"
+        @click="handleBatchDelete"
+        >删除选中项</el-button
+      >
+    </el-row>
+    <el-table
+      :data="tableData"
+      style="min-height: 400px"
+      v-loading="loading"
+      stripe
+      @sort-change="sortChange"
+      @selection-change="handleSelectionChange"
+    >
+      <el-table-column type="selection" width="55"></el-table-column>
+      <el-table-column
+        prop="caseTypeName"
+        label="督办类型"
+        width="180"
+      ></el-table-column>
+      <el-table-column prop="title" label="标题" width="180"></el-table-column>
+      <el-table-column prop="isFinishedName" label="当前进度" width="180"></el-table-column>
+      <el-table-column
+        prop="createTime"
+        label="登记时间"
+        width="180"
+      ></el-table-column>
+      <el-table-column label="操作" width="300" fixed="right">
+        <template slot-scope="{ row }">
+          <el-button size="mini" type="info" @click="handleInfo(row)">详情</el-button>
+          <el-button size="mini" type="success" @click="handleDetail(row)" v-if="row.isFinished != '0'">督办处置</el-button>
+          <el-button size="mini" type="warning" @click="handleEdit(row)" v-if="row.incidentStepSize < 2">编辑</el-button>
+          <el-button size="mini" type="danger" @click="handleDelete(row)" v-if="row.incidentStepSize < 2">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <el-pagination
+      :current-page.sync="pageIndex"
+      :total="totalElements"
+      :page-sizes="pageSizeList"
+      @current-change="changePage"
+      @size-change="pageSizeChange"
+      layout="total, sizes, prev, pager, next, jumper"
+    ></el-pagination>
+    <incident-detail
+      v-if="showModal"
+      :businessKey="businessKey"
+      :title="modalTitle"
+      @close="onDetailModalClose"
+    ></incident-detail>
+    <incident-doc
+      v-if="showModalDoc"
+      :businessKey="businessKey"
+      :title="modalTitle"
+      @close="onDetailModalClose"
+    ></incident-doc>
+    <incident-info
+      v-if="showModalInfo"
+      :businessKey="businessKey"
+      :title="modalTitle"
+      @close="onDetailModalClose"
+    ></incident-info>
+  </div>
+</template>
+<script>
+import Constant from "@/constant";
+import IncidentDetail from "./incident-detail";
+import IncidentDoc from "./incident-doc";
+import IncidentInfo from "./incident-info";
+import incidentApi from "@/api/base/incident";
+import dataDictionaryApi from "@/api/sys/dataDictionary";
+import NProgress from "nprogress"; // progress bar
+import "nprogress/nprogress.css"; // progress bar style
+
+export default {
+  data() {
+    var self = this;
+
+    return {
+      queryModel: {
+        id: "",
+        title: "",
+        content: "",
+        attachmentUrl: "",
+        imageUrl: "",
+        caseType: "",
+        isFinished: "",
+        instructions: "",
+        instructionsTime: "",
+      },
+      loading: false,
+      tableData: [],
+      pageIndex: 1,
+      pageSize: 10,
+      totalPages: 0,
+      totalElements: 0,
+      field: "",
+      direction: "",
+      pageSizeList: [10, 20, 30],
+      multipleSelection: [],
+      showModal: false,
+      showModalDoc: false,
+      showModalInfo: false,
+      modalTitle: "",
+      businessKey: "",
+      caseTypeResult: [],
+      isFinishedResult: [],
+      showBtn1: false,
+      showBtn2: true,
+    };
+  },
+  created() {
+    var self = this;
+
+    dataDictionaryApi.findByCatalogName({
+      catalogName: "督办类型",
+    })
+    .then((response) => {
+      var jsonData = response.data;
+      this.caseTypeResult = jsonData.data;
+    });
+
+    dataDictionaryApi.findByCatalogName({
+      catalogName: "督查事件步骤",
+    })
+    .then((response) => {
+      var jsonData = response.data;
+      this.isFinishedResult = jsonData.data;
+    });
+  },
+  methods: {
+    changePage(pageIndex) {
+      var self = this;
+
+      self.loading = true;
+
+      self.pageIndex = pageIndex;
+      var formData = new FormData();
+
+      formData.append("pageIndex", self.pageIndex);
+      formData.append("pageSize", self.pageSize);
+
+      formData.append("title", self.queryModel.title);
+      formData.append("caseType", self.queryModel.caseType);
+      formData.append("isFinished", self.queryModel.isFinished);
+
+      if (this.field != null) {
+        formData.append("field", this.field);
+      }
+
+      if (this.direction != null) {
+        formData.append("direction", this.direction);
+      }
+
+      incidentApi
+        .pageList(formData)
+        .then(function (response) {
+          self.loading = false;
+
+          var jsonData = response.data.data;
+
+          self.tableData = jsonData.data;
+          self.totalPages = jsonData.totalPages;
+          self.totalElements = jsonData.recordsTotal;
+        })
+        .catch((error) => {
+          self.loading = false;
+          // self.$message.error(error + "");
+        });
+    },
+    pageSizeChange(pageSize) {
+      this.pageSize = pageSize;
+
+      this.$nextTick(() => {
+        this.changePage(this.pageIndex);
+      });
+    },
+    sortChange(data) {
+      this.field = data.column.field;
+      this.direction = data.order;
+
+      this.changePage(this.pageIndex);
+    },
+    handleSelectionChange(val) {
+      this.multipleSelection = val;
+    },
+    handleReset(name) {
+      this.$refs[name].resetFields();
+    },
+    handleDetail(record) {
+      this.modalTitle = "督办处置";
+      this.businessKey = record.id;
+      this.showModalDoc = true;
+    },
+    handleInfo(record) {
+      this.modalTitle = "详情";
+      this.businessKey = record.id;
+      this.showModalInfo = true;
+    },
+    handleAdd() {
+      this.modalTitle = "新增";
+      this.businessKey = "";
+      this.showModal = true;
+    },
+    handleEdit(record) {
+      this.modalTitle = "编辑";
+      this.businessKey = record.id;
+      this.showModal = true;
+    },
+    handleDelete(record) {
+      var self = this;
+
+      self.$confirm("是否确认删除?", "提示", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning",
+        })
+        .then(() => {
+          incidentApi.remove(record.id).then(function (response) {
+            var jsonData = response.data;
+
+            if (jsonData.result) {
+              // var index = self.tableData.indexOf(record);
+              // self.tableData.splice(index, 1);
+              self.changePage(self.pageIndex);
+
+              self.$message({
+                type: "success",
+                message: "删除成功!",
+              });
+            }
+          });
+        });
+    },
+    handleBatchDelete() {
+      var self = this;
+
+      var idList = this.multipleSelection.map((record) => {
+        return record.id;
+      });
+
+      this.$confirm("是否确认删除选中项?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      }).then(() => {
+        incidentApi.batchRemove(idList).then(function (response) {
+          var jsonData = response.data;
+
+          if (jsonData.result) {
+            self.changePage(self.pageIndex);
+
+            self.$message({
+              type: "success",
+              message: "删除成功!",
+            });
+          }
+        });
+      });
+    },
+    onDetailModalClose(refreshed) {
+      //保存成功后回调
+      this.showModal = false;
+      this.showModalDoc = false;
+      this.showModalInfo = false;
+
+      if (refreshed) {
+        this.changePage(this.pageIndex);
+      }
+    },
+  },
+  mounted: function () {
+    this.changePage(1);
+  },
+  components: {
+    "incident-detail": IncidentDetail,
+    "incident-doc": IncidentDoc,
+    "incident-info": IncidentInfo,
+  },
+};
+</script>
+<style lang="scss" scoped>
+.el-breadcrumb {
+  margin: 10px;
+  line-height: 20px;
+}
+
+.el-divider {
+  margin: 5px 0;
+}
+
+.demo-form-inline {
+  margin-left: 10px;
+  text-align: left;
+}
+
+.button-group {
+  margin-left: 10px;
+  text-align: left;
+}
+</style>

+ 163 - 0
src/views/base/organization-detail.vue

@@ -0,0 +1,163 @@
+
+<style scoped>
+.user-panel {
+  margin: 10px auto;
+}
+</style>
+<template>
+  <el-dialog
+    :visible.sync="showDialog"
+    :title="title"
+    :modal-append-to-body="false"
+    style="text-align: left"
+    @close="closeDialog"
+    :close-on-click-modal="false"
+  >
+    <div class="user-panel" v-loading="loading">
+      <el-form
+        ref="form"
+        :model="formModel"
+        :rules="ruleValidate"
+        :label-width="'100px'"
+      >
+        <el-form-item label="机构名称" prop="name">
+          <el-input
+            v-model="formModel.name"
+            placeholder="请输入机构名称"
+            style="width: 300px"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="上级机构" prop="parentId">
+        <el-select-tree
+            :props="props"
+            :options="queryOrgResult"
+            v-model="formModel.parentId"
+            style="width:300px;"
+            size="mediumn"
+            height="200"
+          ></el-select-tree>
+        </el-form-item>
+      </el-form>
+    </div>
+    <span slot="footer" class="dialog-footer">
+      <el-button @click="closeDialog">取 消</el-button>
+      <el-button type="primary" @click="handleSubmit" :loading="submitting"
+        >确 定</el-button
+      >
+    </span>
+  </el-dialog>
+</template>
+<script>
+import Constant from "@/constant";
+import organizationApi from "@/api/base/organization";
+import SelectTree from "@/components/SelectTree";
+
+export default {
+  props: ["businessKey", "title"],
+  data() {
+    return {
+      formModel: {},
+      ruleValidate: {
+        name: [
+          { required: true, message: "机构名称不能为空", trigger: "blur" },
+        ],
+      },
+      showDialog: true,
+      loading: false,
+      submitting: false,
+      queryOrgResult: [],
+      props: {
+        // 配置项(必选)
+        value: "id",
+        label: "name"
+      }
+    };
+  },
+  methods: {
+    closeDialog() {
+      this.$emit("close", false);
+    },
+    handleReset(name) {
+      this.queryMenu();
+    },
+    handleSubmit() {
+      var self = this;
+
+      this.$refs["form"].validate((valid) => {
+        if (valid) {
+          (function () {
+            var id = self.formModel.id;
+
+            if (id == null || id.length == 0) {
+              return organizationApi.add(self.formModel);
+            } else {
+              return organizationApi.update(self.formModel);
+            }
+          })().then(function (response) {
+            var jsonData = response.data;
+
+            if (jsonData.result) {
+              self.$message({
+                message: "保存成功!",
+                type: "success",
+              });
+
+              self.$emit("close", true);
+            } else {
+              self.$message({
+                message: jsonData.message + "",
+                type: "warning",
+              });
+
+              self.$emit("close", false);
+            }
+          });
+        }
+      });
+    },
+    queryMenu(keywords) {
+      var formData = new FormData();
+      formData.append("keywords",keywords);
+
+      return organizationApi.query(formData).then(response=>{
+        var jsonData = response.data;
+
+        if(jsonData.result){
+          this.queryOrgResult = jsonData.data;
+        }
+        else{
+          this.$message.error(jsonData.message + "");
+        }
+      });
+    },
+  },
+  mounted: function () {
+    this.queryMenu("");
+    var self = this;
+
+    (function () {
+      if (self.businessKey.length == 0) {
+        return organizationApi.create();
+      } else {
+        return organizationApi.edit(self.businessKey);
+      }
+    })()
+      .then((response) => {
+        var jsonData = response.data;
+        self.loading = false;
+
+        if (jsonData.result) {
+          self.formModel = jsonData.data;
+        } else {
+          self.$message.error(jsonData.message + "");
+        }
+      })
+      .catch((error) => {
+        self.$message.error(error + "");
+      });
+  },
+  components: {
+    "el-select-tree": SelectTree
+  },
+};
+</script>

+ 344 - 0
src/views/base/organization-list.vue

@@ -0,0 +1,344 @@
+<template>
+  <div>
+    <el-breadcrumb separator=">">
+      <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
+      <el-breadcrumb-item>
+        <a href="#">系统管理</a>
+      </el-breadcrumb-item>
+      <el-breadcrumb-item>
+        <a href="/base/organization">组织机构管理</a>
+      </el-breadcrumb-item>
+    </el-breadcrumb>
+    <el-divider></el-divider>
+    <!--
+      要resetFields起作用,必须配置:model和prop
+    -->
+    <el-form
+      ref="queryForm"
+      :model="queryModel"
+      inline
+      class="demo-form-inline"
+    >
+      <el-form-item label="机构名称" prop="name">
+        <el-input type="text" size="mini" v-model="queryModel.name"></el-input>
+      </el-form-item>
+      <el-form-item label="上级机构" prop="parentId">
+        <el-select-tree
+            size="mini"
+            :props="props"
+            :options="queryOrgResult"
+            v-model="queryModel.parentId"
+            height="200"
+          ></el-select-tree>
+      </el-form-item>
+      <el-form-item>
+        <el-button
+          type="primary"
+          size="mini"
+          icon="ios-search"
+          @click="changePage(1)"
+          :loading="loading"
+          >查询</el-button
+        >&nbsp;
+        <el-button
+          type="info"
+          size="mini"
+          style="margin-left: 8px"
+          @click="handleReset('queryForm')"
+          >重置</el-button
+        >&nbsp;
+      </el-form-item>
+    </el-form>
+    <el-divider></el-divider>
+    <el-row class="button-group">
+      <el-button
+        type="primary"
+        size="small"
+        plain
+        icon="el-icon-circle-plus"
+        @click="handleAdd"
+        >新增</el-button
+      >
+      <el-button
+        type="primary"
+        size="small"
+        plain
+        icon="el-icon-circle-plus"
+        :disabled="multipleSelection.length == 0"
+        @click="handleBatchDelete"
+        >删除选中项</el-button
+      >
+    </el-row>
+    <el-table
+      :data="tableData"
+      style="min-height: 400px"
+      v-loading="loading"
+      stripe
+      @sort-change="sortChange"
+      @selection-change="handleSelectionChange"
+    >
+      <el-table-column type="selection" width="55"></el-table-column>
+      <el-table-column
+        prop="name"
+        label="机构名称"
+        width="180"
+      ></el-table-column>
+      <el-table-column
+        prop="parentName"
+        label="上级机构"
+        width="180"
+      ></el-table-column>
+      <el-table-column prop="createTime" label="创建时间" width="180"></el-table-column>
+      <el-table-column prop="updateTime" label="更新时间" width="180"></el-table-column>
+      <el-table-column label="操作" width="150" fixed="right">
+        <template slot-scope="{ row }">
+          <el-button size="mini" type="warning" @click="handleEdit(row)"
+            >编辑</el-button
+          >
+          <el-button size="mini" type="danger" @click="handleDelete(row)"
+            >删除</el-button
+          >
+        </template>
+      </el-table-column>
+    </el-table>
+    <el-pagination
+      :current-page.sync="pageIndex"
+      :total="totalElements"
+      :page-sizes="pageSizeList"
+      @current-change="changePage"
+      @size-change="pageSizeChange"
+      layout="total, sizes, prev, pager, next, jumper"
+    ></el-pagination>
+    <organization-detail
+      v-if="showModal"
+      :businessKey="businessKey"
+      :title="modalTitle"
+      @close="onDetailModalClose"
+    ></organization-detail>
+  </div>
+</template>
+<script>
+import Constant from "@/constant";
+import OrganizationDetail from "./organization-detail";
+import organizationApi from "@/api/base/organization";
+import NProgress from "nprogress"; // progress bar
+import "nprogress/nprogress.css"; // progress bar style
+import SelectTree from "@/components/SelectTree";
+
+export default {
+  data() {
+    var self = this;
+
+    return {
+      queryModel: {
+        id: "",
+        name: "",
+        parentId: "",
+        code: "",
+      },
+      loading: false,
+      tableData: [],
+      pageIndex: 1,
+      pageSize: 10,
+      totalPages: 0,
+      totalElements: 0,
+      field: "",
+      direction: "",
+      pageSizeList: [10, 20, 30],
+      multipleSelection: [],
+      showModal: false,
+      modalTitle: "",
+      businessKey: "",
+      queryOrgResult: [],
+      props: {
+        // 配置项(必选)
+        value: "id",
+        label: "name"
+      }
+    };
+  },
+  methods: {
+    changePage(pageIndex) {
+      var self = this;
+
+      self.loading = true;
+
+      self.pageIndex = pageIndex;
+      var formData = new FormData();
+
+      formData.append("pageIndex", self.pageIndex);
+      formData.append("pageSize", self.pageSize);
+
+      formData.append("id", self.queryModel.id);
+      formData.append("name", self.queryModel.name);
+      formData.append("parentId", self.queryModel.parentId);
+      formData.append("code", self.queryModel.code);
+
+      if (this.field != null) {
+        formData.append("field", this.field);
+      }
+
+      if (this.direction != null) {
+        formData.append("direction", this.direction);
+      }
+
+      organizationApi
+        .pageList(formData)
+        .then(function (response) {
+          self.loading = false;
+
+          var jsonData = response.data.data;
+
+          self.tableData = jsonData.data;
+          self.totalPages = jsonData.totalPages;
+          self.totalElements = jsonData.recordsTotal;
+        })
+        .catch((error) => {
+          self.loading = false;
+          // self.$message.error(error + "");
+        });
+    },
+    pageSizeChange(pageSize) {
+      this.pageSize = pageSize;
+
+      this.$nextTick(() => {
+        this.changePage(this.pageIndex);
+      });
+    },
+    sortChange(data) {
+      this.field = data.column.field;
+      this.direction = data.order;
+
+      this.changePage(this.pageIndex);
+    },
+    handleSelectionChange(val) {
+      this.multipleSelection = val;
+    },
+    handleReset(name) {
+      this.$refs[name].resetFields();
+      this.queryMenu();
+    },
+    handleAdd() {
+      this.modalTitle = "新增";
+      this.businessKey = "";
+      this.showModal = true;
+    },
+    handleEdit(record) {
+      this.modalTitle = "编辑";
+      this.businessKey = record.id;
+      this.showModal = true;
+    },
+    handleDelete(record) {
+      var self = this;
+
+      self
+        .$confirm("是否确认删除?", "提示", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning",
+        })
+        .then(() => {
+          organizationApi.remove(record.id).then(function (response) {
+            var jsonData = response.data;
+
+            if (jsonData.result) {
+              // var index = self.tableData.indexOf(record);
+              // self.tableData.splice(index, 1);
+              self.changePage(self.pageIndex);
+
+              self.$message({
+                type: "success",
+                message: "删除成功!",
+              });
+            }
+          });
+        });
+    },
+    handleBatchDelete() {
+      var self = this;
+
+      var idList = this.multipleSelection.map((record) => {
+        return record.id;
+      });
+
+      this.$confirm("是否确认删除选中项?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      }).then(() => {
+        organizationApi.batchRemove(idList).then(function (response) {
+          var jsonData = response.data;
+
+          if (jsonData.result) {
+            self.changePage(self.pageIndex);
+
+            self.$message({
+              type: "success",
+              message: "删除成功!",
+            });
+          }
+        });
+      });
+    },
+    onDetailModalClose(refreshed) {
+      //保存成功后回调
+      this.showModal = false;
+
+      if (refreshed) {
+        this.changePage(this.pageIndex);
+      }
+    },
+    queryMenu(keywords) {
+      var formData = new FormData();
+      formData.append("keywords",keywords);
+
+      return organizationApi.query(formData).then(response=>{
+        var jsonData = response.data;
+
+        if(jsonData.result){
+          this.queryOrgResult = jsonData.data;
+        }
+        else{
+          this.$message.error(jsonData.message + "");
+        }
+      });
+    },
+    showSubmenu(row){
+        this.queryOrgResult.length=0; //清空
+        this.queryOrgResult.push(row);
+
+        this.queryModel.menuName = "";
+        this.queryModel.parentId = row.id;
+        this.changePage(1);
+    },
+  },
+  mounted: function () {
+    this.changePage(1);
+    this.queryMenu("");
+  },
+  components: {
+    "organization-detail": OrganizationDetail,
+    "el-select-tree": SelectTree
+  },
+};
+</script>
+<style lang="scss" scoped>
+.el-breadcrumb {
+  margin: 10px;
+  line-height: 20px;
+}
+
+.el-divider {
+  margin: 5px 0;
+}
+
+.demo-form-inline {
+  margin-left: 10px;
+  text-align: left;
+}
+
+.button-group {
+  margin-left: 10px;
+  text-align: left;
+}
+</style>

+ 152 - 0
src/views/base/person-detail.vue

@@ -0,0 +1,152 @@
+
+<style scoped>
+.user-panel {
+  margin: 10px auto;
+}
+</style>
+<template>
+  <el-dialog
+    :visible.sync="showDialog"
+    :title="title"
+    :modal-append-to-body="false"
+    style="text-align:left;"
+    @close="closeDialog"
+    :close-on-click-modal="false"
+  >
+    <div class="user-panel" v-loading="loading">
+    <el-form ref="form" :model="formModel" :rules="ruleValidate" :label-width="'100px'">
+		<el-form-item label="编号" prop="id">
+	    <el-input v-model="formModel.id" placeholder="请输入编号" style="width:300px"></el-input>
+	</el-form-item>
+		<el-form-item label="机构编号" prop="orgId">
+	    <el-input v-model="formModel.orgId" placeholder="请输入机构编号" style="width:300px"></el-input>
+	</el-form-item>
+		<el-form-item label="姓名" prop="name">
+	    <el-input v-model="formModel.name" placeholder="请输入姓名" style="width:300px"></el-input>
+	</el-form-item>
+		<el-form-item label="电话" prop="phone">
+	    <el-input v-model="formModel.phone" placeholder="请输入电话" style="width:300px"></el-input>
+	</el-form-item>
+		<el-form-item label="是否删除" prop="delFlag">
+	    <el-input v-model="formModel.delFlag" placeholder="请输入是否删除" style="width:300px"></el-input>
+	</el-form-item>
+		<el-form-item label="创建时间" prop="createTime">
+	    <el-input v-model="formModel.createTime" placeholder="请输入创建时间" style="width:300px"></el-input>
+	</el-form-item>
+		<el-form-item label="创建人" prop="createBy">
+	    <el-input v-model="formModel.createBy" placeholder="请输入创建人" style="width:300px"></el-input>
+	</el-form-item>
+		<el-form-item label="更新时间" prop="updateTime">
+	    <el-input v-model="formModel.updateTime" placeholder="请输入更新时间" style="width:300px"></el-input>
+	</el-form-item>
+		<el-form-item label="更新人" prop="updateBy">
+	    <el-input v-model="formModel.updateBy" placeholder="请输入更新人" style="width:300px"></el-input>
+	</el-form-item>
+	    </el-form>
+  </div>
+      <span slot="footer" class="dialog-footer">
+      <el-button @click="closeDialog">取 消</el-button>
+      <el-button type="primary" @click="handleSubmit" :loading="submitting">确 定</el-button>
+    </span>
+  </el-dialog>
+</template>
+<script>
+import Constant from "@/constant";
+import personApi from "@/api/base/person";
+
+export default {
+  props: ["businessKey","title"],
+  data() {
+    return {
+      formModel: {},
+      ruleValidate: {
+                    id: [
+                { required: true, message: '编号不能为空', trigger: 'blur' }
+            ],                    orgId: [
+                { required: true, message: '机构编号不能为空', trigger: 'blur' }
+            ],                    name: [
+                { required: true, message: '姓名不能为空', trigger: 'blur' }
+            ],                    phone: [
+                { required: true, message: '电话不能为空', trigger: 'blur' }
+            ],                    delFlag: [
+                { required: true, message: '是否删除不能为空', trigger: 'blur' }
+            ],                    createTime: [
+                { required: true, message: '创建时间不能为空', trigger: 'blur' }
+            ],                    createBy: [
+                { required: true, message: '创建人不能为空', trigger: 'blur' }
+            ],                    updateTime: [
+                { required: true, message: '更新时间不能为空', trigger: 'blur' }
+            ],                    updateBy: [
+                { required: true, message: '更新人不能为空', trigger: 'blur' }
+            ]              },
+      showDialog: true,
+      loading: false,
+      submitting: false
+    };
+  },
+  methods: {
+    closeDialog() {
+	this.$emit("close",false);
+    },
+    handleSubmit() {
+      var self = this;
+
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          (function(){
+            var id = self.formModel.id;
+
+            if (id == null || id.length == 0) {
+              return personApi.add(self.formModel);
+            }
+            else{
+              return personApi.update(self.formModel);
+            }
+          })().then(function(response) {
+              var jsonData = response.data;
+
+              if (jsonData.result) {
+                self.$message({
+                  message: "保存成功!",
+                  type: "success"
+                });
+
+                self.$emit("close",true);
+              } else {
+                self.$message({
+                  message: jsonData.message + "",
+                  type: "warning"
+                });
+
+                self.$emit("close",false);
+              }
+            });
+        }
+      });
+    }
+  },
+  mounted: function() {
+    var self = this;
+
+    (function(){
+      if(self.businessKey.length==0){
+        return personApi.create()
+      }
+      else{
+        return personApi.edit(self.businessKey)
+      }
+    })().then(response => {
+      var jsonData = response.data;
+      self.loading = false;
+
+      if (jsonData.result) {
+        self.formModel = jsonData.data;
+      } else {
+        self.$message.error(jsonData.message + "");
+      }
+    }).catch(error => {
+      self.$message.error(error + "");
+    });
+  }
+};
+</script>

+ 291 - 0
src/views/base/person-list.vue

@@ -0,0 +1,291 @@
+<template>
+  <div>
+    <el-breadcrumb separator=">">
+      <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
+      <el-breadcrumb-item>
+        <a href="#">系统管理</a>
+      </el-breadcrumb-item>
+      <el-breadcrumb-item>
+        <a href="/base/person">person管理</a>
+      </el-breadcrumb-item>
+    </el-breadcrumb>
+    <el-divider></el-divider>
+    <!--
+      要resetFields起作用,必须配置:model和prop
+    -->
+    <el-form ref="queryForm" :model="queryModel" inline class="demo-form-inline">
+      <el-form-item label="机构编号" prop="orgId">
+          <el-input type="text" size="mini" v-model="queryModel.orgId"></el-input>
+      </el-form-item>
+      <el-form-item label="姓名" prop="name">
+          <el-input type="text" size="mini" v-model="queryModel.name"></el-input>
+      </el-form-item>
+      <el-form-item label="电话" prop="phone">
+          <el-input type="text" size="mini" v-model="queryModel.phone"></el-input>
+      </el-form-item>
+      <el-form-item>
+        <el-button
+          type="primary"
+          size="mini"
+          icon="ios-search"
+          @click="changePage(1)"
+          :loading="loading"
+        >查询</el-button>&nbsp;
+        <el-button
+          type="info"
+          size="mini"
+          style="margin-left: 8px"
+          @click="handleReset('queryForm')"
+        >重置</el-button>&nbsp;
+      </el-form-item>
+    </el-form>
+    <el-divider></el-divider>
+    <el-row class="button-group">
+      <el-button type="primary" size="small" plain icon="el-icon-circle-plus" @click="handleAdd">新增</el-button>
+      <el-button
+        type="primary"
+        size="small"
+        plain
+        icon="el-icon-circle-plus"
+        :disabled="multipleSelection.length==0"
+        @click="handleBatchDelete"
+      >删除选中项</el-button>
+    </el-row>
+    <el-table
+      :data="tableData"
+      style="min-height:400px;"
+      v-loading="loading"
+      stripe
+      @sort-change="sortChange"
+      @selection-change="handleSelectionChange"
+    >
+      <el-table-column type="selection" width="55"></el-table-column>
+		<el-table-column prop="id" label="编号" width="180"></el-table-column>
+		<el-table-column prop="orgId" label="机构编号" width="180"></el-table-column>
+		<el-table-column prop="name" label="姓名" width="180"></el-table-column>
+		<el-table-column prop="phone" label="电话" width="180"></el-table-column>
+		<el-table-column prop="delFlag" label="是否删除" width="180"></el-table-column>
+		<el-table-column prop="createTime" label="创建时间" width="180"></el-table-column>
+		<el-table-column prop="createBy" label="创建人" width="180"></el-table-column>
+		<el-table-column prop="updateTime" label="更新时间" width="180"></el-table-column>
+		<el-table-column prop="updateBy" label="更新人" width="180"></el-table-column>
+      <el-table-column label="操作">
+        <template slot-scope="{row}">
+          <el-button size="mini" type="warning" @click="handleEdit(row)">编辑</el-button>
+          <el-button size="mini" type="danger" @click="handleDelete(row)">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <el-pagination
+      :current-page.sync="pageIndex"
+      :total="totalElements"
+      :page-sizes="pageSizeList"
+      @current-change="changePage"
+      @size-change="pageSizeChange"
+      layout="total, sizes, prev, pager, next, jumper"
+    ></el-pagination>
+	<person-detail
+	v-if="showModal"
+	:businessKey="businessKey"
+	:title="modalTitle"
+	@close="onDetailModalClose"
+	></person-detail>
+  </div>
+</template>
+<script>
+import Constant from "@/constant";
+import PersonDetail from "./person-detail";
+import personApi from "@/api/base/person";
+import NProgress from "nprogress"; // progress bar
+import "nprogress/nprogress.css"; // progress bar style
+
+export default {
+  data() {
+    var self = this;
+
+    return {
+	  queryModel:{
+				"id":""
+		,				"orgId":""
+		,				"name":""
+		,				"phone":""
+		,				"delFlag":""
+		,				"createTime":""
+		,				"createBy":""
+		,				"updateTime":""
+		,				"updateBy":""
+					  },
+      loading: false,
+      tableData: [],
+      pageIndex: 1,
+      pageSize: 10,
+      totalPages: 0,
+      totalElements: 0,
+      field: "",
+      direction: "",
+      pageSizeList: [10, 20, 30],
+      multipleSelection: [],      
+      showModal: false,
+      modalTitle: "",
+      businessKey: ""
+    };
+  },
+  methods: {
+    changePage(pageIndex) {
+      var self = this;
+
+	  self.loading = true;
+
+      self.pageIndex = pageIndex;
+      var formData = new FormData();
+
+      formData.append("pageIndex", self.pageIndex);
+      formData.append("pageSize", self.pageSize);
+
+formData.append("id",self.queryModel.id);
+formData.append("orgId",self.queryModel.orgId);
+formData.append("name",self.queryModel.name);
+formData.append("phone",self.queryModel.phone);
+formData.append("delFlag",self.queryModel.delFlag);
+formData.append("createTime",self.queryModel.createTime);
+formData.append("createBy",self.queryModel.createBy);
+formData.append("updateTime",self.queryModel.updateTime);
+formData.append("updateBy",self.queryModel.updateBy);
+
+      if (this.field != null) {
+        formData.append("field", this.field);
+      }
+
+      if (this.direction != null) {
+        formData.append("direction", this.direction);
+      }
+
+      personApi.pageList(formData).then(function(response) {
+        self.loading = false;
+
+        var jsonData = response.data.data;
+
+        self.tableData = jsonData.data;
+        self.totalPages = jsonData.totalPages;
+        self.totalElements = jsonData.recordsTotal;
+      }).catch((error)=>{
+        self.loading = false;
+        // self.$message.error(error + "");
+      });
+    },
+    pageSizeChange(pageSize) {
+      this.pageSize = pageSize;
+      
+      this.$nextTick(()=>{
+        this.changePage(this.pageIndex);
+      });
+    },
+    sortChange(data) {
+      this.field = data.column.field;
+      this.direction = data.order;
+
+      this.changePage(this.pageIndex);
+    },
+    handleSelectionChange(val) {
+      this.multipleSelection = val;
+    },
+    handleReset(name) {
+      this.$refs[name].resetFields();
+    },
+    handleAdd() {
+      this.modalTitle = "新增";
+      this.businessKey = "";
+      this.showModal = true;
+    },
+    handleEdit(record) {
+      this.modalTitle = "编辑";
+      this.businessKey = record.id;
+      this.showModal = true;
+    },
+    handleDelete(record) {
+      var self = this;
+
+      self.$confirm("是否确认删除?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(() => {
+        personApi.remove(record.id).then(function(response) {
+          var jsonData = response.data;
+
+          if (jsonData.result) {
+            // var index = self.tableData.indexOf(record);
+            // self.tableData.splice(index, 1);
+            self.changePage(self.pageIndex);
+
+            self.$message({
+              type: "success",
+              message: "删除成功!"
+            });
+          }
+        });
+      });
+    },
+    handleBatchDelete() {
+      var self = this;
+
+      var idList = this.multipleSelection.map(record => {
+        return record.id;
+      });
+
+      this.$confirm("是否确认删除选中项?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(() => {
+        personApi.batchRemove(idList).then(function(response) {
+          var jsonData = response.data;
+
+          if (jsonData.result) {
+            self.changePage(self.pageIndex);
+
+            self.$message({
+              type: "success",
+              message: "删除成功!"
+            });
+          }
+        });
+      });
+    },
+    onDetailModalClose(refreshed) {
+      //保存成功后回调
+      this.showModal = false;
+
+      if(refreshed){
+        this.changePage(this.pageIndex);
+      }
+    }
+  },
+  mounted: function() {
+    this.changePage(1);
+  },
+  components: {
+    "person-detail": PersonDetail
+  }
+};
+</script>
+<style lang="scss" scoped>
+.el-breadcrumb {
+  margin: 10px;
+  line-height: 20px;
+}
+
+.el-divider {
+  margin: 5px 0;
+}
+
+.demo-form-inline {
+  margin-left: 10px;
+  text-align: left;
+}
+
+.button-group {
+  margin-left: 10px;
+  text-align: left;
+}
+</style>

+ 1 - 1
src/views/sys/role-menu.vue

@@ -2,7 +2,7 @@
     <el-dialog
       :visible.sync="showDialog"
       title="分配菜单"
-      width="800px"
+      width="870px"
       :modal-append-to-body="false"
       style="text-align:left;"
       @close="closeDialog"

+ 1 - 1
src/views/sys/role-permission.vue

@@ -1,7 +1,7 @@
 <template>
       <el-dialog
         title="分配接口权限"
-        width="800px"
+        width="870px"
         :visible="showDialog"
         :modal-append-to-body="false"
         style="text-align:left;"

+ 4 - 4
yarn.lock

@@ -3059,10 +3059,10 @@ electron-to-chromium@^1.3.306:
   resolved "https://registry.npm.taobao.org/electron-to-chromium/download/electron-to-chromium-1.3.314.tgz#c186a499ed2c9057bce9eb8dca294d6d5450facc"
   integrity sha1-wYakme0skFe86euNyilNbVRQ+sw=
 
-element-ui@^2.4.5:
-  version "2.12.0"
-  resolved "https://registry.yarnpkg.com/element-ui/-/element-ui-2.12.0.tgz#a893bc11ae4f7dbb7e9d541606f23e643f131ee4"
-  integrity sha512-DapyT0PW4i/1ETPHk8K8Qbe8B6hj10+dXsRTrOTFryV9wAs6e9mCxbV65awokyR2/v/KuIHJmqX+mH3wUa4rOQ==
+element-ui@^2.15.1:
+  version "2.15.1"
+  resolved "https://registry.npm.taobao.org/element-ui/download/element-ui-2.15.1.tgz?cache=0&sync_timestamp=1614082623756&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Felement-ui%2Fdownload%2Felement-ui-2.15.1.tgz#ada00aa6e32c02774a2e77563dd84668f813cdff"
+  integrity sha1-raAKpuMsAndKLndWPdhGaPgTzf8=
   dependencies:
     async-validator "~1.8.1"
     babel-helper-vue-jsx-merge-props "^2.0.0"