jiangping
2025-07-03 cd1eb4f48fbbba55154e9aec80ec93f48e9c075b
代码初始化
已添加1个文件
已删除28个文件
已修改15个文件
412 ■■■■ 文件已修改
admin/.env.development 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/.env.production 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/lianhelihua_admin/avatar/man.png 补丁 | 查看 | 原始文档 | blame | 历史
admin/lianhelihua_admin/avatar/woman.png 补丁 | 查看 | 原始文档 | blame | 历史
admin/lianhelihua_admin/favicon.ico 补丁 | 查看 | 原始文档 | blame | 历史
admin/lianhelihua_admin/icon.jpg 补丁 | 查看 | 原始文档 | blame | 历史
admin/lianhelihua_admin/icon.png 补丁 | 查看 | 原始文档 | blame | 历史
admin/lianhelihua_admin/index.html 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/lianhelihua_admin/static/css/chunk-vendors.d9e68312.css 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/lianhelihua_admin/static/fonts/element-icons.535877f5.woff 补丁 | 查看 | 原始文档 | blame | 历史
admin/lianhelihua_admin/static/fonts/element-icons.732389de.ttf 补丁 | 查看 | 原始文档 | blame | 历史
admin/lianhelihua_admin/static/img/404-tip.4d90651f.png 补丁 | 查看 | 原始文档 | blame | 历史
admin/lianhelihua_admin/static/img/404.5c17595f.png 补丁 | 查看 | 原始文档 | blame | 历史
admin/lianhelihua_admin/static/img/bg_shenhe@2x.632406ea.png 补丁 | 查看 | 原始文档 | blame | 历史
admin/lianhelihua_admin/static/img/bg_shenhe_pass@2x.356d8eee.png 补丁 | 查看 | 原始文档 | blame | 历史
admin/lianhelihua_admin/static/img/department.9b0b5285.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/lianhelihua_admin/static/img/dictionary.a4f7c09e.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/lianhelihua_admin/static/img/listener.770879d4.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/lianhelihua_admin/static/img/log-login.2ddfaaaf.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/lianhelihua_admin/static/img/log-opera.af0a9111.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/lianhelihua_admin/static/img/log.6aa1794b.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/lianhelihua_admin/static/img/login.97bc0f97.png 补丁 | 查看 | 原始文档 | blame | 历史
admin/lianhelihua_admin/static/img/logo.32e88954.png 补丁 | 查看 | 原始文档 | blame | 历史
admin/lianhelihua_admin/static/img/man.6eaa0e37.png 补丁 | 查看 | 原始文档 | blame | 历史
admin/lianhelihua_admin/static/img/permission.e4625523.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/lianhelihua_admin/static/img/position.84d5bc25.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/lianhelihua_admin/static/img/pwd.f269b92a.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/lianhelihua_admin/static/img/role.f81aee2b.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/lianhelihua_admin/static/img/shield.7b210670.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/lianhelihua_admin/static/img/woman.e651ccdb.png 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/api/business/company.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/components/business/OperaManagersWindow.vue 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/components/common/Tree.vue 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/components/common/TreeNew.vue 145 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/business/company.vue 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/business/companyMember.vue 27 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/com/doumee/api/business/CompanyController.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/com/doumee/api/common/PublicCloudController.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/com/doumee/dao/business/model/Company.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/com/doumee/service/business/impl/CompanyServiceImpl.java 23 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/com/doumee/service/business/impl/MemberServiceImpl.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/resources/application-pro.yml 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/resources/application.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/.env.development
@@ -1,3 +1,4 @@
# å¼€å‘环境配置
NODE_ENV = 'development'
VUE_APP_API_URL  = 'http://localhost:10010'
#VUE_APP_API_URL  = 'http://localhost:10010'
VUE_APP_API_URL  = 'https://lkshereporting.unilever-china.com/lianhelihua_interface'
admin/.env.production
@@ -4,4 +4,4 @@
# å…³é—­DEBUG
VUE_APP_DEBUG = 'off'
VUE_APP_API_URL  = 'https://dmtest.ahapp.net/lianhelihua_interface'
VUE_APP_API_URL  = 'https://lkshereporting.unilever-china.com/lianhelihua_interface'
admin/lianhelihua_admin/avatar/man.png
Binary files differ
admin/lianhelihua_admin/avatar/woman.png
Binary files differ
admin/lianhelihua_admin/favicon.ico
Binary files differ
admin/lianhelihua_admin/icon.jpg
Binary files differ
admin/lianhelihua_admin/icon.png
Binary files differ
admin/lianhelihua_admin/index.html
ÎļþÒÑɾ³ý
admin/lianhelihua_admin/static/css/chunk-vendors.d9e68312.css
ÎļþÒÑɾ³ý
admin/lianhelihua_admin/static/fonts/element-icons.535877f5.woff
Binary files differ
admin/lianhelihua_admin/static/fonts/element-icons.732389de.ttf
Binary files differ
admin/lianhelihua_admin/static/img/404-tip.4d90651f.png
Binary files differ
admin/lianhelihua_admin/static/img/404.5c17595f.png
Binary files differ
admin/lianhelihua_admin/static/img/bg_shenhe@2x.632406ea.png
Binary files differ
admin/lianhelihua_admin/static/img/bg_shenhe_pass@2x.356d8eee.png
Binary files differ
admin/lianhelihua_admin/static/img/department.9b0b5285.svg
ÎļþÒÑɾ³ý
admin/lianhelihua_admin/static/img/dictionary.a4f7c09e.svg
ÎļþÒÑɾ³ý
admin/lianhelihua_admin/static/img/listener.770879d4.svg
ÎļþÒÑɾ³ý
admin/lianhelihua_admin/static/img/log-login.2ddfaaaf.svg
ÎļþÒÑɾ³ý
admin/lianhelihua_admin/static/img/log-opera.af0a9111.svg
ÎļþÒÑɾ³ý
admin/lianhelihua_admin/static/img/log.6aa1794b.svg
ÎļþÒÑɾ³ý
admin/lianhelihua_admin/static/img/login.97bc0f97.png
Binary files differ
admin/lianhelihua_admin/static/img/logo.32e88954.png
Binary files differ
admin/lianhelihua_admin/static/img/man.6eaa0e37.png
Binary files differ
admin/lianhelihua_admin/static/img/permission.e4625523.svg
ÎļþÒÑɾ³ý
admin/lianhelihua_admin/static/img/position.84d5bc25.svg
ÎļþÒÑɾ³ý
admin/lianhelihua_admin/static/img/pwd.f269b92a.svg
ÎļþÒÑɾ³ý
admin/lianhelihua_admin/static/img/role.f81aee2b.svg
ÎļþÒÑɾ³ý
admin/lianhelihua_admin/static/img/shield.7b210670.svg
ÎļþÒÑɾ³ý
admin/lianhelihua_admin/static/img/woman.e651ccdb.png
Binary files differ
admin/src/api/business/company.js
@@ -12,6 +12,11 @@
    trim: true
  })
}
export function allList (data) {
  return request.post('/business/company/list', encryptData(data), {
    trim: true
  })
}
export function treeWithMember (data) {
  return request.post('/business/company/treeWithMember', encryptData(data), {
    trim: true
admin/src/components/business/OperaManagersWindow.vue
@@ -31,8 +31,8 @@
            default-expand-all
            @check-change="changeTree"
            :expand-on-click-node="false"
            :check-on-click-node="true"
            :props="{children: 'childList',label: 'name'}">
            :check-on-click-node="false"
            :props="{id:'id',children: 'childList',label: 'name',isLeaf:'isLeaf'}">
        </el-tree>
      </el-form-item>
      <el-form-item  label="选择负责人:" prop="memberIds" v-if="form.isMember==2" :required="true">
@@ -64,7 +64,7 @@
import BaseOpera from '@/components/base/BaseOpera'
import GlobalWindow from '@/components/common/GlobalWindow'
import { allList } from '@/api/business/member'
import { treeList } from '@/api/business/company'
import { treeList, allList as companyList } from '@/api/business/company'
import { createRoleMenu } from '@/api/system/role'
import { create } from '@/api/business/managers'
@@ -110,7 +110,17 @@
    })
  },
  methods: {
    changeTree(){
    loadData (node, resolve) {
      console.log(node)
      if(!node.hasChildren  || (node.childList && node.childList.length >0)){
        return
      }
      companyList({ parentId: node.id })
        .then(res => {
          node.childList = res
        })
    },
    changeTree (node) {
      const selectedMenus = this.$refs.tree.getCheckedNodes(false, true)
      this.form.companyIds = selectedMenus.map(menu => menu.id)
      console.log(this.form.companyIds)
@@ -120,9 +130,10 @@
        .then(res => {
          if (res && res.length > 0) {
            res[0].fsStatus = 1
            res[0].isLeaf = res[0].hasChildren
            this.companyTree = res
            // æ‰¾å‡ºå¶èŠ‚ç‚¹
            this.companyTree = this.companyTree.filter(menu => this.companyTree .findIndex(m => m.parentId === menu.id) === -1)
            // this.companyTree = this.companyTree.filter(menu => this.companyTree.findIndex(m => m.parentId === menu.id) === -1)
            console.log(res)
            // this.searchForm.erpOrgId = res[0].erpId
          }
admin/src/components/common/Tree.vue
@@ -2,14 +2,16 @@
    <div class="tree">
        <div v-for="(item, index) of list" :key="index" @click.stop="clickIten(item)">
            <div class="tree_item">
                <i class="el-icon-caret-bottom" :class="{ 'activeColor': item.actived === 1 }" v-show="item.fsStatus === 1 && item.childList.length > 0"></i>
                <i class="el-icon-caret-right color" v-show="item.childList.length > 0 && (item.fsStatus === 0 || !item.fsStatus)"></i>
                <div class="tree_item_label long-title-style" :title="item.name" :class="{ 'activeColor':  item.actived === 1 }">{{ item.name }}</div>
        <i class="el-icon-caret-bottom" :class="{ 'activeColor': item.fsStatus === 1 }" v-show="item.fsStatus === 1 && item.childList && item.childList.length > 0"></i>
        <i class="el-icon-caret-right color" v-show="item.childList && item.childList.length > 0 && (item.fsStatus === 0 || !item.fsStatus)"></i>
        <div class="tree_item_label long-title-style" :title="item.name" :class="{ 'activeColor': item.fsDate === 1 && item.childList && item.childList.length === 0 }">{{ item.name }}</div>
        <!--                <i class="el-icon-caret-bottom" :class="{ 'activeColor': item[defaultProps.status] }" v-show="item[defaultProps.status] && item[defaultProps.children]"></i>-->
        <!--                <i class="el-icon-caret-right color" v-show="item[defaultProps.children] && !item[defaultProps.status]"></i>-->
        <!--                <div class="tree_item_label long-title-style" :title="item[defaultProps.name]" :class="{ 'activeColor': item[defaultProps.status] && !item[defaultProps.children] }">{{ item[defaultProps.name] }}</div>-->
            </div>
            <div class="tree_childern" v-show="item.fsStatus === 1">
                <tree
                  :list="item.childList"
                  :alllist="alllist"
                  :defaultProps="defaultProps"
                  @callback="callback"
                />
@@ -25,11 +27,6 @@
  name: 'tree',
  props: {
    list: {
      type: Array,
      required: false,
      default: () => []
    },
    alllist: {
      type: Array,
      required: false,
      default: () => []
@@ -58,33 +55,45 @@
    }
  },
  methods: {
    listForList(){
      // console.log('===============================',this.alllist)
    },
    // ç‚¹å‡»å½“前项
    clickIten (item) {
      // this.listForList()
      // item[this.defaultProps.status] = !item[this.defaultProps.status]
      // this.list.forEach(subItem => {
      //   if ((subItem[this.defaultProps.id] !== item[this.defaultProps.id] && subItem[this.defaultProps.status]) || (this.list.length === 1 && subItem[this.defaultProps.status] === false)) {
      //     subItem[this.defaultProps.status] = false
      //     if (subItem[this.defaultProps.children]) {
      //       this.recursion(subItem[this.defaultProps.children])
      //     }
      //   }
      // })
      // if (this.tempItem['id'] === item[this.defaultProps.id]) {
      //   this.tempItem = {
      //     id: null,
      //     name: null,
      //     erpId: null
      //   }
      // } else {
      //   this.tempItem.id = item[this.defaultProps.id]
      //   this.tempItem.name = item[this.defaultProps.name]
      //   this.tempItem.erpId = item['erpId']
      // }
      // item.fsDate === 0 || !item.fsDate ? item.fsDate = 1 : item.fsDate = 0
      const fsDate = item.fsDate === 0 || !item.fsDate ? 1 : 0
      this.alllist.forEach(i => {
      this.list.forEach(i => {
        i.fsDate = 0
        i.actived = 0
        this.recursion1(i.childList)
      })
      item.fsDate = fsDate
      item.actived = 1
      if (item.childList.length > 0) {
        item.fsStatus === 0 || !item.fsStatus ? item.fsStatus = 1 : item.fsStatus = 0
      }
      this.$emit('callback', item, item)
    },
    recursion1 (children) {
      if (!children || children.length === 0){
        return
      }
    // é€’归方法
    recursion (children) {
      children.forEach(item => {
        item.actived = 0
        if (item.childList && item.childList.length > 0) {
          this.recursion1(item.childList)
        item.fsDate = 0
        if (item.childList.length > 0) {
          this.recursion(item.childList)
        }
        // item[this.defaultProps.status] = false
        // if (item[this.defaultProps.children]) {
admin/src/components/common/TreeNew.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,145 @@
<template>
    <div class="tree">
        <div v-for="(item, index) of list" :key="index" @click.stop="clickIten(item)">
            <div class="tree_item">
                <i class="el-icon-caret-bottom" :class="{ 'activeColor': item.actived === 1 }" v-show="item.fsStatus === 1 && item.hasChildren"></i>
                <i class="el-icon-caret-right color" v-show="item.hasChildren  && (item.fsStatus === 0 || !item.fsStatus)"></i>
                <div class="tree_item_label long-title-style" :title="item.name" :class="{ 'activeColor':  item.actived === 1 }">{{ item.name }}</div>
            </div>
            <div class="tree_childern" v-show="item.fsStatus === 1">
                <tree
                  :list="item.childList"
                  :alllist="alllist"
                  :defaultProps="defaultProps"
                  @callback="callback"
                />
                 <!-- @callback="callback" -->
            </div>
        </div>
    </div>
</template>
<script>
// import Bus from '@/utils/eventBus'
export default {
  name: 'tree',
  props: {
    list: {
      type: Array,
      required: false,
      default: () => []
    },
    alllist: {
      type: Array,
      required: false,
      default: () => []
    },
    defaultProps: {
      type: Object,
      require: false,
      default: () => {
        return {
          name: 'name',
          status: 'status',
          children: 'children',
          id: 'id',
          erpId: 'erpId'
        }
      }
    }
  },
  data() {
    return {
      tempItem: {
        id: null,
        name: null,
        erpId: null
      }
    }
  },
  methods: {
    listForList(){
      // console.log('===============================',this.alllist)
    },
    // ç‚¹å‡»å½“前项
    clickIten (item) {
      // this.listForList()
      const fsDate = item.fsDate === 0 || !item.fsDate ? 1 : 0
      this.alllist.forEach(i => {
        i.fsDate = 0
        i.actived = 0
        this.recursion1(i.childList)
      })
      item.fsDate = fsDate
      item.actived = 1
      if (item.hasChildren > 0) {
        item.fsStatus === 0 || !item.fsStatus ? item.fsStatus = 1 : item.fsStatus = 0
      }
      this.$emit('callback', item, item)
    },
    recursion1 (children) {
      if (!children || children.length === 0){
        return
      }
      children.forEach(item => {
        item.actived = 0
        if (item.hasChildren) {
          this.recursion1(item.childList)
        }
        // item[this.defaultProps.status] = false
        // if (item[this.defaultProps.children]) {
        //   this.recursion(item[this.defaultProps.children])
        // }
      })
    },
    callback (data, item) {
      if (this.tempItem.id === data.id) {
        this.tempItem = {}
      } else {
        this.tempItem.id = data.id
        this.tempItem.name = data.name
      }
      this.$emit('callback', data, item)
    }
  }
}
</script>
<style lang="scss" scoped>
.tree {
    /*width: 100%;*/
    /*height: auto;*/
    /*border-radius: 5px;*/
    /*overflow: hidden;*/
    /*border: 1px solid #eeeeee;*/
    /*box-sizing: border-box;*/
    .tree_childern {
        margin-left: 20px;
    }
    .activeItem {
        background: #F4F7FC;
    }
    .tree_item {
        display: flex;
        align-items: center;
        height: 48px;
        cursor: pointer;
        padding-left: 10px;
        .tree_item_label {
            font-size: 14px;
            font-weight: 400;
            color: #333333;
            white-space: nowrap;
        }
        i {
            margin-right: 5px;
        }
        .color {
            color: #999999 !important;
        }
        .activeColor {
            color: #305ED5 !important;
        }
    }
}
</style>
admin/src/views/business/company.vue
@@ -4,9 +4,16 @@
      <ul class="toolbar" v-permissions="['business:company:create', 'business:company:sync']">
        <li><el-button type="primary" v-permissions="['business:company:create']" :loading="loading"  @click="synchronous()">全量同步企业微信组织</el-button></li>
      </ul>
      <el-table :height="tableHeightNew" v-loading="isWorking.search" :data="list" stripe
                :tree-props="{ children: 'childList', hasChildren: 'hasChildren' }" row-key="id"
                @selection-change="handleSelectionChange" default-expand-all>
      <el-table :height="tableHeightNew"
                v-loading="isWorking.search"
                :data="list"
                stripe
                lazy
                :load="loadData"
                :tree-props="{ children: 'childList', hasChildren: 'hasChildren' }"
                row-key="id"
                @selection-change="handleSelectionChange"
                :default-expand-all="false">
        <el-table-column prop="name" label="组织名称" min-width="100px"></el-table-column>
        <el-table-column prop="namePath" label="组织路径" min-width="100px"></el-table-column>
        <el-table-column prop="qwId" label="企业微信标识" min-width="100px"></el-table-column>
@@ -21,7 +28,7 @@
<script>
import BaseTable from '@/components/base/BaseTable'
import TableLayout from '@/layouts/TableLayout'
import { companySync } from '@/api/business/company'
import {allList, companySync} from '@/api/business/company'
export default {
  name: 'internalCompany',
  extends: BaseTable,
@@ -48,11 +55,12 @@
  },
  methods: {
    // é¡µç å˜æ›´å¤„理
    handlePageChange (pageIndex) {
    handlePageChange (pid) {
      this.__checkApi()
      this.isWorking.search = true
      this.api.treeList({})
      this.api.allList({parentId:pid})
        .then(data => {
          console.log(data)
          this.list = data
        })
        .catch(e => {
@@ -62,6 +70,20 @@
          this.isWorking.search = false
        })
    },
    // èŽ·å–å­çº§æ•°æ®
    loadData (row, treeNode, resolve) {
      console.log(row, treeNode)
      this.api.allList({parentId: row.id})
          .then(data => {
            resolve(data)
          })
          .catch(e => {
            this.$tip.apiFailed(e)
          })
          .finally(() => {
            this.isWorking.search = false
          })
    },
    // åŒæ­¥ä¿¡æ¯
    async synchronous () {
      this.$dialog.actionConfirm(' æ‚¨ç¡®è®¤åŒæ­¥å…¨éƒ¨ä¿¡æ¯å—?', '操作确认提醒')
admin/src/views/business/companyMember.vue
@@ -17,7 +17,8 @@
        style="width: 100%; height: 50px; background: rgba(242, 242, 242, 1); line-height: 50px; text-align: center; font-size: 14px;">
        ä¼ä¸šç»„织</div>
      <div style="width: 100%; height: calc(100vh - 130px); overflow-y: scroll;">
        <Tree :list="companyTree" :alllist="companyTree" :defaultProps="{ name: 'name', status: 'fsStatus', children: 'childList', id: 'id' }"
       <Tree :list="companyTree" :alllist="companyTree"
              :defaultProps="{ name: 'name', status: 'fsStatus', children: 'childList', id: 'id' }"
          @callback="callback" />
      </div>
    </template>
@@ -75,9 +76,9 @@
import BaseTable from '@/components/base/BaseTable'
import TableLayout1 from '@/layouts/TableLayout1'
import Pagination from '@/components/common/Pagination'
import Tree from '@/components/common/Tree'
import Tree from '@/components/common/TreeNew'
import OperaMemberWindow from '@/components/business/OperaMemberWindow'
import { treeList } from '@/api/business/company'
import { allList,treeList } from '@/api/business/company'
import { memberSync} from '@/api/business/member'
export default {
  name: 'internalMember',
@@ -86,6 +87,7 @@
  data() {
    return {
      TreeList: [],
      defaultExpanedKeys:null,
      // æœç´¢
      searchForm: {
        name: '' ,
@@ -96,6 +98,7 @@
      loading: false,
      heading: false,
      working: false,
      dataList: [],
      companyTree: [],
      department: []
    }
@@ -113,13 +116,24 @@
  methods: {
    // èŽ·å–ç»„ç»‡æ ‘
    getfindCompanyTreePage() {
      treeList({})
      allList({})
        .then(res => {
          console.log(res)
          if (res && res.length > 0) {
            res[0].fsStatus = 1
            this.getCompanyList(res[0])
            this.companyTree = res
            this.search()
            this.department = this.getDepartmentTree(res)
            // this.department = this.getDepartmentTree(res)
          }
        })
    },
    getCompanyList(row){
      allList({parentId:row.id})
          .then(res => {
            console.log(res)
            if (res && res.length > 0) {
              row.childList = res
          }
        })
    },
@@ -170,6 +184,9 @@
      this.searchForm.erpOrgId = row.erpId
      this.searchForm.companyId = row.id
      this.search()
      if(row.hasChildren && (row.childList == null || row.childList.length == 0)){
        this.getCompanyList(row)
      }
    }
  }
}
admin/src/views/index.vue
@@ -48,8 +48,8 @@
<!--              <img src="@/assets/icons/home_icon3.png" alt="" />-->
            </div>
            <div class="content">
              <div>符合项:{{ headerData.dcaNoNum || 0}}</div>
              <div>不符合项:{{ headerData.dcaYesNum || 0}}</div>
              <div>符合项:{{ headerData.dcaYesNum || 0}}</div>
              <div>不符合项:{{ headerData.dcaNoNum || 0}}</div>
              <div>总上报次数:{{ headerData.dcaNum || 0}}</div>
            </div>
          </div>
server/src/main/java/com/doumee/api/business/CompanyController.java
@@ -58,6 +58,14 @@
    public ApiResponse<List<Company>> tree (@RequestBody Company company){
        return ApiResponse.success(companyService.companyTree());
    }
    @ApiOperation("根据父级查询集合")
    @PostMapping("/list")
    @EncryptionResp
    @EncryptionReq
    @RequiresPermissions("business:company:query")
    public ApiResponse<List<Company>> list (@RequestBody Company company){
        return ApiResponse.success(companyService.findList(company));
    }
    @ApiOperation("组织树查询")
    @PostMapping("/treeWithMember")
    @EncryptionResp
server/src/main/java/com/doumee/api/common/PublicCloudController.java
@@ -144,7 +144,6 @@
    @ApiOperation(value = "批量上传文件到FTP")
    @RequestMapping(method= RequestMethod.POST,value="/uploadBatch")
    @ResponseBody
//    public void uploadBatch(@RequestParam("files") MultipartFile[] fileList,HttpServletRequest request, HttpServletResponse response, String folder) throws Exception {
    public void uploadBatch(MultipartRequest request, HttpServletResponse response, String folder) throws Exception {
        if(Objects.isNull(folder)){
            throw new BusinessException(ResponseStatus.BAD_REQUEST);
server/src/main/java/com/doumee/dao/business/model/Company.java
@@ -102,5 +102,8 @@
    @ApiModelProperty(value = "人员编码(关联member", example = "1")
    @TableField(exist = false)
    private Integer memberId;
    @ApiModelProperty(value = "下级部门数量", example = "1")
    @TableField(exist = false)
    private Integer childNum;
}
server/src/main/java/com/doumee/service/business/impl/CompanyServiceImpl.java
@@ -1,5 +1,6 @@
package com.doumee.service.business.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -107,8 +108,21 @@
    @Override
    public List<Company> findList(Company company) {
        QueryWrapper<Company> wrapper = new QueryWrapper<>(company);
        return companyMapper.selectList(wrapper);
        MPJLambdaWrapper<Company> wrapper = new MPJLambdaWrapper<Company>();
        wrapper.selectAll(Company.class )
                .select(" (select count(1) from company t1 where t1.isdeleted=0 and t1.parent_id = t.id )",Company::getChildNum)
                .isNull(company.getParentId()==null,Company::getParentId)
                .eq(company.getParentId()!=null,Company::getParentId,company.getParentId())
                .eq(Company::getIsdeleted,Constants.ZERO)
                .orderByAsc(Company::getName);
        List<Company> companyList = companyMapper.selectJoinList(Company.class,wrapper);
        if(companyList.size()>0){
            for (Company c : companyList){
                c.setHasChildren(Constants.formatIntegerNum(c.getChildNum())>0);
            }
        }
        return  companyList;
    }
  
    @Override
@@ -166,7 +180,7 @@
        queryWrapper.leftJoin(Company.class,Company::getId,Company::getParentId);
        queryWrapper.leftJoin(SystemUser.class,SystemUser::getId,Company::getEditor);
        queryWrapper.eq(Company::getIsdeleted,Constants.ZERO);
        queryWrapper.orderByAsc( "t.code");
        queryWrapper.orderByAsc( "t.name");
        List<Company> companyList = companyMapper.selectJoinList(Company.class,queryWrapper);
        List<CompanyMember> memberList = null;
        if(type == 1){
@@ -175,7 +189,8 @@
                    .selectAs(Member::getName,CompanyMember::getMemberName)
                    .leftJoin(Member.class,Member::getId,CompanyMember::getMemberId)
                    .eq(Member::getIsdeleted,Constants.ZERO )
                    .eq(CompanyMember::getIsdeleted,Constants.ZERO ));
                    .eq(CompanyMember::getIsdeleted,Constants.ZERO )
                    .orderByAsc(Member::getName));
        }
        CompanyTree treeBuild = new CompanyTree(companyList, 0,memberList);
        companyList = treeBuild.buildTree();
server/src/main/java/com/doumee/service/business/impl/MemberServiceImpl.java
@@ -26,11 +26,13 @@
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestHeader;
@@ -48,6 +50,7 @@
 * @since 2025/04/02 17:49
 */
@Service
@Slf4j
public class MemberServiceImpl implements MemberService {
    @Resource(name="sessionRedisTemplate")
@@ -249,6 +252,7 @@
    }
    @Override
    @Transactional
    public  void syncQwAll(){
        if(Constants.DEALING_MEMBER_SYNC){
            throw  new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"对不起,同步任务正在进行,请稍后刷新页面重试!");
@@ -266,15 +270,20 @@
            LoginUserInfo user = (LoginUserInfo) SecurityUtils.getSubject().getPrincipal();
            Date date = new Date();
            List<QywxUserListResponse>  list = new ArrayList<>();
            int index =0;
            for(Company c : companyList){
                List<QywxUserListResponse> tList =   QywxUtil.getUserList(systemDictDataBiz.queryByCode(Constants.QYWX,Constants.QYWX_TOKEN).getCode(),c.getQwId());
                if(tList!=null){
                    log.error((index++)+"==============="+c.getName()+"============人员数量:"+tList.size());
                    list.addAll(tList);
                }else{
                    log.error((index++)+"==============="+c.getName()+"============人员数量:0");
                }
            }
            if(list == null || list.size() ==0){
                throw  new BusinessException(ResponseStatus.DATA_EMPTY.getCode(),"未同步到任何组织信息!");
            }
            log.error( "###################=================人员总数量:"+list.size());
            List<Member>  memberList = memberMapper.selectList(new LambdaQueryWrapper<Member>().eq(Member::getIsdeleted,Constants.ZERO));
            List<Member>  newList = new ArrayList<>();
            List<Member>  updateList = new ArrayList<>();
server/src/main/resources/application-pro.yml
@@ -3,17 +3,15 @@
  env: production
  # æ¨¡å¼ï¼Œtesting测试模式
  mode: production
# WEB服务器配置
server:
  port: 10010
  port: 10040
spring:
  # æ•°æ®æºé…ç½®
  datasource:
    url: jdbc:mysql://solution-cnn3-d-shereport-db-mysql01.mysql.database.chinacloudapi.cn:3306/lianhelihua?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
    url: jdbc:mysql://solution-cnn3-p-shereport-db-mysql01.mysql.database.chinacloudapi.cn:3306/lianhelihua?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
    username: service_account
    password: yP5@jJzqME63
    password: vW3&QbcdMSyF
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
  redis:
@@ -25,11 +23,30 @@
  jackson:
    time-zone: GMT+8
    date-format: yyyy-MM-dd HH:mm:ss
  #  mail:
  #    username: jiangping0849@outlook.com
  #    password: mwzaislgioyhxnig
  #    host: smtp-mail.outlook.com
  #    port: 587
  #    default-encoding: UTF-8
  #    properties:
  #      mail:
  #        debug: true
  #        smtp:
  #          ssl:
  #            socketFactory:
  #              class: com.sun.mail.util.MailSSLSocketFactory
  #              fallback: false
  #          auth: true
  #          starttls:
  #            enable: true
  #            required: true
  mail:
    host: smtp.aliyun.com
    port: 465
    username: your_email@aliyun.com
    password: your_password
    host: smtpdm.aliyun.com
    username: lkshereport@mail.unilever-china.com
    password: f2fLk384RChX
    default-encoding: UTF-8
    port: 80
    properties:
      mail:
        smtp:
@@ -37,32 +54,33 @@
          starttls:
            enable: true
            required: true
          ssl:
            enable: true
debug_model: true
# Swagger配置
swagger:
  host: 127.0.0.1
  host:
  title: ${project.name}接口文档
  description: ${project.name}接口文档
  # å¯ç”¨Swagger,生产环境建议关闭
  enabled: true
  context-path:
  # å¯ç”¨swagger加密
  enable-encrypt: true
  # ç¦ç”¨swagger时的重定向地址
  redirect-uri: /
des_pwd: 123456SDFKDJF
des_pwd: 123456SDFKDJF
knife4j:
  enable: true
  basic:
    enable: true
    username: admin
    password:
    password: Doumee@168
upload:
  type: blob
qiwei:
  serviceurl: https://wecom-qyapi.unilever-china.com/
  serviceurl: https://wecom-qyapi.unilever-china.com
server/src/main/resources/application.yml
@@ -5,7 +5,7 @@
spring:
  profiles:
    active: test
    active: pro
  # JSON返回配置
  jackson:
    # é»˜è®¤æ—¶åŒº