Browse Source

图片base64存储至数据库,模版保存本地,log导出xls,文件下载接口,安保人员接口

zhangnaiwen 2 years ago
parent
commit
2c2c1fbde5

+ 1 - 20
config/config.yml

@@ -4,26 +4,7 @@ common:
   MESSAGR_TYPE: ["普通消息","提醒消息"]
   MESSAGR_TYPE: ["普通消息","提醒消息"]
   INFORMATION_TYPE: ["楼层地图信息配置", "安保人员信息配置"]
   INFORMATION_TYPE: ["楼层地图信息配置", "安保人员信息配置"]
 
 
-  # 设备Excel存醋位置
-  DEVICE_EXCEL_SAVE_PATH: /data/device
-  # 公司商标存储地址
-  COMPANY_LOGO_PATH: /data/company_logo
-  COMPANY_LOGO_URL: http://127.0.0.1/company_logo/
-  # 模版存储地址
-  TEMPLATE_FILE_PATH: /data/template
-  TEMPLATE_FILE_URL: http://127.0.0.1/template/
-  # 楼层地图信息配置附件存醋位置
-  FLOOR_CONFIGURATION_PATH: /data/floor_configuration
-  FLOOR_CONFIGURATION_URL: http://127.0.0.1/floor_configuration/
-  # 公司图片存醋地址
-  COMPANY_PICTURE_PATH: /data/company
-  COMPANY_PICTURE_URL: http://127.0.0.1/company/
-  # 楼宇图片存醋地址
-  BUILDING_PICTURE_PATH: /data/building
-  BUILDING_PICTURE_URL: http://127.0.0.1/building/
-  # 底层系统信息图片存醋地址
-  UNDERLYING_SYSTEM_PICTURE_PATH: /data/underlying_system
-  UNDERLYING_SYSTEM_PICTURE_URL: http://127.0.0.1/underlying_system/
+  SAVE_FILE_PATH: /Users/mac/data/files
 
 
 RabbitMq:
 RabbitMq:
   HOST: 8.130.177.22 # ip地址
   HOST: 8.130.177.22 # ip地址

+ 1 - 5
docker-compose-v3.yml

@@ -19,11 +19,7 @@ services:
 
 
       volumes:
       volumes:
         - /data/logs:/data/logs # 日志
         - /data/logs:/data/logs # 日志
-        - /data/company_logo:/data/company_logo  # 公司商标存储地址
-        - /data/template:/data/template  # 模版存储地址
-        - /data/company:/data/company  # 公司图片存醋地址
-        - /data/building:/data/building  # 楼宇图片存醋地址
-        - /data/underlying_system:/data/underlying_system  # 底层系统信息图片存醋地址
+        - /data/files:/data/files
         - ./config:/work/operation_management_center/config  # 配置文件目录,包括软件配置信息
         - ./config:/work/operation_management_center/config  # 配置文件目录,包括软件配置信息
 
 
       privileged: true
       privileged: true

+ 1 - 5
docker-compose.yml

@@ -17,11 +17,7 @@ service:
 
 
   volumes:
   volumes:
     - /data/logs:/data/logs # 日志
     - /data/logs:/data/logs # 日志
-    - /data/company_logo:/data/company_logo  # 公司商标存储地址
-    - /data/template:/data/template  # 模版存储地址
-    - /data/company:/data/company  # 公司图片存醋地址
-    - /data/building:/data/building  # 楼宇图片存醋地址
-    - /data/underlying_system:/data/underlying_system  # 底层系统信息图片存醋地址
+    - /data/files:/data/files # 文件保存地址
     - ./config:/work/operation_management_center/config  # 配置文件目录,包括软件配置信息
     - ./config:/work/operation_management_center/config  # 配置文件目录,包括软件配置信息
 
 
 
 

+ 3 - 0
requirements.txt

@@ -4,6 +4,7 @@ attrs==22.2.0
 cffi==1.15.1
 cffi==1.15.1
 click==8.1.3
 click==8.1.3
 cryptography==39.0.2
 cryptography==39.0.2
+et-xmlfile==1.1.0
 Flask==2.2.3
 Flask==2.2.3
 Flask-APScheduler==1.12.4
 Flask-APScheduler==1.12.4
 Flask-Cors==3.0.10
 Flask-Cors==3.0.10
@@ -29,3 +30,5 @@ typing_extensions==4.5.0
 tzdata==2022.7
 tzdata==2022.7
 tzlocal==4.3
 tzlocal==4.3
 Werkzeug==2.2.3
 Werkzeug==2.2.3
+xlrd==2.0.1
+xlwt==1.3.0

+ 2 - 0
src/app/api/__init__.py

@@ -10,6 +10,7 @@ from app.api.message import ns as message
 from app.api.permission import ns as permission
 from app.api.permission import ns as permission
 from app.api.information import ns as information
 from app.api.information import ns as information
 from app.api.device import ns as device
 from app.api.device import ns as device
+from app.api.download import ns as download
 
 
 api = Api(version='v1.0', title='operation_management_center', description='运营管理中心', doc='/api')
 api = Api(version='v1.0', title='operation_management_center', description='运营管理中心', doc='/api')
 
 
@@ -23,3 +24,4 @@ api.add_namespace(information)
 api.add_namespace(device)
 api.add_namespace(device)
 api.add_namespace(data)
 api.add_namespace(data)
 api.add_namespace(log)
 api.add_namespace(log)
+api.add_namespace(download)

+ 55 - 45
src/app/api/data.py

@@ -1,4 +1,5 @@
 import json
 import json
+import base64
 import os
 import os
 
 
 from flask import request, jsonify, g, current_app
 from flask import request, jsonify, g, current_app
@@ -124,12 +125,11 @@ class TemplateConfigApi(Resource):
         if template_name is None and template_type is None:
         if template_name is None and template_type is None:
             return jsonify(code=StatesCode.PARA_ERROR, message='报表模版名和模版类型不能为空')
             return jsonify(code=StatesCode.PARA_ERROR, message='报表模版名和模版类型不能为空')
 
 
-        # 模版存储(url),
         if template_file:
         if template_file:
-            template_file.save(os.path.join(config.common.TEMPLATE_FILE_PATH, template_file.filename))
-            template_url = config.common.TEMPLATE_FILE_URL + template_file.filename
+            template_file.save(os.path.join(config.common.SAVE_FILE_PATH, template_file.filename))
+            template_file_name = template_file.filename
         else:
         else:
-            template_url = None
+            template_file_name = None
 
 
         try:
         try:
             with Session(current_app.engine) as session:
             with Session(current_app.engine) as session:
@@ -148,7 +148,7 @@ class TemplateConfigApi(Resource):
                     creator=g.user_name,
                     creator=g.user_name,
                     create_time=cn_now(),
                     create_time=cn_now(),
                     update_time=cn_now(),
                     update_time=cn_now(),
-                    template_url=template_url,
+                    template=template_file_name,
                     template_type=template_type
                     template_type=template_type
                 )
                 )
                 session.execute(stmt)
                 session.execute(stmt)
@@ -177,12 +177,11 @@ class TemplateConfigApi(Resource):
         if template_id is None or template_name is None:
         if template_id is None or template_name is None:
             return jsonify(code=StatesCode.PARA_ERROR, message="模版id和模版名不能为空")
             return jsonify(code=StatesCode.PARA_ERROR, message="模版id和模版名不能为空")
 
 
-        # 报表模版存储(url),
         if template_file:
         if template_file:
-            template_file.save(os.path.join(config.common.TEMPLATE_FILE_PATH, template_file.filename))
-            template_url = config.common.TEMPLATE_FILE_URL + template_file.filename
+            template_file.save(os.path.join(config.common.SAVE_FILE_PATH, template_file.filename))
+            template_file_name = template_file.filename
         else:
         else:
-            template_url = None
+            template_file_name = None
         try:
         try:
             with Session(current_app.engine) as session:
             with Session(current_app.engine) as session:
                 stmt = update(Template).where(Template.id == template_id).values(
                 stmt = update(Template).where(Template.id == template_id).values(
@@ -193,7 +192,7 @@ class TemplateConfigApi(Resource):
                     creator=g.user_name,
                     creator=g.user_name,
                     create_time=cn_now(),
                     create_time=cn_now(),
                     update_time=cn_now(),
                     update_time=cn_now(),
-                    template_url=template_url,
+                    template=template_file_name,
                     template_type=template_type
                     template_type=template_type
                 )
                 )
                 session.execute(stmt)
                 session.execute(stmt)
@@ -318,12 +317,14 @@ class CompanyApi(Resource):
         if management_unit is None:
         if management_unit is None:
             return jsonify(code=StatesCode.UNKNOWN_ERROR, message='管理单位不能为空')
             return jsonify(code=StatesCode.UNKNOWN_ERROR, message='管理单位不能为空')
 
 
-        # 多图片存储(url),
-        picture_urls = []
+        pictures_base64 = []
+
         if pictures:
         if pictures:
             for picture in pictures:
             for picture in pictures:
-                picture.save(os.path.join(config.common.COMPANY_PICTURE_PATH, picture.filename))
-                picture_urls.append(config.common.COMPANY_PICTURE_URL + picture.filename)
+                ext = picture.filename.split('.')[-1]
+                base64_data = b'data:image/%s;base64,' % ext.encode('utf-8') + base64.b64encode(picture.read())
+                base64_data = base64_data.decode('utf-8')
+                pictures_base64.append(base64_data)
 
 
         try:
         try:
             with Session(current_app.engine) as session:
             with Session(current_app.engine) as session:
@@ -340,7 +341,7 @@ class CompanyApi(Resource):
                     introduction=introduction,
                     introduction=introduction,
                     contact_person=contact_person,
                     contact_person=contact_person,
                     contact_information=contact_information,
                     contact_information=contact_information,
-                    picture=json.dumps(picture_urls),
+                    picture=json.dumps(pictures_base64),
                 )
                 )
                 session.execute(stmt)
                 session.execute(stmt)
 
 
@@ -369,12 +370,15 @@ class CompanyApi(Resource):
         if company_id is None:
         if company_id is None:
             return jsonify(code=StatesCode.PARA_ERROR, message='公司id不能为空')
             return jsonify(code=StatesCode.PARA_ERROR, message='公司id不能为空')
 
 
-        # 多图片存储(url),
-        picture_urls = []
+        pictures_base64 = []
+
         if pictures:
         if pictures:
             for picture in pictures:
             for picture in pictures:
-                picture.save(os.path.join(config.common.COMPANY_PICTURE_PATH, picture.filename))
-                picture_urls.append(config.common.COMPANY_PICTURE_URL + picture.filename)
+
+                ext = picture.filename.split('.')[-1]
+                base64_data = b'data:image/%s;base64,' % ext.encode('utf-8') + base64.b64encode(picture.read())
+                base64_data = base64_data.decode('utf-8')
+                pictures_base64.append(base64_data)
 
 
         try:
         try:
             with Session(current_app.engine) as session:
             with Session(current_app.engine) as session:
@@ -384,7 +388,7 @@ class CompanyApi(Resource):
                     introduction=introduction,
                     introduction=introduction,
                     contact_person=contact_person,
                     contact_person=contact_person,
                     contact_information=contact_information,
                     contact_information=contact_information,
-                    picture=json.dumps(picture_urls),
+                    picture=json.dumps(pictures_base64),
                 )
                 )
 
 
                 session.execute(stmt)
                 session.execute(stmt)
@@ -476,12 +480,14 @@ class BuildingApi(Resource):
         if building_name is None:
         if building_name is None:
             return jsonify(code=StatesCode.UNKNOWN_ERROR, message='楼宇名称不能为空')
             return jsonify(code=StatesCode.UNKNOWN_ERROR, message='楼宇名称不能为空')
 
 
-        # 多图片存储(url),
-        picture_urls = []
+        pictures_base64 = []
         if pictures:
         if pictures:
             for picture in pictures:
             for picture in pictures:
-                picture.save(os.path.join(config.common.BUILDING_PICTURE_PATH, picture.filename))
-                picture_urls.append(config.common.BUILDING_PICTURE_URL + picture.filename)
+
+                ext = picture.filename.split('.')[-1]
+                base64_data = b'data:image/%s;base64,' % ext.encode('utf-8') + base64.b64encode(picture.read())
+                base64_data = base64_data.decode('utf-8')
+                pictures_base64.append(base64_data)
 
 
         try:
         try:
             with Session(current_app.engine) as session:
             with Session(current_app.engine) as session:
@@ -494,7 +500,7 @@ class BuildingApi(Resource):
                     contact_person=contact_person,
                     contact_person=contact_person,
                     contact_information=contact_information,
                     contact_information=contact_information,
                     introduction=building_introduction,
                     introduction=building_introduction,
-                    picture=json.dumps(picture_urls)
+                    picture=json.dumps(pictures_base64)
                 )
                 )
                 session.execute(stmt)
                 session.execute(stmt)
                 session.commit()
                 session.commit()
@@ -524,12 +530,14 @@ class BuildingApi(Resource):
         if building_id is None and building_name is None:
         if building_id is None and building_name is None:
             return jsonify(code=StatesCode.UNKNOWN_ERROR, message='楼宇id和楼宇名称不能为空')
             return jsonify(code=StatesCode.UNKNOWN_ERROR, message='楼宇id和楼宇名称不能为空')
 
 
-        # 多图片存储(url),
-        picture_urls = []
+        pictures_base64 = []
         if pictures:
         if pictures:
             for picture in pictures:
             for picture in pictures:
-                picture.save(os.path.join(config.common.BUILDING_PICTURE_PATH, picture.filename))
-                picture_urls.append(config.common.BUILDING_PICTURE_URL + picture.filename)
+
+                ext = picture.filename.split('.')[-1]
+                base64_data = b'data:image/%s;base64,' % ext.encode('utf-8') + base64.b64encode(picture.read())
+                base64_data = base64_data.decode('utf-8')
+                pictures_base64.append(base64_data)
 
 
         try:
         try:
             with Session(current_app.engine) as session:
             with Session(current_app.engine) as session:
@@ -542,7 +550,7 @@ class BuildingApi(Resource):
                     contact_person=contact_person,
                     contact_person=contact_person,
                     contact_information=contact_information,
                     contact_information=contact_information,
                     introduction=building_introduction,
                     introduction=building_introduction,
-                    picture=json.dumps(picture_urls)
+                    picture=json.dumps(pictures_base64)
                 )
                 )
                 session.execute(stmt)
                 session.execute(stmt)
                 session.commit()
                 session.commit()
@@ -607,23 +615,25 @@ class UnderlyingSystemMessageApi(Resource):
         """添加底层系统信息"""
         """添加底层系统信息"""
         picture = request.files.get('picture')
         picture = request.files.get('picture')
 
 
-        # 存储(url),
         if picture:
         if picture:
-            picture.save(os.path.join(config.common.UNDERLYING_SYSTEM_PICTURE_PATH, picture.filename))
-            picture_url = config.common.UNDERLYING_SYSTEM_PICTURE_URL + picture.filename
+            ext = picture.filename.split('.')[-1]
+            base64_data = b'data:image/%s;base64,' % ext.encode('utf-8') + base64.b64encode(picture.read())
+            base64_data = base64_data.decode('utf-8')
+        else:
+            base64_data = None
 
 
-            try:
-                with Session(current_app.engine) as session:
-                    stmt = insert(UnderlyingSystem).values(
-                        picture=picture_url
-                    )
-                    session.execute(stmt)
-                    session.commit()
+        try:
+            with Session(current_app.engine) as session:
+                stmt = insert(UnderlyingSystem).values(
+                    picture=base64_data
+                )
+                session.execute(stmt)
+                session.commit()
 
 
-                save_log(request, Module.DATA, OperationType.ADD, StatesCode.SUCCESS)
+            save_log(request, Module.DATA, OperationType.ADD, StatesCode.SUCCESS)
 
 
-                return jsonify(code=StatesCode.SUCCESS, message='成功')
+            return jsonify(code=StatesCode.SUCCESS, message='成功')
 
 
-            except Exception as e:
-                save_log(request, Module.DATA, OperationType.ADD, StatesCode.UNKNOWN_ERROR)
-                return jsonify(code=StatesCode.UNKNOWN_ERROR, message=str(e))
+        except Exception as e:
+            save_log(request, Module.DATA, OperationType.ADD, StatesCode.UNKNOWN_ERROR)
+            return jsonify(code=StatesCode.UNKNOWN_ERROR, message=str(e))

+ 41 - 0
src/app/api/download.py

@@ -0,0 +1,41 @@
+import os
+
+from flask import request, jsonify, Response
+from flask_restx import Resource, Namespace, reqparse
+
+from app.defines import StatesCode
+from app.utils.jwt_util import login_required
+from config import Config
+
+ns = Namespace('download', description='文件下载接口')
+
+config = Config()
+
+download_file = reqparse.RequestParser(bundle_errors=True)
+download_file.add_argument(name='name', type=str, location='args', required=False, help='文件名')
+
+
+@ns.route('')
+class DownloadFileApi(Resource):
+    method_decorators = [login_required]
+
+    @ns.doc(id='download_file', description='文件下载')
+    @ns.expect(download_file)
+    def get(self):
+        """文件下载"""
+
+        file_name = request.args.get('name')
+
+        file_path = os.path.join(config.common.SAVE_FILE_PATH, file_name)
+
+        if not os.path.exists(file_path):
+            return jsonify(code=StatesCode.UNKNOWN_ERROR, message='文件%s不存在' % file_name)
+
+        with open(file_path, 'rb') as f:
+            data = f.read()
+
+        response = Response(data)
+        response.headers['Content-Type'] = 'application/octet-stream'
+        response.headers['Content-Disposition'] = 'attachment; filename=%s' % file_name
+
+        return response

+ 144 - 12
src/app/api/information.py

@@ -1,4 +1,4 @@
-import os
+import base64
 
 
 from flask import request, jsonify, current_app, g
 from flask import request, jsonify, current_app, g
 from flask_restx import Resource, Namespace, reqparse
 from flask_restx import Resource, Namespace, reqparse
@@ -7,7 +7,7 @@ from sqlalchemy.orm import Session
 from werkzeug.datastructures import FileStorage
 from werkzeug.datastructures import FileStorage
 
 
 from app.defines import Module, OperationType, StatesCode
 from app.defines import Module, OperationType, StatesCode
-from app.modle.information import FloorConfiguration, StaffConfiguration
+from app.modle.information import FloorConfiguration, StaffConfiguration, SecurityPerson
 from app.utils.jwt_util import login_required
 from app.utils.jwt_util import login_required
 from app.utils.save_log import save_log
 from app.utils.save_log import save_log
 from app.utils.util import to_dict
 from app.utils.util import to_dict
@@ -109,12 +109,12 @@ class FloorConfigurationApi(Resource):
         if name is None:
         if name is None:
             return jsonify(code=StatesCode.UNKNOWN_ERROR, message="配置名不能为空")
             return jsonify(code=StatesCode.UNKNOWN_ERROR, message="配置名不能为空")
 
 
-        # 附件存储(url),
         if attachment:
         if attachment:
-            attachment.save(os.path.join(config.common.FLOOR_CONFIGURATION_PATH, attachment.filename))
-            attachment_url = config.common.FLOOR_CONFIGURATION_URL + attachment.filename
+            ext = attachment.filename.split('.')[-1]
+            base64_data = b'data:image/%s;base64,' % ext.encode('utf-8') + base64.b64encode(attachment.read())
+            base64_data = base64_data.decode('utf-8')
         else:
         else:
-            attachment_url = None
+            base64_data = None
 
 
         try:
         try:
             with Session(current_app.engine) as session:
             with Session(current_app.engine) as session:
@@ -123,7 +123,7 @@ class FloorConfigurationApi(Resource):
                     location=location,
                     location=location,
                     use=use,
                     use=use,
                     remark=remark,
                     remark=remark,
-                    attachment=attachment_url,
+                    attachment=base64_data,
                     account=g.user_name
                     account=g.user_name
                 )
                 )
                 session.execute(stmt)
                 session.execute(stmt)
@@ -151,12 +151,12 @@ class FloorConfigurationApi(Resource):
         if name is None:
         if name is None:
             return jsonify(code=StatesCode.UNKNOWN_ERROR, message="配置名不能为空")
             return jsonify(code=StatesCode.UNKNOWN_ERROR, message="配置名不能为空")
 
 
-        # 附件存储(url),
         if attachment:
         if attachment:
-            attachment.save(os.path.join(config.common.FLOOR_CONFIGURATION_PATH, attachment.filename))
-            attachment_url = config.common.FLOOR_CONFIGURATION_URL + attachment.filename
+            ext = attachment.filename.split('.')[-1]
+            base64_data = b'data:image/%s;base64,' % ext.encode('utf-8') + base64.b64encode(attachment.read())
+            base64_data = base64_data.decode('utf-8')
         else:
         else:
-            attachment_url = None
+            base64_data = None
 
 
         try:
         try:
             with Session(current_app.engine) as session:
             with Session(current_app.engine) as session:
@@ -165,7 +165,7 @@ class FloorConfigurationApi(Resource):
                     location=location,
                     location=location,
                     use=use,
                     use=use,
                     remark=remark,
                     remark=remark,
-                    attachment=attachment_url,
+                    attachment=base64_data,
                     account=g.user_name
                     account=g.user_name
                 )
                 )
                 session.execute(stmt)
                 session.execute(stmt)
@@ -201,15 +201,147 @@ class FloorConfigurationApi(Resource):
             return jsonify(code=StatesCode.UNKNOWN_ERROR, message=str(e))
             return jsonify(code=StatesCode.UNKNOWN_ERROR, message=str(e))
 
 
 
 
+@ns.route('/security_person')
+class GetSecurityPersonApi(Resource):
+    method_decorators = [login_required]
+
+    def get(self):
+        """获取人员名单"""
+        try:
+            with Session(current_app.engine) as session:
+                stmt = select(SecurityPerson)
+                results = information_list(session.execute(stmt))
+
+            save_log(request, Module.INFORMATION, OperationType.INQUIRE, StatesCode.SUCCESS)
+
+            return jsonify(code=StatesCode.SUCCESS, message='成功', data=results)
+        except Exception as e:
+            save_log(request, Module.INFORMATION, OperationType.INQUIRE, StatesCode.UNKNOWN_ERROR)
+            return jsonify(code=StatesCode.UNKNOWN_ERROR, message=str(e))
+
+
+staff_configuration_details = reqparse.RequestParser(bundle_errors=True)
+staff_configuration_details.add_argument(name='id', type=str, location='args', required=False, help='配置id')
+
+floor_configuration = reqparse.RequestParser(bundle_errors=True)
+floor_configuration.add_argument(name='id', type=str, location='form', required=False, help='配置id')
+floor_configuration.add_argument(name='name', type=str, location='form', required=False, help='配置名称')
+floor_configuration.add_argument(name='personnel_type', type=str, location='form', required=False, help='人员类别')
+floor_configuration.add_argument(name='responsibility_range', type=str, location='form', required=False,
+                                 help='职责范围')
+floor_configuration.add_argument(name='staff_list', type=str, location='form', required=False, help='人员名单')
+floor_configuration.add_argument(name='remark', type=str, location='form', required=False, help='备注')
+
+
+@ns.route('/staff_configuration')
 class StaffConfigurationApi(Resource):
 class StaffConfigurationApi(Resource):
+    method_decorators = [login_required]
+
+    @ns.doc(id='staff_configuration', description='获取人员配置信息')
+    @ns.expect(staff_configuration_details)
     def get(self):
     def get(self):
         """获取安保人员信息配置"""
         """获取安保人员信息配置"""
 
 
+        staff_configuration_id = request.args.get('id')
+        if staff_configuration_id is None:
+            return jsonify(code=StatesCode.UNKNOWN_ERROR, message="配置id不能为空")
+
+        try:
+            with Session(current_app.engine) as session:
+                stmt = select(StaffConfiguration).where(StaffConfiguration.id == staff_configuration_id)
+                results = session.execute(stmt).scalars().all()
+
+            save_log(request, Module.INFORMATION, OperationType.INQUIRE, StatesCode.SUCCESS)
+
+            return jsonify(code=StatesCode.SUCCESS, message='成功', data=to_dict(results))
+        except Exception as e:
+            save_log(request, Module.INFORMATION, OperationType.INQUIRE, StatesCode.UNKNOWN_ERROR)
+            return jsonify(code=StatesCode.UNKNOWN_ERROR, message=str(e))
+
+    @ns.doc(id='add_staff_configuration', description='添加人员配置信息')
+    @ns.expect(floor_configuration)
     def post(self):
     def post(self):
         """添加安保人员信息配置"""
         """添加安保人员信息配置"""
+        name = request.form.get('name')
+        personnel_type = request.form.get('personnel_type')
+        responsibility_range = request.form.get('responsibility_range')
+        staff_list = request.form.get('staff_list')
+        remark = request.form.get('remark')
 
 
+        try:
+            with Session(current_app.engine) as session:
+                stmt = insert(StaffConfiguration).values(
+                    name=name,
+                    personnel_type=personnel_type,
+                    responsibility_range=responsibility_range,
+                    staff_list=staff_list,
+                    remark=remark
+                )
+                session.execute(stmt)
+                session.commit()
+
+            save_log(request, Module.INFORMATION, OperationType.ADD, StatesCode.SUCCESS)
+
+            return jsonify(code=StatesCode.SUCCESS, message='成功')
+
+        except Exception as e:
+            save_log(request, Module.INFORMATION, OperationType.ADD, StatesCode.UNKNOWN_ERROR)
+            return jsonify(code=StatesCode.UNKNOWN_ERROR, message=str(e))
+
+    @ns.doc(id='update_staff_configuration', description='修改人员配置信息')
+    @ns.expect(floor_configuration)
     def put(self):
     def put(self):
         """修改安保人员信息配置"""
         """修改安保人员信息配置"""
+        staff_configuration_id = request.form.get('id')
+        name = request.form.get('name')
+        personnel_type = request.form.get('personnel_type')
+        responsibility_range = request.form.get('responsibility_range')
+        staff_list = request.form.get('staff_list')
+        remark = request.form.get('remark')
+
+        if staff_configuration_id is None:
+            return jsonify(code=StatesCode.UNKNOWN_ERROR, message="配置id不能为空")
+
+        try:
+            with Session(current_app.engine) as session:
+                stmt = update(StaffConfiguration).where(StaffConfiguration.id == staff_configuration_id).values(
+                    name=name,
+                    personnel_type=personnel_type,
+                    responsibility_range=responsibility_range,
+                    staff_list=staff_list,
+                    remark=remark
+                )
+                session.execute(stmt)
+                session.commit()
+
+            save_log(request, Module.INFORMATION, OperationType.UPDATE, StatesCode.SUCCESS)
 
 
+            return jsonify(code=StatesCode.SUCCESS, message='成功')
+
+        except Exception as e:
+            save_log(request, Module.INFORMATION, OperationType.UPDATE, StatesCode.UNKNOWN_ERROR)
+            return jsonify(code=StatesCode.UNKNOWN_ERROR, message=str(e))
+
+    @ns.doc(id='delete_staff_configuration', description='删除人员配置信息')
+    @ns.expect(floor_configuration)
     def delete(self):
     def delete(self):
         """删除安保人员信息配置"""
         """删除安保人员信息配置"""
+
+        staff_configuration_id = request.form.get('id')
+
+        if staff_configuration_id is None:
+            return jsonify(code=StatesCode.UNKNOWN_ERROR, message="配置id不能为空")
+
+        try:
+            with Session(current_app.engine) as session:
+                stmt = delete(StaffConfiguration).where(StaffConfiguration.id == staff_configuration_id)
+                session.execute(stmt)
+                session.commit()
+
+            save_log(request, Module.INFORMATION, OperationType.DELETE, StatesCode.SUCCESS)
+
+            return jsonify(code=StatesCode.SUCCESS, message='成功')
+
+        except Exception as e:
+            save_log(request, Module.INFORMATION, OperationType.DELETE, StatesCode.UNKNOWN_ERROR)
+            return jsonify(code=StatesCode.UNKNOWN_ERROR, message=str(e))

+ 23 - 5
src/app/api/log.py

@@ -1,5 +1,4 @@
-import json
-from io import StringIO
+from io import BytesIO
 
 
 from flask import request, jsonify, Response, current_app
 from flask import request, jsonify, Response, current_app
 from flask_restx import Resource, Namespace, reqparse
 from flask_restx import Resource, Namespace, reqparse
@@ -10,7 +9,7 @@ from app.defines import StatesCode, Module, OperationType
 from app.modle.log import Log
 from app.modle.log import Log
 from app.utils.jwt_util import login_required
 from app.utils.jwt_util import login_required
 from app.utils.save_log import save_log
 from app.utils.save_log import save_log
-from app.utils.util import to_dict
+from app.utils.util import to_dict, MyXlwt
 
 
 ns = Namespace('log', description='日志管理接口')
 ns = Namespace('log', description='日志管理接口')
 
 
@@ -85,9 +84,28 @@ class LogExportApi(Resource):
                 stmt = select(Log)
                 stmt = select(Log)
                 results = session.execute(stmt).scalars().all()
                 results = session.execute(stmt).scalars().all()
 
 
-            response = Response(StringIO(json.dumps(to_dict(results))))
+            my_xlwt = MyXlwt()
+
+            title = ['id', 'module', 'operation_type', 'request', 'operation_staff', 'operation_address',
+                     'operation_status', 'operation_time']
+
+            # 写入标题
+            my_xlwt.write_row(0, 0, title)
+            # 写入内容
+            start_row = 1  # 内容起始行
+            for result in results:
+                data = [result.id, result.module, result.operation_type, result.request, result.operation_staff,
+                        result.operation_address, result.operation_status, result.operation_time]
+
+                my_xlwt.write_row(start_row, 0, data)
+
+                start_row += 1
+
+            output = BytesIO()
+            my_xlwt.save(output)
+            response = Response(output.getvalue())
             response.headers['Content-Type'] = 'application/octet-stream'
             response.headers['Content-Type'] = 'application/octet-stream'
-            response.headers['Content-Disposition'] = 'attachment; filename=%s' % 'log.json'
+            response.headers['Content-Disposition'] = 'attachment; filename=%s' % 'log.xls'
 
 
             save_log(request, Module.LOG, OperationType.EXPORT, StatesCode.SUCCESS)
             save_log(request, Module.LOG, OperationType.EXPORT, StatesCode.SUCCESS)
 
 

+ 11 - 11
src/app/api/organization.py

@@ -1,5 +1,5 @@
+import base64
 import json
 import json
-import os
 
 
 from flask import request, jsonify, current_app
 from flask import request, jsonify, current_app
 from flask_restx import Resource, Namespace, reqparse
 from flask_restx import Resource, Namespace, reqparse
@@ -117,12 +117,12 @@ class CompanyApi(Resource):
         if company_name is None:
         if company_name is None:
             return jsonify(code=StatesCode.PARA_ERROR, message="公司名不能为空")
             return jsonify(code=StatesCode.PARA_ERROR, message="公司名不能为空")
 
 
-        # 公司商标存储(url),
         if logo:
         if logo:
-            logo.save(os.path.join(config.common.COMPANY_LOGO_PATH, logo.filename))
-            logo_url = config.common.COMPANY_LOGO_URL + logo.filename
+            ext = logo.filename.split('.')[-1]
+            base64_data = b'data:image/%s;base64,' % ext.encode('utf-8') + base64.b64encode(logo.read())
+            base64_data = base64_data.decode('utf-8')
         else:
         else:
-            logo_url = None
+            base64_data = None
 
 
         try:
         try:
             with Session(current_app.engine) as session:
             with Session(current_app.engine) as session:
@@ -135,7 +135,7 @@ class CompanyApi(Resource):
                 # 添加公司
                 # 添加公司
                 stmt = insert(Company).values(
                 stmt = insert(Company).values(
                     company_name=company_name,
                     company_name=company_name,
-                    logo=logo_url,
+                    logo=base64_data,
                     abbreviation=abbreviation,
                     abbreviation=abbreviation,
                     code=code,
                     code=code,
                     registered_address=registered_address,
                     registered_address=registered_address,
@@ -175,18 +175,18 @@ class CompanyApi(Resource):
         if company_name is None:
         if company_name is None:
             return jsonify(code=StatesCode.PARA_ERROR, message="公司名不能为空")
             return jsonify(code=StatesCode.PARA_ERROR, message="公司名不能为空")
 
 
-        # 公司商标存储(url),
         if logo:
         if logo:
-            logo.save(os.path.join(config.common.COMPANY_LOGO_PATH, logo.filename))
-            logo_url = config.common.COMPANY_LOGO_URL + logo.filename
+            ext = logo.filename.split('.')[-1]
+            base64_data = b'data:image/%s;base64,' % ext.encode('utf-8') + base64.b64encode(logo.read())
+            base64_data = base64_data.decode('utf-8')
         else:
         else:
-            logo_url = None
+            base64_data = None
 
 
         try:
         try:
             with Session(current_app.engine) as session:
             with Session(current_app.engine) as session:
                 stmt = update(Company).where(Company.id == company_id).values(
                 stmt = update(Company).where(Company.id == company_id).values(
                     company_name=company_name,
                     company_name=company_name,
-                    logo=logo_url,
+                    logo=base64_data,
                     abbreviation=abbreviation,
                     abbreviation=abbreviation,
                     code=code,
                     code=code,
                     registered_address=registered_address,
                     registered_address=registered_address,

+ 25 - 8
src/app/api/users.py

@@ -1,3 +1,4 @@
+import base64
 import json
 import json
 from io import BytesIO
 from io import BytesIO
 
 
@@ -5,6 +6,7 @@ from flask import request, jsonify, Response, current_app
 from flask_restx import Resource, Namespace, reqparse
 from flask_restx import Resource, Namespace, reqparse
 from sqlalchemy import insert, select, update, delete, func
 from sqlalchemy import insert, select, update, delete, func
 from sqlalchemy.orm import Session
 from sqlalchemy.orm import Session
+from werkzeug.datastructures import FileStorage
 
 
 from app.defines import StatesCode, Module, OperationType
 from app.defines import StatesCode, Module, OperationType
 from app.modle.users import User
 from app.modle.users import User
@@ -55,7 +57,7 @@ add_user = reqparse.RequestParser(bundle_errors=True)
 add_user.add_argument(name='id', type=str, required=False, location='form', help='用户id')
 add_user.add_argument(name='id', type=str, required=False, location='form', help='用户id')
 add_user.add_argument(name='username', type=str, required=True, location='form', help='用户名')
 add_user.add_argument(name='username', type=str, required=True, location='form', help='用户名')
 add_user.add_argument(name='password', type=str, required=True, location='form', help='密码')
 add_user.add_argument(name='password', type=str, required=True, location='form', help='密码')
-add_user.add_argument(name='photograph', type=str, required=False, location='form', help='照片')
+add_user.add_argument(name='photograph', type=FileStorage, required=False, location='files', help='照片')
 add_user.add_argument(name='name', type=str, required=False, location='form', help='姓名')
 add_user.add_argument(name='name', type=str, required=False, location='form', help='姓名')
 add_user.add_argument(name='phone', type=str, required=False, location='form', help='电话')
 add_user.add_argument(name='phone', type=str, required=False, location='form', help='电话')
 add_user.add_argument(name='email', type=str, required=False, location='form', help='邮箱')
 add_user.add_argument(name='email', type=str, required=False, location='form', help='邮箱')
@@ -73,7 +75,7 @@ user_details.add_argument(name='id', type=int, required=True, location='args', h
 
 
 @ns.route('/user')
 @ns.route('/user')
 class UsersApi(Resource):
 class UsersApi(Resource):
-    method_decorators = [login_required]
+    # method_decorators = [login_required]
 
 
     @ns.doc(id='get_users_details', description='获取用户详情')
     @ns.doc(id='get_users_details', description='获取用户详情')
     @ns.expect(user_details)
     @ns.expect(user_details)
@@ -102,7 +104,7 @@ class UsersApi(Resource):
         """添加用户"""
         """添加用户"""
         username = request.form.get('username')
         username = request.form.get('username')
         password = request.form.get('password')
         password = request.form.get('password')
-        photograph = request.form.get('photograph')
+        photograph = request.files.get('photograph')
         name = request.form.get('name')
         name = request.form.get('name')
         phone = request.form.get('phone')
         phone = request.form.get('phone')
         email = request.form.get('email')
         email = request.form.get('email')
@@ -117,6 +119,13 @@ class UsersApi(Resource):
         if username is None or password is None:
         if username is None or password is None:
             return jsonify(code=StatesCode.PARA_ERROR, message="用户名或密码不能为空")
             return jsonify(code=StatesCode.PARA_ERROR, message="用户名或密码不能为空")
 
 
+        if photograph:
+            ext = photograph.filename.split('.')[-1]
+            base64_data = b'data:image/%s;base64,' % ext.encode('utf-8') + base64.b64encode(photograph.read())
+            base64_data = base64_data.decode('utf-8')
+        else:
+            base64_data = None
+
         try:
         try:
             with Session(current_app.engine) as session:
             with Session(current_app.engine) as session:
                 # 判断用户是否存在
                 # 判断用户是否存在
@@ -130,7 +139,7 @@ class UsersApi(Resource):
                     insert(User).values(
                     insert(User).values(
                         user_name=username,
                         user_name=username,
                         password=User().generate_password(password),
                         password=User().generate_password(password),
-                        photograph=photograph,
+                        photograph=base64_data,
                         name=name,
                         name=name,
                         phone=phone,
                         phone=phone,
                         email=email,
                         email=email,
@@ -162,7 +171,7 @@ class UsersApi(Resource):
         user_id = request.form.get('id')
         user_id = request.form.get('id')
         username = request.form.get('username')
         username = request.form.get('username')
         password = request.form.get('password')
         password = request.form.get('password')
-        photograph = request.form.get('photograph')
+        photograph = request.files.get('photograph')
         name = request.form.get('name')
         name = request.form.get('name')
         phone = request.form.get('phone')
         phone = request.form.get('phone')
         email = request.form.get('email')
         email = request.form.get('email')
@@ -176,12 +185,20 @@ class UsersApi(Resource):
 
 
         if user_id is None:
         if user_id is None:
             return jsonify(code=StatesCode.PARA_ERROR, message='用户id不能为空')
             return jsonify(code=StatesCode.PARA_ERROR, message='用户id不能为空')
+
+        if photograph:
+            ext = photograph.filename.split('.')[-1]
+            base64_data = b'data:image/%s;base64,' % ext.encode('utf-8') + base64.b64encode(photograph.read())
+            base64_data = base64_data.decode('utf-8')
+        else:
+            base64_data = None
+
         try:
         try:
             with Session(current_app.engine) as session:
             with Session(current_app.engine) as session:
                 stmt = update(User).where(User.id == user_id).values(
                 stmt = update(User).where(User.id == user_id).values(
                     user_name=username,
                     user_name=username,
                     password=User().generate_password(password),
                     password=User().generate_password(password),
-                    photograph=photograph,
+                    photograph=base64_data,
                     name=name,
                     name=name,
                     phone=phone,
                     phone=phone,
                     email=email,
                     email=email,
@@ -352,7 +369,7 @@ class ExportDataApi(Resource):
 
 
             my_xlwt = MyXlwt()
             my_xlwt = MyXlwt()
 
 
-            title = ['id', 'user_name', 'password', 'photograph', 'name', 'phone', 'email', 'company', 'department',
+            title = ['id', 'user_name', 'password', 'name', 'phone', 'email', 'company', 'department',
                      'role',
                      'role',
                      'permission', 'on_job_status', 'duty', 'account_status', 'nationality', 'register_time',
                      'permission', 'on_job_status', 'duty', 'account_status', 'nationality', 'register_time',
                      'common_menus']
                      'common_menus']
@@ -362,7 +379,7 @@ class ExportDataApi(Resource):
             # 写入内容
             # 写入内容
             start_row = 1  # 内容起始行
             start_row = 1  # 内容起始行
             for result in results:
             for result in results:
-                data = [result.id, result.user_name, result.password, result.photograph, result.name, result.phone,
+                data = [result.id, result.user_name, result.password, result.name, result.phone,
                         result.email, result.company, result.department, result.role, result.permission,
                         result.email, result.company, result.department, result.role, result.permission,
                         result.on_job_status,
                         result.on_job_status,
                         result.duty, result.account_status, result.nationality, result.register_time,
                         result.duty, result.account_status, result.nationality, result.register_time,

+ 4 - 4
src/app/modle/data.py

@@ -16,7 +16,7 @@ class Template(Base):
     creator = Column(String, nullable=True, unique=False, index=False, doc='创建者')
     creator = Column(String, nullable=True, unique=False, index=False, doc='创建者')
     create_time = Column(String, nullable=True, unique=False, index=False, doc='创建时间')
     create_time = Column(String, nullable=True, unique=False, index=False, doc='创建时间')
     update_time = Column(String, nullable=True, unique=False, index=False, doc='修改时间')
     update_time = Column(String, nullable=True, unique=False, index=False, doc='修改时间')
-    template_url = Column(String, nullable=True, unique=False, index=False, doc='模版存储地址')
+    template = Column(String, nullable=True, unique=False, index=False, doc='模版文件名')
     template_type = Column(String, nullable=True, unique=False, index=False, doc='模版类型')
     template_type = Column(String, nullable=True, unique=False, index=False, doc='模版类型')
 
 
 
 
@@ -31,7 +31,7 @@ class CompanyData(Base):
     introduction = Column(String, nullable=True, unique=False, index=False, doc='公司简介')
     introduction = Column(String, nullable=True, unique=False, index=False, doc='公司简介')
     contact_person = Column(String, nullable=True, unique=False, index=False, doc='联系人')
     contact_person = Column(String, nullable=True, unique=False, index=False, doc='联系人')
     contact_information = Column(String, nullable=True, unique=False, index=False, doc='联系人方式')
     contact_information = Column(String, nullable=True, unique=False, index=False, doc='联系人方式')
-    picture = Column(String, nullable=True, unique=False, index=False, doc='公司图片url')
+    picture = Column(String, nullable=True, unique=False, index=False, doc='公司图片base64')
 
 
 
 
 class Building(Base):
 class Building(Base):
@@ -48,7 +48,7 @@ class Building(Base):
     contact_person = Column(String, nullable=True, unique=False, index=False, doc='联系人')
     contact_person = Column(String, nullable=True, unique=False, index=False, doc='联系人')
     contact_information = Column(String, nullable=True, unique=False, index=False, doc='联系人方式')
     contact_information = Column(String, nullable=True, unique=False, index=False, doc='联系人方式')
     introduction = Column(String, nullable=True, unique=False, index=False, doc='楼宇简介')
     introduction = Column(String, nullable=True, unique=False, index=False, doc='楼宇简介')
-    picture = Column(String, nullable=True, unique=False, index=False, doc='楼宇图片url')
+    picture = Column(String, nullable=True, unique=False, index=False, doc='楼宇图片basee64')
 
 
 
 
 class UnderlyingSystem(Base):
 class UnderlyingSystem(Base):
@@ -57,4 +57,4 @@ class UnderlyingSystem(Base):
     __tablename__ = 'underlying_system'
     __tablename__ = 'underlying_system'
 
 
     id = Column(Integer, primary_key=True, autoincrement=True, nullable=False, unique=True, doc='id')
     id = Column(Integer, primary_key=True, autoincrement=True, nullable=False, unique=True, doc='id')
-    picture = Column(String, nullable=True, unique=False, index=False, doc='图片url')
+    picture = Column(String, nullable=True, unique=False, index=False, doc='图片base64')

+ 20 - 1
src/app/modle/information.py

@@ -1,4 +1,4 @@
-from sqlalchemy import String, Column, Integer
+from sqlalchemy import String, Column, Integer, DateTime
 
 
 from app.modle import Base
 from app.modle import Base
 from app.utils.util import cn_now
 from app.utils.util import cn_now
@@ -30,3 +30,22 @@ class StaffConfiguration(Base):
     responsibility_range = Column(String, nullable=True, unique=False, index=False, doc='职责范围')
     responsibility_range = Column(String, nullable=True, unique=False, index=False, doc='职责范围')
     staff_list = Column(String, nullable=True, unique=False, index=False, doc='人员名单')
     staff_list = Column(String, nullable=True, unique=False, index=False, doc='人员名单')
     remark = Column(String, nullable=True, unique=False, index=False, doc='备注')
     remark = Column(String, nullable=True, unique=False, index=False, doc='备注')
+
+
+class SecurityPerson(Base):
+    """人员表"""
+
+    __tablename__ = 'security_person'
+
+    id = Column(Integer, primary_key=True, autoincrement=True, nullable=False, unique=True, doc='id')
+    name = Column(String, nullable=True, unique=False, index=False, doc='姓名')
+    work_number = Column(String, nullable=True, unique=False, index=False, doc='工号')
+    phone = Column(String, nullable=True, unique=False, index=False, doc='联系电话')
+    scope = Column(String, nullable=True, unique=False, index=False, doc='工作区域')
+    company_id = Column(Integer, nullable=True, unique=False, index=False, doc='单位id')
+    dept_id = Column(Integer, nullable=True, unique=False, index=False, doc='部门id')
+    company = Column(String, nullable=True, unique=False, index=False, doc='单位')
+    department = Column(String, nullable=True, unique=False, index=False, doc='部门')
+    register_time = Column(String, nullable=True, unique=False, index=False, doc='入职时间')
+    type = Column(Integer, nullable=True, unique=False, index=False, doc='人员类型 1安防人员 2前台人员')
+    photo = Column(String, nullable=True, unique=False, index=False, doc='头像')