From 2d15fa034660d03a84c1d51928ab28b9219f16f8 Mon Sep 17 00:00:00 2001
From: jiangping <jp@doumee.com>
Date: 星期一, 30 六月 2025 09:42:04 +0800
Subject: [PATCH] 最新版本541200007

---
 server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/CompanyDocuments.java               |   91 +++++
 server/db/business.company_documents.permissions.sql                                                          |    6 
 server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/CompanyDocumentsServiceImpl.java |  158 +++++++++
 admin/src/components/common/uploadProgress.vue                                                                |  211 ++++++++++++
 admin/src/components/business/OperaCompanyDocumentsWindow.vue                                                 |   71 ++++
 admin/src/views/business/inoutRecord.vue                                                                      |    5 
 admin/src/api/business/companyDocuments.js                                                                    |   32 +
 server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/HiddenDangerParam.java              |    4 
 server/visits/dmvisit_service/src/main/java/com/doumee/service/business/CompanyDocumentsService.java          |  100 +++++
 server/visits/dmvisit_admin/src/main/java/com/doumee/api/business/CompanyDocumentsController.java             |   90 +++++
 server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/CompanyDocumentsMapper.java               |   12 
 admin/src/views/business/companyDocuments.vue                                                                 |  102 ++++++
 server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/CompanyDocumentsCloudController.java         |   93 +++++
 13 files changed, 970 insertions(+), 5 deletions(-)

diff --git a/admin/src/api/business/companyDocuments.js b/admin/src/api/business/companyDocuments.js
new file mode 100644
index 0000000..39b3cd6
--- /dev/null
+++ b/admin/src/api/business/companyDocuments.js
@@ -0,0 +1,32 @@
+import request from '../../utils/request'
+
+// 鏌ヨ
+export function fetchList (data) {
+  return request.post('/business/companyDocuments/page', data, {
+    trim: true
+  })
+}
+
+// 鍒涘缓
+export function create (data) {
+  return request.post('/business/companyDocuments/create', data)
+}
+
+// 淇敼
+export function updateById (data) {
+  return request.post('/business/companyDocuments/updateById', data)
+}
+
+// 鍒犻櫎
+export function deleteById (id) {
+  return request.get(`/business/companyDocuments/delete/${id}`)
+}
+
+// 鎵归噺鍒犻櫎
+export function deleteByIdInBatch (ids) {
+  return request.get('/business/companyDocuments/delete/batch', {
+    params: {
+      ids
+    }
+  })
+}
diff --git a/admin/src/components/business/OperaCompanyDocumentsWindow.vue b/admin/src/components/business/OperaCompanyDocumentsWindow.vue
new file mode 100644
index 0000000..7e70f3a
--- /dev/null
+++ b/admin/src/components/business/OperaCompanyDocumentsWindow.vue
@@ -0,0 +1,71 @@
+<template>
+  <GlobalWindow
+    :title="title"
+    :visible.sync="visible"
+    :confirm-working="isWorking"
+    @confirm="confirm"
+  >
+    <el-form :model="form" ref="form" :rules="rules">
+      <el-form-item label="璧勬枡鍚嶇О" prop="name">
+        <el-input v-model="form.name" placeholder="璇疯緭鍏ヨ祫鏂欏悕绉�" v-trim/>
+      </el-form-item>
+      <el-form-item label="璧勬枡绫诲瀷" prop="categoryId">
+        <el-input v-model="form.categoryId" placeholder="璇疯緭鍏ヨ矗浠婚儴闂ㄧ紪鐮�(鍏宠仈company)" v-trim/>
+      </el-form-item>
+      <el-form-item label="璐d换閮ㄩ棬" prop="companyId">
+        <el-input v-model="form.companyId" placeholder="璇疯緭鍏ヨ矗浠婚儴闂ㄧ紪鐮�(鍏宠仈company)" v-trim/>
+      </el-form-item>
+      <el-form-item label="鎺掑簭鐮�" prop="sortnum">
+        <el-input v-model="form.sortnum" placeholder="璇疯緭鍏ユ帓搴忕爜" v-trim/>
+      </el-form-item>
+      <el-form-item label="闄勪欢鍦板潃" prop="fileurl">
+        <el-input v-model="form.fileurl" placeholder="璇疯緭鍏ラ檮浠跺湴鍧�" v-trim/>
+      </el-form-item>
+      <el-form-item label="闄勪欢鎻忚堪" prop="content">
+        <el-input type="textarea" v-model="form.content" placeholder="璇疯緭鍏ラ檮浠舵弿杩�" v-trim/>
+      </el-form-item>
+    </el-form>
+  </GlobalWindow>
+</template>
+
+<script>
+import BaseOpera from '@/components/base/BaseOpera'
+import GlobalWindow from '@/components/common/GlobalWindow'
+export default {
+  name: 'OperaCompanyDocumentsWindow',
+  extends: BaseOpera,
+  components: { GlobalWindow },
+  data () {
+    return {
+      // 琛ㄥ崟鏁版嵁
+      form: {
+        id: null,
+        creator: '',
+        createDate: '',
+        editor: '',
+        editDate: '',
+        isdeleted: '',
+        name: '',
+        remark: '',
+        status: '',
+        sortnum: '',
+        fileurl: '',
+        fileName: '',
+        fileSize: '',
+        categoryId: '',
+        companyId: '',
+        content: ''
+      },
+      // 楠岃瘉瑙勫垯
+      rules: {
+      }
+    }
+  },
+  created () {
+    this.config({
+      api: '/business/companyDocuments',
+      'field.id': 'id'
+    })
+  }
+}
+</script>
diff --git a/admin/src/components/common/uploadProgress.vue b/admin/src/components/common/uploadProgress.vue
new file mode 100644
index 0000000..cb4bc39
--- /dev/null
+++ b/admin/src/components/common/uploadProgress.vue
@@ -0,0 +1,211 @@
+<template>
+    <div class="file">
+        <div class="file_list">
+            <div class="file_list_item" :style="{width: width, height: height}" v-for="(item, index) in list" :key="index">
+                <div class="dele" @click="deleItem(index)">
+                    <i class="el-icon-close"></i>
+                </div>
+                <img :src="item.url" v-if="fileType(item.url) === 'img'" />
+                <video controls autoplay :src="item.url" v-else></video>
+            </div>
+            <div class="file_list_item" :style="{width: width, height: height, cursor: 'pointer'}" @click="$refs.file.click()">
+                <i class="el-icon-plus"></i>
+            </div>
+        </div>
+        <div style="display: block;">
+          <input type="file" ref="file" :accept="accept" @change="getFile" />
+<!--          <progress id="progressBar" value="0" max="100" ></progress>-->
+<!--          <span id="status">0%</span>-->
+        </div>
+    </div>
+</template>
+
+<script>
+import axios from 'axios'
+export default {
+  props: {
+    width: {
+      type: String,
+      default: '90px'
+    },
+    height: {
+      type: String,
+      default: '90px'
+    },
+    list: {
+      type: Array,
+      // eslint-disable-next-line vue/require-valid-default-prop
+      default: []
+    },
+    accept: {
+      type: String,
+      default: ''
+    },
+    folder: {
+      type: String,
+      default: ''
+    }
+  },
+  data () {
+    return {
+      loading:null,
+      uuid: null,
+      timer: null,
+      message:'寮�濮嬩笂浼�',
+      uploadImgUrl: process.env.VUE_APP_API_PREFIX + '/public/upload',
+      uploadProgressUrl: process.env.VUE_APP_API_PREFIX + '/public'
+    }
+  },
+
+  methods: {
+    fileType (url) {
+      if (url.indexOf('.mp4') !== -1) {
+        return 'video'
+      } else {
+        return 'img'
+      }
+    },
+    getFile (e) {
+      if (e.target && e.target.files.length > 0) {
+        var that = this
+        const config = {
+          onUploadProgress: function (progressEvent) {
+            console.log(progressEvent)
+            const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total)
+            // document.getElementById('progressBar').value = percentCompleted
+            // document.getElementById('status').textContent = '鍑嗗' + percentCompleted + '%'
+            that.loading.setText('涓婁紶涓�� ' + percentCompleted + ' 銆�%')
+          },
+          headers: {
+            'Content-Type': 'multipart/form-data'
+          }
+        }
+        this.loading = this.$loading({
+          lock: true,
+          text: '涓婁紶涓紝璇风瓑寰�',
+          spinner: 'el-icon-loading',
+          customClass: 'loadingclz',
+          background: 'rgba(0, 0, 0, 0.7)'
+        })
+        this.$emit('loading')
+        const formdate = new FormData()
+        this.uuid = this.generateUUID().replaceAll('-', '')
+        formdate.append('file', e.target.files[0])
+        formdate.append('folder', this.folder)
+        formdate.append('uuid', this.uuid)
+        axios.post(this.uploadImgUrl, formdate, config)
+          .then(res => {
+            if(res.data.data == null || res.data.data.imgaddr == null){
+              this.$message.error('鏁版嵁涓婁紶澶辫触锛�')
+            }else{
+              this.$emit('success', res.data.data)
+            }
+          })
+          .catch(e => {
+            if(this.timer){
+              clearInterval(this.timer)
+            }
+            this.$message.error(e)
+          })
+          .finally(() => {
+            if(this.timer){
+              clearInterval(this.timer)
+            }
+            that.loading.close()
+            this.$refs.file.value = null
+          })
+        this.startProgress()
+      }
+    },
+    startProgress () {
+    },
+    generateUUID () {
+      return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
+        const r = (Math.random() * 16) | 0
+        const v = c === 'x' ? r : (r & 0x3) | 0x8
+        return v.toString(16)
+      })
+    },
+    deleItem (index) {
+      this.$emit('dele', index)
+    }
+  }
+}
+</script>
+<style>
+  .loadingclz {
+    .el-loading-text{
+      font-size: 18px  !important;
+      color: #2977f8 !important;
+    }
+   .el-loading-spinner i {
+      color: #2977f8 !important;
+    }
+  }
+</style>
+<style lang="scss" scoped>
+    .file {
+        /*width: 100%;*/
+        /*height: 90px;*/
+      padding: 10px;
+      box-sizing: border-box;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      position: relative;
+      margin-bottom: 10px;
+      /* margin-right: 20px; */
+       /* margin: 10px 0;*/
+        input {
+            opacity: 0;
+        }
+        .file_list {
+            width: 100%;
+            height: 100%;
+            display: flex;
+            align-items: center;
+            flex-wrap: wrap;
+            .file_list_item {
+                display: flex;
+                flex-direction: column;
+                align-items: center;
+                justify-content: center;
+                overflow: hidden;
+                border-radius: 5px;
+                border: 1px solid #d5d5d5;
+                margin-left: 15px;
+                position: relative;
+                &:first-child {
+                    margin: 0 !important;
+                }
+                .dele {
+                    position: absolute;
+                    right: 0;
+                    top: 0;
+                    width: 20px;
+                    height: 20px;
+                    background: red;
+                    display: flex;
+                    align-items: center;
+                    justify-content: center;
+                    cursor: pointer;
+                    .el-icon-close {
+                        color: #ffffff;
+                        font-size: 19px;
+                    }
+                }
+                .el-icon-plus {
+                    font-size: 30px;
+                    color: black;
+                }
+                img {
+                    width: 100%;
+                }
+                video {
+                    width: 100%;
+                    height: 100%;
+                }
+            }
+        }
+    }
+</style>
diff --git a/admin/src/views/business/companyDocuments.vue b/admin/src/views/business/companyDocuments.vue
new file mode 100644
index 0000000..9525c11
--- /dev/null
+++ b/admin/src/views/business/companyDocuments.vue
@@ -0,0 +1,102 @@
+<template>
+  <TableLayout :permissions="['business:companydocuments: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>
+      <el-form-item label="绠$悊閮ㄩ棬" prop="companyName">
+        <el-input v-model="searchForm.companyName" clearable placeholder="璇疯緭鍏ョ鐞嗛儴闂�" @keypress.enter.native="search"></el-input>
+      </el-form-item>
+      <el-form-item label="璧勬枡绫诲瀷" prop="categoryId">
+        <el-input v-model="searchForm.categoryId" clearable 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:companydocuments:create', 'business:companydocuments:delete']">
+        <li><el-button type="primary" @click="$refs.operaCompanyDocumentsWindow.open('鏂板璧勬枡')" icon="el-icon-plus" v-permissions="['business:companydocuments:create']">鏂板缓</el-button></li>
+        <li><el-button @click="deleteByIdInBatch" icon="el-icon-delete" v-permissions="['business:companydocuments:delete']">鍒犻櫎</el-button></li>
+      </ul>
+      <el-table
+        v-loading="isWorking.search"
+        :data="tableData.list"
+        stripe
+        @selection-change="handleSelectionChange"
+      >
+        <el-table-column type="selection" width="55"></el-table-column>
+        <el-table-column prop="name" label="璧勬枡鍚嶇О" min-width="150px"></el-table-column>
+        <el-table-column prop="categoryName" label="璧勬枡绫诲瀷" min-width="100px"></el-table-column>
+        <el-table-column prop="content" label="闄勪欢鎻忚堪" min-width="200px"></el-table-column>
+        <el-table-column prop="companyName" label="绠$悊閮ㄩ棬" min-width="150px"></el-table-column>
+        <el-table-column prop="sortnum" label="鎺掑簭鐮�(鍊掑簭)" min-width="100px"></el-table-column>
+        <el-table-column prop="createDate" label="鍒涘缓鏃堕棿" min-width="150px"></el-table-column>
+        <el-table-column prop="creatorName" label="鍒涘缓浜�" min-width="100px"></el-table-column>
+<!--    <el-table-column prop="fileName" label="闄勪欢鍚嶇О" min-width="100px"></el-table-column>
+        <el-table-column prop="fileSize" label="闄勪欢澶у皬" min-width="100px"></el-table-column>-->
+        <el-table-column
+          v-if="containPermissions(['business:companydocuments:update', 'business:companydocuments:delete'])"
+          label="鎿嶄綔"
+          min-width="120"
+          fixed="right"
+        >
+          <template slot-scope="{row}">
+            <el-button type="text" @click="$refs.operaCompanyDocumentsWindow.open('缂栬緫璧勬枡', row)" icon="el-icon-edit" v-permissions="['business:companydocuments:update']">缂栬緫</el-button>
+            <el-button type="text" v-if="row.fileurlFull" @click="download(row)" icon="el-icon-download" v-permissions="['business:companydocuments:download']">涓嬭浇</el-button>
+            <el-button type="text" @click="deleteById(row)" icon="el-icon-delete" v-permissions="['business:companydocuments:delete']">鍒犻櫎</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination
+        @size-change="handleSizeChange"
+        @current-change="handlePageChange"
+        :pagination="tableData.pagination"
+      >
+      </pagination>
+    </template>
+    <!-- 鏂板缓/淇敼 -->
+    <OperaCompanyDocumentsWindow ref="operaCompanyDocumentsWindow" @success="handlePageChange"/>
+  </TableLayout>
+</template>
+
+<script>
+import BaseTable from '@/components/base/BaseTable'
+import TableLayout from '@/layouts/TableLayout'
+import Pagination from '@/components/common/Pagination'
+import OperaCompanyDocumentsWindow from '@/components/business/OperaCompanyDocumentsWindow'
+export default {
+  name: 'CompanyDocuments',
+  extends: BaseTable,
+  components: { TableLayout, Pagination, OperaCompanyDocumentsWindow },
+  data () {
+    return {
+      // 鎼滅储
+      searchForm: {
+        name: '',
+        categoryId: '',
+        companyId: ''
+      }
+    }
+  },
+  created () {
+    this.config({
+      module: '璧勬枡绠$悊',
+      api: '/business/companyDocuments',
+      'field.id': 'id',
+      'field.main': 'id'
+    })
+    this.search()
+  },
+  methods:{
+    download(row){
+      if(row.fileurlFull){
+        window.open(row.fileurlFull)
+      }
+    }
+  }
+}
+</script>
diff --git a/admin/src/views/business/inoutRecord.vue b/admin/src/views/business/inoutRecord.vue
index c976ee6..6b0c029 100644
--- a/admin/src/views/business/inoutRecord.vue
+++ b/admin/src/views/business/inoutRecord.vue
@@ -68,8 +68,7 @@
                      @click="exportExcel">瀵煎嚭</el-button>
         </li>
       </ul>
-      <el-table
-          :height="tableHeightNew"
+      <el-table :height="tableHeightNew+10"
         v-loading="isWorking.search"
         :data="tableData.list"
         stripe
@@ -141,7 +140,7 @@
 export default {
   name: 'InoutRecord',
   extends: BaseTable,
-  components: {  TableLayout, Pagination, OperaInoutRecordWindow },
+  components: { TableLayout, Pagination, OperaInoutRecordWindow },
   data () {
     return {
       // 鎼滅储
diff --git a/server/db/business.company_documents.permissions.sql b/server/db/business.company_documents.permissions.sql
new file mode 100644
index 0000000..ccc3ff1
--- /dev/null
+++ b/server/db/business.company_documents.permissions.sql
@@ -0,0 +1,6 @@
+INSERT INTO `SYSTEM_PERMISSION`(`CODE`, `NAME`, `REMARK`, `FIXED`, `CREATE_USER`, `CREATE_TIME`, `UPDATE_USER`, `UPDATE_TIME`, `DELETED`) VALUES ('business:companydocuments:create', '鏂板缓闅愭偅鍖哄煙閰嶇疆绫诲瀷淇℃伅琛�', '', 0, 1, CURRENT_TIMESTAMP, NULL, NULL, 0);
+INSERT INTO `SYSTEM_PERMISSION`(`CODE`, `NAME`, `REMARK`, `FIXED`, `CREATE_USER`, `CREATE_TIME`, `UPDATE_USER`, `UPDATE_TIME`, `DELETED`) VALUES ('business:companydocuments:delete', '鍒犻櫎闅愭偅鍖哄煙閰嶇疆绫诲瀷淇℃伅琛�', '', 0, 1, CURRENT_TIMESTAMP, NULL, NULL, 0);
+INSERT INTO `SYSTEM_PERMISSION`(`CODE`, `NAME`, `REMARK`, `FIXED`, `CREATE_USER`, `CREATE_TIME`, `UPDATE_USER`, `UPDATE_TIME`, `DELETED`) VALUES ('business:companydocuments:update', '淇敼闅愭偅鍖哄煙閰嶇疆绫诲瀷淇℃伅琛�', '', 0, 1, CURRENT_TIMESTAMP, NULL, NULL, 0);
+INSERT INTO `SYSTEM_PERMISSION`(`CODE`, `NAME`, `REMARK`, `FIXED`, `CREATE_USER`, `CREATE_TIME`, `UPDATE_USER`, `UPDATE_TIME`, `DELETED`) VALUES ('business:companydocuments:query', '鏌ヨ闅愭偅鍖哄煙閰嶇疆绫诲瀷淇℃伅琛�', '', 0, 1, CURRENT_TIMESTAMP, NULL, NULL, 0);
+INSERT INTO `SYSTEM_PERMISSION`(`CODE`, `NAME`, `REMARK`, `FIXED`, `CREATE_USER`, `CREATE_TIME`, `UPDATE_USER`, `UPDATE_TIME`, `DELETED`) VALUES ('business:companydocuments:exportExcel', '瀵煎嚭闅愭偅鍖哄煙閰嶇疆绫诲瀷淇℃伅琛�(Excel)', '', 0, 1, CURRENT_TIMESTAMP, NULL, NULL, 0);
+
diff --git a/server/visits/dmvisit_admin/src/main/java/com/doumee/api/business/CompanyDocumentsController.java b/server/visits/dmvisit_admin/src/main/java/com/doumee/api/business/CompanyDocumentsController.java
new file mode 100644
index 0000000..08c2e9a
--- /dev/null
+++ b/server/visits/dmvisit_admin/src/main/java/com/doumee/api/business/CompanyDocumentsController.java
@@ -0,0 +1,90 @@
+package com.doumee.api.business;
+
+import com.doumee.api.BaseController;
+import com.doumee.core.annotation.excel.ExcelExporter;
+import com.doumee.core.annotation.pr.PreventRepeat;
+import com.doumee.dao.business.model.CompanyDocuments;
+import com.doumee.service.business.CompanyDocumentsService;
+import com.doumee.service.business.third.model.ApiResponse;
+import com.doumee.service.business.third.model.PageData;
+import com.doumee.service.business.third.model.PageWrap;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+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 java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author 姹熻箘韫�
+ * @date 2025/06/27 16:01
+ */
+@Api(tags = "闅愭偅鍖哄煙閰嶇疆绫诲瀷淇℃伅琛�")
+@RestController
+@RequestMapping("/business/companyDocuments")
+public class CompanyDocumentsController extends BaseController {
+
+    @Autowired
+    private CompanyDocumentsService companyDocumentsService;
+
+    @PreventRepeat
+    @ApiOperation("鏂板缓")
+    @PostMapping("/create")
+    @RequiresPermissions("business:companydocuments:create")
+    public ApiResponse create(@RequestBody CompanyDocuments companyDocuments) {
+        return ApiResponse.success(companyDocumentsService.create(companyDocuments));
+    }
+
+    @ApiOperation("鏍规嵁ID鍒犻櫎")
+    @GetMapping("/delete/{id}")
+    @RequiresPermissions("business:companydocuments:delete")
+    public ApiResponse deleteById(@PathVariable Integer id) {
+        companyDocumentsService.deleteById(id,this.getLoginUser(null));
+        return ApiResponse.success(null);
+    }
+
+    @ApiOperation("鎵归噺鍒犻櫎")
+    @GetMapping("/delete/batch")
+    @RequiresPermissions("business:companydocuments:delete")
+    public ApiResponse deleteByIdInBatch(@RequestParam String ids) {
+        String [] idArray = ids.split(",");
+        List<Integer> idList = new ArrayList<>();
+        for (String id : idArray) {
+            idList.add(Integer.valueOf(id));
+        }
+        companyDocumentsService.deleteByIdInBatch(idList,this.getLoginUser(null));
+        return ApiResponse.success(null);
+    }
+
+    @ApiOperation("鏍规嵁ID淇敼")
+    @PostMapping("/updateById")
+    @RequiresPermissions("business:companydocuments:update")
+    public ApiResponse updateById(@RequestBody CompanyDocuments companyDocuments) {
+        companyDocumentsService.updateById(companyDocuments);
+        return ApiResponse.success(null);
+    }
+
+    @ApiOperation("鍒嗛〉鏌ヨ")
+    @PostMapping("/page")
+    @RequiresPermissions("business:companydocuments:query")
+    public ApiResponse<PageData<CompanyDocuments>> findPage (@RequestBody PageWrap<CompanyDocuments> pageWrap) {
+        return ApiResponse.success(companyDocumentsService.findPage(pageWrap));
+    }
+
+    @ApiOperation("瀵煎嚭Excel")
+    @PostMapping("/exportExcel")
+    @RequiresPermissions("business:companydocuments:exportExcel")
+    public void exportExcel (@RequestBody PageWrap<CompanyDocuments> pageWrap, HttpServletResponse response) {
+        ExcelExporter.build(CompanyDocuments.class).export(companyDocumentsService.findPage(pageWrap).getRecords(), "闅愭偅鍖哄煙閰嶇疆绫诲瀷淇℃伅琛�", response);
+    }
+
+    @ApiOperation("鏍规嵁ID鏌ヨ")
+    @GetMapping("/{id}")
+    @RequiresPermissions("business:companydocuments:query")
+    public ApiResponse findById(@PathVariable Integer id) {
+        return ApiResponse.success(companyDocumentsService.findById(id));
+    }
+}
diff --git a/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/CompanyDocumentsCloudController.java b/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/CompanyDocumentsCloudController.java
new file mode 100644
index 0000000..b0094e4
--- /dev/null
+++ b/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/CompanyDocumentsCloudController.java
@@ -0,0 +1,93 @@
+package com.doumee.cloud.admin;
+
+import com.doumee.api.BaseController;
+import com.doumee.config.annotation.CloudRequiredPermission;
+import com.doumee.core.annotation.excel.ExcelExporter;
+import com.doumee.core.annotation.pr.PreventRepeat;
+import com.doumee.core.utils.Constants;
+import com.doumee.dao.business.model.CompanyDocuments;
+import com.doumee.service.business.CompanyDocumentsService;
+import com.doumee.service.business.third.model.ApiResponse;
+import com.doumee.service.business.third.model.PageData;
+import com.doumee.service.business.third.model.PageWrap;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author 姹熻箘韫�
+ * @date 2025/06/27 16:01
+ */
+@Api(tags = "闅愭偅鍖哄煙閰嶇疆绫诲瀷淇℃伅琛�")
+@RestController
+@RequestMapping(Constants.CLOUD_SERVICE_URL_INDEX+"/business/companyDocuments")
+public class CompanyDocumentsCloudController extends BaseController {
+
+    @Autowired
+    private CompanyDocumentsService companyDocumentsService;
+
+    @PreventRepeat
+    @ApiOperation("鏂板缓")
+    @PostMapping("/create")
+    @CloudRequiredPermission("business:companydocuments:create")
+    public ApiResponse create(@RequestHeader(Constants.HEADER_USER_TOKEN) String token,@RequestBody CompanyDocuments companyDocuments) {
+        companyDocuments.setLoginUserInfo(this.getLoginUser(token));
+        return ApiResponse.success(companyDocumentsService.create(companyDocuments));
+    }
+
+    @ApiOperation("鏍规嵁ID鍒犻櫎")
+    @GetMapping("/delete/{id}")
+    @CloudRequiredPermission("business:companydocuments:delete")
+    public ApiResponse deleteById(@RequestHeader(Constants.HEADER_USER_TOKEN) String token,@PathVariable Integer id) {
+        companyDocumentsService.deleteById(id,this.getLoginUser(token));
+        return ApiResponse.success(null);
+    }
+
+    @ApiOperation("鎵归噺鍒犻櫎")
+    @GetMapping("/delete/batch")
+    @CloudRequiredPermission("business:companydocuments:delete")
+    public ApiResponse deleteByIdInBatch(@RequestHeader(Constants.HEADER_USER_TOKEN) String token,@RequestParam String ids) {
+        String [] idArray = ids.split(",");
+        List<Integer> idList = new ArrayList<>();
+        for (String id : idArray) {
+            idList.add(Integer.valueOf(id));
+        }
+        companyDocumentsService.deleteByIdInBatch(idList,this.getLoginUser(token));
+        return ApiResponse.success(null);
+    }
+
+    @ApiOperation("鏍规嵁ID淇敼")
+    @PostMapping("/updateById")
+    @CloudRequiredPermission("business:companydocuments:update")
+    public ApiResponse updateById(@RequestHeader(Constants.HEADER_USER_TOKEN) String token,@RequestBody CompanyDocuments companyDocuments) {
+        companyDocuments.setLoginUserInfo(this.getLoginUser(token));
+        companyDocumentsService.updateById(companyDocuments);
+        return ApiResponse.success(null);
+    }
+
+    @ApiOperation("鍒嗛〉鏌ヨ")
+    @PostMapping("/page")
+    @CloudRequiredPermission("business:companydocuments:query")
+    public ApiResponse<PageData<CompanyDocuments>> findPage (@RequestHeader(Constants.HEADER_USER_TOKEN) String token,@RequestBody PageWrap<CompanyDocuments> pageWrap) {
+        return ApiResponse.success(companyDocumentsService.findPage(pageWrap));
+    }
+
+    @ApiOperation("瀵煎嚭Excel")
+    @PostMapping("/exportExcel")
+    @CloudRequiredPermission("business:companydocuments:exportExcel")
+    public void exportExcel (@RequestHeader(Constants.HEADER_USER_TOKEN) String token,@RequestBody PageWrap<CompanyDocuments> pageWrap, HttpServletResponse response) {
+        ExcelExporter.build(CompanyDocuments.class).export(companyDocumentsService.findPage(pageWrap).getRecords(), "闅愭偅鍖哄煙閰嶇疆绫诲瀷淇℃伅琛�", response);
+    }
+
+    @ApiOperation("鏍规嵁ID鏌ヨ")
+    @GetMapping("/{id}")
+    @CloudRequiredPermission("business:companydocuments:query")
+    public ApiResponse findById(@RequestHeader(Constants.HEADER_USER_TOKEN) String token,@PathVariable Integer id) {
+        return ApiResponse.success(companyDocumentsService.findById(id));
+    }
+}
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/CompanyDocumentsMapper.java b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/CompanyDocumentsMapper.java
new file mode 100644
index 0000000..6034e25
--- /dev/null
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/CompanyDocumentsMapper.java
@@ -0,0 +1,12 @@
+package com.doumee.dao.business;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.doumee.dao.business.model.CompanyDocuments;
+
+/**
+ * @author 姹熻箘韫�
+ * @date 2025/06/27 16:01
+ */
+public interface CompanyDocumentsMapper extends BaseMapper<CompanyDocuments> {
+
+}
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/CompanyDocuments.java b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/CompanyDocuments.java
new file mode 100644
index 0000000..d810f29
--- /dev/null
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/CompanyDocuments.java
@@ -0,0 +1,91 @@
+package com.doumee.dao.business.model;
+
+import com.doumee.core.annotation.excel.ExcelColumn;
+import com.doumee.service.business.third.model.LoginUserModel;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import java.util.Date;
+
+/**
+ * 闅愭偅鍖哄煙閰嶇疆绫诲瀷淇℃伅琛�
+ * @author 姹熻箘韫�
+ * @date 2025/06/27 16:01
+ */
+@Data
+@ApiModel("闅愭偅鍖哄煙閰嶇疆绫诲瀷淇℃伅琛�")
+@TableName("`company_documents`")
+public class CompanyDocuments  extends LoginUserModel {
+
+    @TableId(type = IdType.AUTO)
+    @ApiModelProperty(value = "涓婚敭", example = "1")
+    @ExcelColumn(name="涓婚敭")
+    private Integer id;
+
+    @ApiModelProperty(value = "鍒涘缓浜虹紪鐮�", example = "1")
+    @ExcelColumn(name="鍒涘缓浜虹紪鐮�")
+    private Integer creator;
+
+    @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+    @ExcelColumn(name="鍒涘缓鏃堕棿")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private Date createDate;
+
+    @ApiModelProperty(value = "鏇存柊浜虹紪鐮�", example = "1")
+    @ExcelColumn(name="鏇存柊浜虹紪鐮�")
+    private Integer editor;
+
+    @ApiModelProperty(value = "鏇存柊鏃堕棿")
+    @ExcelColumn(name="鏇存柊鏃堕棿")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private Date editDate;
+
+    @ApiModelProperty(value = "鏄惁鍒犻櫎0鍚� 1鏄�", example = "1")
+    @ExcelColumn(name="鏄惁鍒犻櫎0鍚� 1鏄�")
+    private Integer isdeleted;
+
+    @ApiModelProperty(value = "鍚嶇О")
+    @ExcelColumn(name="鍚嶇О")
+    private String name;
+
+    @ApiModelProperty(value = "澶囨敞")
+    @ExcelColumn(name="澶囨敞")
+    private String remark;
+
+    @ApiModelProperty(value = "鐘舵�� 0鍚敤 1绂佺敤", example = "1")
+    @ExcelColumn(name="鐘舵�� 0鍚敤 1绂佺敤")
+    private Integer status;
+
+    @ApiModelProperty(value = "鎺掑簭鐮�", example = "1")
+    @ExcelColumn(name="鎺掑簭鐮�")
+    private Integer sortnum;
+
+    @ApiModelProperty(value = "闄勪欢鍦板潃")
+    @ExcelColumn(name="闄勪欢鍦板潃")
+    private String fileurl;
+
+    @ApiModelProperty(value = "闄勪欢鍚嶇О")
+    @ExcelColumn(name="闄勪欢鍚嶇О")
+    private String fileName;
+
+    @ApiModelProperty(value = "闄勪欢澶у皬锛坆ytes)", example = "1")
+    @ExcelColumn(name="闄勪欢澶у皬锛坆ytes)")
+    private Long fileSize;
+
+    @ApiModelProperty(value = "鍒嗙被缂栫爜锛堝叧鑱攃ategory锛�", example = "1")
+    @ExcelColumn(name="鍒嗙被缂栫爜锛堝叧鑱攃ategory锛�")
+    private Integer categoryId;
+
+    @ApiModelProperty(value = "璐d换閮ㄩ棬缂栫爜(鍏宠仈company)", example = "1")
+    @ExcelColumn(name="璐d换閮ㄩ棬缂栫爜(鍏宠仈company)")
+    private Integer companyId;
+
+    @ApiModelProperty(value = "闄勪欢鎻忚堪")
+    @ExcelColumn(name="闄勪欢鎻忚堪")
+    private String content;
+
+}
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/HiddenDangerParam.java b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/HiddenDangerParam.java
index 2bc7807..06d20a5 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/HiddenDangerParam.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/HiddenDangerParam.java
@@ -76,8 +76,8 @@
     @ExcelColumn(name="瀹夊叏鍛樺鍚嶉泦鍚堬紝澶氫釜鑻辨枃閫楀彿闅斿紑")
     private String memberNames;
 
-    @ApiModelProperty(value = "绫诲瀷 0闅愭偅鍖哄煙 1闅愭偅绫诲瀷", example = "1")
-    @ExcelColumn(name="绫诲瀷 0闅愭偅鍖哄煙 1闅愭偅绫诲瀷")
+    @ApiModelProperty(value = "绫诲瀷 0闅愭偅鍖哄煙 1闅愭偅绫诲瀷 2妫�鏌ョ被鍨�", example = "1")
+    @ExcelColumn(name="绫诲瀷 0闅愭偅鍖哄煙 1闅愭偅绫诲瀷  2妫�鏌ョ被鍨�")
     private Integer type;
     @ApiModelProperty(value = "鐢ㄦ埛缂栫爜闆嗗悎", example = "1")
     @TableField(exist = false)
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/CompanyDocumentsService.java b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/CompanyDocumentsService.java
new file mode 100644
index 0000000..0b38154
--- /dev/null
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/CompanyDocumentsService.java
@@ -0,0 +1,100 @@
+package com.doumee.service.business;
+
+import com.doumee.dao.business.model.CompanyDocuments;
+import com.doumee.service.business.third.model.LoginUserInfo;
+import com.doumee.service.business.third.model.LoginUserModel;
+import com.doumee.service.business.third.model.PageData;
+import com.doumee.service.business.third.model.PageWrap;
+
+import java.util.List;
+
+/**
+ * 闅愭偅鍖哄煙閰嶇疆绫诲瀷淇℃伅琛⊿ervice瀹氫箟
+ * @author 姹熻箘韫�
+ * @date 2025/06/27 16:01
+ */
+public interface CompanyDocumentsService {
+
+    /**
+     * 鍒涘缓
+     * 
+     * @param companyDocuments 瀹炰綋瀵硅薄
+     * @return Integer
+     */
+    Integer create(CompanyDocuments companyDocuments);
+
+    /**
+     * 涓婚敭鍒犻櫎
+     *
+     * @param id 涓婚敭
+     */
+    void deleteById(Integer id, LoginUserInfo user);
+
+    /**
+     * 鍒犻櫎
+     *
+     * @param companyDocuments 瀹炰綋瀵硅薄
+     */
+    void delete(CompanyDocuments companyDocuments);
+
+    /**
+     * 鎵归噺涓婚敭鍒犻櫎
+     *
+     * @param ids 涓婚敭闆�
+     */
+    void deleteByIdInBatch(List<Integer> ids, LoginUserInfo user);
+
+    /**
+     * 涓婚敭鏇存柊
+     *
+     * @param companyDocuments 瀹炰綋瀵硅薄
+     */
+    void updateById(CompanyDocuments companyDocuments);
+
+    /**
+     * 鎵归噺涓婚敭鏇存柊
+     *
+     * @param companyDocumentss 瀹炰綋闆�
+     */
+    void updateByIdInBatch(List<CompanyDocuments> companyDocumentss);
+
+    /**
+     * 涓婚敭鏌ヨ
+     *
+     * @param id 涓婚敭
+     * @return CompanyDocuments
+     */
+    CompanyDocuments findById(Integer id);
+
+    /**
+     * 鏉′欢鏌ヨ鍗曟潯璁板綍
+     *
+     * @param companyDocuments 瀹炰綋瀵硅薄
+     * @return CompanyDocuments
+     */
+    CompanyDocuments findOne(CompanyDocuments companyDocuments);
+
+    /**
+     * 鏉′欢鏌ヨ
+     *
+     * @param companyDocuments 瀹炰綋瀵硅薄
+     * @return List<CompanyDocuments>
+     */
+    List<CompanyDocuments> findList(CompanyDocuments companyDocuments);
+  
+    /**
+     * 鍒嗛〉鏌ヨ
+     *
+     * @param pageWrap 鍒嗛〉瀵硅薄
+     * @return PageData<CompanyDocuments>
+     */
+    PageData<CompanyDocuments> findPage(PageWrap<CompanyDocuments> pageWrap);
+
+    /**
+     * 鏉′欢缁熻
+     *
+     * @param companyDocuments 瀹炰綋瀵硅薄
+     * @return long
+     */
+    long count(CompanyDocuments companyDocuments);
+}
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/CompanyDocumentsServiceImpl.java b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/CompanyDocumentsServiceImpl.java
new file mode 100644
index 0000000..33712c1
--- /dev/null
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/CompanyDocumentsServiceImpl.java
@@ -0,0 +1,158 @@
+package com.doumee.service.business.impl;
+
+import com.doumee.core.utils.Utils;
+import com.doumee.dao.business.CompanyDocumentsMapper;
+import com.doumee.dao.business.model.CompanyDocuments;
+import com.doumee.service.business.CompanyDocumentsService;
+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.doumee.service.business.third.model.LoginUserInfo;
+import com.doumee.service.business.third.model.PageData;
+import com.doumee.service.business.third.model.PageWrap;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.util.List;
+
+/**
+ * 闅愭偅鍖哄煙閰嶇疆绫诲瀷淇℃伅琛⊿ervice瀹炵幇
+ * @author 姹熻箘韫�
+ * @date 2025/06/27 16:01
+ */
+@Service
+public class CompanyDocumentsServiceImpl implements CompanyDocumentsService {
+
+    @Autowired
+    private CompanyDocumentsMapper companyDocumentsMapper;
+
+    @Override
+    public Integer create(CompanyDocuments companyDocuments) {
+        companyDocumentsMapper.insert(companyDocuments);
+        return companyDocuments.getId();
+    }
+
+    @Override
+    public void deleteById(Integer id, LoginUserInfo user) {
+        companyDocumentsMapper.deleteById(id);
+    }
+
+    @Override
+    public void delete(CompanyDocuments companyDocuments) {
+        UpdateWrapper<CompanyDocuments> deleteWrapper = new UpdateWrapper<>(companyDocuments);
+        companyDocumentsMapper.delete(deleteWrapper);
+    }
+
+    @Override
+    public void deleteByIdInBatch(List<Integer> ids, LoginUserInfo user) {
+        if (CollectionUtils.isEmpty(ids)) {
+            return;
+        }
+        companyDocumentsMapper.deleteBatchIds(ids);
+    }
+
+    @Override
+    public void updateById(CompanyDocuments companyDocuments) {
+        companyDocumentsMapper.updateById(companyDocuments);
+    }
+
+    @Override
+    public void updateByIdInBatch(List<CompanyDocuments> companyDocumentss) {
+        if (CollectionUtils.isEmpty(companyDocumentss)) {
+            return;
+        }
+        for (CompanyDocuments companyDocuments: companyDocumentss) {
+            this.updateById(companyDocuments);
+        }
+    }
+
+    @Override
+    public CompanyDocuments findById(Integer id) {
+        return companyDocumentsMapper.selectById(id);
+    }
+
+    @Override
+    public CompanyDocuments findOne(CompanyDocuments companyDocuments) {
+        QueryWrapper<CompanyDocuments> wrapper = new QueryWrapper<>(companyDocuments);
+        return companyDocumentsMapper.selectOne(wrapper);
+    }
+
+    @Override
+    public List<CompanyDocuments> findList(CompanyDocuments companyDocuments) {
+        QueryWrapper<CompanyDocuments> wrapper = new QueryWrapper<>(companyDocuments);
+        return companyDocumentsMapper.selectList(wrapper);
+    }
+  
+    @Override
+    public PageData<CompanyDocuments> findPage(PageWrap<CompanyDocuments> pageWrap) {
+        IPage<CompanyDocuments> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
+        QueryWrapper<CompanyDocuments> queryWrapper = new QueryWrapper<>();
+        Utils.MP.blankToNull(pageWrap.getModel());
+        if (pageWrap.getModel().getId() != null) {
+            queryWrapper.lambda().eq(CompanyDocuments::getId, pageWrap.getModel().getId());
+        }
+        if (pageWrap.getModel().getCreator() != null) {
+            queryWrapper.lambda().eq(CompanyDocuments::getCreator, pageWrap.getModel().getCreator());
+        }
+        if (pageWrap.getModel().getCreateDate() != null) {
+            queryWrapper.lambda().ge(CompanyDocuments::getCreateDate, Utils.Date.getStart(pageWrap.getModel().getCreateDate()));
+            queryWrapper.lambda().le(CompanyDocuments::getCreateDate, Utils.Date.getEnd(pageWrap.getModel().getCreateDate()));
+        }
+        if (pageWrap.getModel().getEditor() != null) {
+            queryWrapper.lambda().eq(CompanyDocuments::getEditor, pageWrap.getModel().getEditor());
+        }
+        if (pageWrap.getModel().getEditDate() != null) {
+            queryWrapper.lambda().ge(CompanyDocuments::getEditDate, Utils.Date.getStart(pageWrap.getModel().getEditDate()));
+            queryWrapper.lambda().le(CompanyDocuments::getEditDate, Utils.Date.getEnd(pageWrap.getModel().getEditDate()));
+        }
+        if (pageWrap.getModel().getIsdeleted() != null) {
+            queryWrapper.lambda().eq(CompanyDocuments::getIsdeleted, pageWrap.getModel().getIsdeleted());
+        }
+        if (pageWrap.getModel().getName() != null) {
+            queryWrapper.lambda().eq(CompanyDocuments::getName, pageWrap.getModel().getName());
+        }
+        if (pageWrap.getModel().getRemark() != null) {
+            queryWrapper.lambda().eq(CompanyDocuments::getRemark, pageWrap.getModel().getRemark());
+        }
+        if (pageWrap.getModel().getStatus() != null) {
+            queryWrapper.lambda().eq(CompanyDocuments::getStatus, pageWrap.getModel().getStatus());
+        }
+        if (pageWrap.getModel().getSortnum() != null) {
+            queryWrapper.lambda().eq(CompanyDocuments::getSortnum, pageWrap.getModel().getSortnum());
+        }
+        if (pageWrap.getModel().getFileurl() != null) {
+            queryWrapper.lambda().eq(CompanyDocuments::getFileurl, pageWrap.getModel().getFileurl());
+        }
+        if (pageWrap.getModel().getFileName() != null) {
+            queryWrapper.lambda().eq(CompanyDocuments::getFileName, pageWrap.getModel().getFileName());
+        }
+        if (pageWrap.getModel().getFileSize() != null) {
+            queryWrapper.lambda().eq(CompanyDocuments::getFileSize, pageWrap.getModel().getFileSize());
+        }
+        if (pageWrap.getModel().getCategoryId() != null) {
+            queryWrapper.lambda().eq(CompanyDocuments::getCategoryId, pageWrap.getModel().getCategoryId());
+        }
+        if (pageWrap.getModel().getCompanyId() != null) {
+            queryWrapper.lambda().eq(CompanyDocuments::getCompanyId, pageWrap.getModel().getCompanyId());
+        }
+        if (pageWrap.getModel().getContent() != null) {
+            queryWrapper.lambda().eq(CompanyDocuments::getContent, pageWrap.getModel().getContent());
+        }
+        for(PageWrap.SortData sortData: pageWrap.getSorts()) {
+            if (sortData.getDirection().equalsIgnoreCase(PageWrap.DESC)) {
+                queryWrapper.orderByDesc(sortData.getProperty());
+            } else {
+                queryWrapper.orderByAsc(sortData.getProperty());
+            }
+        }
+        return PageData.from(companyDocumentsMapper.selectPage(page, queryWrapper));
+    }
+
+    @Override
+    public long count(CompanyDocuments companyDocuments) {
+        QueryWrapper<CompanyDocuments> wrapper = new QueryWrapper<>(companyDocuments);
+        return companyDocumentsMapper.selectCount(wrapper);
+    }
+}

--
Gitblit v1.9.3