Bladeren bron

费用报销

lilei 3 jaren geleden
bovenliggende
commit
72c099089c

+ 96 - 0
src/config/router.config.js

@@ -591,6 +591,102 @@ export const asyncRouterMap = [
           }
         ]
       },
+      // 费用报销
+      {
+        path: '/expenseManagement',
+        redirect: '/expenseManagement/expenseReimbursement',
+        component: PageView,
+        meta: {
+          title: '费用报销',
+          icon: 'account-book'
+          // permission: 'M_salesManagement'
+        },
+        children: [
+          {
+            path: '/expenseManagement/expenseReimbursement',
+            redirect: '/expenseManagement/expenseReimbursement/list',
+            name: 'expenseReimbursement',
+            component: BlankLayout,
+            meta: {
+              title: '费用报销单',
+              icon: 'monitor'
+              // permission: 'M_salesQueryList'
+            },
+            hideChildrenInMenu: true,
+            children: [
+              {
+                path: 'list',
+                name: 'expenseReimbursementList',
+                component: () => import(/* webpackChunkName: "expenseManagement" */ '@/views/expenseManagement/expenseReimbursement/list.vue'),
+                meta: {
+                  title: '费用报销单列表',
+                  icon: 'monitor',
+                  hidden: true
+                  // permission: 'M_salesQueryList'
+                }
+              },
+              {
+                path: 'detail/:sn',
+                name: 'expenseReimbursementListDetail',
+                component: () => import(/* webpackChunkName: "expenseManagement" */ '@/views/expenseManagement/expenseReimbursement/detail.vue'),
+                meta: {
+                  title: '费用报销单详情',
+                  icon: 'monitor',
+                  hidden: true
+                  // permission: 'M_salesDetail'
+                }
+              },
+              {
+                path: 'add',
+                name: 'expenseReimbursementAdd',
+                component: () => import(/* webpackChunkName: "expenseManagement" */ '@/views/expenseManagement/expenseReimbursement/add.vue'),
+                meta: {
+                  title: '新增费用报销单',
+                  icon: 'monitor',
+                  hidden: true
+                  // permission: 'M_salesNew'
+                }
+              },
+              {
+                path: 'edit/:sn',
+                name: 'expenseReimbursementEdit',
+                component: () => import(/* webpackChunkName: "expenseManagement" */ '@/views/expenseManagement/expenseReimbursement/add.vue'),
+                meta: {
+                  title: '编辑费用报销单',
+                  icon: 'monitor',
+                  hidden: true
+                  // permission: 'M_salesNew'
+                }
+              }
+            ]
+          },
+          {
+            path: '/expenseManagement/expenseReimbursementDetail',
+            redirect: '/expenseManagement/expenseReimbursementDetail/list',
+            name: 'expenseReimbursementDetail',
+            component: BlankLayout,
+            meta: {
+              title: '费用报销明细统计',
+              icon: 'audit'
+              // permission: 'M_examineVerifyList'
+            },
+            hideChildrenInMenu: true,
+            children: [
+              {
+                path: 'list',
+                name: 'expenseReimbursementDetailList',
+                component: () => import(/* webpackChunkName: "expenseManagement" */ '@/views/expenseManagement/expenseReimbursementDetail/list.vue'),
+                meta: {
+                  title: '费用报销明细统计列表',
+                  icon: 'audit',
+                  hidden: true
+                  // permission: 'M_examineVerifyList'
+                }
+              }
+            ]
+          }
+        ]
+      },
       // 库存管理
       {
         path: '/inventoryManagement',

+ 102 - 0
src/views/common/area.js

@@ -0,0 +1,102 @@
+import { getArea } from '@/api/data'
+const Area = {
+  template: `
+        <a-select
+          :id="id"
+          :placeholder="placeholder"
+          allowClear
+          :value="defaultVal"
+          :showSearch="true"
+          @change="handleChange"
+          :filter-option="filterOption">
+          <a-select-option v-for="item in list" :key="item[defValKey]" :value="item[defValKey]">{{ item.name }}</a-select-option>
+        </a-select>
+    `,
+  props: {
+    value: {
+      type: String,
+      defatut: ''
+    },
+    id: {
+      type: String,
+      default: ''
+    },
+    defValKey: {
+      type: String,
+      default: 'areaSn'
+    },
+    placeholder: {
+      type: String,
+      default: '请选择'
+    },
+    leve: {
+      type: String,
+      default: 'province'
+    },
+    parentId: {
+      type: String,
+      default: ''
+    }
+  },
+  data() {
+    return {
+      defaultVal: this.value,
+      list: []
+    };
+  },
+  watch: {
+    value(newValue, oldValue) {
+      console.log(newValue)
+      this.defaultVal = newValue
+    },
+    parentId(newValue,oldValue){
+      if(this.leve != 'province'&&newValue){
+        this.getList(this.leve)
+      }
+    }
+  },
+  mounted() {
+    if(this.leve == 'province'){
+      this.getList(this.leve)
+    }
+  },
+  methods: {
+    filterOption (input, option) {
+      return (
+        option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
+      )
+    },
+    handleChange(value) {
+      console.log(value)
+      this.defaultVal = value;
+      const item = this.list.find(item => item[this.defValKey] == value)
+      this.$emit('change', this.value, item);
+      this.$emit('input', value);
+    },
+    //  省/市/区
+    getList (leve) {
+      let params
+      if (leve == 'province') {
+        params = { type: '2' }
+      } else {
+        params = { parentId: this.parentId, type: leve == 'city' ? '3' : '4' }
+      }
+      console.log(params)
+      getArea(params).then(res => {
+        if (res.status == 200) {
+          if (leve == 'province') {
+            this.list = res.data || []
+          } else if (leve == 'city') {
+            this.list = res.data || []
+          } else if (leve == 'district') {
+            this.list = res.data || []
+          }
+        } else {
+          this.list = []
+        }
+      })
+    },
+  },
+};
+
+export default Area

+ 16 - 2
src/views/common/custList.vue

@@ -4,7 +4,7 @@
     label-in-value
     :size="size"
     :value="dealerName"
-    placeholder="请输入名称搜索"
+    :placeholder="placeholder"
     style="width: 100%"
     :filter-option="false"
     :not-found-content="fetching ? undefined : null"
@@ -24,6 +24,10 @@ import debounce from 'lodash/debounce'
 import { dealerQueryList, dealerFindUpdateInfoBySn } from '@/api/dealer'
 export default {
   props: {
+    id: {
+      type: String,
+      default: ''
+    },
     size: {
       type: String,
       default: 'default'
@@ -31,6 +35,10 @@ export default {
     itemSn: {
       type: String || Number,
       default: undefined
+    },
+    placeholder: {
+      type: String,
+      default: '请输入名称搜索'
     }
   },
   data () {
@@ -65,12 +73,14 @@ export default {
       })
     },
     handleChange (value) {
+      const row = this.data.filter(item => item.dealerSn == value.key)
       Object.assign(this, {
         dealerName: value,
         data: [],
         fetching: false
       })
-      this.$emit('change', value || { key: undefined })
+      this.$emit('change', value || { key: undefined }, row[0], this.id)
+      // this.$emit('input', value.key)
     },
     resetForm () {
       this.dealerName = []
@@ -87,6 +97,10 @@ export default {
         data: [],
         fetching: false
       })
+    },
+    setDufaultVal (itemSn) {
+      this.fetchUser(itemSn)
+      this.setData({ key: itemSn })
     }
   },
   mounted () {

+ 120 - 0
src/views/common/dingDepartUser.js

@@ -0,0 +1,120 @@
+import { getDingTalkDepartmentList, queryDingTalkDeptUser } from '@/api/expenseManagement'
+const DingDepartUser = {
+  template: `
+      <a-tree-select
+          :value="defaultVal"
+          tree-data-simple-mode
+          style="width: 100%"
+          :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
+          :tree-data="treeData"
+          :placeholder="placeholder"
+          :load-data="onLoadData"
+          multiple
+          treeCheckable
+          treeNodeFilterProp="title"
+          @change="handleChange"
+        />
+    `,
+  props: {
+    value: {
+      type: Array,
+      defatut: function(){
+        return []
+      }
+    },
+    id: {
+      type: String,
+      default: ''
+    },
+    placeholder: {
+      type: String,
+      default: '请选择人员'
+    }
+  },
+  data() {
+    return {
+      defaultVal: this.value,
+      treeData: []
+    };
+  },
+  mounted() {
+    this.genTreeNode(1)
+  },
+  watch: {
+    value(newValue, oldValue) {
+      this.defaultVal = newValue
+    },
+  },
+  methods: {
+    filterOption (input, option) {
+      return (
+        option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
+      )
+    },
+    handleChange(value) {
+      console.log(value);
+      this.defaultVal = value;
+      const row = this.treeData.find(item => item.brandSn == value)
+      this.$emit('change', value, this.id, row);
+      this.$emit('input', value);
+    },
+    // 格式化数据
+    formatData(data,type){
+      const ret = []
+      data.map(item => {
+        if(type == 'bm'){
+          ret.push({
+            title: item.name,
+            id:item.deptId,
+            value: item.deptId,
+            pId: item.parentId,
+            autoAddUser: item.autoAddUser,
+            createDeptGroup: item.createDeptGroup,
+            disableCheckbox: true,
+            checkable: false
+          })
+        }else{
+          ret.push({
+            title: item.name,
+            id:item.userid,
+            value: item.userid,
+            pId: item.parentId,
+            avatar: item.avatar,
+            leader: item.leader,
+            boss: item.boss,
+            admin: item.admin,
+            active: item.active,
+            userid: item.userid,
+            isLeaf: true
+          })
+        }
+      })
+      return ret
+    },
+    // 获取部门
+    genTreeNode(parentId, isLeaf = false) {
+       Promise.all([
+         getDingTalkDepartmentList({deptId:parentId}),
+         queryDingTalkDeptUser({deptId:parentId,pageNo:1,pageSize:10})
+         ]).then(res => {
+          const res1 = res[0].data||[]
+          const res2 = res[1].data||[]
+          this.treeData = this.treeData.concat(this.formatData(res1,'bm')).concat(this.formatData(res2,'yg'));
+          if(res1.length==0&&res2.length==0){
+            this.$message.info("没有下一级了")
+          }
+       })
+    },
+    onLoadData(treeNode) {
+      return new Promise(resolve => {
+        const { value } = treeNode.dataRef;
+         this.genTreeNode(value)
+         setTimeout(()=>{
+           resolve();
+         },1000)
+      });
+    },
+  },
+};
+
+export default DingDepartUser

+ 2 - 1
src/views/common/productBrand.js

@@ -57,7 +57,8 @@ const ProductBrand = {
     },
     handleChange(value) {
       this.defaultVal = value;
-      this.$emit('change', value);
+      const row = this.productBrandList.find(item => item.brandSn == value)
+      this.$emit('change', value, this.id, row);
       this.$emit('input', value);
     },
     //  产品品牌列表, sysFlag: 1 箭冠 0 自建

+ 9 - 1
src/views/common/productCodeList.vue

@@ -26,6 +26,10 @@ export default {
     mode: {
       type: String,
       default: 'default'
+    },
+    id: {
+      type: String,
+      default: ''
     }
   },
   data () {
@@ -79,11 +83,15 @@ export default {
         data: [],
         fetching: false
       })
-      this.$emit('change', value || { key: undefined })
+      this.$emit('change', value || { key: undefined }, this.id)
     },
     resetForm () {
       this.dealerName = undefined
     },
+    setDufaultVal (itemSn) {
+      this.fetchUser(itemSn)
+      this.setData({ key: itemSn })
+    },
     setData (value) {
       Object.assign(this, {
         dealerName: value,

+ 5 - 2
src/views/common/productType.js

@@ -39,9 +39,12 @@ const ProductType = {
     this.getProductType()
   },
   methods: {
-    handleChange (value) {
+    setDefValue(defaultVal){
+      this.handleChange(defaultVal)
+    },
+    handleChange (value,row) {
       this.defaultVal = value
-      this.$emit('change', this.defaultVal)
+      this.$emit('change', this.defaultVal, this.id,row)
       this.$emit('input', this.defaultVal)
     },
     //  产品分类列表

+ 87 - 0
src/views/common/productTypeAll.js

@@ -0,0 +1,87 @@
+import { productTypeQueryAll } from '@/api/productType'
+const ProductType = {
+  template: `
+      <a-cascader
+        @change="handleChange"
+        change-on-select
+        :value="defaultVal"
+        expand-trigger="hover"
+        :options="productTypeList"
+        :fieldNames="{ label: 'productTypeName', value: 'productTypeSn', children: 'children' }"
+        :id="id"
+        placeholder="请选择产品分类"
+        allowClear />
+    `,
+  props: {
+    value: {
+      type: Array,
+      defatut: function () {
+        return []
+      }
+    },
+    id: {
+      type: String,
+      default: ''
+    }
+  },
+  data () {
+    return {
+      defaultVal: this.value,
+      productTypeList: []
+    }
+  },
+  watch: {
+    value (newValue, oldValue) {
+      this.defaultVal = newValue
+    }
+  },
+  mounted () {
+    this.getProductType()
+  },
+  methods: {
+    setDefValue(defaultVal){
+      this.handleChange(defaultVal)
+    },
+    handleChange (value,row) {
+      this.defaultVal = value
+      this.$emit('change', this.defaultVal, this.id,row)
+      this.$emit('input', this.defaultVal)
+    },
+    //  产品分类  列表
+    getProductType () {
+      productTypeQueryAll({}).then(res => {
+        if (res.status == 200) {
+          if (res.data && res.data.length > 0) {
+            //  递归处理disabled禁用
+            this.recursionFun(res.data, false)
+            this.productTypeList = res.data
+          } else {
+            this.productTypeList = []
+          }
+        } else {
+          this.productTypeList = []
+        }
+      })
+    },
+    //  递归函数
+    recursionFun (data, state) {
+      if (data) {
+        data.map((item, index) => {
+          // enabledFlag为0表示禁用,父级禁用则子级也为禁用
+          if ((item.enabledFlag && item.enabledFlag == 0) || state) {
+            item.disabled = true
+          } else {
+            item.disabled = false
+          }
+          if (item.children && item.children.length == 0) {
+            delete item.children
+          } else {
+            this.recursionFun(item.children, item.disabled)
+          }
+        })
+      }
+    },
+  }
+}
+
+export default ProductType

+ 25 - 4
src/views/common/subarea.js

@@ -3,9 +3,10 @@ const Subarea = {
   template: `
         <a-select
           :id="id"
-          placeholder="请选择分区"
+          :placeholder="placeholder"
           allowClear
           :value="defaultVal"
+          :mode="mode"
           :showSearch="true"
           @change="handleChange"
           :filter-option="filterOption">
@@ -14,9 +15,13 @@ const Subarea = {
     `,
   props: {
     value: {
-      type: String,
+      type: [String,Array],
       defatut: ''
     },
+    mode: {
+      type: String,
+      default:'default'
+    },
     id: {
       type: String,
       default: ''
@@ -24,6 +29,10 @@ const Subarea = {
     defValKey: {
       type: String,
       default: 'subareaSn'
+    },
+    placeholder: {
+      type: String,
+      default: '请选择分区'
     }
   },
   data() {
@@ -34,7 +43,6 @@ const Subarea = {
   },
   watch: {
     value(newValue, oldValue) {
-      console.log(newValue)
       this.defaultVal = newValue
     }
   },
@@ -50,7 +58,14 @@ const Subarea = {
     handleChange(value) {
       console.log(value)
       this.defaultVal = value;
-      this.$emit('change', this.value);
+      const item = this.list.filter(item =>{
+        if(this.mode !== 'multiple'){
+          return item[this.defValKey] == value
+        }else{
+          return value.includes(item[this.defValKey])
+        }
+      })
+      this.$emit('change', value, item);
       this.$emit('input', value);
     },
     // 列表数据
@@ -64,6 +79,12 @@ const Subarea = {
         }
       })
     },
+    // 根据名称数组 返回对应的 sn 数组
+    getValByName(data){
+      let ret = []
+      this.list.filter(item => data.includes(item.subareaName)).map(item => ret.push(item.subareaSn))
+      return ret
+    }
   },
 };
 

+ 70 - 0
src/views/common/supplier.js

@@ -0,0 +1,70 @@
+import { supplierAllList } from '@/api/supplier.js'
+const Employee = {
+  template: `
+      <a-select
+        :placeholder="placeholder"
+        :id="id"
+        allowClear
+        :value="defaultVal"
+        :showSearch="true"
+        @change="handleChange"
+        option-filter-prop="children"
+        :filter-option="filterOption">
+        <a-select-option v-for="item in list" :key="item.supplierSn" :value="item.supplierSn">
+        {{ item.supplierName }}
+        </a-select-option>
+      </a-select>
+    `,
+  props: {
+    value: {
+      type: String,
+      defatut: ''
+    },
+    id: {
+      type: String,
+      default: ''
+    },
+    placeholder: {
+      type: String,
+      default: '请选择供应商'
+    },
+  },
+  data() {
+    return {
+      defaultVal: this.value,
+      list: []
+    };
+  },
+  mounted() {
+    this.getList()
+  },
+  watch: {
+    value(newValue, oldValue) {
+      this.defaultVal = newValue
+    },
+  },
+  methods: {
+    filterOption (input, option) {
+      return (
+        option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
+      )
+    },
+    handleChange(value) {
+      this.defaultVal = value;
+      const item = this.list.find(item => item.supplierSn == value)
+      this.$emit('change', value, item);
+      this.$emit('input', value);
+    },
+    getList () {
+      supplierAllList({}).then(res => {
+        if (res.status == 200) {
+          this.list = res.data
+        } else {
+          this.list = []
+        }
+      })
+    },
+  },
+};
+
+export default Employee