From e1b74e9a33f947f87bc87b2921db9a72598d4d47 Mon Sep 17 00:00:00 2001
From: doum <doum>
Date: 星期四, 29 一月 2026 09:23:18 +0800
Subject: [PATCH] 提交忽略文件

---
 server/admin/src/main/java/com/doumee/api/business/CategoryController.java                  |    6 
 admin/src/components/business/OperaMemberImportWindow.vue                                   |   86 +++
 admin/src/views/business/categoryBusType.vue                                                |   19 
 admin/public/template/casees.xlsx                                                           |    0 
 admin/src/api/business/category.js                                                          |    5 
 server/admin/src/main/java/com/doumee/api/business/ImportRecordController.java              |   19 
 server/services/src/main/java/com/doumee/dao/business/model/ImportRecord.java               |   14 
 admin/src/api/business/importRecord.js                                                      |   48 +
 admin/src/views/business/categoryLevel.vue                                                  |  121 ++++
 server/services/src/main/java/com/doumee/core/constants/Constants.java                      |    3 
 server/services/src/main/java/com/doumee/service/business/MemberService.java                |    3 
 server/services/src/main/java/com/doumee/service/business/ImportRecordService.java          |    5 
 server/services/src/main/java/com/doumee/dao/business/model/Category.java                   |   14 
 server/services/src/main/java/com/doumee/service/business/impl/ImportRecordServiceImpl.java |  135 +++++
 admin/src/api/business/member.js                                                            |    3 
 admin/src/components/common/UploadAvatarImage.vue                                           |    2 
 server/services/pom.xml                                                                     |    5 
 server/services/src/main/java/com/doumee/dao/business/model/Multifile.java                  |    6 
 admin/public/template/member.xlsx                                                           |    0 
 server/services/src/main/java/com/doumee/service/business/impl/CategoryServiceImpl.java     |  113 ++-
 admin/src/components/business/OperaCategoryWindow.vue                                       |   87 +-
 admin/src/views/business/category.vue                                                       |   12 
 admin/src/views/business/member.vue                                                         |  246 +++++---
 server/services/src/main/java/com/doumee/core/annotation/excel/ExcelImporter.java           |    7 
 server/services/src/main/java/com/doumee/dao/business/dto/MemberImport.java                 |   42 +
 admin/src/components/common/UploadImage.vue                                                 |  124 +--
 server/pom.xml                                                                              |    5 
 server/services/src/main/java/com/doumee/core/annotation/excel/ExcelPictureUtil.java        |  305 +++++++++++
 server/admin/src/main/java/com/doumee/api/business/MemberController.java                    |    8 
 server/services/src/main/java/com/doumee/service/business/impl/MemberServiceImpl.java       |   14 
 admin/src/views/business/categoryField.vue                                                  |  113 ++++
 server/services/src/main/java/com/doumee/dao/business/dto/CasesImport.java                  |   36 +
 32 files changed, 1,328 insertions(+), 278 deletions(-)

diff --git a/admin/public/template/casees.xlsx b/admin/public/template/casees.xlsx
new file mode 100644
index 0000000..38aaf8c
--- /dev/null
+++ b/admin/public/template/casees.xlsx
Binary files differ
diff --git a/admin/public/template/member.xlsx b/admin/public/template/member.xlsx
new file mode 100644
index 0000000..be97d45
--- /dev/null
+++ b/admin/public/template/member.xlsx
Binary files differ
diff --git a/admin/src/api/business/category.js b/admin/src/api/business/category.js
index 3162d80..12abda9 100644
--- a/admin/src/api/business/category.js
+++ b/admin/src/api/business/category.js
@@ -6,6 +6,11 @@
     trim: true
   })
 }
+export function findAll (data) {
+  return request.post('/business/category/list', data, {
+    trim: true
+  })
+}
 
 // 鍒涘缓
 export function create (data) {
diff --git a/admin/src/api/business/importRecord.js b/admin/src/api/business/importRecord.js
new file mode 100644
index 0000000..82a5f2e
--- /dev/null
+++ b/admin/src/api/business/importRecord.js
@@ -0,0 +1,48 @@
+import request from '../../utils/request'
+
+// 鏌ヨ
+export function fetchList (data) {
+  return request.post('/business/importRecord/page', data, {
+    trim: true
+  })
+}
+
+// 鍒涘缓
+export function create (data) {
+  return request.post('/business/importRecord/create', data)
+}
+export function updateStatus (data) {
+  return request.post('/business/importRecord/updateStatus', data)
+}
+
+// 瀵煎嚭Excel
+export function exportExcel (data) {
+  return request.post('/business/importRecord/exportExcel', data, {
+    download: true
+  })
+}
+export function importExcel (data) {
+  return request.post('/business/importRecord/importExcel', data)
+}
+
+// 淇敼
+export function updateById (data) {
+  return request.post('/business/importRecord/updateById', data)
+}
+
+// 鍒犻櫎
+export function deleteById (id) {
+  return request.get(`/business/importRecord/delete/${id}`)
+}
+export function getById (id) {
+  return request.get(`/business/importRecord/${id}`)
+}
+
+// 鎵归噺鍒犻櫎
+export function deleteByIdInBatch (ids) {
+  return request.get('/business/importRecord/delete/batch', {
+    params: {
+      ids
+    }
+  })
+}
diff --git a/admin/src/api/business/member.js b/admin/src/api/business/member.js
index 9901389..df77a7f 100644
--- a/admin/src/api/business/member.js
+++ b/admin/src/api/business/member.js
@@ -21,6 +21,9 @@
     download: true
   })
 }
+export function importExcel (data) {
+  return request.post('/business/member/importExcel', data)
+}
 
 // 淇敼
 export function updateById (data) {
diff --git a/admin/src/components/business/OperaCategoryWindow.vue b/admin/src/components/business/OperaCategoryWindow.vue
index 326f991..c897b92 100644
--- a/admin/src/components/business/OperaCategoryWindow.vue
+++ b/admin/src/components/business/OperaCategoryWindow.vue
@@ -7,45 +7,34 @@
   >
     <el-form :model="form" ref="form" :rules="rules">
       <el-form-item label="鍚嶇О" prop="name">
-        <el-input v-if="form.type !=3"  v-model="form.name" placeholder="璇疯緭鍏ュ悕绉�" v-trim/>
-        <el-select v-else  v-model="form.name" placeholder="璇烽�夋嫨璁㈠崟绫诲瀷" v-trim>
-          <el-option :value="'0'" label="鐢ㄥ伐鍗�"></el-option>
-          <el-option :value="'1'" label="璐ц繍鍗�"></el-option>
-          <el-option :value="'2'" label="璁㈤鍗�"></el-option>
-        </el-select>
+        <el-input   v-model="form.name" placeholder="璇疯緭鍏ュ悕绉�" v-trim/>
       </el-form-item>
-      <el-form-item v-if="form.type ==3 " label="鎵嬬画璐癸紙%锛�" prop="detail">
-        <el-input  type="number"   v-model="form.detail" placeholder="璇疯緭鍏ュ悕绉�" v-trim/>
+      <el-form-item label="鎴樺尯缂栫爜" prop="detail"  v-if="form.type ==0" >
+        <el-input v-model="form.detail" placeholder="璇疯緭鍏ユ垬鍖虹紪鐮�" v-trim/>
       </el-form-item>
-      <el-form-item v-if="form.type == 1 || form.type == 2" :label=" form.type == 1?'杞﹁締瑙勬牸':'椁愭爣閰嶇疆锛堝厓锛�'" prop="detailList">
-        <div style="display: flex;flex-direction: column">
-          <div style="position: relative;display: block;width: 100%;" v-for="(item,index) in form.detailList"   >
-            <el-input  :type="form.type == 1?'text':'number'" style="display:inline-block;width: 60%;margin:5px ;float: left" v-model="form.detailList[index]"   placeholder="璇疯緭鍏ュ唴瀹�" v-trim/>
-            <el-button  style="display:inline-block;margin : 5px " @click="del(index)" v-if="form.detailList.length>0">x</el-button>
-          </div>
-          <div style="position: relative;display: block;width: 100%;">
-            <el-button style="width: 100px;margin: 5px;" type="primary" @click="add()">娣诲姞瑙勬牸</el-button>
-          </div>
-        </div>
-      </el-form-item>
-      <el-form-item v-if="form.type == 1" label="鍥炬爣" prop="icon">
+      <el-form-item v-if="form.type == 3" label="鍥炬爣" prop="icon">
         <UploadAvatarImage
             :file="{ imgurlfull: form.iconFull, imgurl: form.icon }"
             :uploadData="uploadData"
             @uploadSuccess="uploadAvatarSuccess"
         />
       </el-form-item>
-      <el-form-item  v-if="form.id ==null && form.type == 1"  label="鏄惁鍥哄畾杞﹁締" prop="isFixed">
-        <el-radio-group v-model="form.isFixed">
-          <el-radio :label="0">闈炲浐瀹�</el-radio>
-          <el-radio :label="1">鍥哄畾杞﹀瀷</el-radio>
-        </el-radio-group>
+      <el-form-item v-if="form.type == 1" label="鎺掕姒滃浘闆�" prop="icon">
+        <UploadImage
+            :fileList="tempfileList"
+            :uploadData="uploadData"
+            @beginUpload="isUploading=true"
+            @endUpload="isUploading=false"/>
+        <p class="tip-warn">
+          寤鸿灏哄锛�750px X 750px锛屼笂闄�6寮�
+          鏀寔png銆乯pg銆乯peg鏍煎紡锛屽ぇ灏忎笉瓒呰繃2M锛屼笂浼犲浘鐗囦笉鍏佽娑夊強鏀挎不鏁忔劅涓庤壊鎯�,
+        </p>
       </el-form-item>
       <el-form-item label="鎺掑簭鐮�" prop="sortnum">
-        <el-input v-model="form.sortnum" placeholder="璇疯緭鍏ユ帓搴忕爜" v-trim/>
+        <el-input v-model="form.sortnum" type="" placeholder="璇疯緭鍏ユ帓搴忕爜" v-trim/>
       </el-form-item>
       <el-form-item label="鎻忚堪" prop="remark">
-        <el-input v-model="form.remark" placeholder="璇疯緭鍏ユ弿杩�" v-trim/>
+        <el-input type="textarea" v-model="form.remark" placeholder="璇疯緭鍏ユ弿杩�" v-trim/>
       </el-form-item>
     </el-form>
   </GlobalWindow>
@@ -54,16 +43,17 @@
 <script>
 import BaseOpera from '@/components/base/BaseOpera'
 import GlobalWindow from '@/components/common/GlobalWindow'
+import UploadImage from '@/components/common/UploadImage'
 import UploadAvatarImage from '@/components/common/UploadAvatarImage'
 export default {
   name: 'OperaCategoryWindow',
   extends: BaseOpera,
-  components: { GlobalWindow ,UploadAvatarImage},
+  components: { GlobalWindow, UploadAvatarImage,UploadImage },
   data () {
     return {
       isUploading: false,
       uploadData: {
-        folder: 'category'
+        folder: 'dianjiang/category'
       },
       // 琛ㄥ崟鏁版嵁
       form: {
@@ -74,14 +64,15 @@
         type: null,
         detail: null,
         remark: null,
-        detailList: [''],
+        fileList: [],
         icon: '',
         iconFull: '',
         isFixed: 0
       },
+      tempfileList: [],
       // 楠岃瘉瑙勫垯
       rules: {
-        name: [{ required: true, message: '璇疯緭鍏ラ厤缃悕绉�' }]
+        name: [{ required: true, message: '璇疯緭鍏ュ悕绉�' }]
       }
     }
   },
@@ -91,23 +82,32 @@
       'field.id': 'id'
     })
   },
-  methods:{
-    del(index){
-      if(this.form.detailList.length<=1){
+  methods: {
+    del (index) {
+      if (this.form.detailList.length <= 1) {
         return
       }
-      this.form.detailList.splice(index,1)
+      this.form.detailList.splice(index, 1)
     },
-    add(){
+    add () {
       this.form.detailList.push('')
     },
     uploadAvatarSuccess (file) {
       this.$set(this.form, 'icon', file.imgurl)
       this.$set(this.form, 'iconFull', file.imgurlfull)
     },
-    open(title, target, type) {
+    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.tempfileList = []
       this.form = {
         id: null,
         status: 0,
@@ -116,7 +116,7 @@
         detail: null,
         type: type,
         remark: null,
-        detailList: [''],
+        fileList: [],
         icon: '',
         iconFull: '',
         isFixed: 0
@@ -135,9 +135,14 @@
         for (const key in this.form) {
           this.form[key] = target[key]
         }
-        if(this.form.detailList==null){
-          this.form.detailList = ['']
-        }
+        this.form.fileList = this.form.fileList||[]
+        this.form.fileList.forEach(item=>{
+          this.tempfileList.push({
+            fileurl: item.fileurl,
+            name: item.name,
+            url: item.url
+          })
+        })
       })
     }
   }
diff --git a/admin/src/components/business/OperaMemberImportWindow.vue b/admin/src/components/business/OperaMemberImportWindow.vue
new file mode 100644
index 0000000..4f2c245
--- /dev/null
+++ b/admin/src/components/business/OperaMemberImportWindow.vue
@@ -0,0 +1,86 @@
+<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: 'OperaMemberImportWindow',
+  extends: BaseOpera,
+  // eslint-disable-next-line vue/no-unused-components
+  components: { GlobalWindow },
+  data () {
+    return {
+      importing: false,
+      fileName: '',
+      type: 0
+    }
+  },
+  methods: {
+    open (title) {
+      this.title = title
+      this.fileName = ''
+      this.visible = true
+      this.type = 0
+    },
+    // 瀵煎嚭妯℃澘
+    exportTemplate () {
+      // 鎶曚繚鐢宠
+      window.open('/template/member.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 = ''
+        })
+        .finally(() => {
+          this.$refs.fileExcel.value = null
+          this.importing=false
+        })
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>
diff --git a/admin/src/components/common/UploadAvatarImage.vue b/admin/src/components/common/UploadAvatarImage.vue
index e39f3e5..e541df7 100644
--- a/admin/src/components/common/UploadAvatarImage.vue
+++ b/admin/src/components/common/UploadAvatarImage.vue
@@ -31,7 +31,7 @@
   data() {
     return {
       loading: null,
-      uploadImgUrl: process.env.VUE_APP_API_PREFIX + '/web/public/upload'
+      uploadImgUrl: process.env.VUE_APP_API_PREFIX + '/public/upload'
     }
   },
 
diff --git a/admin/src/components/common/UploadImage.vue b/admin/src/components/common/UploadImage.vue
index 8ada0f0..d9237a4 100644
--- a/admin/src/components/common/UploadImage.vue
+++ b/admin/src/components/common/UploadImage.vue
@@ -8,32 +8,13 @@
       accept=".jpg,.png"
       :before-upload="beforeUpload"
       :on-success="uploadSuccess"
+      :on-preview="handlePreview"
+      :on-remove="handleRemove"
       :on-error="fail"
     >
       <i class="el-icon-plus icon"></i>
-      <div slot="file" slot-scope="{file}">
-        <img
-          class="el-upload-list__item-thumbnail"
-          :src="file.url" alt=""
-          style="width: 100px;height: 100px;"
-        >
-        <span class="el-upload-list__item-actions">
-          <span
-            class="el-upload-list__item-preview"
-            @click="handlePictureCardPreview(file)"
-          >
-            <i class="el-icon-zoom-in"></i>
-          </span>
-          <span
-            class="el-upload-list__item-delete"
-            @click="handleRemove(file)"
-          >
-            <i class="el-icon-delete"></i>
-          </span>
-        </span>
-      </div>
     </el-upload>
-    <el-image-viewer
+   <el-image-viewer
       v-if="showViewer"
       :on-close="closeViewer"
       :initialIndex="tempIndex"
@@ -55,79 +36,77 @@
       type: Array,
       default: () => []
     },
-    uploadData: Object,
+    maxNum: {
+      type: Number,
+      default: () => null
+    },
+    uploadData: Object
   },
-  data() {
+  data () {
     return {
-      uploadImgUrl: process.env.VUE_APP_API_PREFIX + '/web/public/uploadLocal',
+      uploadImgUrl: process.env.VUE_APP_API_PREFIX + '/public/upload',
       realList: [],
-      srcList: [],
+      // srcList: [],
       tempIndex: 0,
-      showViewer: false,
+      showViewer: false
+    }
+  },
+  computed:{
+    srcList(){
+      return this.fileList.map(item => { return item.url })
     }
   },
   watch: {
-    fileList: {
-      handler(val) {
-        console.log(val);
-        if (val.length==0) {
-          this.realList = []
-          this.srcList = []
-        }
-      }
-
-    }
   },
   methods: {
-    beforeUpload(file) {
+    handlePreview(file) {
+      // console.log('棰勮鏂囦欢锛�', file,this.fileList);
+      this.tempIndex = this.srcList.findIndex(item => item == file.url)
+      this.showViewer = true
+    },
+    beforeUpload (file) {
       this.$emit('beginUpload')
+      const isJPGOrPNG = file.type === 'image/jpeg' || file.type === 'image/png'
+      const isLt2M = file.size / 1024 / 1024 < 1; // 500kb
+      if (!isJPGOrPNG) {
+        this.$message.error('涓婁紶澶村儚鍥剧墖鍙兘鏄� JPG/PNG 鏍煎紡!');
+        return false
+      }
+      if (!isLt2M) {
+        this.$message.error('涓婁紶澶村儚鍥剧墖澶у皬涓嶈兘瓒呰繃 500KB!');
+        return false
+      }
       return true
     },
-     // 涓婁紶鍥剧墖鎴愬姛
-     uploadSuccess (res, file, fileList) {
-      // console.log('this.fileList', this.fileList);
-      // console.log('fileList', fileList);
-      this.$emit('uploadEnd')
-      this.realList = fileList
-      this.srcList.push(res.data.url)
-      // console.log('file', file);
+    // 涓婁紶鍥剧墖鎴愬姛
+    uploadSuccess (res, file, fileList) {
+      this.$emit('endUpload')
+      console.log('涓婁紶鎴愬姛1锛�',fileList);
       if (res.code === 200) {
-        this.fileList.push(
-          {
-            fileurl: res.data.imgaddr,
-            name: res.data.originname,
-            url: res.data.url
-          }
-        )
+        this.fileList.push({
+          fileurl: res.data.imgaddr,
+          name: res.data.originname,
+          url: res.data.url
+        })
+        console.log('涓婁紶鎴愬姛2锛�', this.fileList);
       } else {
         this.$message.error(res.msg || '涓婁紶澶辫触')
       }
     },
     fail (err, file, fileList) {
-      this.$emit('uploadEnd')
+      this.$emit('endUpload')
       this.$message.error('涓婁紶澶辫触')
     },
-    handlePictureCardPreview(file) {
-      // this.tempIndex = this.srcList.findIndex(item => item == file.response.data.url )
-      // console.log(file);
-      this.tempIndex = this.fileList.findIndex(item => item.url == file.url )
-      // console.log( this.tempIndex);
-      this.srcList = this.fileList.map(item => item.url)
-      this.showViewer = true
-    },
-    closeViewer() {
+    closeViewer () {
       this.showViewer = false
     },
-    handleRemove(file) {
-      console.log(this.fileList);
-      let tempIndex = this.realList.findIndex(item => item.url === file.url)
-      // debugger
-      this.realList.splice(tempIndex, 1)
-      this.fileList.splice(tempIndex, 1)
-      this.srcList.splice(tempIndex, 1)
-
+    handleRemove (file) {
+      const tempIndex = this.fileList.findIndex(item => item.url === file.url)
+      if(tempIndex >= 0){
+        this.fileList.splice(tempIndex, 1)
+      }
     }
-  },
+  }
 }
 </script>
 
@@ -150,4 +129,3 @@
   height: 90px !important;
 }
 </style>
-
diff --git a/admin/src/views/business/category.vue b/admin/src/views/business/category.vue
index 0581cdd..c202c48 100644
--- a/admin/src/views/business/category.vue
+++ b/admin/src/views/business/category.vue
@@ -13,8 +13,9 @@
     <!-- 琛ㄦ牸鍜屽垎椤� -->
     <template v-slot:table-wrap>
       <ul class="toolbar" v-permissions="['business:category:create', 'business:category:delete']">
-        <li><el-button type="primary" @click="$refs.operaCategoryWindow.open('鏂板缓鍝佺閰嶇疆',null,searchForm.type)" icon="el-icon-plus" v-permissions="['business:category:create']">鏂板缓</el-button></li>
-        <li><el-button @click="deleteByIdInBatch" icon="el-icon-delete" v-permissions="['business:category:delete']">鍒犻櫎</el-button></li>
+        <li><el-button type="primary" @click="$refs.operaCategoryWindow.open('鏂板缓鎴樺尯',null,searchForm.type)" icon="el-icon-plus" v-permissions="['business:category:create']">鏂板缓</el-button></li>
+        <li><el-button type="primary" icon="el-icon-refresh" v-permissions="['business:category:create']">鍚屾</el-button></li>
+        <li><el-button type="danger" @click="deleteByIdInBatch" icon="el-icon-delete" v-permissions="['business:category:delete']">鍒犻櫎</el-button></li>
       </ul>
       <el-table
           :height="tableHeightNew"
@@ -24,7 +25,8 @@
         @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="name" label="鎴樺尯鍚嶇О" min-width="100px"></el-table-column>
+        <el-table-column prop="detail" label="鎴樺尯缂栫爜" min-width="100px"></el-table-column>
         <el-table-column label="鐘舵��">
           <template slot-scope="{row}">
             <el-switch @change="changeStatus($event, row)" v-model="row.status" active-color="#13ce66"
@@ -42,8 +44,8 @@
           fixed="right"
         >
           <template slot-scope="{row}">
-            <el-button type="text" @click="$refs.operaCategoryWindow.open('缂栬緫鏂板缓鍝佺閰嶇疆', row,searchForm.type)" icon="el-icon-edit" v-permissions="['business:category:update']">缂栬緫</el-button>
-            <el-button type="text" @click="deleteById(row)" icon="el-icon-delete" v-permissions="['business:category:delete']">鍒犻櫎</el-button>
+            <el-button type="text" @click="$refs.operaCategoryWindow.open('缂栬緫鎴樺尯', row,searchForm.type)" icon="el-icon-edit" v-permissions="['business:category:update']">缂栬緫</el-button>
+            <el-button type="text" style="color: red" @click="deleteById(row)" icon="el-icon-delete" v-permissions="['business:category:delete']">鍒犻櫎</el-button>
           </template>
         </el-table-column>
       </el-table>
diff --git a/admin/src/views/business/categoryBusType.vue b/admin/src/views/business/categoryBusType.vue
index e77a6c1..e952fe4 100644
--- a/admin/src/views/business/categoryBusType.vue
+++ b/admin/src/views/business/categoryBusType.vue
@@ -13,7 +13,7 @@
     <!-- 琛ㄦ牸鍜屽垎椤� -->
     <template v-slot:table-wrap>
       <ul class="toolbar" v-permissions="['business:category:create', 'business:category:delete']">
-        <li><el-button type="primary" @click="$refs.operaCategoryWindow.open('鏂板缓璐ц繍閰嶇疆',null,searchForm.type)" icon="el-icon-plus" v-permissions="['business:category:create']">鏂板缓</el-button></li>
+        <li><el-button type="primary" @click="$refs.operaCategoryWindow.open('鏂板缓鍟嗕笟鍖栫被鍨�',null,searchForm.type)" icon="el-icon-plus" v-permissions="['business:category:create']">鏂板缓</el-button></li>
         <li><el-button @click="deleteByIdInBatch" icon="el-icon-delete" v-permissions="['business:category:delete']">鍒犻櫎</el-button></li>
       </ul>
       <el-table
@@ -24,14 +24,19 @@
         @selection-change="handleSelectionChange"
       >
         <el-table-column type="selection" :selectable="isChangeSelected" width="55"></el-table-column>
-        <el-table-column  prop="icon" label="鍥炬爣" min-width="100px">
+        <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}">
-            <el-image v-if="row.iconFull" style="width: 50px; height: 50px; margin-right: 10px" :src="row.iconFull"
-                      :preview-src-list="[row.iconFull]">
-            </el-image>
+            <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="name" label="鍚嶇О" min-width="100px"></el-table-column>
+
         <el-table-column label="鐘舵��">
           <template slot-scope="{row}">
             <el-switch :disabled="row.isFixed ==1" @change="changeStatus($event, row)" v-model="row.status" active-color="#13ce66"
@@ -50,7 +55,7 @@
           fixed="right"
         >
           <template slot-scope="{row}">
-            <el-button type="text"   @click="$refs.operaCategoryWindow.open('缂栬緫鏂板缓璐ц繍閰嶇疆', row,searchForm.type)" icon="el-icon-edit" v-permissions="['business:category:update']">缂栬緫</el-button>
+            <el-button type="text"   @click="$refs.operaCategoryWindow.open('缂栬緫鍟嗕笟鍖栫被鍨�', row,searchForm.type)" icon="el-icon-edit" v-permissions="['business:category:update']">缂栬緫</el-button>
             <el-button type="text"   @click="deleteById(row)" icon="el-icon-delete" v-permissions="['business:category:delete']">鍒犻櫎</el-button>
           </template>
         </el-table-column>
diff --git a/admin/src/views/business/categoryField.vue b/admin/src/views/business/categoryField.vue
new file mode 100644
index 0000000..3b6135c
--- /dev/null
+++ b/admin/src/views/business/categoryField.vue
@@ -0,0 +1,113 @@
+<template>
+  <TableLayout :permissions="['business:category: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" placeholder="璇疯緭鍏ュ悕绉�" @keypress.enter.native="search"></el-input>
+      </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:category:create', 'business:category:delete']">
+        <li><el-button type="primary" @click="$refs.operaCategoryWindow.open('鏂板缓鎿呴暱棰嗗煙',null,searchForm.type)" icon="el-icon-plus" v-permissions="['business:category:create']">鏂板缓</el-button></li>
+        <li><el-button @click="deleteByIdInBatch" icon="el-icon-delete" v-permissions="['business:category: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" :selectable="isChangeSelected" width="55"></el-table-column>
+        <el-table-column prop="name" label="鍚嶇О" min-width="100px"></el-table-column>
+        <el-table-column label="鐘舵��">
+          <template slot-scope="{row}">
+            <el-switch :disabled="row.isFixed ==1" @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 prop="remark" label="鎻忚堪" min-width="100px"></el-table-column>
+        <el-table-column prop="sortnum" 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-column
+          v-if="containPermissions(['business:category:update', 'business:category:delete'])"
+          label="鎿嶄綔"
+          min-width="120"
+          fixed="right"
+        >
+          <template slot-scope="{row}">
+            <el-button type="text"   @click="$refs.operaCategoryWindow.open('缂栬緫鎿呴暱棰嗗煙', row,searchForm.type)" icon="el-icon-edit" v-permissions="['business:category:update']">缂栬緫</el-button>
+            <el-button type="text"   @click="deleteById(row)" icon="el-icon-delete" v-permissions="['business:category:delete']">鍒犻櫎</el-button>
+          </template>
+        </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: {
+        name: '',
+        type: 2
+      }
+    }
+  },
+  created () {
+    this.config({
+      module: '鍒嗙被淇℃伅琛�',
+      api: '/business/category',
+      'field.id': 'id',
+      'field.main': 'id'
+    })
+    this.search()
+  },
+  methods: {
+    isChangeSelected(row,index){
+      // if(row.isFixed ==1) {
+      //   return false
+      // }
+      return true
+    },
+    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>
diff --git a/admin/src/views/business/categoryLevel.vue b/admin/src/views/business/categoryLevel.vue
new file mode 100644
index 0000000..e080855
--- /dev/null
+++ b/admin/src/views/business/categoryLevel.vue
@@ -0,0 +1,121 @@
+<template>
+  <TableLayout :permissions="['business:category: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" placeholder="璇疯緭鍏ュ悕绉�" @keypress.enter.native="search"></el-input>
+      </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:category:create', 'business:category:delete']">
+        <li><el-button type="primary" @click="$refs.operaCategoryWindow.open('鏂板缓鑰佸笀绛夌骇',null,searchForm.type)" icon="el-icon-plus" v-permissions="['business:category:create']">鏂板缓</el-button></li>
+        <li><el-button @click="deleteByIdInBatch" icon="el-icon-delete" v-permissions="['business:category: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" :selectable="isChangeSelected" 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="100px">
+          <template slot-scope="{row}">
+            <el-image v-if="row.iconFull" style="width: 50px; height: 50px; margin-right: 10px" :src="row.iconFull"
+                      :preview-src-list="[row.iconFull]">
+            </el-image>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="鐘舵��">
+          <template slot-scope="{row}">
+            <el-switch :disabled="row.isFixed ==1" @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 prop="remark" label="鎻忚堪" min-width="100px"></el-table-column>
+        <el-table-column prop="sortnum" 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-column
+          v-if="containPermissions(['business:category:update', 'business:category:delete'])"
+          label="鎿嶄綔"
+          min-width="120"
+          fixed="right"
+        >
+          <template slot-scope="{row}">
+            <el-button type="text"   @click="$refs.operaCategoryWindow.open('缂栬緫鑰佸笀绛夌骇', row,searchForm.type)" icon="el-icon-edit" v-permissions="['business:category:update']">缂栬緫</el-button>
+            <el-button type="text"   @click="deleteById(row)" icon="el-icon-delete" v-permissions="['business:category:delete']">鍒犻櫎</el-button>
+          </template>
+        </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: {
+        name: '',
+        type: 3
+      }
+    }
+  },
+  created () {
+    this.config({
+      module: '鍒嗙被淇℃伅琛�',
+      api: '/business/category',
+      'field.id': 'id',
+      'field.main': 'id'
+    })
+    this.search()
+  },
+  methods: {
+    isChangeSelected(row,index){
+      // if(row.isFixed ==1) {
+      //   return false
+      // }
+      return true
+    },
+    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>
diff --git a/admin/src/views/business/member.vue b/admin/src/views/business/member.vue
index 6e99eef..c89fec6 100644
--- a/admin/src/views/business/member.vue
+++ b/admin/src/views/business/member.vue
@@ -2,42 +2,104 @@
   <TableLayout :permissions="['business:member:query']">
     <!-- 鎼滅储琛ㄥ崟 -->
     <el-form ref="searchForm" slot="search-form" :model="searchForm" label-width="100px" inline>
-      <el-form-item label="鎵嬫満鍙�" prop="telephone">
-        <el-input v-model="searchForm.telephone" clearable placeholder="璇疯緭鍏ユ墜鏈哄彿" @keypress.enter.native="search"></el-input>
+      <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="name">
-        <el-input v-model="searchForm.name" clearable placeholder="璇疯緭鍏ョ湡瀹炲鍚�" @keypress.enter.native="search"></el-input>
+      <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="type">
-        <el-select v-model="searchForm.type" clearable placeholder="璇烽�夋嫨绫诲瀷" @change="search">
-            <el-option :value="0" label="鍏ㄩ儴"></el-option>
-            <el-option :value="1" label="鎺ュ崟鏂�"></el-option>
+      <el-form-item label="鎴樺尯" prop="fieldIdList">
+        <el-select
+            v-model="searchForm.fieldIdList"
+            style="width: 150px"
+            placeholder="鎴樺尯"
+            clearable
+            multiple
+            @change="search"
+        >
+          <el-option
+              v-for="item in cateList"
+              :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"  @keypress.enter.native="search" clearable placeholder="鐘舵��">
-          <el-option label="鍚敤" value="0"></el-option>
-          <el-option label="绂佺敤" value="1"></el-option>
+      <el-form-item label="鍟嗕笟鍖栫被鍨�" prop="busTypeIdList">
+        <el-select
+            v-model="searchForm.busTypeIdList"
+            style="width: 150px"
+            placeholder="鍟嗕笟鍖栫被鍨�"
+            clearable
+            multiple
+            @change="search"
+        >
+          <el-option
+              v-for="item in cateList1"
+              :key="item.id"
+              :value="item.id"
+              :label="item.name"
+          ></el-option>
         </el-select>
-      </el-form-item>-->
-      <el-form-item label="娉ㄥ唽鏃堕棿" prop="eventType">
-        <el-date-picker type="datetime" style="width: 120px" v-model="searchForm.startTime" clearable value-format="yyyy-MM-dd HH:mm:ss"
-                        placeholder="寮�濮嬫椂闂�" />-
-        <el-date-picker type="datetime"  style="width: 120px"  v-model="searchForm.endTime" clearable value-format="yyyy-MM-dd HH:mm:ss"
-                        placeholder="缁撴潫鏃堕棿" />
+      </el-form-item>
+      <el-form-item label="鎿呴暱棰嗗煙" prop="levelIdList">
+        <el-select
+            v-model="searchForm.levelIdList"
+            style="width: 150px"
+            placeholder="鎿呴暱棰嗗煙"
+            clearable
+            multiple
+            @change="search"
+        >
+          <el-option
+              v-for="item in cateList2"
+              :key="item.id"
+              :value="item.id"
+              :label="item.name"
+          ></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="鑰佸笀绛夌骇" prop="levelIdList">
+        <el-select
+            v-model="searchForm.levelIdList"
+            style="width: 150px"
+            placeholder="鑰佸笀绛夌骇"
+            clearable
+            multiple
+            @change="search"
+        >
+          <el-option
+              v-for="item in cateList3"
+              :key="item.id"
+              :value="item.id"
+              :label="item.name"
+          ></el-option>
+        </el-select>
+        <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>
       </el-form-item>
       <section>
         <el-button type="primary" @click="search">鎼滅储</el-button>
         <el-button @click="reset">閲嶇疆</el-button>
-        <el-button type="primary" :loading="isWorking.export" @click="exportExcel">瀵煎嚭</el-button>
       </section>
     </el-form>
     <!-- 琛ㄦ牸鍜屽垎椤� -->
     <template v-slot:table-wrap>
-<!--      <ul class="toolbar" v-permissions="['business:member:create', 'business:member:delete']">
-        <li><el-button type="primary" @click="$refs.operaMemberWindow.open('鏂板缓浼氬憳淇℃伅琛�')" icon="el-icon-plus" v-permissions="['business:member:create']">鏂板缓</el-button></li>
-        <li><el-button @click="deleteByIdInBatch" icon="el-icon-delete" v-permissions="['business:member:delete']">鍒犻櫎</el-button></li>
-      </ul>-->
+      <ul class="toolbar" v-permissions="['business:member:create', 'business:member:delete']">
+        <li><el-button type="primary" @click="$refs.operaMemberWindow.open('鏂板缓鑰佸笀',null)" icon="el-icon-plus" v-permissions="['business:member:create']">鏂板缓</el-button></li>
+        <li><el-button type="primary" icon="el-icon-refresh" v-permissions="['business:member:create']" @click="$refs.OperaMemberImportWindow.open('鑰佸笀瀵煎叆', searchForm.companyType)">鎵归噺瀵煎叆</el-button></li>
+        <li><el-button type="danger" @click="deleteByIdInBatch" icon="el-icon-delete" v-permissions="['business:member:delete']">鍒犻櫎</el-button></li>
+      </ul>
       <el-table
           :height="tableHeightNew"
         v-loading="isWorking.search"
@@ -46,55 +108,57 @@
         @selection-change="handleSelectionChange"
       >
         <el-table-column type="selection" width="55"></el-table-column>
-        <el-table-column prop="openid" label="openid" min-width="100px">
+        <el-table-column  prop="imgurl" label="鍥剧墖" min-width="100px">
           <template slot-scope="{row}">
-           <span style="cursor: pointer;color: #2E68EC" @click="openDetail(row)">{{row.openid}}</span>
+            <el-image v-if="row.imgurlfull" style="width: 50px; height: 50px; margin-right: 10px" :src="row.imgurlfull"
+                      :preview-src-list="[row.imgurlfull]">
+            </el-image>
           </template>
         </el-table-column>
-        <el-table-column prop="nickName" label="鏄电О" min-width="100px"></el-table-column>
-        <el-table-column prop="name" label="鐪熷疄濮撳悕" min-width="100px"></el-table-column>
-        <el-table-column prop="telephone" label="鎵嬫満鍙�" min-width="100px"></el-table-column>
-        <el-table-column prop="workerIdentity" label="韬唤" min-width="100px">
+        <el-table-column prop="code" label="宸ュ彿" min-width="100px"></el-table-column>
+        <el-table-column prop="name" label="濮撳悕" min-width="100px"></el-table-column>
+        <el-table-column prop="sex" label="鎬у埆" min-width="100px">
           <template slot-scope="{row}">
-            鍙戝崟鏂�<span v-if="row.workerIdentity == 2 || row.driverIdentity == 2 || row.chefIdentity == 2">{{'  |  鎺ュ崟鏂�'}}</span>
+            <span v-if="row.sex ==0">鐢�</span>
+            <span v-if="row.sex ==1">濂�</span>
           </template>
         </el-table-column>
-        <el-table-column prop="workerIdentity" label="鎺ュ崟璁よ瘉韬唤"  width="120px">
+        <el-table-column prop="position" 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">
           <template slot-scope="{row}">
-            <div v-if="row.workerIdentity == 2" class="renzhen">宸ヤ汉</div>
-            <div v-if=" row.driverIdentity == 2"  class="renzhen">鍙告満</div>
-            <div v-if="row.chefIdentity == 2"    class="renzhen">渚涢</div>
+            <span v-if="row.serveNum">{{row.serveNum}}涓�</span>
           </template>
         </el-table-column>
-        <el-table-column prop="amount" label="褰撳墠浣欓(鍏�)" min-width="100px">
+        <el-table-column prop="caseNum" label="鏍囨潌妗堜緥" min-width="100px">
           <template slot-scope="{row}">
-            <span class="yellowstate">{{((row.amount || 0)/100).toFixed(2)}}</span>
+            <span v-if="row.caseNum">{{row.caseNum}}涓�</span>
           </template>
         </el-table-column>
-        <el-table-column prop="createTime" label="娉ㄥ唽鏃堕棿" min-width="100px"></el-table-column>
-        <el-table-column prop="autoReciveStatus" label="鎺ュ彈鑷姩娲惧崟" min-width="100px">
-            <template slot-scope="{row}">
-              {{row.autoReceiveStatus ==1?"鏄�":"鍚�"}}
-            </template>
-        </el-table-column>
-<!--        <el-table-column label="鐘舵��">
+        <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="鐘舵��">
           <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
-              v-if="containPermissions(['business:member:update', 'business:member:delete'])"
-              label="鎿嶄綔"
-              min-width="120"
-              fixed="right"
-            >
+        <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="鎿嶄綔"
+          min-width="120"
+          fixed="right"
+        >
           <template slot-scope="{row}">
-            <el-button type="text" @click="$refs.operaMemberWindow.open('缂栬緫浼氬憳淇℃伅琛�', row)" icon="el-icon-edit" v-permissions="['business:member:update']">缂栬緫</el-button>
-            <el-button type="text" @click="deleteById(row)" icon="el-icon-delete" v-permissions="['business:member:delete']">鍒犻櫎</el-button>
+            <el-button type="text" @click="$refs.operaMemberWindow.open('缂栬緫鑰佸笀', row,searchForm.type)" icon="el-icon-edit" v-permissions="['business:member:update']">缂栬緫</el-button>
+            <el-button type="text" style="color: red" @click="deleteById(row)" icon="el-icon-delete" v-permissions="['business:member:delete']">鍒犻櫎</el-button>
           </template>
-        </el-table-column>-->
+        </el-table-column>
       </el-table>
       <pagination
         @size-change="handleSizeChange"
@@ -104,8 +168,8 @@
       </pagination>
     </template>
     <!-- 鏂板缓/淇敼 -->
-    <OperaMemberDetailWindow ref="OperaMemberDetailWindow" />
     <OperaMemberWindow ref="operaMemberWindow" @success="handlePageChange"/>
+    <OperaMemberImportWindow ref="OperaMemberImportWindow" @success="handlePageChange" />
   </TableLayout>
 </template>
 
@@ -114,51 +178,63 @@
 import TableLayout from '@/layouts/TableLayout'
 import Pagination from '@/components/common/Pagination'
 import OperaMemberWindow from '@/components/business/OperaMemberWindow'
-import OperaMemberDetailWindow from '@/components/business/OperaMemberDetailWindow'
+import OperaMemberImportWindow from '@/components/business/OperaMemberImportWindow'
+import { findAll as cateList } from '@/api/business/category'
 export default {
-  name: 'Member',
+  name: 'Category',
   extends: BaseTable,
-  components: { TableLayout, Pagination, OperaMemberDetailWindow, OperaMemberWindow },
+  components: { TableLayout, Pagination, OperaMemberWindow ,OperaMemberImportWindow},
   data () {
     return {
       // 鎼滅储
       searchForm: {
-        type: 0,
-        startTime: '',
-        endTime: '',
-        telephone: '',
         name: '',
-        status: ''
-      }
+        code: '',
+        status: null,
+        levelIdList:[],
+        fieldIdList: [],
+        busTypeIdList:[],
+        type: 0
+      },
+      cateList:[],
+      cateList1:[],
+      cateList2:[],
+      cateList3:[],
     }
   },
   created () {
     this.config({
-      module: '浼氬憳淇℃伅琛�',
+      module: '璁插笀淇℃伅琛�',
       api: '/business/member',
       'field.id': 'id',
       'field.main': 'id'
     })
     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: {
-    reset () {
-      this.searchForm = {
-        type: 0,
-        startTime: '',
-        endTime: '',
-        telephone: '',
-        name: '',
-        status: ''
-      }
-      this.search()
-    },
-    openDetail (row) {
-      this.$refs.OperaMemberDetailWindow.open('鐢ㄦ埛璇︽儏', row.id)
-    },
     changeStatus (e, row) {
       this.working = true
-      this.api.updateStatus({ id: row.id, workStatus: e })
+      this.api.updateStatus({ id: row.id, status: e })
         .then(res => {
           this.$tip.apiSuccess(res || '鎿嶄綔鎴愬姛')
           this.search()
@@ -169,19 +245,7 @@
         .finally(() => {
           this.working = false
         })
-        .catch(() => { })
     }
   }
 }
 </script>
-<style  scoped lang="scss">
-.renzhen{
-  margin: 5px;
-  line-height: 30px;
-  color:#67c23a;
-  height: 30px;
-  text-align:center;
-  border-color: #e1f3d8;
-  background-color: #f0f9eb;
-}
-</style>
diff --git a/server/admin/src/main/java/com/doumee/api/business/CategoryController.java b/server/admin/src/main/java/com/doumee/api/business/CategoryController.java
index e949e2b..6bec36e 100644
--- a/server/admin/src/main/java/com/doumee/api/business/CategoryController.java
+++ b/server/admin/src/main/java/com/doumee/api/business/CategoryController.java
@@ -85,6 +85,12 @@
     public ApiResponse<PageData<Category>> findPage (@RequestBody PageWrap<Category> pageWrap) {
         return ApiResponse.success(categoryService.findPage(pageWrap));
     }
+    @ApiOperation("鍒楄〃鏌ヨ")
+    @PostMapping("/list")
+    @RequiresPermissions("business:category:query")
+    public ApiResponse<List<Category>> findList (@RequestBody  Category pageWrap) {
+        return ApiResponse.success(categoryService.findList(pageWrap));
+    }
 
     @ApiOperation("瀵煎嚭Excel")
     @PostMapping("/exportExcel")
diff --git a/server/admin/src/main/java/com/doumee/api/business/ImportRecordController.java b/server/admin/src/main/java/com/doumee/api/business/ImportRecordController.java
index b7a6427..b506794 100644
--- a/server/admin/src/main/java/com/doumee/api/business/ImportRecordController.java
+++ b/server/admin/src/main/java/com/doumee/api/business/ImportRecordController.java
@@ -9,14 +9,17 @@
 import com.doumee.dao.business.model.ImportRecord;
 import com.doumee.core.utils.Utils;
 import com.doumee.service.business.ImportRecordService;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.*;
 import org.apache.shiro.authz.annotation.RequiresPermissions;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 import javax.servlet.http.HttpServletResponse;
 
 import  com.doumee.api.BaseController;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.File;
+
 /**
  * 鍒嗙被淇℃伅琛–ontroller瀹氫箟
  * @author doumee
@@ -82,4 +85,16 @@
     public ApiResponse findById(@PathVariable Integer id) {
         return ApiResponse.success(importRecordService.findById(id));
     }
+
+    @ApiOperation(value = "淇℃伅瀵煎叆" ,notes = "淇濆崟鐢宠")
+    @PostMapping("/importExcel")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "file", value = "file", required = true, paramType = "query", dataType = "file", dataTypeClass = File.class),
+            @ApiImplicitParam(name = "瀵煎叆绫诲瀷 0浜哄憳 1妗堜緥", value = "type", required = true, paramType = "query", dataType = "Integer",example = "0",dataTypeClass = Integer.class),
+    })
+    public ApiResponse<String> importExcel (@ApiParam(value = "file") MultipartFile file, @ApiParam(value = "type") Integer type) {
+        ImportRecord importRecord = importRecordService.importBatch(file,type);
+        importRecordService.dealImporTask(importRecord);
+        return ApiResponse.success("鏂囦欢涓婁紶鎴愬姛");
+    }
 }
diff --git a/server/admin/src/main/java/com/doumee/api/business/MemberController.java b/server/admin/src/main/java/com/doumee/api/business/MemberController.java
index 1d5df62..42bf73a 100644
--- a/server/admin/src/main/java/com/doumee/api/business/MemberController.java
+++ b/server/admin/src/main/java/com/doumee/api/business/MemberController.java
@@ -9,14 +9,17 @@
 import com.doumee.dao.business.model.Member;
 import com.doumee.core.utils.Utils;
 import com.doumee.service.business.MemberService;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.*;
 import org.apache.shiro.authz.annotation.RequiresPermissions;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 import javax.servlet.http.HttpServletResponse;
 
 import  com.doumee.api.BaseController;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.File;
+
 /**
  * 浼氬憳淇℃伅琛–ontroller瀹氫箟
  * @author doumee
@@ -76,6 +79,7 @@
         ExcelExporter.build(Member.class).export(memberService.findPage(pageWrap).getRecords(), "浼氬憳淇℃伅琛�", response);
     }
 
+
     @ApiOperation("鏍规嵁ID鏌ヨ")
     @GetMapping("/{id}")
     @RequiresPermissions("business:member:query")
diff --git a/server/pom.xml b/server/pom.xml
index 195fccc..4c972ee 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -46,6 +46,11 @@
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-data-redis</artifactId>
     </dependency>
+    <dependency>
+      <groupId>cn.hutool</groupId>
+      <artifactId>hutool-all</artifactId>
+      <version>5.8.40</version>
+    </dependency>
     <!-- Shiro -->
     <dependency>
       <groupId>org.apache.shiro</groupId>
diff --git a/server/services/pom.xml b/server/services/pom.xml
index 17915b2..f8eb953 100644
--- a/server/services/pom.xml
+++ b/server/services/pom.xml
@@ -19,6 +19,11 @@
       <!--鏈湴鐨刯acob.jar鐨勮矾寰�-->
       <systemPath>${project.basedir}/lib/zos-sdk.jar</systemPath>
     </dependency>
+    <dependency>
+      <groupId>cn.hutool</groupId>
+      <artifactId>hutool-all</artifactId>
+      <version>5.8.40</version>
+    </dependency>
   </dependencies>
   <properties>
     <maven.compiler.source>8</maven.compiler.source>
diff --git a/server/services/src/main/java/com/doumee/core/annotation/excel/ExcelImporter.java b/server/services/src/main/java/com/doumee/core/annotation/excel/ExcelImporter.java
index f8f067c..a1d7252 100644
--- a/server/services/src/main/java/com/doumee/core/annotation/excel/ExcelImporter.java
+++ b/server/services/src/main/java/com/doumee/core/annotation/excel/ExcelImporter.java
@@ -4,6 +4,7 @@
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
 import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.xssf.usermodel.XSSFPictureData;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -42,7 +43,7 @@
      * 鏍囬琛屽彿
      */
     private CellType changeType;
-
+    private Map<String, XSSFPictureData> pictureList;
     /**
      * 鏋勯�犲嚱鏁�
      * @param--path 瀵煎叆鏂囦欢锛岃鍙栫涓�涓伐浣滆〃
@@ -161,6 +162,7 @@
         this.sheet = this.wb.getSheetAt(sheetIndex);
         this.headerNum = headerNum;
         this.changeType = cellType;
+        this.pictureList = ExcelPictureUtil.getExcelPictures(in);
         log.debug("Initialize success.");
     }
 
@@ -228,6 +230,9 @@
         }
         return val;
     }
+    public Map<String,XSSFPictureData> getExcelPictures(){
+        return this.pictureList;
+    }
 
     /**
      * 鑾峰彇瀵煎叆鏁版嵁鍒楄〃
diff --git a/server/services/src/main/java/com/doumee/core/annotation/excel/ExcelPictureUtil.java b/server/services/src/main/java/com/doumee/core/annotation/excel/ExcelPictureUtil.java
new file mode 100644
index 0000000..08b073c
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/annotation/excel/ExcelPictureUtil.java
@@ -0,0 +1,305 @@
+package com.doumee.core.annotation.excel;
+import cn.hutool.json.JSONArray;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.XML;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.map.HashedMap;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.openxml4j.opc.PackagePartName;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.ss.usermodel.WorkbookFactory;
+import org.apache.poi.xssf.usermodel.*;
+
+import java.io.*;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+
+/**
+ * @author bianhl
+ * @version 1.0
+ * @description 鑾峰彇鍥剧墖璧勬簮
+ * @date 2024骞�4鏈�28鏃�08:44:42
+ */
+@Slf4j
+public class ExcelPictureUtil {
+
+    public static Map<String, XSSFPictureData> getExcelPictures(InputStream is) {
+        byte[] fileData =  getFileStream(is);
+        Map<String, XSSFPictureData> pictures = getPictures(fileData);
+        pictures.forEach((id, xssfPictureData) -> {
+            System.out.println("id锛�" + id);
+            String fileName = xssfPictureData.getPackagePart().getPartName().getName();
+            System.out.println("fileName锛�" + fileName);
+        });
+        return pictures;
+    }
+
+    /**
+     * 鑾峰彇娴姩鍥剧墖锛屼互 map 褰㈠紡杩斿洖锛岄敭涓鸿鍒楁牸寮� x-y銆�
+     *
+     * @param xssfSheet WPS 宸ヤ綔琛�
+     * @return 娴姩鍥剧墖鐨� map
+     */
+    public static Map<String, XSSFPictureData> getFloatingPictures(XSSFSheet xssfSheet) {
+        Map<String, XSSFPictureData> mapFloatingPictures = new HashMap<>();
+        XSSFDrawing drawingPatriarch = xssfSheet.getDrawingPatriarch();
+        if (drawingPatriarch != null) {
+            List<XSSFShape> shapes = drawingPatriarch.getShapes();
+            for (XSSFShape shape : shapes) {
+                if (shape instanceof XSSFPicture ) {
+                    XSSFPicture picture = (XSSFPicture)shape;
+                    XSSFClientAnchor anchor = (XSSFClientAnchor) picture.getAnchor();
+                    XSSFPictureData pictureData = picture.getPictureData();
+                    String key = anchor.getRow1() + "-" + anchor.getCol1();
+                    mapFloatingPictures.put(key, pictureData);
+                }
+            }
+        }
+        return mapFloatingPictures;
+    }
+
+    /**
+     * 澶勭悊 WPS 鏂囦欢涓殑鍥剧墖鏁版嵁锛岃繑鍥炲浘鐗囦俊鎭� map銆�
+     *
+     * @param stream    杈撳叆娴�
+     * @param mapConfig 閰嶇疆鏄犲皠
+     * @return 鍥剧墖淇℃伅鐨� map
+     * @throws IOException
+     */
+    private static Map<String, XSSFPictureData> processPictures(ByteArrayInputStream stream, Map<String, String> mapConfig) throws IOException {
+        Map<String, XSSFPictureData> mapPictures = new HashedMap<>();
+        Workbook workbook = WorkbookFactory.create(stream);
+        List<XSSFPictureData> allPictures = (List<XSSFPictureData>) workbook.getAllPictures();
+        for (XSSFPictureData pictureData : allPictures) {
+            PackagePartName partName = pictureData.getPackagePart().getPartName();
+            String uri = partName.getURI().toString();
+            if (mapConfig.containsKey(uri)) {
+                String strId = mapConfig.get(uri);
+                mapPictures.put(strId, pictureData);
+            }
+        }
+        return mapPictures;
+    }
+
+    /**
+     * 鑾峰彇 WPS 鏂囨。涓殑鍥剧墖锛屽寘鎷祵鍏ュ紡鍥剧墖鍜屾诞鍔ㄥ紡鍥剧墖銆�
+     *
+     * @param data 浜岃繘鍒舵暟鎹�
+     * @return 鍥剧墖淇℃伅鐨� map
+     * @throws IOException
+     */
+    public static Map<String, XSSFPictureData> getPictures(byte[] data) {
+        try {
+            Map<String, String> mapConfig = processZipEntries(new ByteArrayInputStream(data));
+            Map<String, XSSFPictureData> mapPictures = processPictures(new ByteArrayInputStream(data), mapConfig);
+            Iterator<Sheet> sheetIterator = WorkbookFactory.create(new ByteArrayInputStream(data)).sheetIterator();
+            while (sheetIterator.hasNext()) {
+                mapPictures.putAll(getFloatingPictures((XSSFSheet) sheetIterator.next()));
+            }
+            return mapPictures;
+        } catch (IOException e) {
+            return new HashedMap<>();
+        }
+    }
+
+    /**
+     * 澶勭悊 Zip 鏂囦欢涓殑鏉$洰锛屾洿鏂板浘鐗囬厤缃俊鎭��
+     *
+     * @param stream Zip 杈撳叆娴�
+     * @return 閰嶇疆淇℃伅鐨� map
+     * @throws IOException
+     */
+    private static Map<String, String> processZipEntries(ByteArrayInputStream stream) throws IOException {
+        Map<String, String> mapConfig = new HashedMap<>();
+        ZipInputStream zipInputStream = new ZipInputStream(stream);
+        ZipEntry zipEntry;
+        while ((zipEntry = zipInputStream.getNextEntry()) != null) {
+            try {
+                final String fileName = zipEntry.getName();
+                if ("xl/cellimages.xml".equals(fileName)) {
+                    processCellImages(zipInputStream, mapConfig);
+                } else if ("xl/_rels/cellimages.xml.rels".equals(fileName)) {
+                    return processCellImagesRels(zipInputStream, mapConfig);
+                }
+            } finally {
+                zipInputStream.closeEntry();
+            }
+        }
+        return new HashedMap<>();
+    }
+
+    /**
+     * 澶勭悊 Zip 鏂囦欢涓殑 cellimages.xml 鏂囦欢锛屾洿鏂板浘鐗囬厤缃俊鎭��
+     *
+     * @param zipInputStream Zip 杈撳叆娴�
+     * @param mapConfig      閰嶇疆淇℃伅鐨� map
+     * @throws IOException
+     */
+    private static void processCellImages(ZipInputStream zipInputStream, Map<String, String> mapConfig) throws IOException {
+        String content = IOUtils.toString(zipInputStream);
+        JSONObject jsonObject = XML.toJSONObject(content);
+        if (jsonObject != null) {
+            JSONObject cellImages = jsonObject.getJSONObject("etc:cellImages");
+            if (cellImages != null) {
+                JSONArray cellImageArray = null;
+                Object cellImage = cellImages.get("etc:cellImage");
+                if (cellImage != null && cellImage instanceof JSONArray) {
+                    cellImageArray = (JSONArray) cellImage;
+                } else if (cellImage != null && cellImage instanceof JSONObject) {
+                    JSONObject cellImageObj = (JSONObject) cellImage;
+                    if (cellImageObj != null) {
+                        cellImageArray = new JSONArray();
+                        cellImageArray.add(cellImageObj);
+                    }
+                }
+                if (cellImageArray != null) {
+                    processImageItems(cellImageArray, mapConfig);
+                }
+            }
+        }
+    }
+
+    /**
+     * 澶勭悊 cellImageArray 涓殑鍥剧墖椤癸紝鏇存柊鍥剧墖閰嶇疆淇℃伅銆�
+     *
+     * @param cellImageArray 鍥剧墖椤圭殑 JSONArray
+     * @param mapConfig      閰嶇疆淇℃伅鐨� map
+     */
+    private static  void processImageItems(JSONArray cellImageArray, Map<String, String> mapConfig) {
+        for (int i = 0; i < cellImageArray.size(); i++) {
+            JSONObject imageItem = cellImageArray.getJSONObject(i);
+            if (imageItem != null) {
+                JSONObject pic = imageItem.getJSONObject("xdr:pic");
+                if (pic != null) {
+                    processPic(pic, mapConfig);
+                }
+            }
+        }
+    }
+
+    /**
+     * 澶勭悊 pic 涓殑鍥剧墖淇℃伅锛屾洿鏂板浘鐗囬厤缃俊鎭��
+     *
+     * @param pic       鍥剧墖鐨� JSONObject
+     * @param mapConfig 閰嶇疆淇℃伅鐨� map
+     */
+    private static  void processPic(JSONObject pic, Map<String, String> mapConfig) {
+        JSONObject nvPicPr = pic.getJSONObject("xdr:nvPicPr");
+        if (nvPicPr != null) {
+            JSONObject cNvPr = nvPicPr.getJSONObject("xdr:cNvPr");
+            if (cNvPr != null) {
+                String name = cNvPr.getStr("name");
+                if (StringUtils.isNotEmpty(name)) {
+                    String strImageEmbed = updateImageEmbed(pic);
+                    if (strImageEmbed != null) {
+                        mapConfig.put(strImageEmbed, name);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * 鑾峰彇宓屽叆寮忓浘鐗囩殑 embed 淇℃伅銆�
+     *
+     * @param pic 鍥剧墖鐨� JSONObject
+     * @return embed 淇℃伅
+     */
+    private  static String updateImageEmbed(JSONObject pic) {
+        JSONObject blipFill = pic.getJSONObject("xdr:blipFill");
+        if (blipFill != null) {
+            JSONObject blip = blipFill.getJSONObject("a:blip");
+            if (blip != null) {
+                return blip.getStr("r:embed");
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 澶勭悊 Zip 鏂囦欢涓殑 relationship 鏉$洰锛屾洿鏂伴厤缃俊鎭��
+     *
+     * @param zipInputStream Zip 杈撳叆娴�
+     * @param mapConfig      閰嶇疆淇℃伅鐨� map
+     * @return 閰嶇疆淇℃伅鐨� map
+     * @throws IOException
+     */
+    private static Map<String, String> processCellImagesRels(ZipInputStream zipInputStream, Map<String, String> mapConfig) throws IOException {
+        String content = IOUtils.toString(zipInputStream );
+        JSONObject jsonObject = XML.toJSONObject(content);
+        JSONObject relationships = jsonObject.getJSONObject("Relationships");
+        if (relationships != null) {
+            JSONArray relationshipArray = null;
+            Object relationship = relationships.get("Relationship");
+
+            if (relationship != null && relationship instanceof JSONArray) {
+                relationshipArray = (JSONArray) relationship;
+            } else if (relationship != null && relationship instanceof JSONObject  ) {
+                JSONObject relationshipObj = (JSONObject) relationship;
+                if (relationshipObj != null) {
+                    relationshipArray = new JSONArray();
+                    relationshipArray.add(relationshipObj);
+                }
+            }
+            if (relationshipArray != null) {
+                return processRelationships(relationshipArray, mapConfig);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 澶勭悊 relationshipArray 涓殑鍏崇郴椤癸紝鏇存柊閰嶇疆淇℃伅銆�
+     *
+     * @param relationshipArray 鍏崇郴椤圭殑 JSONArray
+     * @param mapConfig         閰嶇疆淇℃伅鐨� map
+     * @return 閰嶇疆淇℃伅鐨� map
+     */
+    private static Map<String, String> processRelationships(JSONArray relationshipArray, Map<String, String> mapConfig) {
+        Map<String, String> mapRelationships = new HashedMap<>();
+        for (int i = 0; i < relationshipArray.size(); i++) {
+            JSONObject relaItem = relationshipArray.getJSONObject(i);
+            if (relaItem != null) {
+                String id = relaItem.getStr("Id");
+                String value = "/xl/" + relaItem.getStr("Target");
+                if (mapConfig.containsKey(id)) {
+                    String strImageId = mapConfig.get(id);
+                    mapRelationships.put(value, strImageId);
+                }
+            }
+        }
+        return mapRelationships;
+    }
+
+    /**
+     * @return {@link byte[]}
+     * @description
+     * @author bianhl
+     * @date 2024/4/26 13:52
+     */
+    private static byte[] getFileStream(InputStream inputStream) {
+            // 鍒涘缓 ByteArrayOutputStream 鏉ユ殏瀛樻祦鏁版嵁
+        try {
+            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+            // 灏� inputStream 璇诲彇鍒� byteArrayOutputStream 涓�
+            byte[] buffer = new byte[1024];
+            int length;
+            while ((length = inputStream.read(buffer)) != -1) {
+                byteArrayOutputStream.write(buffer, 0, length);
+            }
+            // 灏� byteArrayOutputStream 鐨勫唴瀹硅幏鍙栦负瀛楄妭鏁扮粍
+            return byteArrayOutputStream.toByteArray();
+        } catch (IOException e) {
+            return null;
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/server/services/src/main/java/com/doumee/core/constants/Constants.java b/server/services/src/main/java/com/doumee/core/constants/Constants.java
index cdc5e01..8919316 100644
--- a/server/services/src/main/java/com/doumee/core/constants/Constants.java
+++ b/server/services/src/main/java/com/doumee/core/constants/Constants.java
@@ -111,7 +111,8 @@
     interface CacheKey {
     }
     public interface RedisKeys {
-        public static final String ORDER_CODE = "ORDER_CODE";
+       String IMPORTING_RECORD = "IMPORTING_RECORD";
+       String ORDER_CODE = "ORDER_CODE";
     }
     /**
      * 鎿嶄綔绫诲瀷锛岀敤浜庡仛鎺ュ彛楠岃瘉鍒嗙粍
diff --git a/server/services/src/main/java/com/doumee/dao/business/dto/CasesImport.java b/server/services/src/main/java/com/doumee/dao/business/dto/CasesImport.java
new file mode 100644
index 0000000..9589699
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/business/dto/CasesImport.java
@@ -0,0 +1,36 @@
+package com.doumee.dao.business.dto;
+
+import com.doumee.core.annotation.excel.ExcelColumn;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+/**
+ * 鍛樺伐淇℃伅瀵煎叆琛�
+ * @author 姹熻箘韫�
+ * @date 2024/01/16 10:03
+ */
+@Data
+@ApiModel("鍛樺伐淇℃伅瀵煎叆")
+public class CasesImport {
+
+//    @ExcelColumn(name="搴忓彿",value = "sn")
+    private Integer sn;
+
+    @ExcelColumn(name="濮撳悕",value = "name",index = 1)
+    private String name;
+    @ExcelColumn(name="鎵嬫満鍙�",value = "phone",index = 2)
+    private String phone;
+
+    @ExcelColumn(name="韬唤璇佸彿",value = "idcardNo",index = 3)
+    private String idcardNo;
+
+    @ExcelColumn(name="缁勭粐鍚嶇О" , value = "companyName" ,index = 4)
+    private String companyName;
+
+    @ExcelColumn(name="宸ュ彿" , value = "code")
+    private String code;
+
+    @ExcelColumn(name="宀椾綅" , value = "code")
+    private String positionName;
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/business/dto/MemberImport.java b/server/services/src/main/java/com/doumee/dao/business/dto/MemberImport.java
new file mode 100644
index 0000000..6b1e4e2
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/business/dto/MemberImport.java
@@ -0,0 +1,42 @@
+package com.doumee.dao.business.dto;
+
+import com.doumee.core.annotation.excel.ExcelColumn;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+/**
+ * 鍛樺伐淇℃伅瀵煎叆琛�
+ * @author 姹熻箘韫�
+ * @date 2024/01/16 10:03
+ */
+@Data
+@ApiModel("鍛樺伐淇℃伅瀵煎叆")
+public class MemberImport {
+    @ExcelColumn(name="宸ュ彿",value = "code",index = 1)
+    private String code;
+    @ExcelColumn(name="濮撳悕",value = "name",index = 2)
+    private String name;
+    @ExcelColumn(name="鑱屼笟鐓�",value = "imgurl",index = 3)
+    private String imgurl;
+    @ExcelColumn(name="绛夌骇",value = "levelName",index = 4)
+    private String levelName;
+    @ExcelColumn(name="鎬у埆" , value = "sex" ,index = 5)
+    private String sex;
+    @ExcelColumn(name="宀椾綅" , value = "position",index = 6)
+    private String position;
+    @ExcelColumn(name="浠庝笟骞翠唤(骞�)" , value = "jobYear",index = 7)
+    private String jobYear;
+    @ExcelColumn(name="鏈嶅姟鎴樺尯", value = "zqNames",index = 8)
+    private String zqNames;
+    @ExcelColumn(name="鍟嗕笟鍖栫被鍨�", value = "typeNames",index = 9)
+    private String typeNames;
+    @ExcelColumn(name="鎿呴暱棰嗗煙", value = "fieldNames",index = 10)
+    private String fieldNames;
+    @ExcelColumn(name="鏈嶅姟鍟嗗満鏁�(涓�)", value = "serveNum",index = 11)
+    private String serveNum;
+    @ExcelColumn(name="璐圭敤鏍囧噯(鍏�/鍛�)", value = "fee",index = 12)
+    private String fee;
+    @ExcelColumn(name="鑰佸笀绠�浠�", value = "fee",index = 13)
+    private String info;
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/business/model/Category.java b/server/services/src/main/java/com/doumee/dao/business/model/Category.java
index 06048b0..fccea28 100644
--- a/server/services/src/main/java/com/doumee/dao/business/model/Category.java
+++ b/server/services/src/main/java/com/doumee/dao/business/model/Category.java
@@ -63,8 +63,8 @@
     @ExcelColumn(name="鍗曚綅鍚嶇О")
     private String name;
 
-    @ApiModelProperty(value = "绫诲瀷:0=鍝佺閰嶇疆锛�1=杞﹁締绫诲瀷閰嶇疆锛�2=椁愭爣閰嶇疆锛�3=鎵嬬画璐归厤缃紱", example = "1")
-    @ExcelColumn(name="绫诲瀷:0=鍝佺閰嶇疆锛�1=杞﹁締绫诲瀷閰嶇疆锛�2=椁愭爣閰嶇疆锛�3=鎵嬬画璐归厤缃紱")
+    @ApiModelProperty(value = "绫诲瀷:0=鎴樺尯;1=鍟嗕笟鍖�;2=鎿呴暱棰嗗煙;3=璁插笀绛夌骇;", example = "1")
+    @ExcelColumn(name="绫诲瀷:0=鎴樺尯;1=鍟嗕笟鍖�;2=鎿呴暱棰嗗煙;3=璁插笀绛夌骇;")
     private Integer type;
 
     @ApiModelProperty(value = "鍐呭锛堣溅杈嗚鏍笺�侀鏍囥�佹墜缁垂姣斾緥锛�")
@@ -78,15 +78,15 @@
     @ExcelColumn(name="鎺掑簭鐮侊紙鍗囧簭锛�")
     private Integer sortnum;
 
-    @ApiModelProperty(value = "鏄惁鍥哄畾杞﹁締锛堣溅杈嗙被鍨嬩娇鐢級:0=鍚︼紱1=鏄紱", example = "1")
-    @ExcelColumn(name="鏄惁鍥哄畾杞﹁締锛堣溅杈嗙被鍨嬩娇鐢級:0=鍚︼紱1=鏄紱")
+    @ApiModelProperty(value = "鏄惁鍥哄畾锛�:0=鍚︼紱1=鏄紱", example = "1")
+    @ExcelColumn(name="鏄惁鍥哄畾 :0=鍚︼紱1=鏄紱")
     private Integer isFixed;
-    @ApiModelProperty(value = "鏄惁鍥哄畾杞﹁締锛堣溅杈嗙被鍨嬩娇鐢級:0=鍚︼紱1=鏄紱", example = "1")
+    @ApiModelProperty(value = "鏈�鍚庢搷浣滀汉鍛橈紱", example = "1")
     @TableField(exist = false)
     private String updateUserName;
-    @ApiModelProperty(value = "椁愭爣绛夐厤缃」闆嗗悎", example = "1")
+    @ApiModelProperty(value = "闄勪欢闆嗗悎", example = "1")
     @TableField(exist = false)
-    private JSONArray detailList;
+    private List<Multifile> fileList;
     @ApiModelProperty(value = "鍥炬爣鍏ㄨ矾寰�")
     @TableField(exist = false)
     private String iconFull;
diff --git a/server/services/src/main/java/com/doumee/dao/business/model/ImportRecord.java b/server/services/src/main/java/com/doumee/dao/business/model/ImportRecord.java
index ec27b08..c301749 100644
--- a/server/services/src/main/java/com/doumee/dao/business/model/ImportRecord.java
+++ b/server/services/src/main/java/com/doumee/dao/business/model/ImportRecord.java
@@ -2,6 +2,8 @@
 
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.doumee.core.annotation.excel.ExcelColumn;
+import com.doumee.dao.business.dto.CasesImport;
+import com.doumee.dao.business.dto.MemberImport;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import com.baomidou.mybatisplus.annotation.IdType;
@@ -9,8 +11,12 @@
 import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
 import com.fasterxml.jackson.annotation.JsonFormat;
+import org.apache.poi.ss.usermodel.PictureData;
+
 import java.util.Date;
 import java.math.BigDecimal;
+import java.util.List;
+
 /**
  * 鍒嗙被淇℃伅琛∕odel瀹氫箟
  * @author doumee
@@ -76,4 +82,12 @@
     @ApiModelProperty("瀵煎叆澶辫触璁板綍鏁�")
     @ExcelColumn(name="瀵煎叆澶辫触璁板綍鏁�",index=18 ,width=10)
     private Integer errorNum;
+    @TableField(exist = false)
+    private List<CasesImport> caseList;
+    @TableField(exist = false)
+    private List<MemberImport> memberList;
+    @TableField(exist = false)
+    private  List<PictureData> pictureDataList;
+
+
 }
diff --git a/server/services/src/main/java/com/doumee/dao/business/model/Multifile.java b/server/services/src/main/java/com/doumee/dao/business/model/Multifile.java
index cb1df32..6985a4c 100644
--- a/server/services/src/main/java/com/doumee/dao/business/model/Multifile.java
+++ b/server/services/src/main/java/com/doumee/dao/business/model/Multifile.java
@@ -53,9 +53,7 @@
     @ApiModelProperty(value = "绫诲瀷0鍥剧墖 1瑙嗛 2鍏朵粬", example = "1")
     private Integer type;
 
-//    @ApiModelProperty(value = "鍏宠仈瀵硅薄绫诲瀷 0SHE涓婃姤 1璺岀粖婊戜笂鎶� 2璺岀粖婊戝鐞� 3璺岀粖婊戝垎閰嶇墿涓氫富绠� 4璺岀粖婊戝垎閰嶅鐞嗕汉 5DCA椋庨櫓涓婃姤 6DCA椋庨櫓澶勭悊 7DCA宸ュ崟鍥剧墖", example = "1")
-//    @ExcelExportColumn(name="鍏宠仈瀵硅薄绫诲瀷 0SHE涓婃姤 1璺岀粖婊戜笂鎶� 2璺岀粖婊戝鐞� 3璺岀粖婊戝垎閰嶇墿涓氫富绠� 4璺岀粖婊戝垎閰嶅鐞嗕汉 5DCA椋庨櫓涓婃姤 6DCA椋庨櫓澶勭悊 7DCA宸ュ崟鍥剧墖")
-    @ApiModelProperty(value = "鍏宠仈瀵硅薄绫诲瀷 0韬唤鐢宠璧勬枡 1璁㈠崟闄勪欢", example = "1")
+    @ApiModelProperty(value = "鍏宠仈瀵硅薄绫诲瀷 0鍟嗕笟鍖栫被鍨嬪鍥� 1妗堜緥", example = "1")
     private Integer objType;
 
     @ApiModelProperty(value = "鏂囦欢鍦板潃")
@@ -66,7 +64,7 @@
   
     @ApiModelProperty(value = "鏂囦欢鍦板潃")
     @TableField(exist = false)
-    private String fileurlFull;
+    private String url;
 
 
     @ApiModelProperty(value = "鍐呯綉鏂囦欢鍦板潃")
diff --git a/server/services/src/main/java/com/doumee/service/business/ImportRecordService.java b/server/services/src/main/java/com/doumee/service/business/ImportRecordService.java
index 813b65d..cadb3da 100644
--- a/server/services/src/main/java/com/doumee/service/business/ImportRecordService.java
+++ b/server/services/src/main/java/com/doumee/service/business/ImportRecordService.java
@@ -3,6 +3,8 @@
 import com.doumee.core.model.PageData;
 import com.doumee.core.model.PageWrap;
 import com.doumee.dao.business.model.ImportRecord;
+import org.springframework.web.multipart.MultipartFile;
+
 import java.util.List;
 
 /**
@@ -94,4 +96,7 @@
      * @return long
      */
     long count(ImportRecord model);
+    ImportRecord importBatch(MultipartFile file, int type );
+
+    void dealImporTask(ImportRecord importRecord);
 }
diff --git a/server/services/src/main/java/com/doumee/service/business/MemberService.java b/server/services/src/main/java/com/doumee/service/business/MemberService.java
index f955039..d5804e4 100644
--- a/server/services/src/main/java/com/doumee/service/business/MemberService.java
+++ b/server/services/src/main/java/com/doumee/service/business/MemberService.java
@@ -3,6 +3,8 @@
 import com.doumee.core.model.PageData;
 import com.doumee.core.model.PageWrap;
 import com.doumee.dao.business.model.Member;
+import org.springframework.web.multipart.MultipartFile;
+
 import java.util.List;
 
 /**
@@ -94,4 +96,5 @@
      * @return long
      */
     long count(Member model);
+
 }
diff --git a/server/services/src/main/java/com/doumee/service/business/impl/CategoryServiceImpl.java b/server/services/src/main/java/com/doumee/service/business/impl/CategoryServiceImpl.java
index 56d9001..0ce16ed 100644
--- a/server/services/src/main/java/com/doumee/service/business/impl/CategoryServiceImpl.java
+++ b/server/services/src/main/java/com/doumee/service/business/impl/CategoryServiceImpl.java
@@ -11,7 +11,9 @@
 import com.doumee.core.model.PageWrap;
 import com.doumee.core.utils.Utils;
 import com.doumee.dao.business.CategoryMapper;
+import com.doumee.dao.business.MultifileMapper;
 import com.doumee.dao.business.model.Category;
+import com.doumee.dao.business.model.Multifile;
 import com.doumee.dao.system.model.SystemUser;
 import com.doumee.service.business.CategoryService;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@@ -28,6 +30,7 @@
 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;
@@ -42,6 +45,8 @@
 
     @Autowired
     private CategoryMapper categoryMapper;
+    @Autowired
+    private MultifileMapper multifileMapper;
 
     @Autowired
     private SystemDictDataBiz systemDictDataBiz;
@@ -49,12 +54,11 @@
     @Override
     @Transactional(rollbackFor = {Exception.class,BusinessException.class})
     public Integer create(Category category) {
+//        绫诲瀷:0=鎴樺尯;1=鍟嗕笟鍖�;2=鎿呴暱棰嗗煙;3=璁插笀绛夌骇;
         if(Objects.isNull(category)
         || Objects.isNull(category.getType())
         || Objects.isNull(category.getName())
-        || (!Constants.equalsInteger(category.getType(),Constants.ZERO)&& CollectionUtils.isEmpty(category.getDetailList()))
-        || (Constants.equalsInteger(category.getType(),Constants.ONE) && (Objects.isNull(category.getIcon())||Objects.isNull(category.getIsFixed())) )
-        ){
+        || (Constants.equalsInteger(category.getType(),Constants.ZERO)&& StringUtils.isBlank(category.getDetail()))   ){
             throw new BusinessException(ResponseStatus.BAD_REQUEST);
         }
         LoginUserInfo loginUserInfo = (LoginUserInfo) SecurityUtils.getSubject().getPrincipal();
@@ -63,22 +67,40 @@
         category.setCreateUser(loginUserInfo.getId());
         category.setUpdateTime(new Date());
         category.setUpdateUser(loginUserInfo.getId());
-        if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(category.getDetailList())
-                && !Constants.equalsInteger(category.getType(),Constants.THREE)){
-            category.setDetail(category.getDetailList().toJSONString());
-        }
-        if(!Constants.equalsInteger(category.getType(),Constants.ONE)){
-            category.setIsFixed(Constants.ZERO);
-        }
         categoryMapper.insert(category);
+        dealBatchMultiFiles(category, category.getFileList(), loginUserInfo,false);
         return category.getId();
     }
-
+    public void dealBatchMultiFiles(Category 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.ZERO)
+                    .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.ZERO);
+                    multifileList.add(s);
+                }
+            });
+            if(multifileList.size()>0){
+                multifileMapper.insert(multifileList);
+            }
+        }
+    }
     @Override
     public void deleteById(Integer id) {
         categoryMapper.update(new UpdateWrapper<Category>().lambda().set(Category::getDeleted,Constants.ONE).eq(Category::getId,id));
-
-//        categoryMapper.deleteById(id);
     }
 
     @Override
@@ -102,8 +124,6 @@
                 || Objects.isNull(category.getId())
                 || Objects.isNull(category.getType())
                 || Objects.isNull(category.getName())
-                || (!Constants.equalsInteger(category.getType(),Constants.ZERO)&& CollectionUtils.isEmpty(category.getDetailList()))
-                || (Constants.equalsInteger(category.getType(),Constants.ONE) && (Objects.isNull(category.getIcon())||Objects.isNull(category.getIsFixed())) )
         ){
             throw new BusinessException(ResponseStatus.BAD_REQUEST);
         }
@@ -111,25 +131,18 @@
         category.setUpdateTime(new Date());
         category.setIsFixed(null);
         category.setUpdateUser(loginUserInfo.getId());
-        if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(category.getDetailList())
-                && !Constants.equalsInteger(category.getType(),Constants.THREE)){
-            category.setDetail(category.getDetailList().toJSONString());
-        }
         categoryMapper.updateById(category);
+        dealBatchMultiFiles(category, category.getFileList(), loginUserInfo,true);
     }
     @Override
     public void updateStatus(Category category) {
-        if(Objects.isNull(category)
-                || Objects.isNull(category.getId())){
+        if(Objects.isNull(category) || Objects.isNull(category.getId())){
             throw new BusinessException(ResponseStatus.BAD_REQUEST);
         }
         LoginUserInfo loginUserInfo = (LoginUserInfo) SecurityUtils.getSubject().getPrincipal();
         category.setUpdateTime(new Date());
         category.setIsFixed(null);
         category.setUpdateUser(loginUserInfo.getId());
-        if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(category.getDetailList())){
-            category.setDetail(category.getDetailList().toJSONString());
-        }
         categoryMapper.updateById(category);
     }
 
@@ -149,12 +162,9 @@
         if(Objects.isNull(category)){
             throw new BusinessException(ResponseStatus.DATA_EMPTY);
         }
-        if(StringUtils.isNotBlank(category.getDetail())){
-            category.setDetailList(JSONArray.parseArray(category.getDetail()));
-        }
         if(StringUtils.isNotBlank(category.getIcon())){
-            String path  = systemDictDataBiz.queryByCode(Constants.SYSTEM,Constants.RESOURCE_PATH).getCode()
-                    +systemDictDataBiz.queryByCode(Constants.SYSTEM,Constants.CATEGORY_FILES).getCode();
+            String path  = systemDictDataBiz.queryByCode(Constants.OBJCET_STORAGE,Constants.RESOURCE_PATH).getCode()
+                    +systemDictDataBiz.queryByCode(Constants.OBJCET_STORAGE,Constants.CATEGORY_FILES).getCode();
             category.setIconFull(path + category.getIcon());
         }
         return category;
@@ -168,6 +178,7 @@
 
     @Override
     public List<Category> findList(Category category) {
+        category.setDeleted(Constants.ZERO);
         QueryWrapper<Category> wrapper = new QueryWrapper<>(category);
         return categoryMapper.selectList(wrapper);
     }
@@ -225,22 +236,38 @@
         queryWrapper.orderByAsc(Category::getSortnum);
         PageData<Category> result =PageData.from(categoryMapper.selectJoinPage(page, Category.class,queryWrapper));
         if(result!=null && result.getRecords()!=null){
-            String path  = systemDictDataBiz.queryByCode(Constants.SYSTEM,Constants.RESOURCE_PATH).getCode()
-                    +systemDictDataBiz.queryByCode(Constants.SYSTEM,Constants.CATEGORY_FILES).getCode();
+            String path  = systemDictDataBiz.queryByCode(Constants.OBJCET_STORAGE,Constants.RESOURCE_PATH).getCode()
+                    +systemDictDataBiz.queryByCode(Constants.OBJCET_STORAGE,Constants.CATEGORY_FILES).getCode();
             for(Category cate : result.getRecords()){
-                try {
-                    if(StringUtils.isNotBlank(cate.getDetail())){
-                        cate.setDetailList(JSONArray.parseArray(cate.getDetail()));
-                    }
-                    if(StringUtils.isNotBlank(cate.getIcon())){
-                        cate.setIconFull(path + cate.getIcon());
-                    }
-                }catch (Exception e){
-
+                if(Constants.equalsInteger(cate.getType(),Constants.ONE) ){
+                    initMultifileList(cate);
+                }
+                if(StringUtils.isNotBlank(cate.getIcon())){
+                    cate.setIconFull(path + cate.getIcon());
                 }
             }
         }
         return result;
+    }
+
+    private void initMultifileList(Category 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.ZERO);
+        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
@@ -259,12 +286,12 @@
             String path  = systemDictDataBiz.queryByCode(Constants.SYSTEM,Constants.RESOURCE_PATH).getCode()
                     +systemDictDataBiz.queryByCode(Constants.SYSTEM,Constants.CATEGORY_FILES).getCode();
             for (Category category:categoryList) {
-                if(StringUtils.isNotBlank(category.getDetail())){
-                    category.setDetailList(JSONArray.parseArray(category.getDetail()));
-                }
                 if(StringUtils.isNotBlank(category.getIcon())){
                     category.setIconFull(path + category.getIcon());
                 }
+                if(Constants.equalsInteger(category.getType(),Constants.ONE) ){
+                    initMultifileList(category);
+                }
             }
         }
         return categoryList;
diff --git a/server/services/src/main/java/com/doumee/service/business/impl/ImportRecordServiceImpl.java b/server/services/src/main/java/com/doumee/service/business/impl/ImportRecordServiceImpl.java
index d3ca1de..074a1db 100644
--- a/server/services/src/main/java/com/doumee/service/business/impl/ImportRecordServiceImpl.java
+++ b/server/services/src/main/java/com/doumee/service/business/impl/ImportRecordServiceImpl.java
@@ -1,20 +1,41 @@
 package com.doumee.service.business.impl;
 
+import com.doumee.core.annotation.excel.ExcelImporter;
+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;
+import com.doumee.dao.business.dto.CasesImport;
+import com.doumee.dao.business.dto.MemberImport;
 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.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 org.apache.commons.lang3.StringUtils;
+import org.apache.poi.ss.usermodel.CellType;
+import org.apache.shiro.SecurityUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
+import org.springframework.web.multipart.MultipartFile;
 
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
+import java.util.concurrent.TimeUnit;
 
 /**
  * 鍒嗙被淇℃伅琛⊿ervice瀹炵幇
@@ -26,9 +47,21 @@
 
     @Autowired
     private ImportRecordMapper importRecordMapper;
+    @Resource
+    private RedisTemplate<String, Object> redisTemplate;
 
     @Override
     public Integer create(ImportRecord importRecord) {
+        if(StringUtils.isBlank(importRecord.getImgurl())){
+            throw new BusinessException(ResponseStatus.BAD_REQUEST);
+        }
+        LoginUserInfo loginUserInfo = (LoginUserInfo) SecurityUtils.getSubject().getPrincipal();
+        importRecord.setDeleted(Constants.ZERO);
+        importRecord.setStatus(Constants.ZERO);
+        importRecord.setCreateTime(new Date());
+        importRecord.setCreateUser(loginUserInfo.getId());
+        importRecord.setUpdateTime(new Date());
+        importRecord.setUpdateUser(loginUserInfo.getId());
         importRecordMapper.insert(importRecord);
         return importRecord.getId();
     }
@@ -134,4 +167,106 @@
         QueryWrapper<ImportRecord> wrapper = new QueryWrapper<>(importRecord);
         return importRecordMapper.selectCount(wrapper);
     }
+    @Override
+    public ImportRecord importBatch(MultipartFile file,int type ){
+        Boolean importing = (Boolean) redisTemplate.opsForValue().get(Constants.RedisKeys.IMPORTING_RECORD);
+        if(importing!=null && importing){
+            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"瀵逛笉璧凤紝宸插瓨鍦ㄥ鍏ヤ换鍔℃鍦ㄦ墽琛屼腑锛岃绋嶅悗鍐嶈瘯锛�");
+        }
+        redisTemplate.opsForValue().set(Constants.RedisKeys.IMPORTING_RECORD,true,30, TimeUnit.MINUTES);
+        try {
+            ImportRecord model = new ImportRecord();
+            LoginUserInfo loginUserInfo = (LoginUserInfo) SecurityUtils.getSubject().getPrincipal();
+            model.setDeleted(Constants.ZERO);
+            model.setStatus(Constants.ONE);//寮傛澶勭悊涓�
+            model.setCreateTime(new Date());
+            model.setCreateUser(loginUserInfo.getId());
+            model.setUpdateTime(model.getCreateTime());
+            model.setUpdateUser(loginUserInfo.getId());
+            model.setType(type);
+            model.setTitle((type==1?"妗堜緥淇℃伅鎵归噺瀵煎叆":"鑰佸笀淇℃伅鎵归噺瀵煎叆")+ DateUtil.getPlusTime2(model.getCreateTime()));
+            model.setTotalNum(0);
+            ExcelImporter ie= new ExcelImporter(file,0,0, CellType.STRING); // 纭繚鍗曞厓鏍肩被鍨嬩负瀛楃涓�);
+            if(type == 1) {
+              model.setCaseList(ie.getDataList(CasesImport.class,null));
+              if(model.getCaseList() ==null || model.getCaseList().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());
+            }
+//            model.setPictureDataList(ie);
+            importRecordMapper.insert(model);
+            return model;
+        }catch (Exception e){
+            throw  new BusinessException(ResponseStatus.DATA_EMPTY.getCode(),"鏂囦欢淇℃伅璇诲彇澶辫触锛岃妫�鏌ユ枃浠跺唴瀹瑰悗閲嶈瘯锛�");
+        }finally {
+            redisTemplate.delete(Constants.RedisKeys.IMPORTING_RECORD);
+        }
+    }
+
+    /**
+     * 寮傛鎵ц鏂囦欢浠诲姟
+     * @param importRecord
+     */
+    @Override
+    @Async
+    public void dealImporTask(ImportRecord importRecord){
+        int success = 0;
+        if(Constants.equalsInteger(importRecord.getType(),0)){
+           dealUserImportBiz(importRecord);
+        }else{
+            dealCaseImportBiz(importRecord);
+        }
+        importRecord.setStatus(Constants.TWO);
+        importRecord.setUpdateTime(new Date());
+        importRecordMapper.updateById(importRecord);
+
+    }
+
+    /**
+     * 澶勭悊妗堜緥瀵煎叆浠诲姟
+     * @param importRecord
+     */
+
+    private int dealCaseImportBiz(ImportRecord importRecord) {
+        int success=0;
+        String msg ="";
+        try {
+            for(CasesImport param:importRecord.getCaseList()){
+
+            }
+        }catch (Exception e){
+
+        }
+        importRecord.setDoneNum(success);
+        importRecord.setErrorNum(importRecord.getTotalNum() - success);
+        return success;
+    }
+
+    /**
+     * 澶勭悊浜哄憳瀵煎叆璁板綍
+     * @param importRecord
+     */
+    private int dealUserImportBiz(ImportRecord importRecord) {
+        int success=0;
+        String msg = "";
+        try {
+            for(MemberImport param:importRecord.getMemberList()){
+
+            }
+        }catch (Exception e){
+
+        }
+        importRecord.setDoneNum(success);
+        importRecord.setErrorNum(importRecord.getTotalNum() - success);
+        importRecord.setDetail(msg);
+
+        return success;
+    }
 }
diff --git a/server/services/src/main/java/com/doumee/service/business/impl/MemberServiceImpl.java b/server/services/src/main/java/com/doumee/service/business/impl/MemberServiceImpl.java
index 1a1f3c0..3b7e90c 100644
--- a/server/services/src/main/java/com/doumee/service/business/impl/MemberServiceImpl.java
+++ b/server/services/src/main/java/com/doumee/service/business/impl/MemberServiceImpl.java
@@ -1,7 +1,12 @@
 package com.doumee.service.business.impl;
 
+import com.doumee.core.annotation.excel.ExcelImporter;
+import com.doumee.core.constants.ResponseStatus;
+import com.doumee.core.exception.BusinessException;
 import com.doumee.core.model.PageData;
 import com.doumee.core.model.PageWrap;
+import com.doumee.dao.business.ImportRecordMapper;
+import com.doumee.dao.business.dto.MemberImport;
 import com.doumee.dao.business.model.Member;
 import com.doumee.core.utils.Utils;
 import com.doumee.dao.business.MemberMapper;
@@ -10,11 +15,18 @@
 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.poi.ss.usermodel.CellType;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
+import org.springframework.web.multipart.MultipartFile;
 
+import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.TimeUnit;
 
 /**
  * 浼氬憳淇℃伅琛⊿ervice瀹炵幇
@@ -141,4 +153,6 @@
         QueryWrapper<Member> wrapper = new QueryWrapper<>(member);
         return memberMapper.selectCount(wrapper);
     }
+
+
 }

--
Gitblit v1.9.3