浏览代码

项目增删改查

Limengbo 6 年之前
父节点
当前提交
603ef674da

+ 12 - 0
index.html

@@ -5,6 +5,18 @@
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <meta http-equiv="X-UA-Compatible" content="ie=edge">
     <title>Document</title>
+    <style>
+        * {
+            margin: 0;
+            padding: 0;
+        }
+        html,
+        body {
+            width: 100%;
+            height: 100%;
+            box-sizing: border-box;
+        }
+    </style>
 </head>
 <body>
     <div id="app">   

+ 16 - 0
package-lock.json

@@ -558,6 +558,16 @@
       "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==",
       "dev": true
     },
+    "axios": {
+      "version": "0.18.0",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-0.18.0.tgz",
+      "integrity": "sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI=",
+      "dev": true,
+      "requires": {
+        "follow-redirects": "^1.3.0",
+        "is-buffer": "^1.1.5"
+      }
+    },
     "babel-code-frame": {
       "version": "6.26.0",
       "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
@@ -7998,6 +8008,12 @@
         "vue-style-loader": "^4.1.0"
       }
     },
+    "vue-router": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.0.2.tgz",
+      "integrity": "sha512-opKtsxjp9eOcFWdp6xLQPLmRGgfM932Tl56U9chYTnoWqKxQ8M20N7AkdEbM5beUh6wICoFGYugAX9vQjyJLFg==",
+      "dev": true
+    },
     "vue-style-loader": {
       "version": "4.1.2",
       "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.2.tgz",

+ 2 - 0
package.json

@@ -12,6 +12,7 @@
   "license": "ISC",
   "devDependencies": {
     "autoprefixer": "^9.4.7",
+    "axios": "^0.18.0",
     "babel-core": "^6.26.3",
     "babel-loader": "^8.0.5",
     "babel-preset-env": "^1.7.0",
@@ -25,6 +26,7 @@
     "url-loader": "^1.1.2",
     "vue": "^2.6.6",
     "vue-loader": "^15.6.2",
+    "vue-router": "^3.0.2",
     "vue-style-loader": "^4.1.2",
     "vue-template-compiler": "^2.6.6",
     "webpack": "^4.29.3",

+ 7 - 14
src/App.vue

@@ -1,19 +1,5 @@
 <template>
   <div id="app">
-    <el-radio-group v-model="isCollapse" style="margin-bottom: 20px;">
-        <el-radio-button :label="false">展开</el-radio-button>
-        <el-radio-button :label="true">收起</el-radio-button>
-    </el-radio-group>
-    <el-menu default-active="1-4-1" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose" :collapse="isCollapse">
-        <el-menu-item index="2">
-            <i class="el-icon-menu"></i>
-            <span slot="title">导航二</span>
-        </el-menu-item>
-        <el-menu-item index="4">
-            <i class="el-icon-setting"></i>
-            <span slot="title">导航四</span>
-        </el-menu-item>
-    </el-menu>
     <router-view/>
   </div>
 </template>
@@ -36,5 +22,12 @@
     }
   }
 </script>
+<style>
+#app {
+  width: 100%;
+  height: 100%;
+}
+</style>
+
 
 

+ 30 - 0
src/api/costTeamApi.js

@@ -0,0 +1,30 @@
+import request from 'utils/request'
+import { baseApi } from 'utils/config' 
+
+//获取收入支出类别信息
+export function getCostTeamList () {
+  return request({
+    url: baseApi + 'manageBase/company',
+    method: 'get',
+    // params: {
+    //   status: 'NORMAL'
+    // }
+  })
+}
+
+//新增收入支出类别
+export function addCostTeam (data) {
+  return request({
+    url: baseApi + 'manageBase/company',
+    method: 'post',
+    data,
+  })
+}
+//修改收入支出类别
+export function setCostTeam (data) {
+  return request({
+    url: baseApi + 'manageBase/company',
+    method: 'put',
+    data,
+  })
+}

+ 30 - 0
src/api/costTypeApi.js

@@ -0,0 +1,30 @@
+import request from 'utils/request'
+import { baseApi } from 'utils/config' 
+
+//获取收入支出部门信息
+export function getCostTypeList () {
+  return request({
+    url: baseApi + 'manageBase/costType',
+    method: 'get',
+    // params: {
+    //   status: 'NORMAL'
+    // }
+  })
+}
+
+//新增收入支出部门
+export function addCostType (data) {
+  return request({
+    url: baseApi + 'manageBase/costType',
+    method: 'post',
+    data,
+  })
+}
+//修改收入支出部门
+export function setCostType (data) {
+  return request({
+    url: baseApi + 'manageBase/costType',
+    method: 'put',
+    data,
+  })
+}

+ 30 - 0
src/api/productApi.js

@@ -0,0 +1,30 @@
+import request from 'utils/request'
+import { baseApi } from 'utils/config' 
+
+//获取产品信息
+export function getProductList () {
+  return request({
+    url: baseApi + 'manageBase/product',
+    method: 'get',
+    // params: {
+    //   status: 'NORMAL'
+    // }
+  })
+}
+
+//新增产品
+export function addProduct (data) {
+  return request({
+    url: baseApi + 'manageBase/product',
+    method: 'post',
+    data,
+  })
+}
+//修改产品
+export function setProduct (data) {
+  return request({
+    url: baseApi + 'manageBase/product',
+    method: 'put',
+    data,
+  })
+}

+ 30 - 0
src/api/projectApi.js

@@ -0,0 +1,30 @@
+import request from 'utils/request'
+import { baseApi } from 'utils/config' 
+
+//获取项目信息
+export function getProjectList () {
+  return request({
+    url: baseApi + 'manageBase/project',
+    method: 'get',
+    // params: {
+    //   status: 'NORMAL'
+    // }
+  })
+}
+
+//新增项目
+export function addProject (data) {
+  return request({
+    url: baseApi + 'manageBase/project',
+    method: 'post',
+    data,
+  })
+}
+//修改项目
+export function setProject (data) {
+  return request({
+    url: baseApi + 'manageBase/project',
+    method: 'put',
+    data,
+  })
+}

+ 39 - 0
src/api/teamApi.js

@@ -0,0 +1,39 @@
+import request from 'utils/request'
+import { baseApi } from 'utils/config' 
+
+//获取部门信息
+export function getTeamList (deptId) {
+  return request({
+    url: baseApi + 'manageBase/dept/tree',
+    method: 'get',
+    params: {
+      deptId: 0
+    }
+  })
+}
+//获取子部门信息
+export function getTeamChildList (deptId) {
+  return request({
+    url: baseApi + 'manageBase/dept/child',
+    method: 'get',
+    params: {
+      deptId
+    }
+  })
+}
+//新增部门
+export function addTeam (data) {
+  return request({
+    url: baseApi + 'manageBase/dept',
+    method: 'post',
+    data,
+  })
+}
+//修改部门
+export function setTeam (data) {
+  return request({
+    url: baseApi + 'manageBase/dept',
+    method: 'put',
+    data,
+  })
+}

+ 3 - 1
src/main.js

@@ -2,10 +2,12 @@ import Vue from 'vue';
 import ElementUI from 'element-ui';
 import 'element-ui/lib/theme-chalk/index.css';
 import App from './App.vue';
-
+import router from './router'
+console.log(router)
 Vue.use(ElementUI);
 
 new Vue({
   el: '#app',
+  router,
   render: h => h(App)
 });

+ 177 - 0
src/pages/costTeam/index.vue

@@ -0,0 +1,177 @@
+<template>
+  <div class="cost-team">
+    <el-button type="primary" class="add" @click="append">增加收入部门</el-button>
+    <el-card class="right-card">
+      <el-table
+      :data="costTeamData"
+      style="width: 100%">
+        <el-table-column type="expand">
+          <template slot-scope="props">
+            <el-form label-position="left" inline class="demo-table-expand">
+              <el-form-item label="收入部门名称">
+                <span>{{ props.row.name }}</span>
+              </el-form-item>
+              <el-form-item label="收入部门 ID">
+                <span>{{ props.row.id }}</span>
+              </el-form-item>
+            </el-form>
+          </template>
+        </el-table-column>
+        <el-table-column
+          label="收入部门 ID"
+          prop="id">
+        </el-table-column>
+        <el-table-column
+          label="收入部门名称"
+          prop="name">
+        </el-table-column>
+        <el-table-column label="操作">
+          <template slot-scope="scope">
+            <el-button
+              size="mini"
+              @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
+            <el-button
+              size="mini"
+              type="danger"
+              @click="handleDelete(scope.$index, scope.row)">删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-card>
+    <el-dialog title="新增收入部门" :visible.sync="dialogFormVisible">     
+      <el-form :model="form" ref="form">
+        <el-form-item label="收入部门编码" prop="code" :label-width="formLabelWidth" :rules="[{ required: true, message: '编码不能为空'}]">
+          <el-input v-model="form.code" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="收入部门名称" prop="name" :label-width="formLabelWidth" :rules="[{ required: true, message: '名称不能为空'}]">
+          <el-input v-model="form.name" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="收入部门状态" prop="status" :label-width="formLabelWidth" :rules="[{ required: true, message: '状态不能为空'}]">
+          <el-select v-model="form.status" placeholder="请选择状态值">
+            <el-option label="正常" value="NORMAL"></el-option>
+            <el-option label="已删除" value="DEL"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="收入部门排序" prop="sort" :label-width="formLabelWidth" :rules="[
+        { required: true, message: '排序不能为空'},
+        { type: 'number', message: '排序必须为数字值'}
+        ]">
+          <el-input v-model.number="form.sort" autocomplete="off"></el-input>
+        </el-form-item>             
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="resetForm('form')">取 消</el-button>
+        <el-button type="primary" @click="submitForm('form')">确 定</el-button>
+      </div>
+    </el-dialog>    
+  </div>
+</template>
+<script scoped>
+import { getCostTeamList, addCostTeam, setCostTeam } from '@/api/costTeamApi'
+export default {
+  data () {
+    return {
+      costTeamData: [],
+      dialogFormVisible: false,
+      addFlag: false,
+      id: '',
+      form: {
+        code: '',
+        name: '',
+        status: '',
+        sort: ''
+      },
+      formLabelWidth: '120px',
+      index: ''      
+    }
+  },
+  created () {
+    getCostTeamList().then(res => {
+      this.costTeamData = res.data.data
+    });
+  },
+  methods: {
+    // 新增收入部门
+    append() {
+      this.addFlag = true;
+      this.dialogFormVisible = true;
+    },
+    // 编辑收入部门
+    handleEdit(index, row) {
+      this.form.code = row.code;
+      this.form.name = row.name;
+      this.form.status = row.status;
+      this.form.sort = row.sort;
+      this.id = row.id;
+      this.index = index;
+      this.dialogFormVisible = true;
+      this.addFlag = false;
+    },
+    //删除收入部门
+    handleDelete(index, row) {
+      console.log(index, row);
+      setCostTeam({
+        id: row.id,
+        status: 'DEL'
+      }).then(res => {
+        console.log(res);
+      })
+    },
+    // 提交新增
+    submitForm(formName) {
+      //验证表单
+      this.$refs[formName].validate((valid, value) => {
+        if (valid) {
+          console.log(this.form);
+          if(this.addFlag) {
+            addCostTeam(this.form).then(res => {
+              this.costTeamData.unshift(res.data.data)
+            })
+          } else {
+            this.form.id = this.id;
+            setCostTeam(this.form).then(res => {
+              console.log(res);
+              console.log(this.index)
+              this.costTeamData.splice(this.index, 1, res.data.data)
+              this.$refs[formName].resetFields();
+            })
+          }
+          this.dialogFormVisible = false;
+        } else {
+          return false;
+        }
+      });
+    }  
+  }, 
+}
+</script>
+<style scope>
+  .cost-team {
+    padding: 20px;
+    box-sizing: border-box;
+  }
+  .add {
+    float: right;
+    margin-bottom: 20px;
+  }
+  .right-card {
+    width: 100%;
+    margin: 0 auto;
+  }
+  .demo-table-expand {
+    font-size: 0;
+  }
+  .demo-table-expand label {
+    width: 90px;
+    color: #99a9bf;
+  }
+  .demo-table-expand .el-form-item {
+    margin-right: 0;
+    margin-bottom: 0;
+    width: 50%;
+  }
+</style>
+
+
+
+

+ 176 - 0
src/pages/costType/index.vue

@@ -0,0 +1,176 @@
+<template>
+  <div class="cost-type">
+    <el-button type="primary" class="add" @click="append">增加类别</el-button>
+    <el-card class="right-card">
+      <el-table
+      :data="costTypeData"
+      style="width: 100%">
+        <el-table-column type="expand">
+          <template slot-scope="props">
+            <el-form label-position="left" inline class="demo-table-expand">
+              <el-form-item label="类别名称">
+                <span>{{ props.row.name }}</span>
+              </el-form-item>
+              <el-form-item label="类别 ID">
+                <span>{{ props.row.id }}</span>
+              </el-form-item>
+            </el-form>
+          </template>
+        </el-table-column>
+        <el-table-column
+          label="类别 ID"
+          prop="id">
+        </el-table-column>
+        <el-table-column
+          label="类别名称"
+          prop="name">
+        </el-table-column>
+        <el-table-column label="操作">
+          <template slot-scope="scope">
+            <el-button
+              size="mini"
+              @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
+            <el-button
+              size="mini"
+              type="danger"
+              @click="handleDelete(scope.$index, scope.row)">删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-card>
+    <el-dialog title="新增类别" :visible.sync="dialogFormVisible">     
+      <el-form :model="form" ref="form">
+        <el-form-item label="类别编码" prop="code" :label-width="formLabelWidth" :rules="[{ required: true, message: '编码不能为空'}]">
+          <el-input v-model="form.code" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="类别名称" prop="name" :label-width="formLabelWidth" :rules="[{ required: true, message: '名称不能为空'}]">
+          <el-input v-model="form.name" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="类别状态" prop="status" :label-width="formLabelWidth" :rules="[{ required: true, message: '状态不能为空'}]">
+          <el-select v-model="form.status" placeholder="请选择状态值">
+            <el-option label="正常" value="NORMAL"></el-option>
+            <el-option label="已删除" value="DEL"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="类别排序" prop="sort" :label-width="formLabelWidth" :rules="[
+        { required: true, message: '排序不能为空'},
+        { type: 'number', message: '排序必须为数字值'}
+        ]">
+          <el-input v-model.number="form.sort" autocomplete="off"></el-input>
+        </el-form-item>             
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="resetForm('form')">取 消</el-button>
+        <el-button type="primary" @click="submitForm('form')">确 定</el-button>
+      </div>
+    </el-dialog>    
+  </div>
+</template>
+<script scoped>
+import { getCostTypeList, addCostType, setCostType } from '@/api/costTypeApi'
+export default {
+  data () {
+    return {
+      costTypeData: [],
+      dialogFormVisible: false,
+      addFlag: false,
+      id: '',
+      form: {
+        code: '',
+        name: '',
+        status: '',
+        sort: ''
+      },
+      formLabelWidth: '120px',
+      index: ''      
+    }
+  },
+  created () {
+    getCostTypeList().then(res => {
+      this.costTypeData = res.data.data
+    });
+  },
+  methods: {
+    // 新增类别
+    append() {
+      this.addFlag = true;
+      this.dialogFormVisible = true;
+    },
+    // 编辑类别
+    handleEdit(index, row) {
+      this.form.code = row.code;
+      this.form.name = row.name;
+      this.form.status = row.status;
+      this.form.sort = row.sort;
+      this.id = row.id;
+      this.index = index;
+      this.dialogFormVisible = true;
+      this.addFlag = false;
+    },
+    //删除类别
+    handleDelete(index, row) {
+      console.log(index, row);
+      setCostType({
+        id: row.id,
+        status: 'DEL'
+      }).then(res => {
+        console.log(res);
+      })
+    },
+    // 提交新增
+    submitForm(formName) {
+      //验证表单
+      this.$refs[formName].validate((valid, value) => {
+        if (valid) {
+          console.log(this.form);
+          if(this.addFlag) {
+            addCostType(this.form).then(res => {
+              this.costTypeData.unshift(res.data.data)
+            })
+          } else {
+            this.form.id = this.id;
+            setCostType(this.form).then(res => {
+              console.log(res);
+              console.log(this.index)
+              this.costTypeData.splice(this.index, 1, res.data.data)
+              this.$refs[formName].resetFields();
+            })
+          }
+          this.dialogFormVisible = false;
+        } else {
+          return false;
+        }
+      });
+    }  
+  }, 
+}
+</script>
+<style scope>
+  .cost-type {
+    padding: 20px;
+    box-sizing: border-box;
+  }
+  .add {
+    float: right;
+    margin-bottom: 20px;
+  }
+  .right-card {
+    width: 100%;
+    margin: 0 auto;
+  }
+  .demo-table-expand {
+    font-size: 0;
+  }
+  .demo-table-expand label {
+    width: 90px;
+    color: #99a9bf;
+  }
+  .demo-table-expand .el-form-item {
+    margin-right: 0;
+    margin-bottom: 0;
+    width: 50%;
+  }
+</style>
+
+
+

+ 32 - 0
src/pages/layout/Layout.vue

@@ -0,0 +1,32 @@
+<template>
+    <div class="container">
+        <Nav/>
+        <div class="right">
+            <TitleBar/>
+            <Main/>
+        </div>
+    </div>
+</template>
+<script>
+import Nav from './nav/Nav.vue';
+import TitleBar from './titleBar/TitleBar.vue';
+import Main from './main/Main'
+export default {
+ components: {
+    Nav,
+    TitleBar,
+    Main
+  },
+}
+</script>
+<style>
+    .container {
+        width: 100%;
+        height: 100%;
+    }
+    .right {
+        margin-left: 180px;
+        width: calc(100% - 180px);
+        height: 100%;
+    }
+</style>

+ 28 - 0
src/pages/layout/main/Main.vue

@@ -0,0 +1,28 @@
+<template>
+  <section class="main">
+    <transition name="fade-transform" mode="out-in">
+      <router-view/>
+    </transition>
+  </section>
+</template>
+
+<script>
+export default {
+  name: 'Main',
+  computed: {
+    // key() {
+    //   return this.$route.name !== undefined ? this.$route.name + +new Date() : this.$route + +new Date()
+    // }
+  }
+}
+</script>
+
+<style scoped>
+.main {
+  /*50 = navbar  */
+  min-height: calc(100% - 70px);
+  width: 100%;
+  position: relative;
+  overflow: hidden;
+}
+</style>

+ 52 - 0
src/pages/layout/nav/Nav.vue

@@ -0,0 +1,52 @@
+<template>
+    <div class="nav">
+      <el-menu default-active="1-4-1" class="el-menu-vertical-demo" background-color="#545c64" text-color="#fff" active-text-color="#ffd04b" :router=true :default-active="$route.path">
+        <el-menu-item index="/team/index">
+            <span slot="title">部门</span>
+        </el-menu-item>
+        <el-menu-item index="/project/index">
+            <span slot="title">项目</span>
+        </el-menu-item>
+        <el-menu-item index="/product/index">
+            <span slot="title">产品</span>
+        </el-menu-item>
+        <el-menu-item index="/costType/index">
+            <span slot="title">成本/收入类别</span>
+        </el-menu-item>
+        <el-menu-item index="/costTeam/index">
+            <span slot="title">成本/收入部门</span>
+        </el-menu-item>
+      </el-menu>
+    </div>
+</template>
+<script>
+export default {
+     data() {
+      return {
+        isCollapse: true
+      };
+    },
+    methods: {
+     
+    }
+}
+</script>
+<style>
+    .nav {
+        transition: width 0.28s;
+        width: 180px !important;
+        height: 100%;
+        position: fixed;
+        font-size: 0px;
+        top: 0;
+        bottom: 0;
+        left: 0;
+        z-index: 1001;
+        overflow: hidden;
+    }
+    .el-menu {
+        height: 100%;
+    }
+</style>
+
+

+ 18 - 0
src/pages/layout/titleBar/TitleBar.vue

@@ -0,0 +1,18 @@
+<template>
+  <div class="titleBar"></div>
+</template>
+<script>
+  export default {
+      
+  }
+</script>
+<style>
+  .titleBar {
+    height: 70px;
+    width: 100%;
+    box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12), 0 0 3px 0 rgba(0, 0, 0, 0.04);
+  }
+</style>
+
+
+

+ 176 - 0
src/pages/product/index.vue

@@ -0,0 +1,176 @@
+<template>
+  <div class="product">
+    <el-button type="primary" class="add" @click="append">增加产品</el-button>
+    <el-card class="right-card">
+      <el-table
+      :data="productData"
+      style="width: 100%">
+        <el-table-column type="expand">
+          <template slot-scope="props">
+            <el-form label-position="left" inline class="demo-table-expand">
+              <el-form-item label="产品名称">
+                <span>{{ props.row.name }}</span>
+              </el-form-item>
+              <el-form-item label="产品 ID">
+                <span>{{ props.row.id }}</span>
+              </el-form-item>
+            </el-form>
+          </template>
+        </el-table-column>
+        <el-table-column
+          label="产品 ID"
+          prop="id">
+        </el-table-column>
+        <el-table-column
+          label="产品名称"
+          prop="name">
+        </el-table-column>
+        <el-table-column label="操作">
+          <template slot-scope="scope">
+            <el-button
+              size="mini"
+              @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
+            <el-button
+              size="mini"
+              type="danger"
+              @click="handleDelete(scope.$index, scope.row)">删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-card>
+    <el-dialog title="新增产品" :visible.sync="dialogFormVisible">     
+      <el-form :model="form" ref="form">
+        <el-form-item label="产品编码" prop="code" :label-width="formLabelWidth" :rules="[{ required: true, message: '编码不能为空'}]">
+          <el-input v-model="form.code" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="产品名称" prop="name" :label-width="formLabelWidth" :rules="[{ required: true, message: '名称不能为空'}]">
+          <el-input v-model="form.name" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="产品状态" prop="status" :label-width="formLabelWidth" :rules="[{ required: true, message: '状态不能为空'}]">
+          <el-select v-model="form.status" placeholder="请选择状态值">
+            <el-option label="正常" value="NORMAL"></el-option>
+            <el-option label="已删除" value="DEL"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="产品排序" prop="sort" :label-width="formLabelWidth" :rules="[
+        { required: true, message: '排序不能为空'},
+        { type: 'number', message: '排序必须为数字值'}
+        ]">
+          <el-input v-model.number="form.sort" autocomplete="off"></el-input>
+        </el-form-item>             
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="resetForm('form')">取 消</el-button>
+        <el-button type="primary" @click="submitForm('form')">确 定</el-button>
+      </div>
+    </el-dialog>    
+  </div>
+</template>
+<script scoped>
+import { getProductList, addProduct, setProduct } from '@/api/productApi'
+export default {
+  data () {
+    return {
+      productData: [],
+      dialogFormVisible: false,
+      addFlag: false,
+      id: '',
+      form: {
+        code: '',
+        name: '',
+        status: '',
+        sort: ''
+      },
+      formLabelWidth: '120px',
+      index: ''      
+    }
+  },
+  created () {
+    getProductList().then(res => {
+      this.productData = res.data.data
+    });
+  },
+  methods: {
+    // 新增产品
+    append() {
+      this.addFlag = true;
+      this.dialogFormVisible = true;
+    },
+    // 编辑产品
+    handleEdit(index, row) {
+      this.form.code = row.code;
+      this.form.name = row.name;
+      this.form.status = row.status;
+      this.form.sort = row.sort;
+      this.id = row.id;
+      this.index = index;
+      this.dialogFormVisible = true;
+      this.addFlag = false;
+    },
+    //删除产品
+    handleDelete(index, row) {
+      console.log(index, row);
+      setProduct({
+        id: row.id,
+        status: 'DEL'
+      }).then(res => {
+        console.log(res);
+      })
+    },
+    // 提交新增
+    submitForm(formName) {
+      //验证表单
+      this.$refs[formName].validate((valid, value) => {
+        if (valid) {
+          console.log(this.form);
+          if(this.addFlag) {
+            addProduct(this.form).then(res => {
+              this.productData.unshift(res.data.data)
+            })
+          } else {
+            this.form.id = this.id;
+            setProduct(this.form).then(res => {
+              console.log(res);
+              console.log(this.index)
+              this.productData.splice(this.index, 1, res.data.data)
+              this.$refs[formName].resetFields();
+            })
+          }
+          this.dialogFormVisible = false;
+        } else {
+          return false;
+        }
+      });
+    }  
+  }, 
+}
+</script>
+<style scope>
+  .product {
+    padding: 20px;
+    box-sizing: border-box;
+  }
+  .add {
+    float: right;
+    margin-bottom: 20px;
+  }
+  .right-card {
+    width: 100%;
+    margin: 0 auto;
+  }
+  .demo-table-expand {
+    font-size: 0;
+  }
+  .demo-table-expand label {
+    width: 90px;
+    color: #99a9bf;
+  }
+  .demo-table-expand .el-form-item {
+    margin-right: 0;
+    margin-bottom: 0;
+    width: 50%;
+  }
+</style>
+
+
+

+ 176 - 0
src/pages/project/index.vue

@@ -0,0 +1,176 @@
+<template>
+  <div class="project">
+    <el-button type="primary" class="add" @click="append">增加项目</el-button>
+    <el-card class="right-card">
+      <el-table
+      :data="projectData"
+      style="width: 100%">
+        <el-table-column type="expand">
+          <template slot-scope="props">
+            <el-form label-position="left" inline class="demo-table-expand">
+              <el-form-item label="项目名称">
+                <span>{{ props.row.name }}</span>
+              </el-form-item>
+              <el-form-item label="项目 ID">
+                <span>{{ props.row.id }}</span>
+              </el-form-item>
+            </el-form>
+          </template>
+        </el-table-column>
+        <el-table-column
+          label="项目 ID"
+          prop="id">
+        </el-table-column>
+        <el-table-column
+          label="项目名称"
+          prop="name">
+        </el-table-column>
+        <el-table-column label="操作">
+          <template slot-scope="scope">
+            <el-button
+              size="mini"
+              @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
+            <el-button
+              size="mini"
+              type="danger"
+              @click="handleDelete(scope.$index, scope.row)">删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-card>
+    <el-dialog title="新增项目" :visible.sync="dialogFormVisible">     
+      <el-form :model="form" ref="form">
+        <el-form-item label="项目编码" prop="code" :label-width="formLabelWidth" :rules="[{ required: true, message: '编码不能为空'}]">
+          <el-input v-model="form.code" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="项目名称" prop="name" :label-width="formLabelWidth" :rules="[{ required: true, message: '名称不能为空'}]">
+          <el-input v-model="form.name" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="项目状态" prop="status" :label-width="formLabelWidth" :rules="[{ required: true, message: '状态不能为空'}]">
+          <el-select v-model="form.status" placeholder="请选择状态值">
+            <el-option label="正常" value="NORMAL"></el-option>
+            <el-option label="已删除" value="DEL"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="项目排序" prop="sort" :label-width="formLabelWidth" :rules="[
+        { required: true, message: '排序不能为空'},
+        { type: 'number', message: '排序必须为数字值'}
+        ]">
+          <el-input v-model.number="form.sort" autocomplete="off"></el-input>
+        </el-form-item>             
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="resetForm('form')">取 消</el-button>
+        <el-button type="primary" @click="submitForm('form')">确 定</el-button>
+      </div>
+    </el-dialog>    
+  </div>
+</template>
+<script scoped>
+import { getProjectList, addProject, setProject } from '@/api/projectApi'
+export default {
+  data () {
+    return {
+      projectData: [],
+      dialogFormVisible: false,
+      addFlag: false,
+      id: '',
+      form: {
+        code: '',
+        name: '',
+        status: '',
+        sort: ''
+      },
+      formLabelWidth: '120px',
+      index: ''      
+    }
+  },
+  created () {
+    getProjectList().then(res => {
+      console.log(res)
+      this.projectData = res.data.data
+    });
+  },
+  methods: {
+    // 新增项目
+    append() {
+      this.addFlag = true;
+      this.dialogFormVisible = true;
+    },
+    // 编辑项目
+    handleEdit(index, row) {
+      this.form.code = row.code;
+      this.form.name = row.name;
+      this.form.status = row.status;
+      this.form.sort = row.sort;
+      this.id = row.id;
+      this.index = index;
+      this.dialogFormVisible = true;
+      this.addFlag = false;
+    },
+    //删除项目
+    handleDelete(index, row) {
+      console.log(index, row);
+      setProject({
+        id: row.id,
+        status: 'DEL'
+      }).then(res => {
+        console.log(res);
+      })
+    },
+    // 提交新增
+    submitForm(formName) {
+      //验证表单
+      this.$refs[formName].validate((valid, value) => {
+        if (valid) {
+          console.log(this.form);
+          if(this.addFlag) {
+            addProject(this.form).then(res => {
+              this.projectData.unshift(res.data.data)
+            })
+          } else {
+            this.form.id = this.id;
+            setProject(this.form).then(res => {
+              console.log(res);
+              console.log(this.index)
+              this.projectData.splice(this.index, 1, res.data.data)
+              this.$refs[formName].resetFields();
+            })
+          }
+          this.dialogFormVisible = false;
+        } else {
+          return false;
+        }
+      });
+    }  
+  }, 
+}
+</script>
+<style scope>
+  .project {
+    padding: 20px;
+    box-sizing: border-box;
+  }
+  .add {
+    float: right;
+    margin-bottom: 20px;
+  }
+  .right-card {
+    width: 100%;
+    margin: 0 auto;
+  }
+  .demo-table-expand {
+    font-size: 0;
+  }
+  .demo-table-expand label {
+    width: 90px;
+    color: #99a9bf;
+  }
+  .demo-table-expand .el-form-item {
+    margin-right: 0;
+    margin-bottom: 0;
+    width: 50%;
+  }
+</style>
+
+

+ 240 - 0
src/pages/team/index.vue

@@ -0,0 +1,240 @@
+<template>
+  <div class="team">
+    <el-card class="left-card">
+      <el-tree
+        ref="tree"
+        :data="teamData"
+        node-key="id"
+        highlight-current
+        :expand-on-click-node="false"
+        @node-click="currentKey">
+        <span class="custom-tree-node" slot-scope="{ node, data }">
+          <span>{{ node.label }}</span>
+          <span>
+            <el-button
+              type="text"
+              size="mini"
+              @click.stop="() => append(node, data)">
+              Append
+            </el-button>
+            <!--
+            <el-button
+              type="text"
+              size="mini"
+              @click.stop="() => remove(node, data)">
+              Delete
+            </el-button>
+            -->
+          </span>
+        </span>        
+      </el-tree>
+    </el-card> 
+    <el-card class="right-card">
+      <el-table
+      :data="teamChildData"
+      style="width: 100%">
+        <el-table-column type="expand">
+          <template slot-scope="props">
+            <el-form label-position="left" inline class="demo-table-expand">
+            <el-form-item label="部门名称">
+                <span>{{ props.row.name }}</span>
+              </el-form-item>
+              <el-form-item label="部门 ID">
+                <span>{{ props.row.id }}</span>
+              </el-form-item>
+              <el-form-item label="部门分类">
+                <span>{{ props.row.category }}</span>
+              </el-form-item>
+              <el-form-item label="上级部门">
+                <span>{{ props.row.desc }}</span>
+              </el-form-item>
+            </el-form>
+          </template>
+        </el-table-column>
+        <el-table-column
+          label="部门 ID"
+          prop="id">
+        </el-table-column>
+        <el-table-column
+          label="部门名称"
+          prop="name">
+        </el-table-column>
+        <el-table-column
+          label="上级部门"
+          prop="desc">
+        </el-table-column>
+        <el-table-column label="操作">
+          <template slot-scope="scope">
+            <el-button
+              size="mini"
+              @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
+            <!--  
+            <el-button
+              size="mini"
+              type="danger"
+              @click="handleDelete(scope.$index, scope.row)">删除</el-button>
+            -->
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-card>
+    <el-dialog title="新增部门" :visible.sync="dialogFormVisible">     
+      <el-form :model="form" ref="form">
+        <el-form-item label="部门编码" prop="code" :label-width="formLabelWidth" :rules="[{ required: true, message: '编码不能为空'}]">
+          <el-input v-model="form.code" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="部门名称" prop="name" :label-width="formLabelWidth" :rules="[{ required: true, message: '名称不能为空'}]">
+          <el-input v-model="form.name" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="部门状态" prop="status" :label-width="formLabelWidth" :rules="[{ required: true, message: '状态不能为空'}]">
+          <el-select v-model="form.status" placeholder="请选择状态值">
+            <el-option label="正常" value="NORMAL"></el-option>
+            <el-option label="已删除" value="DEL"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="部门排序" prop="sort" :label-width="formLabelWidth" :rules="[
+        { required: true, message: '排序不能为空'},
+        { type: 'number', message: '排序必须为数字值'}
+        ]">
+          <el-input v-model.number="form.sort" autocomplete="off"></el-input>
+        </el-form-item>             
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="resetForm('form')">取 消</el-button>
+        <el-button type="primary" @click="submitForm('form')">确 定</el-button>
+      </div>
+    </el-dialog>    
+  </div>
+</template>
+<script scoped>
+import { getTeamList, getTeamChildList, addTeam, setTeam } from '@/api/teamApi'
+export default {
+  data () {
+    return {
+      teamData: [],
+      teamChildData: [],
+      dialogFormVisible: false,
+      addFlag: false,
+      id: '',
+      form: {
+        path: '',
+        code: '',
+        name: '',
+        status: '',
+        sort: ''
+      },
+      formLabelWidth: '120px',
+      index: ''      
+    }
+  },
+  created () {
+    getTeamList().then(res => {
+      console.log(res.data.data.children)
+      this.teamData = res.data.data.children
+    });
+  },
+  methods: {
+    // 新增部门
+    append(node, data) {
+      this.addFlag = true;
+      this.dialogFormVisible = true;
+      this.form.path = data.id;
+    },
+    // 删除部门
+    // remove(node, data) {
+    //   console.log(data.id)
+    //   const parent = node.parent;
+    //   const children = parent.data.children || parent.data;
+    //   const index = children.findIndex(d => d.id === data.id);
+    //   children.splice(index, 1);
+    //   setTeam({
+    //     id: data.id,
+    //     status: 'DEL'
+    //   }).then( res => {
+    //       console.log(res)
+    //   })
+    // },
+    //选择节点
+    currentKey(val) {
+      getTeamChildList(val.id).then( res => {
+        console.log(res.data.data)
+        this.teamChildData = res.data.data
+      })
+    },
+    // 编辑部门
+    handleEdit(index, row) {
+      console.log(index, row);
+      this.form.code = row.code;
+      this.form.name = row.name;
+      this.form.status = row.status;
+      this.form.sort = row.sort;
+      this.form.path = row.path;
+      this.id = row.id;
+      this.index = index;
+      this.dialogFormVisible = true;
+      this.addFlag = false;
+    },
+    handleDelete(index, row) {
+      console.log(index, row);
+    },
+    // 提交新增
+    submitForm(formName) {
+      //验证表单
+      this.$refs[formName].validate((valid, value) => {
+        if (valid) {
+          console.log(this.form);
+          if(this.addFlag) {
+            addTeam(this.form).then(res => {
+              console.log(res.data.data.name)
+              //追加元素
+              this.$refs.tree.append({
+                id: res.data.data.id,
+                label: res.data.data.name
+              }, this.form.path)
+              this.$refs[formName].resetFields();
+            })
+          } else {
+            this.form.id = this.id;
+            setTeam(this.form).then(res => {
+              console.log(res);
+              console.log(this.index)
+              this.teamChildData.splice(this.index, 1, res.data.data)
+              this.$refs[formName].resetFields();
+            })
+          }
+          this.dialogFormVisible = false;
+        } else {
+          return false;
+        }
+      });
+    }  
+  }, 
+}
+</script>
+<style scope>
+  .team {
+    display: flex;
+    justify-content: space-between; 
+    padding: 20px;
+    box-sizing: border-box;
+  }
+  .left-card {
+    width: 25%;
+  }
+  .right-card {
+    width: 70%;
+  }
+  .demo-table-expand {
+    font-size: 0;
+  }
+  .demo-table-expand label {
+    width: 90px;
+    color: #99a9bf;
+  }
+  .demo-table-expand .el-form-item {
+    margin-right: 0;
+    margin-bottom: 0;
+    width: 50%;
+  }
+</style>
+

+ 72 - 0
src/router/index.js

@@ -0,0 +1,72 @@
+import Vue from 'vue';
+import Router from 'vue-router';
+
+Vue.use(Router);
+
+import Layout from '../pages/layout/Layout.vue';
+// import Team from '../pages/team/index'
+
+export const pageRoter = [
+    {
+        path: '/',
+        component: Layout,
+        redirect: '/team/index',
+        // name: 'Team',
+        // hidden: true,
+        // children: [{
+        //   path: 'team',
+        //   component: {template:"<div>有机蔬菜organic</div>"}
+        // }]
+    },
+    {
+        path: '/team',
+        component: Layout,
+        children: [{
+          path: 'index',
+          name:'Team', 
+          component: () => import('@/pages/team/index'),
+        }]
+    },
+    {
+        path: '/project',
+        component: Layout,
+        children: [{
+          path: 'index',
+          name:'Project', 
+          component: () => import('@/pages/project/index'),
+        }]
+    },
+    {
+        path: '/product',
+        component: Layout,
+        children: [{
+          path: 'index',
+          name:'Product', 
+          component: () => import('@/pages/product/index'),
+        }]
+    },
+    {
+        path: '/costType',
+        component: Layout,
+        children: [{
+          path: 'index',
+          name:'CostType', 
+          component: () => import('@/pages/costType/index'),
+        }]
+    },
+    {
+        path: '/costTeam',
+        component: Layout,
+        children: [{
+          path: 'index',
+          name:'CostTeam', 
+          component: () => import('@/pages/costTeam/index'),
+        }]
+    }
+]
+
+export default new Router({
+    // mode: 'history', //后端支持可开
+    scrollBehavior: () => ({ y: 0 }),
+    routes: pageRoter
+})

+ 2 - 0
src/utils/config.js

@@ -0,0 +1,2 @@
+export const baseApi =  'https://readertest.lingjiao.cn/' 
+    

+ 11 - 11
src/utils/request.js

@@ -7,17 +7,17 @@ const service = axios.create({
 })
 
 // request拦截器
-service.interceptors.request.use(config => {
-// Do something before request is sent
-    if (store.getters.token) {
-        config.headers['X-Token'] = getToken() // 让每个请求携带token--['X-Token']为自定义key 请根据实际情况自行修改
-    }
-    return config
-    }, error => {
-    // Do something with request error
-    console.log(error) // for debug
-    Promise.reject(error)
-})
+// service.interceptors.request.use(config => {
+// // Do something before request is sent
+//     if (store.getters.token) {
+//         config.headers['X-Token'] = getToken() // 让每个请求携带token--['X-Token']为自定义key 请根据实际情况自行修改
+//     }
+//     return config
+//     }, error => {
+//     // Do something with request error
+//     console.log(error) // for debug
+//     Promise.reject(error)
+// })
 
 // respone拦截器
 service.interceptors.response.use(

+ 6 - 2
webpack.config.js

@@ -52,7 +52,7 @@ var config = {
         ]
     },
     resolve: {
-        extensions: ['.js', '.jsx','.ts','.tsx', '.scss','.json','.css'],
+        extensions: ['.js', '.jsx','.ts','.tsx', '.scss','.json','.css', '.vue'],
         alias: {
             'vue$': 'vue/dist/vue.esm.js',
             "@": path.resolve(__dirname, 'src'),
@@ -68,7 +68,11 @@ var config = {
         }),
         new VueLoaderPlugin(),
         new webpack.HotModuleReplacementPlugin()
-    ]
+    ],
+    devServer: {
+        historyApiFallback: true,
+        noInfo: true
+    }
 }
 
 module.exports = config;