doum
2026-01-29 e890eddcac0e51e67ce4e5ee8f69f58497c84af3
提交忽略文件
已添加6个文件
已修改16个文件
1598 ■■■■ 文件已修改
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/components/business/OperaCasesImportWindow.vue 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/components/business/OperaCasesWindow.vue 169 ●●●●● 补丁 | 查看 | 原始文档 | 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/member.vue 41 ●●●● 补丁 | 查看 | 原始文档 | 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/dao/business/model/Cases.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/dao/business/model/Member.java 6 ●●●●● 补丁 | 查看 | 原始文档 | 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 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/service/business/impl/MemberServiceImpl.java 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/package-lock.json
@@ -13564,6 +13564,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/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/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/member.vue
@@ -17,7 +17,7 @@
            @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"
@@ -33,7 +33,7 @@
            @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"
@@ -50,7 +50,7 @@
            @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"
@@ -66,7 +66,7 @@
            @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"
@@ -154,15 +154,16 @@
            </div>
          </template>
        </el-table-column>
        <el-table-column label="状态">
        <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="操作"
@@ -213,10 +214,7 @@
        bustypeIds:null,
        type: 0
      },
      cateList:[],
      cateList1:[],
      cateList2:[],
      cateList3:[],
      cateList:[]
    }
  },
  created () {
@@ -228,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) {
@@ -254,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/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/Member.java
@@ -157,6 +157,12 @@
    @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;
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
@@ -448,6 +448,8 @@
                    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();
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;
@@ -24,7 +25,9 @@
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;
@@ -58,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
@@ -72,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);
    }
@@ -109,6 +202,7 @@
    @Override
    public List<Member> findList(Member member) {
        member.setDeleted(Constants.ZERO);
        QueryWrapper<Member> wrapper = new QueryWrapper<>(member);
        return memberMapper.selectList(wrapper);
    }
@@ -129,13 +223,14 @@
                .like(StringUtils.isNotBlank(model.getName()),Member::getName, model.getName())
                .eq(Objects.nonNull(model.getStatus()),Member::getStatus, model.getStatus())
                .eq(Member::getDeleted, Constants.ZERO)
                .in(Objects.nonNull(model.getLevelId()),Member::getStatus, model.getStatus())
                .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),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);
@@ -175,8 +270,8 @@
                    }
                }
                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){
@@ -188,6 +283,9 @@
    }
    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<>());
@@ -196,14 +294,17 @@
            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());
            }
        }
    }