Compare commits

..

5 Commits

@ -43,6 +43,8 @@ services:
# - "80:80" # - "80:80"
# - "443:443" # - "443:443"
- "8989:8989" - "8989:8989"
environment:
TZ: Asia/Shanghai
volumes: volumes:
- ./nginx.conf:/etc/nginx/conf.d/lemon.conf - ./nginx.conf:/etc/nginx/conf.d/lemon.conf
- ./dist:/app/lemon/dist - ./dist:/app/lemon/dist
@ -59,6 +61,7 @@ services:
environment: environment:
MYSQL_ROOT_PASSWORD: SghjdA887# MYSQL_ROOT_PASSWORD: SghjdA887#
MYSQL_DATABASE: aiplatform MYSQL_DATABASE: aiplatform
TZ: Asia/Shanghai
volumes: volumes:
- /data/mysql_data:/var/lib/mysql - /data/mysql_data:/var/lib/mysql
- ./mysql_auth.sql:/docker-entrypoint-initdb.d/auth.sql - ./mysql_auth.sql:/docker-entrypoint-initdb.d/auth.sql

@ -0,0 +1,10 @@
aiofiles==24.1.0
M2Crypto==0.41.0
pandas==2.2.2
Pillow==10.4.0
pycryptodome==3.20.0
redis==5.0.7
requests==2.27.1
SQLAlchemy==2.0.31
tornado==6.4.1
xlwt==1.3.0

@ -62,10 +62,14 @@ op_type_delete_str = u"删除"
op_type_upload = 1005 # 上传 op_type_upload = 1005 # 上传
op_type_upload_str = u"上传" op_type_upload_str = u"上传"
op_type_login_logout = 1006
op_type_login_logout_str = u"登录/登出"
op_type_map = { op_type_map = {
op_type_add: op_type_add_str, op_type_add: op_type_add_str,
op_type_edit: op_type_edit_str, op_type_edit: op_type_edit_str,
op_type_list: op_type_list_str, op_type_list: op_type_list_str,
op_type_delete: op_type_delete_str, op_type_delete: op_type_delete_str,
op_type_upload: op_type_upload_str, op_type_upload: op_type_upload_str,
op_type_login_logout: op_type_login_logout_str,
} }

@ -1,13 +1,13 @@
from website.handler import BaseHandler import json
from sqlalchemy import text
from typing import Any from typing import Any
from sqlalchemy import text
from website.db_mysql import get_session, get_async_session, to_json, to_json_list from website.db_mysql import get_session, get_async_session, to_json, to_json_list
import json
# 获取企业模型数量 # 获取企业模型数量
def get_enterprise_model_count(id: int) -> int: def get_enterprise_model_count(id: int) -> int:
return 0 return 0
@ -103,8 +103,6 @@ async def get_enterprise_model_and_device_count(
# if res_device: # if res_device:
# device_count = res_device["device_count"] # device_count = res_device["device_count"]
sql_device_count = "SELECT COUNT(*) AS device_count FROM enterprise_device WHERE {where_clause} " sql_device_count = "SELECT COUNT(*) AS device_count FROM enterprise_device WHERE {where_clause} "
sql_base_model = "SELECT base_models FROM enterprise_busi_model WHERE {where_clause} " sql_base_model = "SELECT base_models FROM enterprise_busi_model WHERE {where_clause} "

@ -5,13 +5,13 @@ import logging
from typing import Any, Dict, List, Optional from typing import Any, Dict, List, Optional
from sqlalchemy import Column, Integer, String, DateTime, func from sqlalchemy import Column, Integer, String, DateTime, func
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import text from sqlalchemy import text
from sqlalchemy.ext.declarative import declarative_base
from website.db.alg_model import alg_model as DB_alg_model from website.db.alg_model import alg_model as DB_alg_model
from website.db.enterprise_entity.enterprise_entity import EnterpriseEntityRepository from website.db.enterprise_entity.enterprise_entity import EnterpriseEntityRepository
from website.db.enterprise_node import enterprise_node as DB_Node from website.db.enterprise_node import enterprise_node as DB_Node
from website.db_mysql import get_session, to_json_list, to_json, Row, dict_to_obj from website.db_mysql import get_session, to_json_list, Row, dict_to_obj
from website.util import shortuuid from website.util import shortuuid
Base = declarative_base() Base = declarative_base()
@ -73,6 +73,7 @@ class EnterpriseBusiModel(Base):
filtered_data = {key: value for key, value in kwargs.items() if key in valid_columns} filtered_data = {key: value for key, value in kwargs.items() if key in valid_columns}
super().__init__(**filtered_data) super().__init__(**filtered_data)
class EnterpriseBusiModelRepository(object): class EnterpriseBusiModelRepository(object):
def get_by_id(self, id: int) -> Optional[EnterpriseBusiModel]: def get_by_id(self, id: int) -> Optional[EnterpriseBusiModel]:
@ -161,7 +162,7 @@ class EnterpriseBusiModelRepository(object):
""" """
with get_session() as session: with get_session() as session:
total_count = session.query(func.count(EnterpriseBusiModel.id)).filter( total_count = session.query(func.count(EnterpriseBusiModel.id)).filter(
EnterpriseBusiModel.entity_id == entity_id).scalar() EnterpriseBusiModel.entity_id == entity_id).filter(EnterpriseBusiModel.delete == 0).scalar()
models = ( models = (
session.query( session.query(
@ -170,6 +171,7 @@ class EnterpriseBusiModelRepository(object):
EnterpriseBusiModel.create_time EnterpriseBusiModel.create_time
) )
.filter(EnterpriseBusiModel.entity_id == entity_id) .filter(EnterpriseBusiModel.entity_id == entity_id)
.filter(EnterpriseBusiModel.delete == 0)
.offset((page_no - 1) * page_size) .offset((page_no - 1) * page_size)
.limit(page_size) .limit(page_size)
.all() .all()
@ -204,6 +206,7 @@ class EnterpriseBusiModelRepository(object):
session.commit() session.commit()
return return
class EnterpriseBusiModelNode(Base): class EnterpriseBusiModelNode(Base):
__tablename__ = 'enterprise_busi_model_node' __tablename__ = 'enterprise_busi_model_node'
@ -279,7 +282,6 @@ class EnterpriseBusiModelNodeRepository(object):
.all() .all()
) )
total_count = session.query(func.count(EnterpriseBusiModelNode.id)).filter( total_count = session.query(func.count(EnterpriseBusiModelNode.id)).filter(
EnterpriseBusiModelNode.node_id == node_id).scalar() EnterpriseBusiModelNode.node_id == node_id).scalar()

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import logging
from typing import List, Dict, Any, Union from typing import List, Dict, Any, Union
from sqlalchemy import text from sqlalchemy import text
@ -71,15 +71,18 @@ class EnterpriseNodeRepository(object):
n.id, n.name, n.parent, p.name AS parent_name, n.suid n.id, n.name, n.parent, p.name AS parent_name, n.suid
FROM enterprise_node n FROM enterprise_node n
LEFT JOIN enterprise_node p ON n.parent = p.id LEFT JOIN enterprise_node p ON n.parent = p.id
WHERE n.entity_id=:entity_id AND n.del=0 and n.parent=0 WHERE n.entity_id=:entity_id AND n.del=0
""" """
) )
if name == "":
sql += " and n.parent=0"
param = {"entity_id": entity_id} param = {"entity_id": entity_id}
if name: if name:
sql += " and n.name like :name" sql += " and n.name like :name"
param["name"] = f"%{name}%" param["name"] = f"%{name}%"
# logging.info(f"############################# sql: {sql}, param: {param}")
res = session.execute(text(sql), param) res = session.execute(text(sql), param)
node_list = to_json_list(res) node_list = to_json_list(res)
node_list = node_list and node_list or [] node_list = node_list and node_list or []
@ -115,9 +118,9 @@ class EnterpriseNodeRepository(object):
param = {"parent": node["id"]} param = {"parent": node["id"]}
if name: # if name:
sql += " and n.name like :name" # sql += " and n.name like :name"
param["name"] = f"%{name}%" # param["name"] = f"%{name}%"
res = session.execute(text(sql), param) res = session.execute(text(sql), param)
node_list = to_json_list(res) node_list = to_json_list(res)

@ -53,7 +53,7 @@ class FileRepository(object):
for file in files: for file in files:
obj_dict = file.__dict__ obj_dict = file.__dict__
del obj_dict['_sa_instance_state'] del obj_dict['_sa_instance_state']
print(obj_dict) # print(obj_dict)
resp.append(dict_to_obj(obj_dict)) resp.append(dict_to_obj(obj_dict))
# return session.query(File).filter(File.md5_str.in_(md5_list)).all() # return session.query(File).filter(File.md5_str.in_(md5_list)).all()

@ -108,6 +108,28 @@ class ClassificationDeleteHandler(APIHandler):
self.finish() self.finish()
class ClassificationEditHandler(APIHandler):
"""
编辑模型分类
"""
@authenticated
@operation_log("模型管理", "模型列表", consts.op_type_edit_str, "编辑模型分类", "")
def post(self):
classification_id = self.get_int_argument("id")
name = self.get_escaped_argument("name", "")
if not classification_id or not name:
raise errors.HTTPAPIError(errors.ERROR_BAD_REQUEST, "参数缺失")
with self.app_mysql.connect() as conn:
conn.execute(
text("""update model_classification set name=:name where id=:id"""),
{"name": name, "id": classification_id},
)
conn.commit()
self.finish()
class ListHandler(APIHandler): class ListHandler(APIHandler):
""" """
模型列表 模型列表
@ -279,8 +301,10 @@ class InfoHandler(APIHandler):
select select
m.name, m.model_type, m.default_version, m.comment, m.update_time, m.name, m.model_type, m.default_version, m.comment, m.update_time,
mc.id as classification_id, mc.name as classification_name mc.id as classification_id, mc.name as classification_name
from model m, model_classification mc from model m
where m.id=:id and m.classification=mc.id left join model_classification mc
on m.classification=mc.id
where m.id=:id
""" """
), ),
{"id": mid}, {"id": mid},

@ -5,6 +5,7 @@ handlers = [
("/model/classification/add", handler.ClassificationAddHandler), ("/model/classification/add", handler.ClassificationAddHandler),
("/model/classification/list", handler.ClassificationListHandler), ("/model/classification/list", handler.ClassificationListHandler),
("/model/classification/delete", handler.ClassificationDeleteHandler), ("/model/classification/delete", handler.ClassificationDeleteHandler),
("/model/classification/edit", handler.ClassificationEditHandler),
("/model/list", handler.ListHandler), ("/model/list", handler.ListHandler),
("/model/list/simple", handler.ListSimpleHandler), ("/model/list/simple", handler.ListSimpleHandler),

@ -148,11 +148,14 @@ class InfoHandler(APIHandler):
db_file = DB_File.FileRepository() db_file = DB_File.FileRepository()
files = db_file.get_file_by_md5([busi_model_data.business_conf_file, busi_model_data.business_logic]) files = db_file.get_file_by_md5([busi_model_data.business_conf_file, busi_model_data.business_logic])
business_conf_name = files[0].filename business_logic_name = ""
business_logic_name = files[1].filename business_conf_name = ""
for item in files:
if item.md5_str == busi_model_data.business_logic:
business_logic_name = item.filename
else:
business_conf_name = item.filename
# business_conf_name = db_file.get_file_by_md5(busi_model_data.business_conf_file)
# business_logic_name = db_file.get_file_by_md5(busi_model_data.business_logic)
basemodel_list = json.loads(busi_model_data.base_models) basemodel_list = json.loads(busi_model_data.base_models)
entity_suid = busi_model_data.entity_suid entity_suid = busi_model_data.entity_suid

@ -287,7 +287,7 @@ class DeviceListHandler(APIHandler):
""" """
@authenticated @authenticated
@operation_log("企业管理", "设备管理", consts.op_type_list, "企业节点,设备列表") @operation_log("企业管理", "设备管理", consts.op_type_list_str, "企业节点,设备列表")
def post(self): def post(self):
node_id = self.get_int_argument("node_id") node_id = self.get_int_argument("node_id")
pageNo = self.get_int_argument("pageNo", 1) pageNo = self.get_int_argument("pageNo", 1)
@ -337,7 +337,7 @@ class DeviceInfoHandler(APIHandler):
``` ```
""" """
@authenticated @authenticated
@operation_log("企业管理", "设备管理", consts.op_type_list, "企业节点,设备信息") @operation_log("企业管理", "设备管理", consts.op_type_list_str, "企业节点,设备信息")
def post(self): def post(self):
device_id = self.get_int_argument("device_id") device_id = self.get_int_argument("device_id")
if not device_id: if not device_id:
@ -382,7 +382,7 @@ class DeviceBasemodelListHandler(APIHandler):
""" """
@authenticated @authenticated
@operation_log("企业管理", "节点设置", consts.op_type_list, "企业节点,节点信息 -> 设备列表 -> 基础模型配置 -> 模型列表") @operation_log("企业管理", "节点设置", consts.op_type_list_str, "企业节点,节点信息 -> 设备列表 -> 基础模型配置 -> 模型列表")
def post(self): def post(self):
device_id = self.get_int_argument("device_id") device_id = self.get_int_argument("device_id")
if not device_id: if not device_id:

@ -105,7 +105,7 @@ class EntityIndexHandler(APIHandler):
"industry": consts.industry_map[item["industry"]], "industry": consts.industry_map[item["industry"]],
"modelCount": model_count, "modelCount": model_count,
"deviceCount": device_count, "deviceCount": device_count,
"logo": item["logo"], "logo": str(item["logo"]),
"createTime": str(item["create_time"]), "createTime": str(item["create_time"]),
} }
for item, model_count, device_count in zip( for item, model_count, device_count in zip(
@ -298,12 +298,13 @@ class EntityInfoHandler(APIHandler):
"province": row["province"], "province": row["province"],
"city": row["city"], "city": row["city"],
"addr": row["addr"], "addr": row["addr"],
"industry": consts.industry_map[row["industry"]], "industry": row["industry"],
"industry_name": consts.industry_map[row["industry"]],
"expire_at": "", "expire_at": "",
"contact": row["contact"], "contact": row["contact"],
"phone": row["phone"], "phone": row["phone"],
"summary": row["summary"], "summary": row["summary"],
"logo": row["logo"], "logo": str(row["logo"]),
"createTime": str(row["create_time"]), "createTime": str(row["create_time"]),
"account": row["account"], # 企业账号 "account": row["account"], # 企业账号
} }
@ -321,18 +322,21 @@ class ModelsHandler(APIHandler):
model_ids = [] model_ids = []
with self.app_mysql.connect() as conn: with self.app_mysql.connect() as conn:
cur = conn.execute( cur_modelid = conn.execute(
text("select base_models from enterprise_busi_model where entity_id=:eid"), {"eid": eid} text("select base_models from enterprise_busi_model where entity_id=:eid"), {"eid": eid}
) )
rows = db_mysql.to_json_list(cur) rows = db_mysql.to_json_list(cur_modelid)
for row in rows: for row in rows:
base_models = json.loads(row["base_models"]) base_models = json.loads(row["base_models"])
model_ids.extend([item["id"] for item in base_models]) model_ids.extend([item["id"] for item in base_models])
cur.close() cur_modelid.close()
model_ids = list(set(model_ids)) model_ids = list(set(model_ids))
data = []
if len(model_ids) > 0:
cur = conn.execute(text( cur = conn.execute(text(
""" """
select m.name, m.model_type, mc.name as classification_name, m.default_version select m.name, m.model_type, mc.name as classification_name, m.default_version
@ -344,7 +348,6 @@ class ModelsHandler(APIHandler):
rows = db_mysql.to_json_list(cur) rows = db_mysql.to_json_list(cur)
cur.close() cur.close()
data = []
for row in rows: for row in rows:
data.append({ data.append({
"name": row["name"], "name": row["name"],

@ -1,5 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import json import json
import logging
from website import errors, consts from website import errors, consts
from website.db.enterprise_busi_model import enterprise_busi_model as DB_BusiModel from website.db.enterprise_busi_model import enterprise_busi_model as DB_BusiModel
@ -157,6 +158,7 @@ class TreeHandler(APIHandler):
def post(self): def post(self):
entity_id = self.get_escaped_argument("entity_id", "") entity_id = self.get_escaped_argument("entity_id", "")
name = self.get_escaped_argument("name", "") name = self.get_escaped_argument("name", "")
# logging.info(f"name is {name}")
if not entity_id: if not entity_id:
raise errors.HTTPAPIError(errors.ERROR_BAD_REQUEST, "参数错误") raise errors.HTTPAPIError(errors.ERROR_BAD_REQUEST, "参数错误")

@ -4,11 +4,13 @@ import json
import logging import logging
import uuid import uuid
from io import BytesIO from io import BytesIO
from typing import Optional, Awaitable
from sqlalchemy import text from sqlalchemy import text
from website import db_mysql from website import db_mysql
from website import errors from website import errors
from website import consts
from website import settings from website import settings
from website.handler import APIHandler, authenticated from website.handler import APIHandler, authenticated
from website.util import aes from website.util import aes
@ -17,6 +19,7 @@ from website.util.captcha import create_validate_code
class CaptchaHandler(APIHandler): class CaptchaHandler(APIHandler):
def get(self): def get(self):
self.set_header("Content-Type", "image/png") self.set_header("Content-Type", "image/png")
image, image_str = create_validate_code() image, image_str = create_validate_code()
@ -44,6 +47,23 @@ class LogoutHandler(APIHandler):
# self.current_user.name, self.request.remote_ip, "平台管理中心", "账号管理", "登出", "系统登出", "系统登出" # self.current_user.name, self.request.remote_ip, "平台管理中心", "账号管理", "登出", "系统登出", "系统登出"
# ) # )
with self.app_mysql.connect() as conn:
conn.execute(text(
"insert into sys_log(user, ip, primary_menu, sub_menu, op_type, content, comment) "
"values(:user, :ip, :primary_menu, :sub_menu, :op_type, :content, :comment)"
),
{"user": self.current_user.name,
"ip": self.request.headers[
"X-Forwarded-For"] if "X-Forwarded-For" in self.request.headers else self.request.remote_ip,
"primary_menu": "系统操作",
"sub_menu": "登录/登出",
"op_type": consts.op_type_login_logout_str,
"content": "退出登录",
"comment": ""
}
)
conn.commit()
self.r_app.delete(settings.session_key_prefix % self.current_user.uuid) self.r_app.delete(settings.session_key_prefix % self.current_user.uuid)
self.finish() self.finish()
@ -162,6 +182,23 @@ class LoginHandler(APIHandler):
# "system_status": system_status, # 9000/未激活, 9001/已激活, 9002/过期可查看, 9003/完全过期 # "system_status": system_status, # 9000/未激活, 9001/已激活, 9002/过期可查看, 9003/完全过期
} }
with self.app_mysql.connect() as conn:
conn.execute(text(
"insert into sys_log(user, ip, primary_menu, sub_menu, op_type, content, comment) "
"values(:user, :ip, :primary_menu, :sub_menu, :op_type, :content, :comment)"
),
{"user": username,
"ip": self.request.headers[
"X-Forwarded-For"] if "X-Forwarded-For" in self.request.headers else self.request.remote_ip,
"primary_menu": "系统操作",
"sub_menu": "登录/登出",
"op_type": consts.op_type_login_logout_str,
"content": "登录成功",
"comment": ""
}
)
conn.commit()
self.finish(render_data) self.finish(render_data)

Loading…
Cancel
Save