MrShi
2026-01-30 e6e520abd96702db6b29459a66440801f58bc89d
Merge branch 'master' of http://139.186.142.91:10010/r/productDev/zbom_dianjiang
已添加7个文件
已修改24个文件
2279 ■■■■ 文件已修改
admin/package-lock.json 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/package.json 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/api/business/cases.js 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/api/business/member.js 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/api/system/common.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/assets/style/style.scss 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/components/business/OperaCasesImportWindow.vue 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/components/business/OperaCasesWindow.vue 169 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/components/business/OperaMemberImportWindow.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/components/business/OperaMemberWindow.vue 273 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/components/common/ImageCropper.vue 238 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/components/common/UploadFaceImg.vue 216 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/business/cases.vue 159 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/business/importRecord.vue 134 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/business/member.vue 98 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/admin/src/main/java/com/doumee/api/business/CasesController.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/admin/src/main/java/com/doumee/api/business/MemberController.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/core/annotation/excel/ExcelImporter.java 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/core/annotation/excel/ExcelPictureUtil.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/core/utils/DateUtil.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/core/utils/tyyun/TyyZosUtil.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/dao/business/dto/MemberImport.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/dao/business/model/Cases.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/dao/business/model/ImportRecord.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/dao/business/model/Member.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/service/business/CasesService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/service/business/MemberService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/service/business/impl/CasesServiceImpl.java 181 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/service/business/impl/CategoryServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/service/business/impl/ImportRecordServiceImpl.java 321 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/service/business/impl/MemberServiceImpl.java 163 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/package-lock.json
@@ -13643,6 +13643,12 @@
        "clipboard": "^2.0.0"
      }
    },
    "vue-cropper": {
      "version": "0.6.5",
      "resolved": "https://registry.npmmirror.com/vue-cropper/-/vue-cropper-0.6.5.tgz",
      "integrity": "sha512-lSvY6IpeA/Tv/iPZ/FOkMHVRBPSlm7t57nuHEZFBMRNOH8ElvfqVlnHGDOAMlvPhh9gHiddiQoASS+fY0MFX0g==",
      "dev": true
    },
    "vue-eslint-parser": {
      "version": "7.6.0",
      "resolved": "https://registry.npm.taobao.org/vue-eslint-parser/download/vue-eslint-parser-7.6.0.tgz?cache=0&sync_timestamp=1614679548045&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-eslint-parser%2Fdownload%2Fvue-eslint-parser-7.6.0.tgz",
admin/package.json
@@ -49,6 +49,7 @@
    "node-sass": "^4.12.0",
    "sass-loader": "^8.0.2",
    "vue-cli-plugin-element-ui": "~1.1.4",
    "vue-cropper": "^0.6.5",
    "vue-json-viewer": "^2.2.22",
    "vue-template-compiler": "^2.6.11"
  },
admin/src/api/business/cases.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,52 @@
import request from '../../utils/request'
// æŸ¥è¯¢
export function fetchList (data) {
  return request.post('/business/cases/page', data, {
    trim: true
  })
}
export function findAll (data) {
  return request.post('/business/cases/list', data, {
    trim: true
  })
}
// åˆ›å»º
export function create (data) {
  return request.post('/business/cases/create', data)
}
export function updateStatus (data) {
  return request.post('/business/cases/updateStatus', data)
}
// å¯¼å‡ºExcel
export function exportExcel (data) {
  return request.post('/business/cases/exportExcel', data, {
    download: true
  })
}
export function importExcel (data) {
  return request.post('/business/cases/importExcel', data)
}
// ä¿®æ”¹
export function updateById (data) {
  return request.post('/business/cases/updateById', data)
}
// åˆ é™¤
export function deleteById (id) {
  return request.get(`/business/cases/delete/${id}`)
}
export function getById (id) {
  return request.get(`/business/cases/${id}`)
}
// æ‰¹é‡åˆ é™¤
export function deleteByIdInBatch (ids) {
  return request.get('/business/cases/delete/batch', {
    params: {
      ids
    }
  })
}
admin/src/api/business/member.js
@@ -6,6 +6,11 @@
    trim: true
  })
}
export function findAll (data) {
  return request.post('/business/member/list', data, {
    trim: true
  })
}
// åˆ›å»º
export function create (data) {
@@ -14,7 +19,6 @@
export function updateStatus (data) {
  return request.post('/business/member/updateStatus', data)
}
// å¯¼å‡ºExcel
export function exportExcel (data) {
  return request.post('/business/member/exportExcel', data, {
admin/src/api/system/common.js
@@ -34,3 +34,7 @@
    autoLogin: false
  })
}
// ä¸Šä¼ 
export function upload (data) {
  return request.post('/public/upload', data)
}
admin/src/assets/style/style.scss
@@ -56,3 +56,18 @@
    }
  }
}
.red{
  color: red;
}
.grey{
  color: grey;
}
.green{
  color: green;
}
.blue{
  color: #216EEE;
}.orange{
   color: orange;
 }
admin/src/components/business/OperaCasesImportWindow.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,87 @@
<template>
  <el-dialog
      class="center-title"
      :title="title"
      width="500px"
      top="30vh"
      :visible.sync="visible"
      :confirm-working="isWorking"
      @confirm="confirm"
  >
    <p class="tip-warn"><i class="el-icon-warning"></i>导入说明:<br>
      1.请先下载文件模板,并按照模板要去填写表格内容;<br>
    </p>
    <el-form class="demo-form-inline" >
      <el-form-item label="案例数据" required>
        <div style="width: 100%;display: flex;align-items: center;">
          <el-button type="primary" :loading="importing"   @click="clickRef">点击上传</el-button>
          <el-button type="text" @click="exportTemplate">点击下载模版.EXCEL</el-button>
        </div>
        <div style="font-size: 14px; color: black;" v-if="fileName">{{fileName}}</div>
      </el-form-item>
    </el-form>
    <input type="file" style="position: fixed; left: 0; top: -50px;" accept=".xlsx" ref="fileExcel" @change="result" />
    <template   v-slot:footer>
      <el-button @click="visible=false">返回</el-button>
    </template>
  </el-dialog>
</template>
<script>
import BaseOpera from '@/components/base/BaseOpera'
import GlobalWindow from '@/components/common/GlobalWindow'
import { importExcel } from '@/api/business/importRecord'
export default {
  name: 'OperaCasesImportWindow',
  extends: BaseOpera,
  // eslint-disable-next-line vue/no-unused-components
  components: { GlobalWindow },
  data () {
    return {
      importing: false,
      fileName: '',
      type: 1
    }
  },
  methods: {
    open (title) {
      this.title = title
      this.fileName = ''
      this.visible = true
      this.type = 0
    },
    // å¯¼å‡ºæ¨¡æ¿
    exportTemplate () {
      // æŠ•保申请
      window.open('/template/cases.xlsx')
    },
    clickRef () {
      this.$refs.fileExcel.click()
    },
    result (e) {
      this.importing=true
      const data = new FormData()
      data.append('file', e.target.files[0])
      data.append('type', this.type)
      importExcel(data)
        .then(res => {
          this.$message.success('数据已上传成功,可前往【导入记录】菜单查看任务执行进度。')
          this.$emit('success')
          this.visible = false
        })
        .catch(err => {
          this.fileName = ''
          this.$message.error(err)
        })
        .finally(() => {
          this.$refs.fileExcel.value = null
          this.importing=false
        })
    }
  }
}
</script>
<style lang="scss" scoped>
</style>
admin/src/components/business/OperaCasesWindow.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,169 @@
<template>
  <GlobalWindow
    :title="title"
    :visible.sync="visible"
    :confirm-working="isWorking"
    @confirm="confirm"
  >
    <el-form :model="form" ref="form" :rules="rules">
      <el-form-item label="名称" prop="name">
        <el-input   v-model="form.name" placeholder="请输入名称" v-trim/>
      </el-form-item>
      <el-form-item label="老师" prop="memberId"    >
        <el-select    v-model="form.memberId"  placeholder="选择老师"  clearable  filterable
        >
          <el-option
              v-for="item in memberList"
              :key="item.id"
              :value="item.id"
              :label="item.name"
          ></el-option>
        </el-select>
      </el-form-item>
      <el-form-item  label="图集" prop="icon">
        <UploadImage
            :fileList="tempfileList"
            :uploadData="uploadData"
            @beginUpload="isUploading=true"
            @endUpload="isUploading=false"/>
        <p class="tip-warn">
          å»ºè®®å°ºå¯¸ï¼š750px X 750px
          æ”¯æŒpng、jpg、jpeg格式,大小不超过2M,上传图片不允许涉及政治敏感与色情,
        </p>
      </el-form-item>
      <el-form-item label="开始时间" prop="startDate" >
        <el-date-picker
            clearable
            v-model="form.startDate"
            type="date"
            value-format="yyyy-MM-dd"
            format="yyyy-MM-dd"
            placeholder="开始时间"
        ></el-date-picker>
      </el-form-item>
      <el-form-item label="导入时间" prop="endDate" >
        <el-date-picker
            clearable
            v-model="form.endDate"
            type="date"
            value-format="yyyy-MM-dd"
            format="yyyy-MM-dd"
            placeholder="结束时间"
        ></el-date-picker>
      </el-form-item>
      <el-form-item label="排序码" prop="sortnum">
        <el-input v-model="form.sortnum" type="" placeholder="请输入排序码" v-trim/>
      </el-form-item>
      <el-form-item label="描述" prop="detail">
        <el-input type="textarea" v-model="form.detail" placeholder="请输入描述" v-trim/>
      </el-form-item>
    </el-form>
  </GlobalWindow>
</template>
<script>
import BaseOpera from '@/components/base/BaseOpera'
import GlobalWindow from '@/components/common/GlobalWindow'
import UploadImage from '@/components/common/UploadImage'
import { findAll as memberList } from '@/api/business/member'
export default {
  name: 'OperaCasesWindow',
  extends: BaseOpera,
  components: { GlobalWindow,  UploadImage },
  data () {
    return {
      isUploading: false,
      uploadData: {
        folder: 'dianjiang/category'
      },
      // è¡¨å•数据
      form: {
        id: null,
        status: 0,
        sortnum: null,
        name: '',
        detail: null,
        remark: null,
        fileList: [],
        memberId: null,
        startDate: null,
        endDate: null
      },
      tempfileList: [],
      memberList: [],
      // éªŒè¯è§„则
      rules: {
        name: [{ required: true, message: '请输入标题' }],
        detail: [{ required: true, message: '请输入描述' }],
        memberId: [{ required: true, message: '请选择老师' }],
        startDate: [{ required: true, message: '请选择开始日期' }],
        endDate: [{ required: true, message: '请输入结束日期' }]
      }
    }
  },
  created () {
    this.config({
      api: '/business/cases',
      'field.id': 'id'
    })
  },
  methods: {
    loadMemberList () {
      memberList({
      }).then(res => {
        this.memberList = res
      })
    },
    confirm () {
      this.form.fileList = this.tempfileList
      if (this.form[this.configData['field.id']] == null || this.form[this.configData['field.id']] === '') {
        this.__confirmCreate()
        return
      }
      this.__confirmEdit()
    },
    open (title, target, type) {
      this.title = title
      this.visible = true
      this.loadMemberList()
      this.tempfileList = []
      this.form = {
        id: null,
        status: 0,
        sortnum: null,
        name: '',
        detail: null,
        remark: null,
        fileList: [],
        memberId: null,
        startDate: null,
        endDate: null
      }
      // æ–°å»º
      if (target == null) {
        this.$nextTick(() => {
          this.$refs.form.resetFields()
          this.form[this.configData['field.id']] = null
          this.form.type = type
        })
        return
      }
      // ç¼–辑
      this.$nextTick(() => {
        for (const key in this.form) {
          this.form[key] = target[key]
        }
        this.form.fileList = this.form.fileList || []
        this.form.fileList.forEach(item => {
          this.tempfileList.push({
            fileurl: item.fileurl,
            name: item.name,
            url: item.url
          })
        })
      })
    }
  }
}
</script>
admin/src/components/business/OperaMemberImportWindow.vue
@@ -71,6 +71,7 @@
        })
        .catch(err => {
          this.fileName = ''
          this.$message.error(err)
        })
        .finally(() => {
          this.$refs.fileExcel.value = null
admin/src/components/business/OperaMemberWindow.vue
@@ -1,97 +1,103 @@
<template>
  <GlobalWindow
    :title="title"
    width="50%"
    :visible.sync="visible"
    :confirm-working="isWorking"
    @confirm="confirm"
  >
    <el-form :model="form" ref="form" :rules="rules">
      <el-form-item label="是否已删除 0未删除 1已删除" prop="deleted">
        <el-input v-model="form.deleted" placeholder="请输入是否已删除 0未删除 1已删除" v-trim/>
      <el-form-item label="老师姓名" prop="name">
        <el-input   v-model="form.name" placeholder="请输入姓名" v-trim/>
      </el-form-item>
      <el-form-item label="创建人编码" prop="createUser">
        <el-input v-model="form.createUser" placeholder="请输入创建人编码" v-trim/>
      <el-form-item label="老师工号" prop="code">
        <el-input   v-model="form.code" placeholder="请输入工号" v-trim/>
      </el-form-item>
      <el-form-item label="创建时间" prop="createTime">
        <el-date-picker v-model="form.createTime" value-format="yyyy-MM-dd" placeholder="请输入创建时间"></el-date-picker>
      <el-form-item  label="职业照" prop="imgurl">
<!--        <UploadAvatarImage
            :file="{ imgurlfull: form.fullImgurl, imgurl: form.imgurl }"
            :uploadData="uploadData"
            @uploadSuccess="uploadAvatarSuccess"
        />
        <p class="tip-warn">
          å»ºè®®å°ºå¯¸ï¼š750px X 750px,上限6å¼ 
          æ”¯æŒpng、jpg、jpeg格式,大小不超过2M,上传图片不允许涉及政治敏感与色情,
        </p>-->
        <div class="upload_wrap">
          <UploadFaceImg :file="{ imgurlfull: form.fullImgurl, imgurl: form.imgurl }" :uploadData="uploadData"
                         @uploadSuccess="uploadAvatarSuccess" @uploadEnd="isUploading = false" @uploadBegin="isUploading = true" />
          <div class="content">
            <div>1、建议尺寸:750px X 750px ã€‚</div>
            <div>2、支持png、jpg、jpeg格式,大小不超过2M,上传图片不允许涉及政治敏感与色情。</div>
          </div>
        </div>
      </el-form-item>
      <el-form-item label="更新人编码" prop="updateUser">
        <el-input v-model="form.updateUser" placeholder="请输入更新人编码" v-trim/>
      <el-form-item label="性别" prop="sex">
        <el-radio-group v-model="form.sex"   style="margin-bottom: 20px;">
          <el-radio-button :label="0">男</el-radio-button>
          <el-radio-button :label="1">女</el-radio-button>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="更新时间" prop="updateTime">
        <el-date-picker v-model="form.updateTime" value-format="yyyy-MM-dd" placeholder="请输入更新时间"></el-date-picker>
      <el-form-item label="岗位" prop="positon">
        <el-input   v-model="form.positon" placeholder="请输入岗位" v-trim/>
      </el-form-item>
      <el-form-item label="备注" prop="remark">
        <el-input v-model="form.remark" placeholder="请输入备注" v-trim/>
      <el-form-item label="从业年份" prop="jobYear">
        <el-input type="number" v-model="form.jobYear" placeholder="请输入从业年份" v-trim><template slot="append">å¹´</template></el-input>
      </el-form-item>
      <el-form-item label="头像" prop="coverImage">
        <el-input v-model="form.coverImage" placeholder="请输入头像" v-trim/>
      <el-form-item label="服务战区" prop="zhanquIdList">
        <el-select    v-model="form.zhanquIdList"  placeholder="请选择服务战区" filterable multiple  clearable  >
          <el-option
              v-for="item in cateList.filter(item=>{return item.type==0})"
              :key="item.id"
              :value="item.id"
              :label="item.name"
          ></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="openid" prop="openid">
        <el-input v-model="form.openid" placeholder="请输入openid" v-trim/>
      <el-form-item label="商业化类型" prop="bustypeIdList">
        <el-select    v-model="form.bustypeIdList"  placeholder="请选择商业化类型" filterable multiple clearable  >
          <el-option
              v-for="item in cateList.filter(item=>{return item.type==1})"
              :key="item.id"
              :value="item.id"
              :label="item.name"
          ></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="昵称" prop="nickName">
        <el-input v-model="form.nickName" placeholder="请输入昵称" v-trim/>
      <el-form-item label="老师等级" prop="levelId">
        <el-select    v-model="form.levelId"  placeholder="请选择老师等级" filterable  clearable  >
          <el-option
              v-for="item in cateList.filter(item=>{return item.type==3})"
              :key="item.id"
              :value="item.id"
              :label="item.name"
          ></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="联系电话" prop="telephone">
        <el-input v-model="form.telephone" placeholder="请输入联系电话" v-trim/>
      <el-form-item label="擅长领域" prop="fieldIdList">
        <el-select    v-model="form.fieldIdList"  placeholder="请选择擅长领域" filterable multiple clearable  >
          <el-option
              v-for="item in cateList.filter(item=>{return item.type==2})"
              :key="item.id"
              :value="item.id"
              :label="item.name"
          ></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="姓名" prop="name">
        <el-input v-model="form.name" placeholder="请输入姓名" v-trim/>
      <el-form-item label="费用标准" prop="fee">
        <el-input type="number" v-model="form.fee" placeholder="请输入费用标准" v-trim><template slot="append">元/周</template></el-input>
      </el-form-item>
      <el-form-item label="用工身份:0=未申请;1=申请中;2=已通过;3=未通过;" prop="workerIdentity">
        <el-input v-model="form.workerIdentity" placeholder="请输入用工身份:0=未申请;1=申请中;2=已通过;3=未通过;" v-trim/>
      <el-form-item label="服务商场" prop="serveNum">
        <el-input type="number" v-model="form.serveNum" placeholder="请输入服务商场" v-trim><template slot="append">个</template></el-input>
      </el-form-item>
      <el-form-item label="货运身份:0=未申请;1=申请中;2=已通过;3=未通过;" prop="driverIdentity">
        <el-input v-model="form.driverIdentity" placeholder="请输入货运身份:0=未申请;1=申请中;2=已通过;3=未通过;" v-trim/>
      </el-form-item>
      <el-form-item label="供餐很粉:0=未申请;1=申请中;2=已通过;3=未通过;" prop="chefIdentity">
        <el-input v-model="form.chefIdentity" placeholder="请输入供餐很粉:0=未申请;1=申请中;2=已通过;3=未通过;" v-trim/>
      </el-form-item>
      <el-form-item label="当前余额(单位:分)" prop="amount">
        <el-input v-model="form.amount" placeholder="请输入当前余额(单位:分)" v-trim/>
      </el-form-item>
      <el-form-item label="历史总金额(单位:分)" prop="totalAmount">
        <el-input v-model="form.totalAmount" placeholder="请输入历史总金额(单位:分)" v-trim/>
      <el-form-item label="老师简介" prop="content">
        <el-input type="textarea" v-model="form.content" placeholder="请输入老师简介" v-trim/>
      </el-form-item>
      <el-form-item label="状态" prop="status">
        <el-input v-model="form.status" placeholder="请输入状态" v-trim/>
      </el-form-item>
      <el-form-item label="最后登录时间" prop="loginTime">
        <el-date-picker v-model="form.loginTime" value-format="yyyy-MM-dd" placeholder="请输入最后登录时间"></el-date-picker>
      </el-form-item>
      <el-form-item label="总登录次数" prop="loginTimes">
        <el-input v-model="form.loginTimes" placeholder="请输入总登录次数" v-trim/>
      </el-form-item>
      <el-form-item label="总接单量" prop="reciveNum">
        <el-input v-model="form.reciveNum" placeholder="请输入总接单量" v-trim/>
      </el-form-item>
      <el-form-item label="总发单量" prop="publishNum">
        <el-input v-model="form.publishNum" placeholder="请输入总发单量" v-trim/>
      </el-form-item>
      <el-form-item label="评分" prop="score">
        <el-input v-model="form.score" placeholder="请输入评分" v-trim/>
      </el-form-item>
      <el-form-item label="定位地址" prop="localtion">
        <el-input v-model="form.localtion" placeholder="请输入定位地址" v-trim/>
      </el-form-item>
      <el-form-item label="纬度" prop="lat">
        <el-input v-model="form.lat" placeholder="请输入纬度" v-trim/>
      </el-form-item>
      <el-form-item label="经度" prop="lgt">
        <el-input v-model="form.lgt" placeholder="请输入经度" v-trim/>
      </el-form-item>
      <el-form-item label="省份" prop="province">
        <el-input v-model="form.province" placeholder="请输入省份" v-trim/>
      </el-form-item>
      <el-form-item label="城市" prop="city">
        <el-input v-model="form.city" placeholder="请输入城市" v-trim/>
      </el-form-item>
      <el-form-item label="区县" prop="area">
        <el-input v-model="form.area" placeholder="请输入区县" v-trim/>
      </el-form-item>
      <el-form-item label="是否接受自动派单:0=否;1=是;" prop="autoReciveStatus">
        <el-input v-model="form.autoReciveStatus" placeholder="请输入是否接受自动派单:0=否;1=是;" v-trim/>
        <el-radio-group  v-model="form.status" style="margin-bottom: 20px;">
          <el-radio-button :label="0">启用</el-radio-button>
          <el-radio-button :label="1">禁用</el-radio-button>
        </el-radio-group>
      </el-form-item>
    </el-form>
  </GlobalWindow>
@@ -100,47 +106,51 @@
<script>
import BaseOpera from '@/components/base/BaseOpera'
import GlobalWindow from '@/components/common/GlobalWindow'
import { findAll as cateList } from '@/api/business/category'
import UploadFaceImg from '@/components/common/UploadFaceImg'
export default {
  name: 'OperaMemberWindow',
  extends: BaseOpera,
  components: { GlobalWindow },
  components: { GlobalWindow ,UploadFaceImg},
  data () {
    return {
      // è¡¨å•数据
      isUploading: false,
      cateList: [],
      uploadData: {
        folder: 'dianjiang/member'
      },
      form: {
        id: null,
        deleted: '',
        createUser: '',
        createTime: '',
        updateUser: '',
        updateTime: '',
        remark: '',
        coverImage: '',
        openid: '',
        nickName: '',
        telephone: '',
        imgurl: '',
        fullImgurl: '',
        name: '',
        workerIdentity: '',
        driverIdentity: '',
        chefIdentity: '',
        amount: '',
        totalAmount: '',
        status: '',
        loginTime: '',
        loginTimes: '',
        reciveNum: '',
        publishNum: '',
        score: '',
        localtion: '',
        lat: '',
        lgt: '',
        province: '',
        city: '',
        area: '',
        autoReciveStatus: ''
        code: '',
        sex: 0,
        jobYear: '',
        positon: '',
        zhanquIdList: [],
        bustypeIdList: [],
        fieldIdList: [],
        levelId: '',
        fee: '',
        status: 0,
        content: 0,
        serveNum: '',
        type: 0
      },
      // éªŒè¯è§„则
      rules: {
        name: [{ required: true, message: '请输入姓名' }],
        code: [{ required: true, message: '请输入工号' }],
        imgurl: [{ required: true, message: '请上传职业照' }],
        sex: [{ required: true, message: '请选择性别' }],
        jobYear: [{ required: true, message: '请选择从业年份' }],
        zhanquIdList: [{ required: true, message: '请选择服务战区' }],
        bustypeIdList: [{ required: true, message: '请选择商业化类型' }],
        levelId: [{ required: true, message: '请选择老师等级' }],
        fieldIdList: [{ required: true, message: '请选择擅长领域' }],
        content: [{ required: true, message: '请输入老师简介' }]
      }
    }
  },
@@ -149,6 +159,67 @@
      api: '/business/member',
      'field.id': 'id'
    })
  },
  methods: {
    loadCateList () {
      cateList({
      }).then(res => {
        this.cateList = res
      })
    },
    uploadAvatarSuccess (file) {
      this.$set(this.form, 'imgurl', file.imgurl)
      this.$set(this.form, 'fullImgurl', file.imgurlfull)
    },
    open (title, target, type) {
      this.title = title
      this.visible = true
      this.loadCateList()
      this.form.fullImgurl = null
      this.form.imgurl = null
      // æ–°å»º
      if (target == null) {
        this.$nextTick(() => {
          this.$refs.form.resetFields()
          this.form[this.configData['field.id']] = null
        })
        return
      }
      // ç¼–辑
      this.$nextTick(() => {
        console.log(target.jobYear)
        for (const key in this.form) {
          this.form[key] = target[key]
        }
      })
    }
  }
}
</script>
<style lang="scss" scoped>
.upload_wrap {
  display: flex;
  align-items: center;
  .avatar-uploader {
    display: flex;
    align-items: center;
    justify-content: center;
  }
  ::v-deep .avatar {
    max-width: 90px;
    max-height: 90px;
  }
  .content {
    display: flex;
    flex-direction: column;
    justify-content: center;
    font-size: 12px;
    color: #999999;
    margin-left: 12px;
    line-height: 24px;
  }
}
</style>
admin/src/components/common/ImageCropper.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,238 @@
<template>
  <div class="iconShot">
    <div class="icon-dialog">
      <div class="clip">
        <div class="img" ref="img">
          <vue-cropper
              ref="cropper"
              :img="imgSrc"
              :width="options.width"
              :height="options.height"
              :canScale="options.canScale"
              :autoCrop="options.autoCrop"
              :canMove="options.canMove"
              :output-size="options.outputSize"
              :centerBox="options.centerBox"
              :autoCropWidth="autoCrop.width || options.autoCropWidth"
              :autoCropHeight="autoCrop.height || options.autoCropHeight"
              @realTime="realTime"
          ></vue-cropper>
        </div>
        <div class="previews">
          <img style="width: 150px;height: 150px;border-radius1: 50%;object-fit: cover" :src="cutImgSrc" alt="图片">
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import { VueCropper } from 'vue-cropper'
import { upload } from '@/api/system/common'
export default {
  name: 'ImageCropper',
  components: { VueCropper },
  props: {
    imgSrc: {
      type: String,
      default: ''
    },
    autoCrop: {
      type: Object,
      default () {
        return { width: 500, height: 500 }
      }
    },
    // å›žæ˜¾ä¸Šæ¬¡ä¿å­˜çš„æˆªå›¾çš„位置
    location: {
      type: Object,
      default () {
        return {}
      }
    }
    // iconItem:{
    //   type:Object,
    //   default(){
    //     return {};
    //   }
    // }
  },
  data () {
    return {
      // å­¦ä¹ æˆªå›¾é€‰é¡¹
      iconForm: {
        originImgBase64: '',
        imgBase64: ''
        // location: "",
        // matchingName: "",
        // matchingType: "",
        // note: "",
        // picGroupId: "0",
        // tsId: "",
      },
      // å‚¨å­˜æˆªå›¾åŒºåŸŸçš„图片,自己传
      // imgSrc:'',
      // å‚¨å­˜æˆªå›¾åŽçš„生成的base64图片
      cutImgSrc: '',
      // cropper插件的配置
      options: {
        canScale: false,
        autoCrop: true,
        canMove: false,
        centerBox: true,
        height: 500,
        width: 500,
        outputSize: 1,
        autoCropWidth: 500,
        autoCropHeight: 500,
        fixed: true,
        fixedNumber: [1, 1]
      },
      // æˆªå›¾æ¡†ç›¸å¯¹å›¾ç‰‡çš„位置
      clipAxis: {},
      // æˆªå›¾å›žæ˜¾æ ‡å¿—,只触发一次实现回显,
      flag: true
    }
  },
  mounted () {
  },
  watch: {
  },
  methods: {
    getImagecropper () {
      return this.$refs.cropper
    },
    // å­¦ä¹ æˆªå›¾æ¡†å˜åŒ–事件
    realTime (data) {
      if (data.h) {
        // èŽ·å–å›¾ç‰‡ç›¸å¯¹å®¹å™¨çš„ä½ç½®
        const img = this.$refs.cropper.getImgAxis()
        // èŽ·å–æˆªå›¾æ¡†ç›¸å¯¹å®¹å™¨çš„ä½ç½®
        const clip = this.$refs.cropper.getCropAxis()
        this.clipAxis.x = clip.x1 - img.x1
        this.clipAxis.y = clip.y1 - img.y1
        // èŽ·å–æˆªå›¾å›¾ç‰‡
        this.$refs.cropper.getCropData(img => {
          this.clipAxis.width = data.w
          this.clipAxis.height = data.h
          this.cutImgSrc = img
        })
        // èŽ·å–åŽŸå›¾base64的图片
        // this.imageUrlToBase64(data.url);
        // å›¾æ ‡åˆ—表编辑回显(初始化只触发一次)
        if (this.location.height != undefined && this.flag) {
          this.$nextTick(() => {
            // auto crop
            this.$refs.cropper.goAutoCrop()
            this.$nextTick(() => {
              // if cropped and has position message, update crop box
              this.$refs.cropper.cropOffsertX = this.location.x + img.x1
              this.$refs.cropper.cropOffsertY = this.location.y + img.y1
              this.$refs.cropper.cropW = this.location.width
              this.$refs.cropper.cropH = this.location.height
              // this.iconForm.location=this.iconItem.location;
              // this.iconForm.matchingName=this.iconItem.matchingName;
              // this.iconForm.matchingType=this.iconItem.matchingType;
              // this.iconForm.note=this.iconItem.note;
              // this.picGroupId=this.iconItem.picGroupId.split(',');
              // this.iconForm.id=this.iconItem.id;
              // this.iconForm.tsId=this.iconItem.tsId;
              this.flag = false
            })
          })
        }
      }
    },
    // åŽŸå›¾é€šè¿‡canvas转为base64的格式
    imageUrlToBase64 (src) {
      // ä¸€å®šè¦è®¾ç½®ä¸ºlet,不然图片不显示
      const image = new Image()
      // è§£å†³è·¨åŸŸé—®é¢˜
      image.setAttribute('crossOrigin', 'anonymous')
      const imageUrl = src
      image.src = imageUrl
      // image.onload为异步加载
      image.onload = () => {
        var canvas = document.createElement('canvas')
        canvas.width = image.width
        canvas.height = image.height
        var context = canvas.getContext('2d')
        context.drawImage(image, 0, 0, image.width, image.height)
        // var quality = 0.8;
        // è¿™é‡Œçš„dataurl就是base64类型
        const dataURL = canvas.toDataURL('image/jpeg')// ä½¿ç”¨toDataUrl将图片转换成jpeg的格式
        this.iconForm.originImgBase64 = dataURL
      }
    }
  }
}
</script>
<style lang="scss" scoped>
.iconShot {
  .icon-dialog {
    .clip {
      display: flex;
      .img {
        flex: 7.5;
        height: 500px;
        //float: left;
        // display: inline-block;
        .vue-cropper {
          background-image: none;
        }
        .cropper-move {
          cursor: default;
        }
        .cropper-face.cropper-move {
          cursor: move;
        }
      }
      .previews {
        //width: 100px;
        flex: 2.5;
        //float: right;
        height: 200px;
        //position: relative;
        >img {
          //position: absolute;
          //left: 50%;
          transform: translate(35%, 50px);
          max-height: 100%;
        }
      }
    }
  }
  .icon-options {
    font-size: 12px;
    font-weight: 200;
    >.el-row {
      >.el-col {
        >.el-row {
          height: 36px;
          line-height: 36px;
          >.el-col:nth-child(1) {
            font-weight: 600;
            text-align: right;
          }
          .el-col:nth-child(2) {
            .el-input,.el-select {
              width: 185px !important;
            }
          }
          >.el-col {
            padding: 0 10px;
          }
        }
      }
    }
  }
}
</style>
admin/src/components/common/UploadFaceImg.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,216 @@
<template>
  <div>
    <el-upload
        class="avatar-uploader"
        accept=".png,.jpg,.jpeg"
        :style="customStyle"
        action=""
        :auto-upload="false"
        :show-file-list="false"
        :on-change='openUpdateIcon'>
      <img v-if=" file.imgurlfull" style="width: 100%;" :src="file.imgurlfull" :style="customStyle" class="avatar">
      <div v-else :style="customStyle">
        <i class="el-icon-plus avatar-uploader-icon"></i>
        <div class="tips-style">{{ tipsLabel }}</div>
      </div>
    </el-upload>
    <el-dialog
        append-to-body
        :close-on-click-modal="false"
        title="上传图片"
        :visible.sync="updateImg"
        width="1000px"
        class="icon-dialog-wrapper dialong-com-style">
      <ImageCropper ref="iconShot" v-if="updateImg" :imgSrc="img"  :auto-crop="autoCrop">
      </ImageCropper>
      <span slot="footer" class="dialog-footer">
            <el-button v-if="loading">取 æ¶ˆ</el-button>
            <el-button v-else @click="updateImg = false">取 æ¶ˆ</el-button>
            <el-button :loading="loading" type="primary" @click="uploadIcon">ç¡® å®š</el-button>
          </span>
    </el-dialog>
  </div>
</template>
<script>
import ImageCropper from '@/components/common/ImageCropper'
import { upload } from '@/api/system/common'
export default {
  components: { ImageCropper },
  props: {
    file: {
      type: Object,
      default: () => {}
    },
    autoCrop: {
      type: Object,
      default () {
        return { width: 500, height: 500 }
      }
    },
    // eslint-disable-next-line vue/require-prop-type-constructor
    tipsLabel: {
      type: String,
      default: ''
    },
    customStyle: {
      type: String,
      default: 'width: 90px; height: 90px;'
    },
    uploadData: Object
  },
  data () {
    return {
      loading: false,
      fileInfo: {},
      img: null,
      updateImg: false,
      imageSrc: null,
      uploadImgUrl: process.env.VUE_APP_API_PREFIX + '/public/upload'
    }
  },
  methods: {
    uploadIcon () {
      // èŽ·å–è£å‰ªåŽçš„å›¾ç‰‡
      this.$refs.iconShot.getImagecropper().getCropBlob((fileData) => { // èŽ·å–å½“å‰è£å‰ªå¥½çš„æ•°æ®
        // æ³¨æ­¤æ—¶çš„data是一个Blob数据,部分接口接收的是File转化的FormData数据
        console.log(fileData)
        const formData = new FormData()
        formData.append('folder', this.uploadData.folder || 'member')
        if (this.uploadData.isFace || this.uploadData.isFace == 0) {
          formData.append('isFace', 0)
        }
        formData.append(
          'file',
          new File(
            [fileData], // å°†Blob类型转化成File类型
            this.fileInfo.name, // è®¾ç½®File类型的文件名称
            { type: this.fileInfo.type } // è®¾ç½®File类型的文件类型
          )
        )
        this.loading = true
        upload(formData).then(res => {
          this.loading = false
          console.log(res)
          this.file.imgurl = res.imgaddr
          this.file.imgurlfull = res.url
          this.$message.success('上传成功')
          this.imageSrc = res.url
          this.updateImg = false
          this.$emit('uploadSuccess', { imgurl: res.imgaddr, imgurlfull: res.url, name: res.originname })
          this.$emit('uploadEnd')
        }, () => {
          this.loading = false
        })
      })
    },
    // ä¸Šä¼ å›¾ç‰‡
    openUpdateIcon (file, fileList) {
      const isJPG = file.raw.type === 'image/jpeg' || file.raw.type === 'image/png'
      const isLt2M = file.size / 1024 / 1024 < 5
      if (!isJPG) {
        this.$message.error('上传头像图片只能是 JPG/PNG æ ¼å¼!')
        return false
      }
      if (!isLt2M) {
        this.$message.error('上传头像图片大小不能超过 5MB!')
        return false
      }
      // ä¸Šä¼ æˆåŠŸåŽå°†å›¾ç‰‡åœ°å€èµ‹å€¼ç»™è£å‰ªæ¡†æ˜¾ç¤ºå›¾ç‰‡
      this.$nextTick(async () => {
        // base64方式
        // this.option.img = await fileByBase64(file.raw)
        this.fileInfo.name = file.name
        this.fileInfo.type = file.type
        console.log(file, fileList)
        this.img = URL.createObjectURL(file.raw)
        // this.loading = false
        this.updateImg = true
      })
    },
    handleAvatarSuccess (res, file) {
      if (res.code == 200) {
        const { data } = res
        this.file.imgurl = data.imgaddr
        this.file.imgurlfull = data.url
        this.$message.success('上传成功')
        this.imageSrc = data.url
        this.updateImg = true
        // this.$emit('uploadSuccess', { imgurl: data.imgaddr, imgurlfull: data.url, name: data.originname })
      } else {
        this.$message.error('上传失败')
      }
      this.$emit('uploadEnd')
    },
    uploadError () {
      this.$message.error('上传失败')
      this.$emit('uploadEnd')
    },
    // // æ‹¦æˆª
    beforeAvatarUpload (file) {
      this.$emit('uploadBegin')
      return true
    }
  }
}
</script>
<style lang="scss" scoped>
$image-width: 90px;
.avatar-uploader {
  width: $image-width;
  height: $image-width;
}
::v-deep .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}
.avatar-uploader .el-upload:hover {
  border-color: #409EFF;
}
.avatar-uploader-icon {
  line-height: 90px;
  font-size: 28px;
  color: #8c939d;
  width: $image-width;
  height: $image-width;
  text-align: center;
}
.avatar {
  width: 100% !important;
  height: auto !important;
  display: block;
}
.tips-style {
  height: 13px;
  font-size: 13px;
  font-weight: 400;
  color: #999999;
  line-height: 13px;
}
</style>
<style lang="scss" scoped>
::v-deep .el-upload--picture-card{
  width: 90px !important;
  height: 90px !important;
}
::v-deep .el-upload-list__item {
  width: 90px !important;
  height: 90px !important;
}
.icon {
  -webkit-transform: translate(-50%,-50%);
  -ms-transform: translate(-50%,-50%);
  transform: translate(0%, -85%);
}
::v-deep .el-upload-list__item {
  width: 90px !important;
  height: 90px !important;
}
</style>
admin/src/views/business/cases.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,159 @@
<template>
  <TableLayout :permissions="['business:cases:query']">
    <!-- æœç´¢è¡¨å• -->
    <el-form ref="searchForm" slot="search-form" :model="searchForm" label-width="100px" inline>
      <el-form-item label="标题" prop="name">
        <el-input v-model="searchForm.name"  style="width: 150px" placeholder="请输入标题" @keypress.enter.native="search"></el-input>
      </el-form-item>
      <el-form-item label="老师" prop="memberId">
        <el-select
            v-model="searchForm.memberId"
            style="width: 150px"
            placeholder="老师"
            clearable
            filterable
            @change="search"
        >
          <el-option
              v-for="item in memberList"
              :key="item.id"
              :value="item.id"
              :label="item.name"
          ></el-option>
        </el-select>
      </el-form-item>
        <el-form-item label="状态" prop="status">
          <el-select
              v-model="searchForm.status"
              placeholder="状态"
              clearable
              style="width: 150px"
              @change="search"
          >
            <el-option :key="0" :value="0" label="启用"></el-option>
            <el-option :key="1" :value="1" label="禁用"></el-option>
          </el-select>
        </el-form-item>
      <section>
        <el-button type="primary" @click="search">搜索</el-button>
        <el-button @click="reset">重置</el-button>
      </section>
    </el-form>
    <!-- è¡¨æ ¼å’Œåˆ†é¡µ -->
    <template v-slot:table-wrap>
      <ul class="toolbar" v-permissions="['business:cases:create', 'business:cases:delete']">
        <li><el-button type="primary" @click="$refs.operaCasesWindow.open('新建案例',null)" icon="el-icon-plus" v-permissions="['business:cases:create']">新建</el-button></li>
        <li><el-button type="primary" icon="el-icon-refresh" v-permissions="['business:cases:create']" @click="$refs.OperaCasesImportWindow.open('案例导入')">批量导入</el-button></li>
        <li><el-button type="danger" @click="deleteByIdInBatch" icon="el-icon-delete" v-permissions="['business:cases:delete']">删除</el-button></li>
      </ul>
      <el-table
          :height="tableHeightNew"
        v-loading="isWorking.search"
        :data="tableData.list"
        stripe
        @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" width="55"></el-table-column>
        <el-table-column prop="name" label="案例标题" min-width="100px"></el-table-column>
        <el-table-column  prop="icon" label="排行榜图集" min-width="220px">
          <template slot-scope="{row}">
            <div style="display: flex; flex-wrap: wrap;width: 200px;"  v-if="row.fileList && row.fileList.length">
              <div v-for="item in row.fileList" :key="row.id+'_img'+item.id" style=" box-sizing: border-box;  margin-right: 10px; " >
                <el-image  style="width: 50px; height: 50px;" :src="item.url"
                           :preview-src-list="[item.url]">
                </el-image>
              </div>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="memberName" label="老师" min-width="120px"></el-table-column>
        <el-table-column prop="startDate" label="开始日期" min-width="140px"></el-table-column>
        <el-table-column prop="endDate" label="结束日期" min-width="140px"></el-table-column>
        <el-table-column prop="detail" label="案例描述" min-width="230px" show-overflow-tooltip></el-table-column>
        <el-table-column prop="updateUserName" label="操作人" min-width="100px"></el-table-column>
        <el-table-column prop="updateTime" label="最近操作时间" min-width="150px"></el-table-column>
        <el-table-column label="状态" fixed="right">
          <template slot-scope="{row}">
            <el-switch @change="changeStatus($event, row)" v-model="row.status" active-color="#13ce66"
                       inactive-color="#ff4949" :active-value="0" :inactive-value="1">
            </el-switch>
          </template>
        </el-table-column>
        <el-table-column
          v-if="containPermissions(['business:cases:update', 'business:cases:delete'])"
          label="操作"
          min-width="120"
          fixed="right"
        >
          <template slot-scope="{row}">
            <el-button type="text" @click="$refs.operaCasesWindow.open('编辑案例', row)" icon="el-icon-edit" v-permissions="['business:cases:update']">编辑</el-button>
            <el-button type="text" style="color: red" @click="deleteById(row)" icon="el-icon-delete" v-permissions="['business:cases:delete']">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
      <pagination
        @size-change="handleSizeChange"
        @current-change="handlePageChange"
        :pagination="tableData.pagination"
      >
      </pagination>
    </template>
    <!-- æ–°å»º/修改 -->
    <OperaCasesWindow ref="operaCasesWindow" @success="search"/>
    <OperaCasesImportWindow ref="OperaCasesImportWindow" @success="handlePageChange" />
  </TableLayout>
</template>
<script>
import BaseTable from '@/components/base/BaseTable'
import TableLayout from '@/layouts/TableLayout'
import Pagination from '@/components/common/Pagination'
import OperaCasesWindow from '@/components/business/OperaCasesWindow'
import OperaCasesImportWindow from '@/components/business/OperaCasesImportWindow'
import { findAll as memberList } from '@/api/business/member'
export default {
  name: 'cases',
  extends: BaseTable,
  components: { TableLayout, Pagination, OperaCasesWindow ,OperaCasesImportWindow},
  data () {
    return {
      // æœç´¢
      searchForm: {
        name: '',
        memberId: '',
        status: null
      },
      memberList:[]
    }
  },
  created () {
    this.config({
      module: '案例信息表',
      api: '/business/cases',
      'field.id': 'id',
      'field.main': 'id'
    })
    this.search()
    memberList({
    }).then(res => {
      this.memberList = res
    })
  },
  methods: {
    changeStatus (e, row) {
      this.working = true
      this.api.updateStatus({ id: row.id, status: e })
        .then(res => {
          this.$tip.apiSuccess(res || '操作成功')
          this.handlePageChange()
        })
        .catch(e => {
          this.$tip.apiFailed(e)
        })
        .finally(() => {
          this.working = false
        })
    }
  }
}
</script>
admin/src/views/business/importRecord.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,134 @@
<template>
  <TableLayout :permissions="['business:importrecord:query']">
    <!-- æœç´¢è¡¨å• -->
    <el-form ref="searchForm" slot="search-form" :model="searchForm" label-width="100px" inline>
      <el-form-item label="操作人" prop="name">
        <el-input v-model="searchForm.updateUserName" placeholder="请输入操作人姓名" @keypress.enter.native="search"></el-input>
      </el-form-item>
      <el-form-item label="业务类型" prop="type">
        <el-select v-model="searchForm.type"    placeholder="请选择业务类型" clearable   @change="search" >
          <el-option :key="0" :value="0" label="老师导入"></el-option>
          <el-option :key="1" :value="1" label="案例导入"></el-option>
        </el-select>
      </el-form-item>
      <div class="date-style" style="display: inline">
        <el-form-item label="导入时间" prop="starttime" >
          <el-date-picker
              style="width: 160px"
              clearable
              @change="search"
              v-model="searchForm.starttime"
              type="datetime"
              value-format="yyyy-MM-dd HH:mm:ss"
              format="yyyy-MM-dd HH:mm:ss"
              range-separator="至"
              placeholder="开始时间"
          ></el-date-picker>
        </el-form-item>
        <el-form-item label="-" label-width="10px" prop="endtime" >
          <el-date-picker
              style="width: 160px"
              clearable
              v-model="searchForm.endtime"
              type="datetime"
              @change="search"
              value-format="yyyy-MM-dd HH:mm:ss"
              format="yyyy-MM-dd HH:mm:ss"
              range-separator="至"
              placeholder="截止时间"
          ></el-date-picker>
        </el-form-item>
      </div>
      <section>
        <el-button type="primary" @click="search">搜索</el-button>
        <el-button @click="reset">重置</el-button>
      </section>
    </el-form>
    <!-- è¡¨æ ¼å’Œåˆ†é¡µ -->
    <template v-slot:table-wrap>
      <el-table
          :height="tableHeightNew"
        v-loading="isWorking.search"
        :data="tableData.list"
        stripe
        @selection-change="handleSelectionChange"
      >
        <el-table-column prop="title" label="内容" min-width="200px" show-overflow-tooltip></el-table-column>
        <el-table-column label="业务类型">
          <template slot-scope="{row}">
            <span v-if="row.type ==0 " >老师导入</span>
            <span v-if="row.type == 1"  >案例导入</span>
          </template>
        </el-table-column>
        <el-table-column label="状态">
          <template slot-scope="{row}">
            <span v-if="row.status ==0 " class="blue">未处理</span>
            <span v-if="row.status == 1" class="red">处理中</span>
            <span v-if="row.status == 2" class="grey">已处理</span>
          </template>
        </el-table-column>
        <el-table-column prop="totalNum" label="总记录数" min-width="100px"></el-table-column>
        <el-table-column prop="doneNum" label="成功录入数量" min-width="100px"></el-table-column>
        <el-table-column prop="errorNum" label="录入失败数量" min-width="100px"></el-table-column>
        <el-table-column prop="updateUserName" label="操作人" min-width="100px"></el-table-column>
        <el-table-column prop="updateTime" label="最近操作时间" min-width="150px"></el-table-column>
      </el-table>
      <pagination
        @size-change="handleSizeChange"
        @current-change="handlePageChange"
        :pagination="tableData.pagination"
      >
      </pagination>
    </template>
    <!-- æ–°å»º/修改 -->
    <OperaCategoryWindow ref="operaCategoryWindow" @success="handlePageChange"/>
  </TableLayout>
</template>
<script>
import BaseTable from '@/components/base/BaseTable'
import TableLayout from '@/layouts/TableLayout'
import Pagination from '@/components/common/Pagination'
import OperaCategoryWindow from '@/components/business/OperaCategoryWindow'
export default {
  name: 'Category',
  extends: BaseTable,
  components: { TableLayout, Pagination, OperaCategoryWindow },
  data () {
    return {
      // æœç´¢
      searchForm: {
        updateUserName: '',
        starttime: null,
        endtime: null,
        type: ''
      }
    }
  },
  created () {
    this.config({
      module: '分类信息表',
      api: '/business/importRecord',
      'field.id': 'id',
      'field.main': 'id'
    })
    this.search()
  },
  methods: {
    changeStatus (e, row) {
      this.working = true
      this.api.updateStatus({ id: row.id, status: e })
        .then(res => {
          this.$tip.apiSuccess(res || '操作成功')
          this.search()
        })
        .catch(e => {
          this.$tip.apiFailed(e)
        })
        .finally(() => {
          this.working = false
        })
    }
  }
}
</script>
admin/src/views/business/member.vue
@@ -8,43 +8,41 @@
      <el-form-item label="工号" prop="code">
        <el-input v-model="searchForm.code" style="width: 150px" placeholder="请输入工号" @keypress.enter.native="search"></el-input>
      </el-form-item>
      <el-form-item label="战区" prop="fieldIdList">
      <el-form-item label="战区" prop="zhanquIds">
        <el-select
            v-model="searchForm.fieldIdList"
            v-model="searchForm.zhanquIds"
            style="width: 150px"
            placeholder="战区"
            clearable
            multiple
            @change="search"
        >
          <el-option
              v-for="item in cateList"
              v-for="item in cateList.filter(item=>{return item.type==0})"
              :key="item.id"
              :value="item.id"
              :label="item.name"
          ></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="商业化类型" prop="busTypeIdList">
      <el-form-item label="商业化类型" prop="bustypeIds">
        <el-select
            v-model="searchForm.busTypeIdList"
            v-model="searchForm.bustypeIds"
            style="width: 150px"
            placeholder="商业化类型"
            clearable
            multiple
            @change="search"
        >
          <el-option
              v-for="item in cateList1"
              v-for="item in cateList.filter(item=>{return item.type==1})"
              :key="item.id"
              :value="item.id"
              :label="item.name"
          ></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="擅长领域" prop="levelIdList">
      <el-form-item label="擅长领域" prop="fieldIdList">
        <el-select
            v-model="searchForm.levelIdList"
            v-model="searchForm.fieldIdList"
            style="width: 150px"
            placeholder="擅长领域"
            clearable
@@ -52,24 +50,23 @@
            @change="search"
        >
          <el-option
              v-for="item in cateList2"
              v-for="item in cateList.filter(item=>{return item.type==2})"
              :key="item.id"
              :value="item.id"
              :label="item.name"
          ></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="老师等级" prop="levelIdList">
      <el-form-item label="老师等级" prop="levelId">
        <el-select
            v-model="searchForm.levelIdList"
            v-model="searchForm.levelId"
            style="width: 150px"
            placeholder="老师等级"
            clearable
            multiple
            @change="search"
        >
          <el-option
              v-for="item in cateList3"
              v-for="item in cateList.filter(item=>{return item.type==3})"
              :key="item.id"
              :value="item.id"
              :label="item.name"
@@ -110,8 +107,8 @@
        <el-table-column type="selection" width="55"></el-table-column>
        <el-table-column  prop="imgurl" label="图片" min-width="100px">
          <template slot-scope="{row}">
            <el-image v-if="row.imgurlfull" style="width: 50px; height: 50px; margin-right: 10px" :src="row.imgurlfull"
                      :preview-src-list="[row.imgurlfull]">
            <el-image v-if="row.fullImgurl" style="width: 50px; height: 50px; margin-right: 10px" :src="row.fullImgurl"
                      :preview-src-list="[row.fullImgurl]">
            </el-image>
          </template>
        </el-table-column>
@@ -123,7 +120,7 @@
            <span v-if="row.sex ==1">女</span>
          </template>
        </el-table-column>
        <el-table-column prop="position" label="岗位" min-width="120px"></el-table-column>
        <el-table-column prop="positon" label="岗位" min-width="120px"></el-table-column>
        <el-table-column prop="levelName" label="等级" min-width="100px"></el-table-column>
        <el-table-column prop="jobYear" label="从业年份" min-width="100px"></el-table-column>
        <el-table-column prop="serveNum" label="服务商场" min-width="100px">
@@ -133,21 +130,40 @@
        </el-table-column>
        <el-table-column prop="caseNum" label="标杆案例" min-width="100px">
          <template slot-scope="{row}">
            <span v-if="row.caseNum">{{row.caseNum}}个</span>
            <span >{{row.caseNum || 0}}个</span>
          </template>
        </el-table-column>
        <el-table-column prop="busTypeNames" label="商业化类型" min-width="200px"></el-table-column>
        <el-table-column prop="areaNames" label="服务战区" min-width="200px"></el-table-column>
        <el-table-column prop="fieldNames" label="擅长领域" min-width="200px"></el-table-column>
        <el-table-column label="状态">
        <el-table-column prop="busTypeNames" label="商业化类型" min-width="200px">
          <template slot-scope="{row}">
            <div v-if="row.typeList && row.typeList.length">
             <div style="display:inline-block;" v-for="(item,index) in row.typeList">{{item.name||''}} <span v-if="index < row.typeList.length-1" style="display:inline-block;padding: 0px 3px;">/</span></div>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="areaNames" label="服务战区" min-width="200px">
          <template slot-scope="{row}">
            <div v-if="row.zqList && row.zqList.length">
              <div style="display:inline-block;" v-for="(item,index) in row.zqList">{{item.name||''}} <span v-if="index < row.zqList.length-1" style="display:inline-block;padding: 0px 3px;">/</span></div>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="fieldNames" label="擅长领域" min-width="200px">
          <template slot-scope="{row}">
            <div v-if="row.fieldList && row.fieldList.length">
              <div style="display:inline-block;" v-for="(item,index) in row.fieldList">{{item.name||''}} <span v-if="index < row.fieldList.length-1" style="display:inline-block;padding: 0px 3px;">/</span></div>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="fee" label="费用标准(元/周)" min-width="130px"></el-table-column>
        <el-table-column prop="updateUserName" label="操作人" min-width="100px"></el-table-column>
        <el-table-column prop="updateTime" label="最近操作时间" min-width="150px"></el-table-column>
        <el-table-column label="状态" fixed="right">
          <template slot-scope="{row}">
            <el-switch @change="changeStatus($event, row)" v-model="row.status" active-color="#13ce66"
            inactive-color="#ff4949" :active-value="0" :inactive-value="1">
                       inactive-color="#ff4949" :active-value="0" :inactive-value="1">
            </el-switch>
          </template>
        </el-table-column>
        <el-table-column prop="updateUserName" label="操作人" min-width="100px"></el-table-column>
        <el-table-column prop="updateTime" label="最近操作时间" min-width="150px"></el-table-column>
        <el-table-column
          v-if="containPermissions(['business:member:update', 'business:member:delete'])"
          label="操作"
@@ -189,17 +205,16 @@
      // æœç´¢
      searchForm: {
        name: '',
        queryFlag:1,
        code: '',
        status: null,
        levelIdList:[],
        levelId:null,
        fieldIdList: [],
        busTypeIdList:[],
        zhanquIds:null,
        bustypeIds:null,
        type: 0
      },
      cateList:[],
      cateList1:[],
      cateList2:[],
      cateList3:[],
      cateList:[]
    }
  },
  created () {
@@ -211,25 +226,10 @@
    })
    this.search()
    cateList({
      type: 0 , //战区
    }).then(res => {
      this.cateList = res
    })
    cateList({
      type: 1 , //商业化
    }).then(res => {
      this.cateList1 = res
    })
    cateList({
      type: 2 , //擅长领用
    }).then(res => {
      this.cateList2 = res
    })
    cateList({
      type: 3 , //等级
    }).then(res => {
      this.cateList3 = res
    })
  },
  methods: {
    changeStatus (e, row) {
@@ -237,7 +237,7 @@
      this.api.updateStatus({ id: row.id, status: e })
        .then(res => {
          this.$tip.apiSuccess(res || '操作成功')
          this.search()
          this.handlePageChange()
        })
        .catch(e => {
          this.$tip.apiFailed(e)
server/admin/src/main/java/com/doumee/api/business/CasesController.java
@@ -8,6 +8,7 @@
import com.doumee.core.model.PageWrap;
import com.doumee.dao.business.model.Cases;
import com.doumee.core.utils.Utils;
import com.doumee.dao.business.model.Member;
import com.doumee.service.business.CasesService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@@ -45,7 +46,13 @@
        casesService.deleteById(id);
        return ApiResponse.success(null);
    }
    @ApiOperation("修改状态")
    @PostMapping("/updateStatus")
    @RequiresPermissions("business:cases:update")
    public ApiResponse updateStatus( @RequestBody Cases param) {
        casesService.updateStatus(param);
        return ApiResponse.success(null);
    }
    @ApiOperation("批量删除")
    @GetMapping("/delete/batch")
    @RequiresPermissions("business:cases:delete")
server/admin/src/main/java/com/doumee/api/business/MemberController.java
@@ -6,6 +6,7 @@
import com.doumee.core.model.ApiResponse;
import com.doumee.core.model.PageData;
import com.doumee.core.model.PageWrap;
import com.doumee.dao.business.model.Category;
import com.doumee.dao.business.model.Member;
import com.doumee.core.utils.Utils;
import com.doumee.service.business.MemberService;
@@ -19,6 +20,7 @@
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.util.List;
/**
 * ä¼šå‘˜ä¿¡æ¯è¡¨Controller定义
@@ -64,13 +66,25 @@
        memberService.updateById(member);
        return ApiResponse.success(null);
    }
    @ApiOperation("修改状态")
    @PostMapping("/updateStatus")
    @RequiresPermissions("business:member:update")
    public ApiResponse updateStatus( @RequestBody Member param) {
        memberService.updateStatus(param);
        return ApiResponse.success(null);
    }
    @ApiOperation("分页查询")
    @PostMapping("/page")
    @RequiresPermissions("business:member:query")
    public ApiResponse<PageData<Member>> findPage (@RequestBody PageWrap<Member> pageWrap) {
        return ApiResponse.success(memberService.findPage(pageWrap));
    }
    @ApiOperation("分页查询")
    @PostMapping("/list")
    @RequiresPermissions("business:member:query")
    public ApiResponse<List<Member>> findList (@RequestBody Member  pageWrap) {
        return ApiResponse.success(memberService.findList(pageWrap));
    }
    @ApiOperation("导出Excel")
    @PostMapping("/exportExcel")
server/services/src/main/java/com/doumee/core/annotation/excel/ExcelImporter.java
@@ -10,10 +10,7 @@
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
@@ -147,12 +144,13 @@
    }
    public ExcelImporter(String fileName, InputStream in, int headerNum, int sheetIndex,CellType cellType)
        throws InvalidFormatException, IOException {
        ByteArrayOutputStream buffer = toByteArray(in);
        if (StringUtils.isBlank(fileName)){
            throw new RuntimeException("导入文档为空!");
        }else if(fileName.toLowerCase().endsWith("xls")){
            this.wb = new HSSFWorkbook(in);
            this.wb = new HSSFWorkbook(new ByteArrayInputStream(buffer.toByteArray()));
        }else if(fileName.toLowerCase().endsWith("xlsx")){
            this.wb = new XSSFWorkbook(in);
            this.wb = new XSSFWorkbook(new ByteArrayInputStream(buffer.toByteArray()));
        }else{
            throw new RuntimeException("文档格式不正确!");
        }
@@ -162,10 +160,27 @@
        this.sheet = this.wb.getSheetAt(sheetIndex);
        this.headerNum = headerNum;
        this.changeType = cellType;
        this.pictureList = ExcelPictureUtil.getExcelPictures(in);
        this.pictureList = ExcelPictureUtil.getExcelPictures(new ByteArrayInputStream(buffer.toByteArray()));
        log.debug("Initialize success.");
    }
    public static ByteArrayOutputStream toByteArray(InputStream inputStream) {
        try {
            // ç¼“存文件流
            ByteArrayOutputStream buffer = new ByteArrayOutputStream();
            byte[] data = new byte[1024];
            int nRead;
            while ((nRead = inputStream.read(data, 0, data.length))!= -1) {
                buffer.write(data, 0, nRead);
            }
            buffer.flush();
           return  buffer;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
@@ -357,6 +372,7 @@
                                    "fieldtype."+valType.getSimpleName()+"Type")).getMethod("getValue", String.class).invoke(null, val.toString());
                            }
                        }
                    } catch (Exception ex) {
                        log.info("Get cell value ["+i+","+column+"] error: " + ex.toString());
                        val = null;
server/services/src/main/java/com/doumee/core/annotation/excel/ExcelPictureUtil.java
@@ -33,7 +33,7 @@
    public static Map<String, XSSFPictureData> getExcelPictures(InputStream is) {
        try {
            byte[] fileData =  getFileStream(is);
            byte[] fileData = toByteArray(is);
            Map<String, XSSFPictureData> pictures = getPictures(fileData);
            pictures.forEach((id, xssfPictureData) -> {
                System.out.println("id:" + id);
@@ -46,6 +46,15 @@
        }
    }
    public static byte[] toByteArray(InputStream input) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        int bytesRead;
        byte[] buffer = new byte[1024]; // å¯ä»¥æ ¹æ®éœ€è¦è°ƒæ•´ç¼“冲区大小
        while ((bytesRead = input.read(buffer)) != -1) {
            byteArrayOutputStream.write(buffer, 0, bytesRead);
        }
        return byteArrayOutputStream.toByteArray();
    }
    /**
     * èŽ·å–æµ®åŠ¨å›¾ç‰‡ï¼Œä»¥ map å½¢å¼è¿”回,键为行列格式 x-y。
server/services/src/main/java/com/doumee/core/utils/DateUtil.java
@@ -438,7 +438,7 @@
     * @return String
     * @throws Exception
     */
    public static String getNowShortDate() throws Exception {
    public static String getNowShortDate() {
        String nowDate = "";
        try {
            java.sql.Date date = null;
@@ -446,7 +446,7 @@
            nowDate = sdfShort.format(date);
            return nowDate;
        } catch (Exception e) {
            throw e;
            return  null;
        }
    }
server/services/src/main/java/com/doumee/core/utils/tyyun/TyyZosUtil.java
@@ -163,7 +163,6 @@
    }
    public boolean uploadInputstreamObject(InputStream inputStream, String bucketName, String key )     {
        try {
            if (inputStream != null) {
                ObjectMetadata metadata = new ObjectMetadata();
                metadata.setContentLength(inputStream.available());
@@ -181,5 +180,23 @@
        return false;
    }
    public boolean uploadInputstreamObjectNoShutdown(InputStream inputStream, String bucketName, String key )     {
        try {
            if (inputStream != null) {
                ObjectMetadata metadata = new ObjectMetadata();
                metadata.setContentLength(inputStream.available());
                PutObjectRequest request = new PutObjectRequest(bucketName, key, inputStream,metadata);
                request.setCannedAcl(CannedAccessControlList.PublicRead);
                PutObjectResult result = client.putObject(request);
                return true;
            }
        }catch (Exception e){
            log.error("对象存储==================== æ–‡ä»¶ä¸Šä¼ å¤±è´¥"+e.getMessage());
        }finally {
        }
        return false;
    }
}
server/services/src/main/java/com/doumee/dao/business/dto/MemberImport.java
@@ -1,8 +1,12 @@
package com.doumee.dao.business.dto;
import com.doumee.core.annotation.excel.ExcelColumn;
import com.doumee.core.constants.Constants;
import com.doumee.dao.business.model.Category;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import java.util.List;
/**
 * å‘˜å·¥ä¿¡æ¯å¯¼å…¥è¡¨
@@ -39,4 +43,6 @@
    @ExcelColumn(name="老师简介", value = "fee",index = 13)
    private String info;
}
server/services/src/main/java/com/doumee/dao/business/model/Cases.java
@@ -11,6 +11,8 @@
import com.fasterxml.jackson.annotation.JsonFormat;
import java.util.Date;
import java.math.BigDecimal;
import java.util.List;
/**
 * åˆ†ç±»ä¿¡æ¯è¡¨Model定义
 * @author doumee
@@ -66,9 +68,11 @@
    private String imgurl;
    @ApiModelProperty("开始时间")
    @ExcelColumn(name="开始时间",index=13 ,width=10)
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date startDate;
    @ApiModelProperty("结束时间")
    @ExcelColumn(name="结束时间",index=14 ,width=10)
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date endDate;
    @ApiModelProperty("排序码(升序使用)")
    @ExcelColumn(name="排序码(升序使用)",index=15 ,width=10)
@@ -79,4 +83,13 @@
    @ApiModelProperty("导入记录编码(关联import_record)")
    @ExcelColumn(name="导入记录编码(关联import_record)",index=17 ,width=10)
    private Integer importId;
    @ApiModelProperty(value = "老师姓名", example = "1")
    @TableField(exist = false)
    private String memberName  ;
    @ApiModelProperty(value = "图集附件集合", example = "1")
    @TableField(exist = false)
    private List<Multifile> fileList;
    @ApiModelProperty(value = "最后操作人员;", example = "1")
    @TableField(exist = false)
    private String updateUserName;
}
server/services/src/main/java/com/doumee/dao/business/model/ImportRecord.java
@@ -83,11 +83,19 @@
    @ExcelColumn(name="导入失败记录数",index=18 ,width=10)
    private Integer errorNum;
    @TableField(exist = false)
    private List<CasesImport> caseList;
    private List<Cases> caseList;
    @TableField(exist = false)
    private List<MemberImport> memberList;
    private List<Member> memberList;
    @TableField(exist = false)
    private  List<PictureData> pictureDataList;
    @ApiModelProperty(value = "最后操作人员;", example = "1")
    @TableField(exist = false)
    private String updateUserName;
    @ApiModelProperty(value = "结束时间;", example = "1")
    @TableField(exist = false)
    private Date starttime;
    @ApiModelProperty(value = "结束时间;", example = "1")
    @TableField(exist = false)
    private Date endtime;
}
server/services/src/main/java/com/doumee/dao/business/model/Member.java
@@ -144,14 +144,41 @@
    @ApiModelProperty("查询用户类型")
    @TableField(exist = false)
    private String queryUserRole;
    @ApiModelProperty("标杆案例数量")
    @TableField(exist = false)
    private Integer caseNum;
    @ApiModelProperty("查询入口 1后台")
    @TableField(exist = false)
    private Integer queryFlag  ;
    @ApiModelProperty("擅长领域")
    @TableField(exist = false)
    private List<Category> fieldList;
    @ApiModelProperty("擅长领域")
    @TableField(exist = false)
    private List<Integer> fieldIdList;
    @ApiModelProperty("商业化类型编码集合")
    @TableField(exist = false)
    private List<Integer> bustypeIdList;
    @ApiModelProperty("战区编码集合")
    @TableField(exist = false)
    private List<Integer> zhanquIdList;
    @ApiModelProperty("战区集合")
    @TableField(exist = false)
    private List<Category> zqList;
    @ApiModelProperty("商业化类型")
    @TableField(exist = false)
    private List<Category> typeList;
    @ApiModelProperty("案例信息")
    @TableField(exist = false)
    private List<Cases> casesList;
    @TableField(exist = false)
    private byte[] imgurlData;
    @ApiModelProperty(value = "最后操作人员;", example = "1")
    @TableField(exist = false)
    private String updateUserName;
}
server/services/src/main/java/com/doumee/service/business/CasesService.java
@@ -26,7 +26,7 @@
     * @param id ä¸»é”®
     */
    void deleteById(Integer id);
    void updateStatus(Cases cases);
    /**
     * åˆ é™¤
     *
server/services/src/main/java/com/doumee/service/business/MemberService.java
@@ -49,7 +49,7 @@
     * @param model å®žä½“对象
     */
    void updateById(Member model);
    void updateStatus(Member member);
    /**
     * æ‰¹é‡ä¸»é”®æ›´æ–°
     *
server/services/src/main/java/com/doumee/service/business/impl/CasesServiceImpl.java
@@ -1,20 +1,37 @@
package com.doumee.service.business.impl;
import com.doumee.biz.system.SystemDictDataBiz;
import com.doumee.core.constants.Constants;
import com.doumee.core.constants.ResponseStatus;
import com.doumee.core.exception.BusinessException;
import com.doumee.core.model.LoginUserInfo;
import com.doumee.core.model.PageData;
import com.doumee.core.model.PageWrap;
import com.doumee.dao.business.MultifileMapper;
import com.doumee.dao.business.model.Cases;
import com.doumee.core.utils.Utils;
import com.doumee.dao.business.CasesMapper;
import com.doumee.dao.business.model.Category;
import com.doumee.dao.business.model.Member;
import com.doumee.dao.business.model.Multifile;
import com.doumee.dao.system.model.SystemUser;
import com.doumee.service.business.CasesService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
/**
 * åˆ†ç±»ä¿¡æ¯è¡¨Service实现
@@ -25,19 +42,78 @@
public class CasesServiceImpl implements CasesService {
    @Autowired
    private SystemDictDataBiz systemDictDataBiz;
    @Autowired
    private CasesMapper casesMapper;
    @Autowired
    private MultifileMapper multifileMapper;
    @Override
    @Transactional
    public Integer create(Cases cases) {
        LoginUserInfo loginUserInfo = (LoginUserInfo) SecurityUtils.getSubject().getPrincipal();
        if(StringUtils.isBlank(cases.getName())
                ||StringUtils.isBlank(cases.getDetail())
                ||cases.getStartDate()==null
                ||cases.getEndDate()==null  ){
            throw new BusinessException(ResponseStatus.BAD_REQUEST);
        }
        cases.setDeleted(Constants.ZERO);
        cases.setCreateTime(new Date());
        cases.setCreateUser(loginUserInfo.getId());
        cases.setUpdateTime(new Date());
        cases.setUpdateUser(loginUserInfo.getId());
        casesMapper.insert(cases);
        dealBatchMultiFiles(cases, cases.getFileList(), loginUserInfo,true);
        return cases.getId();
    }
    public void dealBatchMultiFiles(Cases category, List<Multifile> fileList, LoginUserInfo user,boolean update) {
        Date today = new Date();
        //清空原有的
        if(update){
            multifileMapper.delete(new UpdateWrapper<Multifile>().lambda()
                    .eq(Multifile::getIsdeleted,Constants.ZERO)
                    .eq(Multifile::getObjType,Constants.ONE)
                    .eq(Multifile::getObjId,category.getId()));
        }
        if(fileList!=null && fileList.size()>0){
            List<Multifile> multifileList = new ArrayList<>();
            fileList.stream().forEach(s -> {
                if(StringUtils.isNotBlank(s.getFileurl())){
                    s.setIsdeleted(Constants.ZERO);
                    s.setCreator(user.getId());
                    s.setCreateDate(today);
                    s.setObjId(category.getId());
                    s.setType(Constants.ZERO);
                    s.setObjType(Constants.ONE);
                    multifileList.add(s);
                }
            });
            if(multifileList.size()>0){
                multifileMapper.insert(multifileList);
            }
        }
    }
    @Override
    public void deleteById(Integer id) {
        casesMapper.deleteById(id);
        Cases cases =new Cases();
        LoginUserInfo loginUserInfo = (LoginUserInfo) SecurityUtils.getSubject().getPrincipal();
        cases.setUpdateTime(new Date());
        cases.setId(id);
        cases.setUpdateUser(loginUserInfo.getId());
        cases.setDeleted(Constants.ONE);
        casesMapper.updateById(cases);
    }
    @Override
    public void updateStatus(Cases cases) {
        if(Objects.isNull(cases) || Objects.isNull(cases.getId())){
            throw new BusinessException(ResponseStatus.BAD_REQUEST);
        }
        LoginUserInfo loginUserInfo = (LoginUserInfo) SecurityUtils.getSubject().getPrincipal();
        cases.setUpdateTime(new Date());
        cases.setUpdateUser(loginUserInfo.getId());
        casesMapper.updateById(cases);
    }
    @Override
    public void delete(Cases cases) {
        UpdateWrapper<Cases> deleteWrapper = new UpdateWrapper<>(cases);
@@ -49,12 +125,25 @@
        if (CollectionUtils.isEmpty(ids)) {
            return;
        }
        casesMapper.deleteBatchIds(ids);
        for(Integer id : ids){
            this.deleteById(id);
        }
    }
    @Override
    public void updateById(Cases cases) {
        LoginUserInfo loginUserInfo = (LoginUserInfo) SecurityUtils.getSubject().getPrincipal();
        if(StringUtils.isBlank(cases.getName())
                ||StringUtils.isBlank(cases.getDetail())
                ||cases.getStartDate()==null
                ||cases.getEndDate()==null  ){
            throw new BusinessException(ResponseStatus.BAD_REQUEST);
        }
        cases.setDeleted(Constants.ZERO);
        cases.setUpdateTime(new Date());
        cases.setUpdateUser(loginUserInfo.getId());
        casesMapper.updateById(cases);
        dealBatchMultiFiles(cases, cases.getFileList(), loginUserInfo,true);
    }
    @Override
@@ -83,49 +172,59 @@
        QueryWrapper<Cases> wrapper = new QueryWrapper<>(cases);
        return casesMapper.selectList(wrapper);
    }
    @Override
    public PageData<Cases> findPage(PageWrap<Cases> pageWrap) {
        IPage<Cases> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
        QueryWrapper<Cases> queryWrapper = new QueryWrapper<>();
        MPJLambdaWrapper<Cases> queryWrapper = new MPJLambdaWrapper<>();
        queryWrapper.selectAll(Cases.class)
                .selectAs(Member::getName,Cases::getMemberName)
                .selectAs(SystemUser::getRealname, Member::getUpdateUserName)
                .leftJoin(SystemUser.class,SystemUser::getId,Cases::getUpdateUser)
                 .leftJoin(Member.class,Member::getId,Cases::getMemberId);
        Utils.MP.blankToNull(pageWrap.getModel());
               queryWrapper.lambda().eq(pageWrap.getModel().getId() != null,Cases::getId, pageWrap.getModel().getId());
               queryWrapper.lambda().eq(pageWrap.getModel().getDeleted() != null,Cases::getDeleted, pageWrap.getModel().getDeleted());
               queryWrapper.lambda().eq(pageWrap.getModel().getCreateUser() != null,Cases::getCreateUser, pageWrap.getModel().getCreateUser());
             if (pageWrap.getModel().getId() != null) {
                  queryWrapper.lambda().ge(Cases::getCreateTime, Utils.Date.getStart(pageWrap.getModel().getCreateTime()));
                  queryWrapper.lambda().le(Cases::getCreateTime, Utils.Date.getEnd(pageWrap.getModel().getCreateTime()));
             }
               queryWrapper.lambda().eq(pageWrap.getModel().getUpdateUser() != null,Cases::getUpdateUser, pageWrap.getModel().getUpdateUser());
             if (pageWrap.getModel().getId() != null) {
                  queryWrapper.lambda().ge(Cases::getUpdateTime, Utils.Date.getStart(pageWrap.getModel().getUpdateTime()));
                  queryWrapper.lambda().le(Cases::getUpdateTime, Utils.Date.getEnd(pageWrap.getModel().getUpdateTime()));
             }
               queryWrapper.lambda().eq(pageWrap.getModel().getRemark() != null,Cases::getRemark, pageWrap.getModel().getRemark());
               queryWrapper.lambda().eq(pageWrap.getModel().getStatus() != null,Cases::getStatus, pageWrap.getModel().getStatus());
               queryWrapper.lambda().eq(pageWrap.getModel().getName() != null,Cases::getName, pageWrap.getModel().getName());
               queryWrapper.lambda().eq(pageWrap.getModel().getMemberId() != null,Cases::getMemberId, pageWrap.getModel().getMemberId());
               queryWrapper.lambda().eq(pageWrap.getModel().getDetail() != null,Cases::getDetail, pageWrap.getModel().getDetail());
               queryWrapper.lambda().eq(pageWrap.getModel().getImgurl() != null,Cases::getImgurl, pageWrap.getModel().getImgurl());
             if (pageWrap.getModel().getId() != null) {
                  queryWrapper.lambda().ge(Cases::getStartDate, Utils.Date.getStart(pageWrap.getModel().getStartDate()));
                  queryWrapper.lambda().le(Cases::getStartDate, Utils.Date.getEnd(pageWrap.getModel().getStartDate()));
             }
             if (pageWrap.getModel().getId() != null) {
                  queryWrapper.lambda().ge(Cases::getEndDate, Utils.Date.getStart(pageWrap.getModel().getEndDate()));
                  queryWrapper.lambda().le(Cases::getEndDate, Utils.Date.getEnd(pageWrap.getModel().getEndDate()));
             }
               queryWrapper.lambda().eq(pageWrap.getModel().getSortnum() != null,Cases::getSortnum, pageWrap.getModel().getSortnum());
               queryWrapper.lambda().eq(pageWrap.getModel().getAddType() != null,Cases::getAddType, pageWrap.getModel().getAddType());
               queryWrapper.lambda().eq(pageWrap.getModel().getImportId() != null,Cases::getImportId, pageWrap.getModel().getImportId());
        for(PageWrap.SortData sortData: pageWrap.getSorts()) {
            if (sortData.getDirection().equalsIgnoreCase(PageWrap.DESC)) {
                queryWrapper.orderByDesc(sortData.getProperty());
            } else {
                queryWrapper.orderByAsc(sortData.getProperty());
        queryWrapper.eq(pageWrap.getModel().getId() != null,Cases::getId, pageWrap.getModel().getId());
        queryWrapper.eq(pageWrap.getModel().getDeleted() != null,Cases::getDeleted, pageWrap.getModel().getDeleted());
        queryWrapper.eq(pageWrap.getModel().getCreateUser() != null,Cases::getCreateUser, pageWrap.getModel().getCreateUser());
        queryWrapper.eq(pageWrap.getModel().getUpdateUser() != null,Cases::getUpdateUser, pageWrap.getModel().getUpdateUser());
        queryWrapper.eq(pageWrap.getModel().getRemark() != null,Cases::getRemark, pageWrap.getModel().getRemark());
        queryWrapper.eq(pageWrap.getModel().getStatus() != null,Cases::getStatus, pageWrap.getModel().getStatus());
        queryWrapper.like(StringUtils.isNotBlank(pageWrap.getModel().getName() ),Cases::getName, pageWrap.getModel().getName());
        queryWrapper.eq(pageWrap.getModel().getMemberId() != null,Cases::getMemberId, pageWrap.getModel().getMemberId());
        queryWrapper.eq(pageWrap.getModel().getDetail() != null,Cases::getDetail, pageWrap.getModel().getDetail());
        queryWrapper.eq(pageWrap.getModel().getImgurl() != null,Cases::getImgurl, pageWrap.getModel().getImgurl());
        queryWrapper.eq(pageWrap.getModel().getSortnum() != null,Cases::getSortnum, pageWrap.getModel().getSortnum());
        queryWrapper.eq(pageWrap.getModel().getAddType() != null,Cases::getAddType, pageWrap.getModel().getAddType());
        queryWrapper.eq(pageWrap.getModel().getImportId() != null,Cases::getImportId, pageWrap.getModel().getImportId());
        queryWrapper.orderByDesc(Cases::getId);
        PageData<Cases> result =PageData.from(casesMapper.selectJoinPage(page, Cases.class,queryWrapper));
        if(result!=null && result.getRecords()!=null){
            String path  = systemDictDataBiz.queryByCode(Constants.OBJCET_STORAGE,Constants.RESOURCE_PATH).getCode()
                    +systemDictDataBiz.queryByCode(Constants.OBJCET_STORAGE,Constants.CASES_FILES).getCode();
            for(Cases cate : result.getRecords()){
                initMultifileList(cate);
            }
        }
        return PageData.from(casesMapper.selectPage(page, queryWrapper));
        return result;
    }
    private void initMultifileList(Cases cate) {
        String path = systemDictDataBiz.queryByCode(Constants.OBJCET_STORAGE, Constants.RESOURCE_PATH).getCode()
                + systemDictDataBiz.queryByCode(Constants.OBJCET_STORAGE, Constants.CATEGORY_FILES).getCode();
        Multifile find = new Multifile();
        find.setObjId(cate.getId());
        find.setObjType(Constants.ONE);
        find.setIsdeleted(Constants.ZERO);
        List<Multifile> fileList=  multifileMapper.selectList(new QueryWrapper<>(find));
        if(fileList!=null){
            for(Multifile f : fileList){
                if(StringUtils.isNotBlank(f.getFileurl())){
                    f.setUrl(path+f.getFileurl());
                }
            }
        }
        cate.setFileList(fileList);
    }
    @Override
server/services/src/main/java/com/doumee/service/business/impl/CategoryServiceImpl.java
@@ -190,7 +190,7 @@
        Utils.MP.blankToNull(pageWrap.getModel());
        pageWrap.getModel().setDeleted(Constants.ZERO);
        queryWrapper.selectAll(Category.class)
                .selectAs(SystemUser::getUsername, Category::getUpdateUserName)
                .selectAs(SystemUser::getRealname, Category::getUpdateUserName)
                .leftJoin(SystemUser.class,SystemUser::getId,Category::getUpdateUser);
        if (pageWrap.getModel().getId() != null) {
            queryWrapper.eq(Category::getId, pageWrap.getModel().getId());
server/services/src/main/java/com/doumee/service/business/impl/ImportRecordServiceImpl.java
@@ -1,5 +1,6 @@
package com.doumee.service.business.impl;
import com.doumee.biz.system.SystemDictDataBiz;
import com.doumee.core.annotation.excel.ExcelImporter;
import com.doumee.core.constants.Constants;
import com.doumee.core.constants.ResponseStatus;
@@ -8,21 +9,33 @@
import com.doumee.core.model.PageData;
import com.doumee.core.model.PageWrap;
import com.doumee.core.utils.DateUtil;
import com.doumee.core.utils.tyyun.TyyZosUtil;
import com.doumee.dao.business.CasesMapper;
import com.doumee.dao.business.CategoryMapper;
import com.doumee.dao.business.MemberMapper;
import com.doumee.dao.business.dto.CasesImport;
import com.doumee.dao.business.dto.MemberImport;
import com.doumee.dao.business.model.Cases;
import com.doumee.dao.business.model.Category;
import com.doumee.dao.business.model.ImportRecord;
import com.doumee.core.utils.Utils;
import com.doumee.dao.business.ImportRecordMapper;
import com.doumee.dao.business.model.Member;
import com.doumee.dao.system.model.SystemUser;
import com.doumee.service.business.ImportRecordService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.sun.xml.internal.messaging.saaj.util.ByteInputStream;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.xssf.usermodel.XSSFPictureData;
import org.apache.shiro.SecurityUtils;
import org.checkerframework.checker.units.qual.A;
import org.checkerframework.checker.units.qual.C;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
@@ -32,9 +45,9 @@
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.io.ByteArrayInputStream;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
@@ -43,12 +56,21 @@
 * @date 2026-01-27 16:02:37
 */
@Service
@Slf4j
public class ImportRecordServiceImpl implements ImportRecordService {
    @Autowired
    private ImportRecordMapper importRecordMapper;
    @Autowired
    private CategoryMapper categoryMapper;
    @Autowired
    private MemberMapper memberMapper;
    @Autowired
    private CasesMapper casesMapper;
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    @Resource
    private SystemDictDataBiz systemDictDataBiz;
    @Override
    public Integer create(ImportRecord importRecord) {
@@ -120,45 +142,29 @@
    @Override
    public PageData<ImportRecord> findPage(PageWrap<ImportRecord> pageWrap) {
        IPage<ImportRecord> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
        QueryWrapper<ImportRecord> queryWrapper = new QueryWrapper<>();
        MPJLambdaWrapper<ImportRecord> queryWrapper = new MPJLambdaWrapper<>();
        Utils.MP.blankToNull(pageWrap.getModel());
               queryWrapper.lambda().eq(pageWrap.getModel().getId() != null,ImportRecord::getId, pageWrap.getModel().getId());
               queryWrapper.lambda().eq(pageWrap.getModel().getDeleted() != null,ImportRecord::getDeleted, pageWrap.getModel().getDeleted());
               queryWrapper.lambda().eq(pageWrap.getModel().getCreateUser() != null,ImportRecord::getCreateUser, pageWrap.getModel().getCreateUser());
             if (pageWrap.getModel().getId() != null) {
                  queryWrapper.lambda().ge(ImportRecord::getCreateTime, Utils.Date.getStart(pageWrap.getModel().getCreateTime()));
                  queryWrapper.lambda().le(ImportRecord::getCreateTime, Utils.Date.getEnd(pageWrap.getModel().getCreateTime()));
             }
               queryWrapper.lambda().eq(pageWrap.getModel().getUpdateUser() != null,ImportRecord::getUpdateUser, pageWrap.getModel().getUpdateUser());
             if (pageWrap.getModel().getId() != null) {
                  queryWrapper.lambda().ge(ImportRecord::getUpdateTime, Utils.Date.getStart(pageWrap.getModel().getUpdateTime()));
                  queryWrapper.lambda().le(ImportRecord::getUpdateTime, Utils.Date.getEnd(pageWrap.getModel().getUpdateTime()));
             }
               queryWrapper.lambda().eq(pageWrap.getModel().getRemark() != null,ImportRecord::getRemark, pageWrap.getModel().getRemark());
               queryWrapper.lambda().eq(pageWrap.getModel().getStatus() != null,ImportRecord::getStatus, pageWrap.getModel().getStatus());
               queryWrapper.lambda().eq(pageWrap.getModel().getTitle() != null,ImportRecord::getTitle, pageWrap.getModel().getTitle());
               queryWrapper.lambda().eq(pageWrap.getModel().getTotalNum() != null,ImportRecord::getTotalNum, pageWrap.getModel().getTotalNum());
               queryWrapper.lambda().eq(pageWrap.getModel().getDetail() != null,ImportRecord::getDetail, pageWrap.getModel().getDetail());
               queryWrapper.lambda().eq(pageWrap.getModel().getImgurl() != null,ImportRecord::getImgurl, pageWrap.getModel().getImgurl());
             if (pageWrap.getModel().getId() != null) {
                  queryWrapper.lambda().ge(ImportRecord::getStartDate, Utils.Date.getStart(pageWrap.getModel().getStartDate()));
                  queryWrapper.lambda().le(ImportRecord::getStartDate, Utils.Date.getEnd(pageWrap.getModel().getStartDate()));
             }
             if (pageWrap.getModel().getId() != null) {
                  queryWrapper.lambda().ge(ImportRecord::getEndDate, Utils.Date.getStart(pageWrap.getModel().getEndDate()));
                  queryWrapper.lambda().le(ImportRecord::getEndDate, Utils.Date.getEnd(pageWrap.getModel().getEndDate()));
             }
               queryWrapper.lambda().eq(pageWrap.getModel().getSortnum() != null,ImportRecord::getSortnum, pageWrap.getModel().getSortnum());
               queryWrapper.lambda().eq(pageWrap.getModel().getType() != null,ImportRecord::getType, pageWrap.getModel().getType());
               queryWrapper.lambda().eq(pageWrap.getModel().getDoneNum() != null,ImportRecord::getDoneNum, pageWrap.getModel().getDoneNum());
               queryWrapper.lambda().eq(pageWrap.getModel().getErrorNum() != null,ImportRecord::getErrorNum, pageWrap.getModel().getErrorNum());
        for(PageWrap.SortData sortData: pageWrap.getSorts()) {
            if (sortData.getDirection().equalsIgnoreCase(PageWrap.DESC)) {
                queryWrapper.orderByDesc(sortData.getProperty());
            } else {
                queryWrapper.orderByAsc(sortData.getProperty());
            }
        }
        queryWrapper.selectAll(ImportRecord.class )
        .selectAs(SystemUser::getRealname,ImportRecord::getUpdateUserName)
                .leftJoin(SystemUser.class,SystemUser::getId,ImportRecord::getUpdateUser);
       queryWrapper.eq(pageWrap.getModel().getId() != null,ImportRecord::getId, pageWrap.getModel().getId());
       queryWrapper.eq(pageWrap.getModel().getDeleted() != null,ImportRecord::getDeleted, pageWrap.getModel().getDeleted());
       queryWrapper.eq(pageWrap.getModel().getCreateUser() != null,ImportRecord::getCreateUser, pageWrap.getModel().getCreateUser());
       queryWrapper.eq(pageWrap.getModel().getUpdateUser() != null,ImportRecord::getUpdateUser, pageWrap.getModel().getUpdateUser());
       queryWrapper.eq(pageWrap.getModel().getRemark() != null,ImportRecord::getRemark, pageWrap.getModel().getRemark());
       queryWrapper.eq(pageWrap.getModel().getStatus() != null,ImportRecord::getStatus, pageWrap.getModel().getStatus());
       queryWrapper.eq(pageWrap.getModel().getTitle() != null,ImportRecord::getTitle, pageWrap.getModel().getTitle());
       queryWrapper.eq(pageWrap.getModel().getTotalNum() != null,ImportRecord::getTotalNum, pageWrap.getModel().getTotalNum());
       queryWrapper.eq(pageWrap.getModel().getDetail() != null,ImportRecord::getDetail, pageWrap.getModel().getDetail());
       queryWrapper.eq(pageWrap.getModel().getImgurl() != null,ImportRecord::getImgurl, pageWrap.getModel().getImgurl());
       queryWrapper.eq(pageWrap.getModel().getSortnum() != null,ImportRecord::getSortnum, pageWrap.getModel().getSortnum());
       queryWrapper.eq(pageWrap.getModel().getType() != null,ImportRecord::getType, pageWrap.getModel().getType());
       queryWrapper.eq(pageWrap.getModel().getDoneNum() != null,ImportRecord::getDoneNum, pageWrap.getModel().getDoneNum());
       queryWrapper.eq(pageWrap.getModel().getErrorNum() != null,ImportRecord::getErrorNum, pageWrap.getModel().getErrorNum());
       queryWrapper.like(StringUtils.isNotBlank(pageWrap.getModel().getUpdateUserName()),SystemUser::getRealname, pageWrap.getModel().getUpdateUserName());
       queryWrapper.ge(pageWrap.getModel().getEndtime() != null,ImportRecord::getCreateTime, pageWrap.getModel().getEndtime());
       queryWrapper.ne(pageWrap.getModel().getStarttime() != null,ImportRecord::getCreateTime, pageWrap.getModel().getStarttime());
       queryWrapper.orderByDesc(ImportRecord::getId);
        return PageData.from(importRecordMapper.selectPage(page, queryWrapper));
    }
@@ -175,6 +181,13 @@
        }
        redisTemplate.opsForValue().set(Constants.RedisKeys.IMPORTING_RECORD,true,30, TimeUnit.MINUTES);
        try {
            List<Category> categoryList = null;
            if(type == 0){
              categoryList = categoryMapper.selectList(new QueryWrapper<Category>().lambda().eq(Category::getDeleted,Constants.ZERO));
                if(categoryList == null || categoryList.size()==0){
                    throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"对不起, è¯»å–老师基数数据配置出错,请先配置基础数据信息!");
                }
            }
            ImportRecord model = new ImportRecord();
            LoginUserInfo loginUserInfo = (LoginUserInfo) SecurityUtils.getSubject().getPrincipal();
            model.setDeleted(Constants.ZERO);
@@ -184,30 +197,201 @@
            model.setUpdateTime(model.getCreateTime());
            model.setUpdateUser(loginUserInfo.getId());
            model.setType(type);
            model.setTitle((type==1?"案例信息批量导入":"老师信息批量导入")+ DateUtil.getPlusTime2(model.getCreateTime()));
            model.setTitle((type==1?"案例信息批量导入":"老师信息批量导入,")+"文件:"+file.getOriginalFilename());
            model.setTotalNum(0);
            ExcelImporter ie= new ExcelImporter(file,0,0, CellType.STRING); // ç¡®ä¿å•元格类型为字符串);
            Map<String, XSSFPictureData> pics = ie.getExcelPictures();
            if(type == 1) {
              model.setCaseList(ie.getDataList(CasesImport.class,null));
              if(model.getCaseList() ==null || model.getCaseList().size()==0){
              List<CasesImport> importList =  (ie.getDataList(CasesImport.class,null));
              if(importList==null || importList.size()==0){
                  throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(),"导入文件案例信息内容为空!");
              }
              model.setTotalNum(model.getCaseList().size());
            }else{
              model.setMemberList(ie.getDataList(MemberImport.class,null));
              if(model.getMemberList() ==null || model.getMemberList().size()==0){
                  throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(),"导入文件老师信息内容为空!");
              }
              model.setTotalNum(model.getMemberList().size());
               List<MemberImport> importList = (ie.getDataList(MemberImport.class,null));
               model.setMemberList(isvalidImpartMemberParam(loginUserInfo,categoryList,pics,importList));
               model.setTotalNum(model.getMemberList().size());
            }
//            model.setPictureDataList(ie);
            importRecordMapper.insert(model);
            return model;
        }catch (BusinessException e){
            redisTemplate.delete(Constants.RedisKeys.IMPORTING_RECORD);
            throw  e;
        }catch (Exception e){
            redisTemplate.delete(Constants.RedisKeys.IMPORTING_RECORD);
            throw  new BusinessException(ResponseStatus.DATA_EMPTY.getCode(),"文件信息读取失败,请检查文件内容后重试!");
        }finally {
            redisTemplate.delete(Constants.RedisKeys.IMPORTING_RECORD);
//            redisTemplate.delete(Constants.RedisKeys.IMPORTING_RECORD);
        }
    }
    private  List<Member> isvalidImpartMemberParam(LoginUserInfo user, List<Category> categoryList ,Map<String, XSSFPictureData> pics, List<MemberImport> memberList) {
        if(memberList ==null || memberList.size()==0){
            throw  new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,未读取到有效数据");
        }
        if(pics ==null || pics.size()==0){
            throw  new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,未读取到任何职业照图片数据");
        }
        List<Member> insertMember = new ArrayList<>();
        List<Member> allList = memberMapper.selectList(new QueryWrapper<Member>().lambda()
                .eq(Member::getDeleted,Constants.ZERO));
        allList=allList==null?new ArrayList<>():allList;
        if(categoryList == null || categoryList.size()==0){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"对不起, è¯»å–老师基数数据配置出错,请先配置基础数据信息!");
        }
        Date date = new Date();
        int index = 1;
         for(MemberImport param :memberList){
             index ++;
             if(StringUtils.isBlank(param.getImgurl())
             ||StringUtils.isBlank(param.getFee())
             ||StringUtils.isBlank(param.getName())
             ||StringUtils.isBlank(param.getInfo())
             ||StringUtils.isBlank(param.getJobYear())
             ||StringUtils.isBlank(param.getPosition())
             ||StringUtils.isBlank(param.getFieldNames())
             ||StringUtils.isBlank(param.getSex())
             ||StringUtils.isBlank(param.getCode())
             ||StringUtils.isBlank(param.getZqNames())
             ||StringUtils.isBlank(param.getLevelName())
             ||StringUtils.isBlank(param.getServeNum())
             ||StringUtils.isBlank(param.getTypeNames())){
                 continue;
             }
             Member member = new Member();
             if(StringUtils.isBlank(param.getCode())){
                 throw  new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,第"+index+"行数据, å·¥å·ä¿¡æ¯ä¸èƒ½ä¸ºç©º");
             }
             for(Member m : allList){
                 if(StringUtils.equals(param.getCode(),m.getCode())){
                     throw  new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,第"+index+"行数据, å·¥å·ã€"+param.getCode()+"】信息已存在,请确认不要重复录入");
                 }
             }
             for(Member m : insertMember){
                 if(StringUtils.equals(param.getCode(),m.getCode())){
                     throw  new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,第"+index+"行数据, å·¥å·ã€"+param.getCode()+"】在文档中重复出现");
                 }
             }
             if(StringUtils.isBlank(param.getName())){
                 throw  new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,第"+index+"行数据, å§“名信息不能为空");
             }
             if(StringUtils.isBlank(param.getLevelName())){
                 throw  new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,第"+index+"行数据, ç­‰çº§ä¿¡æ¯ä¸èƒ½ä¸ºç©º");
             }
             if(StringUtils.isBlank(param.getJobYear())){
                 throw  new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,第"+index+"行数据, ä»Žä¸šå¹´ä»½ä¿¡æ¯ä¸èƒ½ä¸ºç©º");
             }
             Integer year ;
             try {
                 year = Integer.parseInt(param.getJobYear());
             }catch (Exception e){
                 throw  new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,第"+index+"行数据, ä»Žä¸šå¹´ä»½ä¿¡æ¯ä¸æ­£ç¡®");
             }
             if(StringUtils.isBlank(param.getZqNames())){
                 throw  new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,第"+index+"行数据, æœåŠ¡æˆ˜åŒºä¿¡æ¯ä¸èƒ½ä¸ºç©º");
             }
             if(StringUtils.isBlank(param.getTypeNames())){
                 throw  new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,第"+index+"行数据, å•†ä¸šåŒ–类型信息不能为空");
             }
             if(StringUtils.isBlank(param.getFee())){
                 throw  new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,第"+index+"行数据, è´¹ç”¨æ ‡å‡†ä¿¡æ¯ä¸èƒ½ä¸ºç©º");
             }
             if(pics!=null && StringUtils.isNotBlank(param.getImgurl())){
                log.info("===================="+param.getImgurl());
                int start = param.getImgurl().indexOf("(\"")+2;
                int end = param.getImgurl().indexOf("\",");
                if(start>=0&& end>=1 && end>start){
                    String picId = param.getImgurl().substring(start,end);
                    log.info("====================PICID:"+param.getImgurl());
                    XSSFPictureData data = pics.get(picId);
                    if(data!= null && data.getData() != null){
                        member.setImgurlData(data.getData());
                    }
                }
            }
             if(member.getImgurlData() ==null || member.getImgurlData().length==0){
                 throw  new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,第"+index+"行【"+param.getName()+"】数据, æœªè¯»å–到任何职业照图片数据");
             }
             //类型:0=战区;1=商业化;2=擅长领域;3=讲师等级;"
             List<Category> list0 =  isValidCategoryParam(param.getZqNames(),Constants.ZERO,categoryList,index );//战区
             List<Category> list1 =  isValidCategoryParam(param.getTypeNames(),Constants.ONE,categoryList,index);//商业化
             List<Category> list2 =  isValidCategoryParam(param.getFieldNames(),Constants.TWO,categoryList,index);//擅长领域
             Category levelCate =  getCategoryModelByName(param.getLevelName(),Constants.THREE,categoryList);//讲师等级
             if(levelCate == null){
                 throw  new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,第"+index+"行数据, ç­‰çº§ä¿¡æ¯ã€"+param.getLevelName()+"】尚未配置");
             }
             member.setCreateTime(date);
             member.setUpdateTime(date);
             member.setCreateUser(user.getId());
             member.setUpdateUser(user.getId());
             member.setAddType(Constants.ONE);
             member.setDeleted(Constants.ZERO);
             member.setStatus(Constants.ZERO);
             member.setName(param.getName());
             member.setContent(param.getInfo());
             member.setJobYear(year);
             member.setCode(param.getCode());
             member.setPositon(param.getPosition());
             try {
                 member.setServeNum(Integer.parseInt(param.getServeNum()));
             }catch (Exception e){
             }
             try {
                 member.setFee(new BigDecimal(param.getFee()));
             }catch (Exception e){
             }
             member.setSex(StringUtils.equals(param.getSex(),"男")?Constants.ZERO:(StringUtils.equals(param.getSex(),"女")?Constants.ZERO:null));
             member.setZhanquIds(getIdStrListByList(list0));
             member.setBustypeIds(getIdStrListByList(list1));
             member.setFieldIds(getIdStrListByList(list2));
             member.setLevelId(levelCate.getId());
             insertMember.add(member);
         }
        if(insertMember ==null || insertMember.size()==0){
            throw  new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,未读取到有效数据");
        }
         return insertMember;
    }
    private String getIdStrListByList(List<Category> categoryList) {
         String[] idList = new String[categoryList.size()];
        for (int i = 0; i <categoryList.size(); i++) {
            idList[i]="["+categoryList.get(i).getId()+"]";
        }
        return String.join(",",idList);
    }
    private List<Category> isValidCategoryParam(String zqNames, int type, List<Category> categoryList,int index) {
        if(StringUtils.isBlank(zqNames)){
            return null;
        }
        //获客类|市场类|培训类
        List<Category> list = new ArrayList<>();
        String names[] = zqNames.split("/");
        String title = type==0?"服务战区":( type==1?"商业化类型":"擅长领域");
        for(String str : names){
            if(StringUtils.isBlank(str)){
                continue;
            }
            Category cate = getCategoryModelByName(str,type,categoryList);
            if(cate == null){
                throw  new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,第"+index+"行数据,"+title+"中【"+str+"】尚未配置");
            }
            list.add(cate);
        }
        if(list == null || list.size() ==0){
            throw  new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,第"+index+"行数据,"+title+"未查询到有效配置");
        }
        return list;
    }
    private Category getCategoryModelByName(String levelName, int type, List<Category> categoryList) {
        for(Category c : categoryList){
            if(Constants.equalsInteger(c.getType(),type)
                    && StringUtils.equals(levelName.trim(),StringUtils.defaultString(c.getName(),"").trim())){
                return c;
            }
        }
        return null;
    }
    /**
@@ -238,7 +422,7 @@
        int success=0;
        String msg ="";
        try {
            for(CasesImport param:importRecord.getCaseList()){
            for(Cases param:importRecord.getCaseList()){
            }
        }catch (Exception e){
@@ -256,17 +440,44 @@
    private int dealUserImportBiz(ImportRecord importRecord) {
        int success=0;
        String msg = "";
        String nowDate =DateUtil.getNowShortDate();
        try {
            for(MemberImport param:importRecord.getMemberList()){
            String bucket =systemDictDataBiz.queryByCode(Constants.OBJCET_STORAGE,Constants.BUCKETNAME).getCode();
            String folder =systemDictDataBiz.queryByCode(Constants.OBJCET_STORAGE,Constants.MEMBER_FILES).getCode();
            TyyZosUtil obs = new TyyZosUtil(systemDictDataBiz.queryByCode(Constants.OBJCET_STORAGE,Constants.ENDPOINT).getCode(),
                    systemDictDataBiz.queryByCode(Constants.OBJCET_STORAGE,Constants.ACCESS_ID).getCode(),
                    systemDictDataBiz.queryByCode(Constants.OBJCET_STORAGE,Constants.ACCESS_KEY).getCode());
            for(Member param: importRecord.getMemberList()){
                param.setImportId(importRecord.getId());
                param.setAddType(Constants.ONE);
                success +=  dealMemberInsert(obs,param,folder,nowDate,bucket);
            }
            obs.shutDown();
        }catch (Exception e){
            log.error("处理人员信息发生异常{}",e.getMessage());
        }
        importRecord.setDoneNum(success);
        importRecord.setErrorNum(importRecord.getTotalNum() - success);
        importRecord.setDetail(msg);
        redisTemplate.delete(Constants.RedisKeys.IMPORTING_RECORD);
        return success;
    }
    private int dealMemberInsert( TyyZosUtil obs,Member param,String folder,String nowDate,String bucketName) {
        int success =0;
        try {
            String fileName = UUID.randomUUID() + ".png";
            String tempFileName = nowDate + "/" + fileName;
            String key = folder + tempFileName;// æ–‡ä»¶å
           if (obs.uploadInputstreamObjectNoShutdown(new ByteArrayInputStream(param.getImgurlData() ) ,bucketName,  key)) {
               param.setImgurl(tempFileName);//证件照地址
               log.error("处理人员信息证件照成功=================={}",key );
               success= memberMapper.insert(param);
           }
        }catch (Exception e){
            log.error("处理人员信息{}==发生异常{}",param.getName(),e.getMessage());
        }
        return success;
    }
}
server/services/src/main/java/com/doumee/service/business/impl/MemberServiceImpl.java
@@ -8,6 +8,7 @@
import com.doumee.core.constants.Constants;
import com.doumee.core.constants.ResponseStatus;
import com.doumee.core.exception.BusinessException;
import com.doumee.core.model.LoginUserInfo;
import com.doumee.core.model.PageData;
import com.doumee.core.model.PageWrap;
import com.doumee.core.utils.DateUtil;
@@ -20,13 +21,17 @@
import com.doumee.dao.business.model.Category;
import com.doumee.dao.business.model.Member;
import com.doumee.dao.business.model.Multifile;
import com.doumee.dao.system.model.SystemUser;
import com.doumee.service.business.MemberService;
import com.github.xiaoymin.knife4j.core.util.CollectionUtils;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import io.swagger.models.auth.In;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
@@ -56,13 +61,64 @@
    @Override
    public Integer create(Member member) {
        LoginUserInfo loginUserInfo = (LoginUserInfo) SecurityUtils.getSubject().getPrincipal();
        if(StringUtils.isBlank(member.getCode())
                ||StringUtils.isBlank(member.getName())
                ||StringUtils.isBlank(member.getImgurl())
                ||StringUtils.isBlank(member.getContent())
                ||member.getZhanquIdList()==null
                ||member.getZhanquIdList().size()==0
                ||member.getBustypeIdList()==null
                ||member.getBustypeIdList().size()==0
                ||member.getFieldIdList()==null
                ||member.getFieldIdList().size()==0
                ||member.getLevelId()==null  ){
            throw new BusinessException(ResponseStatus.BAD_REQUEST);
        }
        if(memberMapper.selectCount(new QueryWrapper<Member>().lambda()
                .eq(Member::getCode,member.getCode())
                .eq(Member::getDeleted,Constants.ZERO)
                .eq(Member::getType,member.getType()))>0 ){
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"工号已存在,请确认后重新录入");
        }
        member.setDeleted(Constants.ZERO);
        member.setCreateTime(new Date());
        member.setCreateUser(loginUserInfo.getId());
        member.setUpdateTime(new Date());
        member.setUpdateUser(loginUserInfo.getId());
        member.setZhanquIds(getIdsStrFromList(member.getZhanquIdList()));
        member.setFieldIds(getIdsStrFromList(member.getFieldIdList()));
        member.setBustypeIds(getIdsStrFromList(member.getBustypeIdList()));
        memberMapper.insert(member);
        return member.getId();
    }
    private String getIdsStrFromList(List<Integer> zhanquIdList) {
        String t = "";
        if(zhanquIdList!=null && zhanquIdList.size()>0){
            for (int i = 0; i < zhanquIdList.size(); i++) {
                if(zhanquIdList.get(i)==null){
                    continue;
                }
                if(StringUtils.isNotBlank(t)){
                    t+=",";
                }
                t+="["+zhanquIdList.get(i)+"]";
            }
        }
        return t;
    }
    @Override
    public void deleteById(Integer id) {
        memberMapper.deleteById(id);
        Member member =new Member();
        LoginUserInfo loginUserInfo = (LoginUserInfo) SecurityUtils.getSubject().getPrincipal();
        member.setUpdateTime(new Date());
        member.setId(id);
        member.setUpdateUser(loginUserInfo.getId());
        member.setDeleted(Constants.ONE);
        memberMapper.updateById(member);
    }
    @Override
@@ -70,17 +126,56 @@
        UpdateWrapper<Member> deleteWrapper = new UpdateWrapper<>(member);
        memberMapper.delete(deleteWrapper);
    }
    @Override
    public void updateStatus(Member member) {
        if(Objects.isNull(member) || Objects.isNull(member.getId())){
            throw new BusinessException(ResponseStatus.BAD_REQUEST);
        }
        LoginUserInfo loginUserInfo = (LoginUserInfo) SecurityUtils.getSubject().getPrincipal();
        member.setUpdateTime(new Date());
        member.setUpdateUser(loginUserInfo.getId());
        memberMapper.updateById(member);
    }
    @Override
    public void deleteByIdInBatch(List<Integer> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return;
        }
        memberMapper.deleteBatchIds(ids);
        for(Integer id : ids){
            this.deleteById(id);
        }
    }
    @Override
    public void updateById(Member member) {
        LoginUserInfo loginUserInfo = (LoginUserInfo) SecurityUtils.getSubject().getPrincipal();
        if(StringUtils.isBlank(member.getCode())
                ||StringUtils.isBlank(member.getName())
                ||StringUtils.isBlank(member.getImgurl())
                ||StringUtils.isBlank(member.getContent())
                ||member.getId()==null
                ||member.getZhanquIdList()==null
                ||member.getZhanquIdList().size()==0
                ||member.getBustypeIdList()==null
                ||member.getBustypeIdList().size()==0
                ||member.getFieldIdList()==null
                ||member.getFieldIdList().size()==0
                ||member.getLevelId()==null  ){
            throw new BusinessException(ResponseStatus.BAD_REQUEST);
        }
        if(memberMapper.selectCount(new QueryWrapper<Member>().lambda()
                .eq(Member::getCode,member.getCode())
                 .ne(Member::getId,member.getId())
                .eq(Member::getDeleted,Constants.ZERO)
                .eq(Member::getType,member.getType()))>0 ){
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"工号已存在,请确认后重新录入");
        }
        member.setUpdateTime(new Date());
        member.setUpdateUser(loginUserInfo.getId());
        member.setAddType(Constants.ZERO);
        member.setZhanquIds(getIdsStrFromList(member.getZhanquIdList()));
        member.setFieldIds(getIdsStrFromList(member.getFieldIdList()));
        member.setBustypeIds(getIdsStrFromList(member.getBustypeIdList()));
        memberMapper.updateById(member);
    }
@@ -107,6 +202,7 @@
    @Override
    public List<Member> findList(Member member) {
        member.setDeleted(Constants.ZERO);
        QueryWrapper<Member> wrapper = new QueryWrapper<>(member);
        return memberMapper.selectList(wrapper);
    }
@@ -118,20 +214,27 @@
        Utils.MP.blankToNull(pageWrap.getModel());
        Member model = pageWrap.getModel();
        queryWrapper.selectAll(Member.class)
                .select(" c1.NAME ", Member::getPromotionName)
                .select(" c2.NAME ", Member::getLevelName)
                .leftJoin(" category c1 on t.POSITON = c1.id ")
                .leftJoin(" category c2 on t.LEVEL_ID = c2.id ")
                .selectAs(Category::getName, Member::getLevelName)
                .selectAs(SystemUser::getRealname, Member::getUpdateUserName)
                .leftJoin(SystemUser.class,SystemUser::getId,Member::getUpdateUser)
                .leftJoin(Category.class,Category::getId,Member::getLevelId)
                .apply(Objects.nonNull(model.getBustypeIds())," find_in_set( '["+model.getBustypeIds()+"]', t.BUSTYPE_IDS ) ")
                .apply(Objects.nonNull(model.getZhanquIds())," find_in_set( '["+model.getZhanquIds()+"]', t.ZHANQU_IDS ) ")
                .like(StringUtils.isNotBlank(model.getName()),Member::getName, model.getName())
                .eq(Objects.nonNull(model.getStatus()),Member::getStatus, model.getStatus())
                .orderByAsc(Objects.isNull(model.getOrderByType()),"c2.DETAIL")
                .eq(Member::getDeleted, Constants.ZERO)
                .in(Objects.nonNull(model.getLevelId()),Category::getId, model.getLevelId())
                .eq(Objects.nonNull(model.getCode()),Member::getCode, model.getCode())
                .orderByDesc(Objects.nonNull(model.getOrderByType())&&Constants.equalsInteger(model.getOrderByType(), Constants.ZERO),Member::getFee)
                .orderByAsc(Objects.nonNull(model.getOrderByType())&&Constants.equalsInteger(model.getOrderByType(), Constants.ONE),Member::getFee)
                .orderByDesc(Objects.nonNull(model.getOrderByType())&&Constants.equalsInteger(model.getOrderByType(), Constants.TWO),"c2.DETAIL")
                .orderByAsc(Objects.nonNull(model.getOrderByType())&&Constants.equalsInteger(model.getOrderByType(), Constants.THREE),"c2.DETAIL")
                .orderByDesc(Objects.nonNull(model.getOrderByType())&&Constants.equalsInteger(model.getOrderByType(), Constants.TWO),Category::getDetail)
                .orderByAsc(Objects.nonNull(model.getOrderByType())&&Constants.equalsInteger(model.getOrderByType(), Constants.THREE),Category::getDetail)
                .orderByDesc(Objects.nonNull(model.getOrderByType())&&Constants.equalsInteger(model.getOrderByType(), Constants.FOUR),Member::getServeNum)
                .orderByDesc(Member::getId)
        ;
        if(Constants.equalsInteger(pageWrap.getModel().getQueryFlag(),Constants.ONE)){
            queryWrapper.select("(select count(c.id) from cases c where c.deleted=0 and c.member_id=t.id)",Member::getCaseNum);
        }
        if(StringUtils.isNotBlank(model.getFieldIds())){
            String [] fieldIds = model.getFieldIds().split(",");
            for (String s:fieldIds) {
@@ -149,23 +252,26 @@
                queryWrapper.apply(" find_in_set( '["+zhanqu.getId()+"]', t.ZHANQU_IDS ) ");
            }
        }
        IPage<Member> memberIPage  = memberMapper.selectJoinPage(page, Member.class, new MPJLambdaWrapper<>());
        IPage<Member> memberIPage  = memberMapper.selectJoinPage(page, Member.class, queryWrapper);
        if(CollectionUtils.isNotEmpty(memberIPage.getRecords())){
            List<Category> categoryList = categoryMapper.selectList(new QueryWrapper<Category>().lambda()
                    .eq(Category::getDeleted, Constants.ZERO)
                    .eq(Category::getType,Constants.TWO)
//                    .eq(Category::getType,Constants.TWO)
                    .orderByAsc(Category::getSortnum)
            );
            String path = systemDictDataBiz.queryByCode(Constants.OBJCET_STORAGE, Constants.RESOURCE_PATH).getCode() +
                    systemDictDataBiz.queryByCode(Constants.OBJCET_STORAGE, Constants.CATEGORY_FILES).getCode();
                    systemDictDataBiz.queryByCode(Constants.OBJCET_STORAGE, Constants.MEMBER_FILES).getCode();
            String roleConfig = systemDictDataBiz.queryByCode(Constants.SYSTEM, Constants.ROLE_CONFIG).getCode();
            for (Member member:memberIPage.getRecords()) {
                if(CollectionUtils.isNotEmpty(categoryList)){
                    dealMemberField(member,categoryList);
                    if(Constants.equalsInteger(pageWrap.getModel().getQueryFlag(),Constants.ONE)) {
                        dealMemberCategoryList(member, categoryList);
                    }
                }
                member.setFullImgurl(StringUtils.isNotBlank(member.getImgurl())?(path + member.getImgurl()):"");
                if(StringUtils.isBlank(roleConfig)||StringUtils.isBlank(model.getQueryUserRole())
                || !roleConfig.contains(model.getQueryUserRole())){
                if(!Constants.equalsInteger(pageWrap.getModel().getQueryFlag(),Constants.ONE) && (StringUtils.isBlank(roleConfig)||StringUtils.isBlank(model.getQueryUserRole())
                        || !roleConfig.contains(model.getQueryUserRole()))){
                    member.setFee(null);
                }
               if(member.getJobYear()!=null){
@@ -176,6 +282,33 @@
        return PageData.from(memberIPage);
    }
    private void dealMemberCategoryList(Member member, List<Category> categoryList) {
        member.setFieldIdList(new ArrayList<>());
        member.setBustypeIdList(new ArrayList<>());
        member.setZhanquIdList(new ArrayList<>());
        member.setFieldList(new ArrayList<>());
        member.setTypeList(new ArrayList<>());
        member.setZqList(new ArrayList<>());
        for(Category c:categoryList){
//            0=战区;1=商业化;2=擅长领域;
            if(Constants.equalsInteger(c.getType(),Constants.ZERO)&& StringUtils.contains(member.getZhanquIds(),"["+c.getId()+"]")){
                //战区
                member.getZqList().add(c);
                member.getZhanquIdList().add(c.getId());
            }
            if(Constants.equalsInteger(c.getType(),Constants.ONE)&& StringUtils.contains(member.getBustypeIds(),"["+c.getId()+"]")){
                //商业化
                member.getTypeList().add(c);
                member.getBustypeIdList().add(c.getId());
            }
            if(Constants.equalsInteger(c.getType(),Constants.TWO) && StringUtils.contains(member.getFieldIds(),"["+c.getId()+"]")){
                //擅长领域
                member.getFieldList().add(c);
                member.getFieldIdList().add(c.getId());
            }
        }
    }
    @Override
    public Member findDetailById(Integer id,String queryUserRole) {