zc 3 months ago
parent 743fe1017b
commit fa8478d6e3
  1. 27
      app/__init__.py
  2. 2
      app/api/__init__.py
  3. 19
      app/api/chat/ai/chat_service.py
  4. 6
      app/api/upload/__init__.py
  5. 74
      app/api/upload/upload.py
  6. 5
      app/api/v1/__init__.py
  7. 8
      app/api/v1/quick_question/__init__.py
  8. 52
      app/api/v1/quick_question/quick_question.py
  9. 10
      app/controllers/quick_question.py
  10. 26
      app/core/middlewares.py
  11. 13
      app/models/quick_question.py
  12. 21
      app/schemas/quick_question.py
  13. 14
      app/settings/config.py
  14. 1
      pyproject.toml
  15. 3
      requirements.txt
  16. 4
      run.py
  17. 2
      web/.env.development
  18. 3
      web/i18n/messages/cn.json
  19. 3
      web/i18n/messages/en.json
  20. 2
      web/package.json
  21. 482
      web/pnpm-lock.yaml
  22. 6
      web/src/api/index.js
  23. 2
      web/src/router/routes/index.js
  24. 2
      web/src/views/login/index.vue
  25. 342
      web/src/views/system/question/index.vue
  26. 5
      web/vite.config.js

@ -1,7 +1,9 @@
import os
from contextlib import asynccontextmanager
from fastapi import FastAPI
from tortoise import Tortoise
from redis.asyncio import Redis
from fastapi.staticfiles import StaticFiles
from app.core.exceptions import SettingNotFound
from app.core.init_app import (
@ -10,7 +12,7 @@ from app.core.init_app import (
register_exceptions,
register_routers,
)
from aiomysql import create_pool
try:
from app.settings.config import settings
except ImportError:
@ -19,6 +21,25 @@ except ImportError:
@asynccontextmanager
async def lifespan(app: FastAPI):
try:
mysql_port = int(os.getenv("MYSQL_PORT", 3306))
app.state.mysql_pool = await create_pool(
host=settings.FLOW_MYSQL_HOST,
port=settings.FLOW_MYSQL_PORT,
user=settings.FLOW_MYSQL_USER,
password=settings.FLOW_MYSQL_PASSWORD,
db=settings.FLOW_MYSQL_DB,
minsize=5,
maxsize=20,
autocommit=True
)
# 简单测试连接有效性
async with app.state.mysql_pool.acquire() as conn:
await conn.ping()
print("✅ MySQL 连接成功")
except Exception as e:
print(f"❌ MySQL 连接失败: {e}")
raise
try:
# 初始化 Redis 连接
app.state.redis_client = Redis(
@ -53,6 +74,10 @@ def create_app() -> FastAPI:
middleware=make_middlewares(),
lifespan=lifespan,
)
# 配置静态文件服务
app.mount("/resource", StaticFiles(directory=os.path.join(settings.BASE_DIR, 'web', 'public', 'resource')), name="resource")
register_exceptions(app)
register_routers(app, prefix="/api")
return app

@ -1,11 +1,13 @@
from fastapi import APIRouter
from .chat import chat_router
from .upload import upload_router
from .v1 import v1_router
api_router = APIRouter()
api_router.include_router(v1_router, prefix="/v1")
api_router.include_router(chat_router, prefix="")
api_router.include_router(upload_router, prefix="")
__all__ = ["api_router"]

@ -105,20 +105,20 @@ async def query_flow(request: Request, spot: str) -> str:
pool = request.app.state.mysql_pool
async with pool.acquire() as conn:
async with conn.cursor() as cur:
query = "SELECT SUM(t1.init_num) AS init_num, SUM(t1.out_num) AS out_num FROM equipment_passenger_flow.flow_current_video t1 LEFT JOIN cyjcpt_bd.zhly_video_manage t2 ON t1.mac_address = t2.mac_address LEFT JOIN cyjcpt_bd.zhly_scenic_basic t3 ON t2.video_scenic_id = t3.id WHERE t3.`name` LIKE %s"
query = "SELECT SUM(t1.init_num) AS init_num, SUM(t1.out_num) AS out_num,t3.realtime_load_capacity FROM equipment_passenger_flow.flow_current_video t1 LEFT JOIN cyjcpt_bd.zhly_video_manage t2 ON t1.mac_address = t2.mac_address LEFT JOIN cyjcpt_bd.zhly_scenic_basic t3 ON t2.video_scenic_id = t3.id WHERE t3.`name` LIKE %s"
search_spot = f"%{spot}%"
await cur.execute(query, (search_spot,))
row = await cur.fetchone()
except Exception as e:
print(f"[MySQL] 查询失败: {e}")
return f"**未找到景区【{spot}】的信息,请检查名称是否正确。\n\n(内容由AI生成,仅供参考)"
return f"**未找到景区【{spot}】的信息,请检查名称是否正确。\n\n(内容仅供参考)"
print("数据库查询结果", row)
if not row:
print(f"No data found for spot: {spot}")
return f"**未找到景区【{spot}】的信息,请检查名称是否正确。\n\n(内容由AI生成,仅供参考)"
return f"**未找到景区【{spot}】的信息,请检查名称是否正确。\n\n(内容仅供参考)"
# 修改结果拼接部分,使用新的列名
result = f"**{spot} 客流**\n\n进入人数: {row[0]}\n离开人数: {row[1]}\n\n(内容由AI生成,仅供参考)"
result = f"**{spot} 客流**\n\n进入人数: {row[0]}\n离开人数: {row[1]}\n\n景区瞬时承载量:{row[2]},暂无停车场数据(内容仅供参考)"
# Step 3: 写入 Redis 缓存
print(f"Writing data to Redis cache for key: {cache_key}")
@ -130,7 +130,16 @@ async def query_flow(request: Request, spot: str) -> str:
return result
async def gen_markdown_stream(msg: str, data: str, language: str, conversation_history: list) -> AsyncGenerator[str, None]:
prompt = f"用户问题:{msg}\n查询到的内容为:{data}\n请结合用户问题和查询到的内容,自行优化回复内容,如果内容格式允许的话加上markdown语法。输出语言为:{language}"
prompt = f"""结合用户问题:{msg} 和查询内容:{data},生成出行建议,
包括景区实时信息展示景区名称和在园人数=进入人数-离开人数若为负取绝对值超出最大承载量时仅展示在园人数
进入/离开人数和瞬时承载量不展示承载率仅以舒适度等级汉字形式体现不展示百分比
舒适度解读根据承载率范围输出等级并用 HTML 字体颜色标签展示
<font color="green">舒适</font> <font color="blue">较舒适</font> <font color="yellow">一般</font> <font color="orange">较拥挤</font> <font color="red">拥挤</font>不要加括号或冗余说明仅展示彩色词语
核心出行建议是否前往强烈推荐/推荐/谨慎考虑/暂缓前往/强烈不建议错峰建议如当日16:00后或次日8:30
交通建议停车场充足推荐自驾紧张建议打车或备用停车场已满建议使用公共交通如XX路公交路线建议反常规路线或人少区域
时间预留较舒适多10%一般多20%较拥挤/拥挤多30%-50%替代方案当较拥挤或拥挤时推荐1-2个周边承载率低的同类景区并说明优势
温馨提示如安全提醒天气影响整体风格友好专业有条理语言自然不展示原始字段数据结尾不输出数据时间仅加提示结果仅供参考输出语言为{language}"""
messages = conversation_history + [{"role": "user", "content": prompt}]
print(f"Starting markdown stream with message: {msg} and data: {data}")

@ -0,0 +1,6 @@
# app/api/v1/upload/__init__.py
from fastapi import APIRouter
from .upload import router as upload_router
upload_api_router = APIRouter()
upload_api_router.include_router(upload_router, prefix='/upload')

@ -0,0 +1,74 @@
# app/api/v1/upload/upload.py
import os
import uuid
from fastapi import APIRouter, File, UploadFile
from fastapi.responses import JSONResponse
from app.settings.config import settings
router = APIRouter()
# 文件存储根目录
UPLOAD_DIR = os.path.join(settings.BASE_DIR, 'web', 'public', 'resource')
@router.post('/image', summary='上传图片')
async def upload_image(file: UploadFile = File(...)):
try:
# 确保目录存在
os.makedirs(os.path.join(UPLOAD_DIR, 'images'), exist_ok=True)
# 生成唯一文件名
filename = f'{uuid.uuid4()}_{file.filename}'
file_path = os.path.join(UPLOAD_DIR, 'images', filename)
# 保存文件
with open(file_path, 'wb') as f:
f.write(await file.read())
# 构建访问URL
file_url = f'/resource/images/{filename}'
return JSONResponse({
'errno': 0,
'data': [{
'url': file_url,
'alt': '',
'href': ''
}]
})
except Exception as e:
return JSONResponse({
'errno': 1,
'message': str(e)
})
@router.post('/video', summary='上传视频')
async def upload_video(file: UploadFile = File(...)):
try:
# 确保目录存在
os.makedirs(os.path.join(UPLOAD_DIR, 'videos'), exist_ok=True)
# 生成唯一文件名
filename = f'{uuid.uuid4()}_{file.filename}'
file_path = os.path.join(UPLOAD_DIR, 'videos', filename)
# 保存文件
with open(file_path, 'wb') as f:
f.write(await file.read())
# 构建访问URL
file_url = f'/resource/videos/{filename}'
return JSONResponse({
'errno': 0,
'data': {
'url': file_url,
'duration': 0 # 实际应用中可以计算视频时长
}
})
except Exception as e:
return JSONResponse({
'errno': 1,
'message': str(e)
})

@ -9,6 +9,8 @@ from .depts import depts_router
from .menus import menus_router
from .roles import roles_router
from .users import users_router
from .quick_question import quick_question_router
from app.api.upload import upload_api_router
v1_router = APIRouter()
@ -19,4 +21,7 @@ v1_router.include_router(menus_router, prefix="/menu", dependencies=[DependPermi
v1_router.include_router(apis_router, prefix="/api", dependencies=[DependPermission])
v1_router.include_router(depts_router, prefix="/dept", dependencies=[DependPermission])
v1_router.include_router(auditlog_router, prefix="/auditlog", dependencies=[DependPermission])
v1_router.include_router(quick_question_router, prefix="/question", dependencies=[DependPermission])
v1_router.include_router(upload_api_router)

@ -0,0 +1,8 @@
# app/api/v1/quick_question/__init__.py
from fastapi import APIRouter
from .quick_question import router
quick_question_router = APIRouter()
quick_question_router.include_router(router, tags=["快捷问题模块"])
__all__ = ["quick_question_router"]

@ -0,0 +1,52 @@
# app/api/v1/quick_question/quick_question.py
import logging
from fastapi import APIRouter, Body, Query
from tortoise.expressions import Q
from app.controllers.quick_question import quick_question_controller
from app.schemas.base import Fail, Success, SuccessExtra
from app.schemas.quick_question import QuickQuestionCreate, QuickQuestionUpdate, QuickQuestionResponse
logger = logging.getLogger(__name__)
router = APIRouter()
@router.get("/list", summary="查看快捷问题列表")
async def list_quick_question(
page: int = Query(1, description="页码"),
page_size: int = Query(10, description="每页数量"),
title: str = Query("", description="标题,用于搜索"),
):
q = Q()
if title:
q &= Q(title__contains=title)
total, question_objs = await quick_question_controller.list(page=page, page_size=page_size, search=q)
data = [await obj.to_dict() for obj in question_objs]
return SuccessExtra(data=data, total=total, page=page, page_size=page_size)
@router.get("/get", summary="查看快捷问题")
async def get_quick_question(
question_id: int = Query(..., description="快捷问题ID"),
):
question_obj = await quick_question_controller.get(id=question_id)
question_dict = await question_obj.to_dict()
return Success(data=question_dict)
@router.post("/create", summary="创建快捷问题")
async def create_quick_question(
question_in: QuickQuestionCreate,
):
new_question = await quick_question_controller.create(obj_in=question_in)
return Success(msg="Created Successfully")
@router.post("/update", summary="更新快捷问题")
async def update_quick_question(
question_in: QuickQuestionUpdate,
):
question = await quick_question_controller.update(id=question_in.id, obj_in=question_in)
return Success(msg="Updated Successfully")
@router.delete("/delete", summary="删除快捷问题")
async def delete_quick_question(
question_id: int = Query(..., description="快捷问题ID"),
):
await quick_question_controller.remove(id=question_id)
return Success(msg="Deleted Successfully")

@ -0,0 +1,10 @@
# app/controllers/quick_question.py
from app.core.crud import CRUDBase
from app.models.quick_question import QuickQuestion
from app.schemas.quick_question import QuickQuestionCreate, QuickQuestionUpdate
class QuickQuestionController(CRUDBase[QuickQuestion, QuickQuestionCreate, QuickQuestionUpdate]):
def __init__(self):
super().__init__(model=QuickQuestion)
quick_question_controller = QuickQuestionController()

@ -63,12 +63,27 @@ class HttpAuditLogMiddleware(BaseHTTPMiddleware):
# 获取请求体
if request.method in ["POST", "PUT", "PATCH"]:
try:
body = await request.json()
args.update(body)
except json.JSONDecodeError:
# 检查内容类型
content_type = request.headers.get("content-type", "")
if "multipart/form-data" in content_type:
# 文件上传请求,使用form()
body = await request.form()
for k, v in body.items():
if hasattr(v, "filename"): # 文件上传行为
args[k] = v.filename
elif isinstance(v, list) and v and hasattr(v[0], "filename"):
args[k] = [file.filename for file in v]
else:
args[k] = v
else:
# 尝试JSON解析
body = await request.json()
args.update(body)
except (json.JSONDecodeError, UnicodeDecodeError, Exception):
# 捕获所有可能的错误,包括UnicodeDecodeError
try:
# 尝试作为普通表单数据处理
body = await request.form()
# args.update(body)
for k, v in body.items():
if hasattr(v, "filename"): # 文件上传行为
args[k] = v.filename
@ -78,7 +93,8 @@ class HttpAuditLogMiddleware(BaseHTTPMiddleware):
args[k] = v
except Exception:
pass
except Exception:
pass
return args
async def get_response_body(self, request: Request, response: Response) -> Any:

@ -0,0 +1,13 @@
# app/models/quick_question.py
from tortoise import fields
from .base import BaseModel
class QuickQuestion(BaseModel):
title = fields.CharField(max_length=255, null=True, description="标题")
order_num = fields.IntField(null=True, description="显示顺序")
status = fields.CharField(max_length=1, default='0', description="状态(0正常 1停用)")
content = fields.TextField(null=True, description="内容")
create_time = fields.DatetimeField(auto_now_add=True, description="创建时间")
class Meta:
table = "quick_question"

@ -0,0 +1,21 @@
# app/schemas/quick_question.py
from pydantic import BaseModel
class QuickQuestionBase(BaseModel):
title: str
order_num: int
status: str
content: str
class QuickQuestionCreate(QuickQuestionBase):
pass
class QuickQuestionUpdate(QuickQuestionBase):
id: int
class QuickQuestionResponse(QuickQuestionBase):
id: int
create_time: str
class Config:
orm_mode = True

@ -31,6 +31,12 @@ class Settings(BaseSettings):
REDIS_PORT: int = 33062
REDIS_DB: int = 1
REDIS_PASSWORD: str = "cjy@123abc"
# flow mysql
FLOW_MYSQL_HOST: str = "39.105.17.128"
FLOW_MYSQL_PORT: int = 33068
FLOW_MYSQL_USER: str = "root"
FLOW_MYSQL_PASSWORD: str = "Mysql@1303"
FLOW_MYSQL_DB: str = "equipment_passenger_flow"
# 验签秘钥
SIGN_KEY: str = "qIaGO0fZJNW2f0DM6upT"
TORTOISE_ORM: dict = {
@ -45,10 +51,10 @@ class Settings(BaseSettings):
"mysql": {
"engine": "tortoise.backends.mysql",
"credentials": {
"host": "localhost", # Database host address
"port": 3306, # Database port
"host": "39.105.17.128", # Database host address
"port": 33068, # Database port
"user": "root", # Database username
"password": "root", # Database password
"password": "Mysql@1303", # Database password
"database": "bd_ai_fastapi", # Database name
},
},
@ -91,7 +97,7 @@ class Settings(BaseSettings):
},
"apps": {
"models": {
"models": ["app.models", "aerich.models"],
"models": ["app.models", "aerich.models","app.models.quick_question"],
"default_connection": "mysql",
},
},

@ -72,6 +72,7 @@ dependencies = [
"openai>=1.97.1",
"aiomysql>=0.2.0",
"redis>=6.2.0",
"sqlalchemy>=2.0.42"
]
[tool.setuptools]

@ -60,4 +60,5 @@ watchfiles==1.0.4
websockets==14.1
openai==1.97.1
aiomysql==0.2.0
redis==6.2.0
redis==6.2.0
sqlalchemy==2.0.42

@ -10,4 +10,6 @@ if __name__ == "__main__":
] = '%(asctime)s - %(levelname)s - %(client_addr)s - "%(request_line)s" %(status_code)s'
LOGGING_CONFIG["formatters"]["access"]["datefmt"] = "%Y-%m-%d %H:%M:%S"
uvicorn.run("app:app", host="0.0.0.0", port=9999, reload=True, log_config=LOGGING_CONFIG)
uvicorn.run("app:app", host="0.0.0.0", port=8111, reload=False, log_config=LOGGING_CONFIG
#,ssl_keyfile="/data/docker/sh_toilet/nginx/conf/cert/www.hbcjy.com.key",ssl_certfile="/data/docker/sh_toilet/nginx/conf/cert/www.hbcjy.com.pem"
)

@ -5,4 +5,4 @@ VITE_PUBLIC_PATH = '/'
VITE_USE_PROXY = true
# base api
VITE_BASE_API = 'http://localhost:9999/api/v1'
VITE_BASE_API = 'http://localhost:8111/api/v1'

@ -46,6 +46,9 @@
"message_password_confirmation_required": "请再次输入密码",
"message_password_confirmation_diff": "两次密码输入不一致"
},
"quick_question": {
"label_quick_question": "快捷问题管理"
},
"errors": {
"label_error": "错误页",
"text_back_to_home": "返回首页"

@ -46,6 +46,9 @@
"message_password_confirmation_required": "Please enter confirm password",
"message_password_confirmation_diff": "Two password inputs are inconsistent"
},
"quick_question": {
"label_quick_question": "Quick Question Management"
},
"errors": {
"label_error": "Error",
"text_back_to_home": "Back to home"

@ -16,6 +16,8 @@
"@iconify/vue": "^4.1.1",
"@unocss/eslint-config": "^0.55.0",
"@vueuse/core": "^10.3.0",
"@wangeditor/editor": "^5.1.23",
"@wangeditor/editor-for-vue": "^5.1.12",
"@zclzone/eslint-config": "^0.0.4",
"axios": "^1.4.0",
"dayjs": "^1.11.9",

@ -20,6 +20,12 @@ importers:
'@vueuse/core':
specifier: ^10.3.0
version: 10.11.0(vue@3.4.34(typescript@5.5.4))
'@wangeditor/editor':
specifier: ^5.1.23
version: 5.1.23
'@wangeditor/editor-for-vue':
specifier: ^5.1.12
version: 5.1.12(@wangeditor/editor@5.1.23)(vue@3.4.34(typescript@5.5.4))
'@zclzone/eslint-config':
specifier: ^0.0.4
version: 0.0.4
@ -382,6 +388,9 @@ packages:
rollup:
optional: true
'@transloadit/prettier-bytes@0.0.7':
resolution: {integrity: sha512-VeJbUb0wEKbcwaSlj5n+LscBl9IPgLPkHVGBkh00cztv6X4L/TJXK58LzFuBKX7/GAfiGhIwH67YTLTlzvIzBA==}
'@trysound/sax@0.2.0':
resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
engines: {node: '>=10.13.0'}
@ -389,6 +398,9 @@ packages:
'@types/estree@1.0.5':
resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==}
'@types/event-emitter@0.3.5':
resolution: {integrity: sha512-zx2/Gg0Eg7gwEiOIIh5w9TrhKKTeQh7CPCOPNc0el4pLSwzebA8SmnHwZs2dWlLONvyulykSwGSQxQHLhjGLvQ==}
'@types/json-schema@7.0.15':
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
@ -533,6 +545,23 @@ packages:
peerDependencies:
vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0
'@uppy/companion-client@2.2.2':
resolution: {integrity: sha512-5mTp2iq97/mYSisMaBtFRry6PTgZA6SIL7LePteOV5x0/DxKfrZW3DEiQERJmYpHzy7k8johpm2gHnEKto56Og==}
'@uppy/core@2.3.4':
resolution: {integrity: sha512-iWAqppC8FD8mMVqewavCz+TNaet6HPXitmGXpGGREGrakZ4FeuWytVdrelydzTdXx6vVKkOmI2FLztGg73sENQ==}
'@uppy/store-default@2.1.1':
resolution: {integrity: sha512-xnpTxvot2SeAwGwbvmJ899ASk5tYXhmZzD/aCFsXePh/v8rNvR2pKlcQUH7cF/y4baUGq3FHO/daKCok/mpKqQ==}
'@uppy/utils@4.1.3':
resolution: {integrity: sha512-nTuMvwWYobnJcytDO3t+D6IkVq/Qs4Xv3vyoEZ+Iaf8gegZP+rEyoaFT2CK5XLRMienPyqRqNbIfRuFaOWSIFw==}
'@uppy/xhr-upload@2.1.3':
resolution: {integrity: sha512-YWOQ6myBVPs+mhNjfdWsQyMRWUlrDLMoaG7nvf/G6Y3GKZf8AyjFDjvvJ49XWQ+DaZOftGkHmF1uh/DBeGivJQ==}
peerDependencies:
'@uppy/core': ^2.3.3
'@vitejs/plugin-vue@4.6.2':
resolution: {integrity: sha512-kqf7SGFoG+80aZG6Pf+gsZIVvGSCKE98JbiWqcCV9cThtg91Jav0yvYFC9Zb+jKetNGF6ZKeoaxgZfND21fWKw==}
engines: {node: ^14.18.0 || >=16.0.0}
@ -581,6 +610,93 @@ packages:
'@vueuse/shared@10.11.0':
resolution: {integrity: sha512-fyNoIXEq3PfX1L3NkNhtVQUSRtqYwJtJg+Bp9rIzculIZWHTkKSysujrOk2J+NrRulLTQH9+3gGSfYLWSEWU1A==}
'@wangeditor/basic-modules@1.1.7':
resolution: {integrity: sha512-cY9CPkLJaqF05STqfpZKWG4LpxTMeGSIIF1fHvfm/mz+JXatCagjdkbxdikOuKYlxDdeqvOeBmsUBItufDLXZg==}
peerDependencies:
'@wangeditor/core': 1.x
dom7: ^3.0.0
lodash.throttle: ^4.1.1
nanoid: ^3.2.0
slate: ^0.72.0
snabbdom: ^3.1.0
'@wangeditor/code-highlight@1.0.3':
resolution: {integrity: sha512-iazHwO14XpCuIWJNTQTikqUhGKyqj+dUNWJ9288Oym9M2xMVHvnsOmDU2sgUDWVy+pOLojReMPgXCsvvNlOOhw==}
peerDependencies:
'@wangeditor/core': 1.x
dom7: ^3.0.0
slate: ^0.72.0
snabbdom: ^3.1.0
'@wangeditor/core@1.1.19':
resolution: {integrity: sha512-KevkB47+7GhVszyYF2pKGKtCSj/YzmClsD03C3zTt+9SR2XWT5T0e3yQqg8baZpcMvkjs1D8Dv4fk8ok/UaS2Q==}
peerDependencies:
'@uppy/core': ^2.1.1
'@uppy/xhr-upload': ^2.0.3
dom7: ^3.0.0
is-hotkey: ^0.2.0
lodash.camelcase: ^4.3.0
lodash.clonedeep: ^4.5.0
lodash.debounce: ^4.0.8
lodash.foreach: ^4.5.0
lodash.isequal: ^4.5.0
lodash.throttle: ^4.1.1
lodash.toarray: ^4.4.0
nanoid: ^3.2.0
slate: ^0.72.0
snabbdom: ^3.1.0
'@wangeditor/editor-for-vue@5.1.12':
resolution: {integrity: sha512-0Ds3D8I+xnpNWezAeO7HmPRgTfUxHLMd9JKcIw+QzvSmhC5xUHbpCcLU+KLmeBKTR/zffnS5GQo6qi3GhTMJWQ==}
peerDependencies:
'@wangeditor/editor': '>=5.1.0'
vue: ^3.0.5
'@wangeditor/editor@5.1.23':
resolution: {integrity: sha512-0RxfeVTuK1tktUaPROnCoFfaHVJpRAIE2zdS0mpP+vq1axVQpLjM8+fCvKzqYIkH0Pg+C+44hJpe3VVroSkEuQ==}
'@wangeditor/list-module@1.0.5':
resolution: {integrity: sha512-uDuYTP6DVhcYf7mF1pTlmNn5jOb4QtcVhYwSSAkyg09zqxI1qBqsfUnveeDeDqIuptSJhkh81cyxi+MF8sEPOQ==}
peerDependencies:
'@wangeditor/core': 1.x
dom7: ^3.0.0
slate: ^0.72.0
snabbdom: ^3.1.0
'@wangeditor/table-module@1.1.4':
resolution: {integrity: sha512-5saanU9xuEocxaemGdNi9t8MCDSucnykEC6jtuiT72kt+/Hhh4nERYx1J20OPsTCCdVr7hIyQenFD1iSRkIQ6w==}
peerDependencies:
'@wangeditor/core': 1.x
dom7: ^3.0.0
lodash.isequal: ^4.5.0
lodash.throttle: ^4.1.1
nanoid: ^3.2.0
slate: ^0.72.0
snabbdom: ^3.1.0
'@wangeditor/upload-image-module@1.0.2':
resolution: {integrity: sha512-z81lk/v71OwPDYeQDxj6cVr81aDP90aFuywb8nPD6eQeECtOymrqRODjpO6VGvCVxVck8nUxBHtbxKtjgcwyiA==}
peerDependencies:
'@uppy/core': ^2.0.3
'@uppy/xhr-upload': ^2.0.3
'@wangeditor/basic-modules': 1.x
'@wangeditor/core': 1.x
dom7: ^3.0.0
lodash.foreach: ^4.5.0
slate: ^0.72.0
snabbdom: ^3.1.0
'@wangeditor/video-module@1.1.4':
resolution: {integrity: sha512-ZdodDPqKQrgx3IwWu4ZiQmXI8EXZ3hm2/fM6E3t5dB8tCaIGWQZhmqd6P5knfkRAd3z2+YRSRbxOGfoRSp/rLg==}
peerDependencies:
'@uppy/core': ^2.1.4
'@uppy/xhr-upload': ^2.0.7
'@wangeditor/core': 1.x
dom7: ^3.0.0
nanoid: ^3.2.0
slate: ^0.72.0
snabbdom: ^3.1.0
'@zclzone/eslint-config@0.0.4':
resolution: {integrity: sha512-dDDHsLc0qEt/tczC1nRU5d+2LCOPwwKohw5Wlq4A1mTFgTQaFoSDmP/j9XnAbjCYfxbGUeEat0221WwwVbPhuw==}
@ -789,6 +905,9 @@ packages:
component-emitter@1.3.1:
resolution: {integrity: sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==}
compute-scroll-into-view@1.0.20:
resolution: {integrity: sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg==}
concat-map@0.0.1:
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
@ -851,6 +970,10 @@ packages:
csstype@3.1.3:
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
d@1.0.2:
resolution: {integrity: sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==}
engines: {node: '>=0.12'}
data-view-buffer@1.0.1:
resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==}
engines: {node: '>= 0.4'}
@ -947,6 +1070,9 @@ packages:
dom-serializer@1.4.1:
resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==}
dom7@3.0.0:
resolution: {integrity: sha512-oNlcUdHsC4zb7Msx7JN3K0Nro1dzJ48knvBOnDPKJ2GV9wl1i5vydJZUSyOfrkKFDZEud/jBsTk92S/VGSAe/g==}
domelementtype@1.3.1:
resolution: {integrity: sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==}
@ -1026,6 +1152,17 @@ packages:
resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==}
engines: {node: '>= 0.4'}
es5-ext@0.10.64:
resolution: {integrity: sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==}
engines: {node: '>=0.10'}
es6-iterator@2.0.3:
resolution: {integrity: sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==}
es6-symbol@3.1.4:
resolution: {integrity: sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==}
engines: {node: '>=0.12'}
esbuild@0.18.20:
resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==}
engines: {node: '>=12'}
@ -1083,6 +1220,10 @@ packages:
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
hasBin: true
esniff@2.0.1:
resolution: {integrity: sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==}
engines: {node: '>=0.10'}
espree@9.6.1:
resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@ -1113,6 +1254,9 @@ packages:
resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==}
engines: {node: '>= 0.6'}
event-emitter@0.3.5:
resolution: {integrity: sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==}
evtd@0.2.4:
resolution: {integrity: sha512-qaeGN5bx63s/AXgQo8gj6fBkxge+OoLddLniox5qtLAEY5HSnuSlISXVPxnSae1dWblvTh4/HoMIB+mbMsvZzw==}
@ -1124,6 +1268,9 @@ packages:
resolution: {integrity: sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==}
engines: {node: '>=0.10.0'}
ext@1.7.0:
resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==}
extend-shallow@2.0.1:
resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==}
engines: {node: '>=0.10.0'}
@ -1347,6 +1494,9 @@ packages:
engines: {node: '>=12'}
hasBin: true
html-void-elements@2.0.1:
resolution: {integrity: sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==}
htmlparser2@3.10.1:
resolution: {integrity: sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==}
@ -1354,6 +1504,9 @@ packages:
resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
engines: {node: '>=10.17.0'}
i18next@20.6.1:
resolution: {integrity: sha512-yCMYTMEJ9ihCwEQQ3phLo7I/Pwycf8uAx+sRHwwk5U9Aui/IZYgQRyMqXafQOw5QQ7DM1Z+WyEXWIqSuJHhG2A==}
ignore@5.3.1:
resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==}
engines: {node: '>= 4'}
@ -1363,6 +1516,9 @@ packages:
engines: {node: '>=0.10.0'}
hasBin: true
immer@9.0.21:
resolution: {integrity: sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==}
immutable@4.3.7:
resolution: {integrity: sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==}
@ -1460,6 +1616,9 @@ packages:
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
engines: {node: '>=0.10.0'}
is-hotkey@0.2.0:
resolution: {integrity: sha512-UknnZK4RakDmTgz4PI1wIph5yxSs/mvChWs9ifnlXsKuXgWmOkY/hAE0H/k2MIqH0RlRye0i1oC07MCRSD28Mw==}
is-negative-zero@2.0.3:
resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==}
engines: {node: '>= 0.4'}
@ -1488,6 +1647,10 @@ packages:
resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==}
engines: {node: '>=0.10.0'}
is-plain-object@5.0.0:
resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==}
engines: {node: '>=0.10.0'}
is-regex@1.1.4:
resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==}
engines: {node: '>= 0.4'}
@ -1512,6 +1675,9 @@ packages:
resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==}
engines: {node: '>= 0.4'}
is-url@1.2.4:
resolution: {integrity: sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==}
is-weakref@1.0.2:
resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==}
@ -1620,9 +1786,31 @@ packages:
lodash-es@4.17.21:
resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==}
lodash.camelcase@4.3.0:
resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==}
lodash.clonedeep@4.5.0:
resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==}
lodash.debounce@4.0.8:
resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==}
lodash.foreach@4.5.0:
resolution: {integrity: sha512-aEXTF4d+m05rVOAUG3z4vZZ4xVexLKZGF0lIxuHZ1Hplpk/3B6Z1+/ICICYRLm7c41Z2xiejbkCkJoTlypoXhQ==}
lodash.isequal@4.5.0:
resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==}
deprecated: This package is deprecated. Use require('node:util').isDeepStrictEqual instead.
lodash.merge@4.6.2:
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
lodash.throttle@4.1.1:
resolution: {integrity: sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==}
lodash.toarray@4.4.0:
resolution: {integrity: sha512-QyffEA3i5dma5q2490+SgCvDN0pXLmRGSyAANuVi0HQ01Pkfr9fuoKQW8wm1wGBnJITs/mS7wQvS6VshUEBFCw==}
lodash@4.17.21:
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
@ -1669,6 +1857,9 @@ packages:
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
engines: {node: '>= 0.6'}
mime-match@1.0.2:
resolution: {integrity: sha512-VXp/ugGDVh3eCLOBCiHZMYWQaTNUHv2IJrut+yXA6+JbLPXHglHwfS/5A5L0ll+jkCY7fIzRJcH6OIunF+c6Cg==}
mime-types@2.1.35:
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
engines: {node: '>= 0.6'}
@ -1717,6 +1908,9 @@ packages:
peerDependencies:
vue: ^3.0.0
namespace-emitter@2.0.1:
resolution: {integrity: sha512-N/sMKHniSDJBjfrkbS/tpkPj4RAbvW3mr8UAzvlMHyun93XEm83IAvhWtJVHo+RHn/oO8Job5YN4b+wRjSVp5g==}
nanoid@3.3.7:
resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
@ -1729,6 +1923,9 @@ packages:
natural-compare@1.4.0:
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
next-tick@1.1.0:
resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==}
no-case@3.0.4:
resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==}
@ -1909,6 +2106,9 @@ packages:
resolution: {integrity: sha512-spBB5sgC4cv2YcW03f/IAUN1pgDJWNWD8FzkyY4mArLUMJW+KlQhlmUdKAHQuPfb00Jl5xIfImeOsf6YL8QK7Q==}
engines: {node: '>=0.10.0'}
preact@10.27.0:
resolution: {integrity: sha512-/DTYoB6mwwgPytiqQTh/7SFRL98ZdiD8Sk8zIUVOxtwq4oWcwrcd1uno9fE/zZmUaUrFNYzbH14CPebOz9tZQw==}
prelude-ls@1.2.1:
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
engines: {node: '>= 0.8.0'}
@ -1922,6 +2122,10 @@ packages:
engines: {node: '>=10.13.0'}
hasBin: true
prismjs@1.30.0:
resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==}
engines: {node: '>=6'}
proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
@ -2033,6 +2237,9 @@ packages:
engines: {node: '>=14.0.0'}
hasBin: true
scroll-into-view-if-needed@2.2.31:
resolution: {integrity: sha512-dGCXy99wZQivjmjIqihaBQNjryrz5rueJY7eHfTdyWEiR4ttYpsajb14rn9s5d4DY4EcY6+4+U/maARBXJedkA==}
scule@1.3.0:
resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==}
@ -2079,6 +2286,18 @@ packages:
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
engines: {node: '>=8'}
slate-history@0.66.0:
resolution: {integrity: sha512-6MWpxGQZiMvSINlCbMW43E2YBSVMCMCIwQfBzGssjWw4kb0qfvj0pIdblWNRQZD0hR6WHP+dHHgGSeVdMWzfng==}
peerDependencies:
slate: '>=0.65.3'
slate@0.72.8:
resolution: {integrity: sha512-/nJwTswQgnRurpK+bGJFH1oM7naD5qDmHd89JyiKNT2oOKD8marW0QSBtuFnwEbL5aGCS8AmrhXQgNOsn4osAw==}
snabbdom@3.6.2:
resolution: {integrity: sha512-ig5qOnCDbugFntKi6c7Xlib8bA6xiJVk8O+WdFrV3wxbMqeHO0hXFQC4nAhPVWfZfi8255lcZkNhtIBINCc4+Q==}
engines: {node: '>=12.17.0'}
snapdragon-node@2.1.1:
resolution: {integrity: sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==}
engines: {node: '>=0.10.0'}
@ -2122,6 +2341,9 @@ packages:
resolution: {integrity: sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==}
engines: {node: '>=0.10.0'}
ssr-window@3.0.0:
resolution: {integrity: sha512-q+8UfWDg9Itrg0yWK7oe5p/XRCJpJF9OBtXfOPgSJl+u3Xd5KI328RUEvUqSMVM9CiQUEf1QdBzJMkYGErj9QA==}
stable@0.1.8:
resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==}
deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility'
@ -2207,6 +2429,9 @@ packages:
text-table@0.2.0:
resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
tiny-warning@1.0.3:
resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==}
to-fast-properties@2.0.0:
resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
engines: {node: '>=4'}
@ -2255,6 +2480,9 @@ packages:
resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==}
engines: {node: '>=10'}
type@2.7.3:
resolution: {integrity: sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==}
typed-array-buffer@1.0.2:
resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==}
engines: {node: '>= 0.4'}
@ -2499,6 +2727,9 @@ packages:
engines: {node: '>= 8'}
hasBin: true
wildcard@1.1.2:
resolution: {integrity: sha512-DXukZJxpHA8LuotRwL0pP1+rS6CS7FF2qStDDE1C7DDg2rLud2PXRMuEDYIPhgEezwnlHNL4c+N6MfMTjCGTng==}
word-wrap@1.2.5:
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
engines: {node: '>=0.10.0'}
@ -2762,10 +2993,14 @@ snapshots:
optionalDependencies:
rollup: 3.29.4
'@transloadit/prettier-bytes@0.0.7': {}
'@trysound/sax@0.2.0': {}
'@types/estree@1.0.5': {}
'@types/event-emitter@0.3.5': {}
'@types/json-schema@7.0.15': {}
'@types/katex@0.16.7': {}
@ -2987,6 +3222,35 @@ snapshots:
transitivePeerDependencies:
- rollup
'@uppy/companion-client@2.2.2':
dependencies:
'@uppy/utils': 4.1.3
namespace-emitter: 2.0.1
'@uppy/core@2.3.4':
dependencies:
'@transloadit/prettier-bytes': 0.0.7
'@uppy/store-default': 2.1.1
'@uppy/utils': 4.1.3
lodash.throttle: 4.1.1
mime-match: 1.0.2
namespace-emitter: 2.0.1
nanoid: 3.3.7
preact: 10.27.0
'@uppy/store-default@2.1.1': {}
'@uppy/utils@4.1.3':
dependencies:
lodash.throttle: 4.1.1
'@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4)':
dependencies:
'@uppy/companion-client': 2.2.2
'@uppy/core': 2.3.4
'@uppy/utils': 4.1.3
nanoid: 3.3.7
'@vitejs/plugin-vue@4.6.2(vite@4.5.3(@types/node@22.0.0)(sass@1.77.8)(terser@5.31.3))(vue@3.4.34(typescript@5.5.4))':
dependencies:
vite: 4.5.3(@types/node@22.0.0)(sass@1.77.8)(terser@5.31.3)
@ -3067,6 +3331,114 @@ snapshots:
- '@vue/composition-api'
- vue
'@wangeditor/basic-modules@1.1.7(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2))(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2)':
dependencies:
'@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2)
dom7: 3.0.0
is-url: 1.2.4
lodash.throttle: 4.1.1
nanoid: 3.3.7
slate: 0.72.8
snabbdom: 3.6.2
'@wangeditor/code-highlight@1.0.3(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2))(dom7@3.0.0)(slate@0.72.8)(snabbdom@3.6.2)':
dependencies:
'@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2)
dom7: 3.0.0
prismjs: 1.30.0
slate: 0.72.8
snabbdom: 3.6.2
'@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2)':
dependencies:
'@types/event-emitter': 0.3.5
'@uppy/core': 2.3.4
'@uppy/xhr-upload': 2.1.3(@uppy/core@2.3.4)
dom7: 3.0.0
event-emitter: 0.3.5
html-void-elements: 2.0.1
i18next: 20.6.1
is-hotkey: 0.2.0
lodash.camelcase: 4.3.0
lodash.clonedeep: 4.5.0
lodash.debounce: 4.0.8
lodash.foreach: 4.5.0
lodash.isequal: 4.5.0
lodash.throttle: 4.1.1
lodash.toarray: 4.4.0
nanoid: 3.3.7
scroll-into-view-if-needed: 2.2.31
slate: 0.72.8
slate-history: 0.66.0(slate@0.72.8)
snabbdom: 3.6.2
'@wangeditor/editor-for-vue@5.1.12(@wangeditor/editor@5.1.23)(vue@3.4.34(typescript@5.5.4))':
dependencies:
'@wangeditor/editor': 5.1.23
vue: 3.4.34(typescript@5.5.4)
'@wangeditor/editor@5.1.23':
dependencies:
'@uppy/core': 2.3.4
'@uppy/xhr-upload': 2.1.3(@uppy/core@2.3.4)
'@wangeditor/basic-modules': 1.1.7(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2))(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2)
'@wangeditor/code-highlight': 1.0.3(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2))(dom7@3.0.0)(slate@0.72.8)(snabbdom@3.6.2)
'@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2)
'@wangeditor/list-module': 1.0.5(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2))(dom7@3.0.0)(slate@0.72.8)(snabbdom@3.6.2)
'@wangeditor/table-module': 1.1.4(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2))(dom7@3.0.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2)
'@wangeditor/upload-image-module': 1.0.2(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(@wangeditor/basic-modules@1.1.7(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2))(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2))(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2))(dom7@3.0.0)(lodash.foreach@4.5.0)(slate@0.72.8)(snabbdom@3.6.2)
'@wangeditor/video-module': 1.1.4(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2))(dom7@3.0.0)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2)
dom7: 3.0.0
is-hotkey: 0.2.0
lodash.camelcase: 4.3.0
lodash.clonedeep: 4.5.0
lodash.debounce: 4.0.8
lodash.foreach: 4.5.0
lodash.isequal: 4.5.0
lodash.throttle: 4.1.1
lodash.toarray: 4.4.0
nanoid: 3.3.7
slate: 0.72.8
snabbdom: 3.6.2
'@wangeditor/list-module@1.0.5(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2))(dom7@3.0.0)(slate@0.72.8)(snabbdom@3.6.2)':
dependencies:
'@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2)
dom7: 3.0.0
slate: 0.72.8
snabbdom: 3.6.2
'@wangeditor/table-module@1.1.4(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2))(dom7@3.0.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2)':
dependencies:
'@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2)
dom7: 3.0.0
lodash.isequal: 4.5.0
lodash.throttle: 4.1.1
nanoid: 3.3.7
slate: 0.72.8
snabbdom: 3.6.2
'@wangeditor/upload-image-module@1.0.2(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(@wangeditor/basic-modules@1.1.7(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2))(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2))(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2))(dom7@3.0.0)(lodash.foreach@4.5.0)(slate@0.72.8)(snabbdom@3.6.2)':
dependencies:
'@uppy/core': 2.3.4
'@uppy/xhr-upload': 2.1.3(@uppy/core@2.3.4)
'@wangeditor/basic-modules': 1.1.7(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2))(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2)
'@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2)
dom7: 3.0.0
lodash.foreach: 4.5.0
slate: 0.72.8
snabbdom: 3.6.2
'@wangeditor/video-module@1.1.4(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2))(dom7@3.0.0)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2)':
dependencies:
'@uppy/core': 2.3.4
'@uppy/xhr-upload': 2.1.3(@uppy/core@2.3.4)
'@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2)
dom7: 3.0.0
nanoid: 3.3.7
slate: 0.72.8
snabbdom: 3.6.2
'@zclzone/eslint-config@0.0.4':
dependencies:
eslint: 8.57.0
@ -3303,6 +3675,8 @@ snapshots:
component-emitter@1.3.1: {}
compute-scroll-into-view@1.0.20: {}
concat-map@0.0.1: {}
confbox@0.1.7: {}
@ -3361,6 +3735,11 @@ snapshots:
csstype@3.1.3: {}
d@1.0.2:
dependencies:
es5-ext: 0.10.64
type: 2.7.3
data-view-buffer@1.0.1:
dependencies:
call-bind: 1.0.7
@ -3453,6 +3832,10 @@ snapshots:
domhandler: 4.3.1
entities: 2.2.0
dom7@3.0.0:
dependencies:
ssr-window: 3.0.0
domelementtype@1.3.1: {}
domelementtype@2.3.0: {}
@ -3572,6 +3955,24 @@ snapshots:
is-date-object: 1.0.5
is-symbol: 1.0.4
es5-ext@0.10.64:
dependencies:
es6-iterator: 2.0.3
es6-symbol: 3.1.4
esniff: 2.0.1
next-tick: 1.1.0
es6-iterator@2.0.3:
dependencies:
d: 1.0.2
es5-ext: 0.10.64
es6-symbol: 3.1.4
es6-symbol@3.1.4:
dependencies:
d: 1.0.2
ext: 1.7.0
esbuild@0.18.20:
optionalDependencies:
'@esbuild/android-arm': 0.18.20
@ -3681,6 +4082,13 @@ snapshots:
transitivePeerDependencies:
- supports-color
esniff@2.0.1:
dependencies:
d: 1.0.2
es5-ext: 0.10.64
event-emitter: 0.3.5
type: 2.7.3
espree@9.6.1:
dependencies:
acorn: 8.12.1
@ -3707,6 +4115,11 @@ snapshots:
etag@1.8.1: {}
event-emitter@0.3.5:
dependencies:
d: 1.0.2
es5-ext: 0.10.64
evtd@0.2.4: {}
execa@5.1.1:
@ -3733,6 +4146,10 @@ snapshots:
transitivePeerDependencies:
- supports-color
ext@1.7.0:
dependencies:
type: 2.7.3
extend-shallow@2.0.1:
dependencies:
is-extendable: 0.1.1
@ -3973,6 +4390,8 @@ snapshots:
relateurl: 0.2.7
terser: 5.31.3
html-void-elements@2.0.1: {}
htmlparser2@3.10.1:
dependencies:
domelementtype: 1.3.1
@ -3984,10 +4403,16 @@ snapshots:
human-signals@2.1.0: {}
i18next@20.6.1:
dependencies:
'@babel/runtime': 7.25.0
ignore@5.3.1: {}
image-size@0.5.5: {}
immer@9.0.21: {}
immutable@4.3.7: {}
import-fresh@3.3.0:
@ -4078,6 +4503,8 @@ snapshots:
dependencies:
is-extglob: 2.1.1
is-hotkey@0.2.0: {}
is-negative-zero@2.0.3: {}
is-number-object@1.0.7:
@ -4098,6 +4525,8 @@ snapshots:
dependencies:
isobject: 3.0.1
is-plain-object@5.0.0: {}
is-regex@1.1.4:
dependencies:
call-bind: 1.0.7
@ -4121,6 +4550,8 @@ snapshots:
dependencies:
which-typed-array: 1.1.15
is-url@1.2.4: {}
is-weakref@1.0.2:
dependencies:
call-bind: 1.0.7
@ -4218,8 +4649,22 @@ snapshots:
lodash-es@4.17.21: {}
lodash.camelcase@4.3.0: {}
lodash.clonedeep@4.5.0: {}
lodash.debounce@4.0.8: {}
lodash.foreach@4.5.0: {}
lodash.isequal@4.5.0: {}
lodash.merge@4.6.2: {}
lodash.throttle@4.1.1: {}
lodash.toarray@4.4.0: {}
lodash@4.17.21: {}
lower-case@2.0.2:
@ -4273,6 +4718,10 @@ snapshots:
mime-db@1.52.0: {}
mime-match@1.0.2:
dependencies:
wildcard: 1.1.2
mime-types@2.1.35:
dependencies:
mime-db: 1.52.0
@ -4338,6 +4787,8 @@ snapshots:
vue: 3.4.34(typescript@5.5.4)
vueuc: 0.4.58(vue@3.4.34(typescript@5.5.4))
namespace-emitter@2.0.1: {}
nanoid@3.3.7: {}
nanomatch@1.2.13:
@ -4358,6 +4809,8 @@ snapshots:
natural-compare@1.4.0: {}
next-tick@1.1.0: {}
no-case@3.0.4:
dependencies:
lower-case: 2.0.2
@ -4543,6 +4996,8 @@ snapshots:
posthtml-parser: 0.2.1
posthtml-render: 1.4.0
preact@10.27.0: {}
prelude-ls@1.2.1: {}
prettier-linter-helpers@1.0.0:
@ -4551,6 +5006,8 @@ snapshots:
prettier@2.8.8: {}
prismjs@1.30.0: {}
proxy-from-env@1.1.0: {}
punycode@2.3.1: {}
@ -4654,6 +5111,10 @@ snapshots:
immutable: 4.3.7
source-map-js: 1.2.0
scroll-into-view-if-needed@2.2.31:
dependencies:
compute-scroll-into-view: 1.0.20
scule@1.3.0: {}
seemly@0.3.8: {}
@ -4706,6 +5167,19 @@ snapshots:
slash@3.0.0: {}
slate-history@0.66.0(slate@0.72.8):
dependencies:
is-plain-object: 5.0.0
slate: 0.72.8
slate@0.72.8:
dependencies:
immer: 9.0.21
is-plain-object: 5.0.0
tiny-warning: 1.0.3
snabbdom@3.6.2: {}
snapdragon-node@2.1.1:
dependencies:
define-property: 1.0.0
@ -4756,6 +5230,8 @@ snapshots:
dependencies:
extend-shallow: 3.0.2
ssr-window@3.0.0: {}
stable@0.1.8: {}
static-extend@0.1.2:
@ -4864,6 +5340,8 @@ snapshots:
text-table@0.2.0: {}
tiny-warning@1.0.3: {}
to-fast-properties@2.0.0: {}
to-object-path@0.3.0:
@ -4908,6 +5386,8 @@ snapshots:
type-fest@0.20.2: {}
type@2.7.3: {}
typed-array-buffer@1.0.2:
dependencies:
call-bind: 1.0.7
@ -5230,6 +5710,8 @@ snapshots:
dependencies:
isexe: 2.0.0
wildcard@1.1.2: {}
word-wrap@1.2.5: {}
wrap-ansi@7.0.0:

@ -39,4 +39,10 @@ export default {
deleteDept: (params = {}) => request.delete('/dept/delete', { params }),
// auditlog
getAuditLogList: (params = {}) => request.get('/auditlog/list', { params }),
// 快捷问题管理接口
getQuestionList: (params = {}) => request.get('/question/list', { params }),
getQuestion: (params = {}) => request.get('/question/get', { params }),
createQuestion: (data = {}) => request.post('/question/create', data),
updateQuestion: (data = {}) => request.post('/question/update', data),
deleteQuestion: (params = {}) => request.delete('/question/delete', { params }),
}

@ -115,7 +115,7 @@ export const basicRoutes = [
meta: {
title: '登录页',
},
},
}
]
export const NOT_FOUND_ROUTE = {

@ -18,7 +18,6 @@
v-model:value="loginInfo.username"
autofocus
class="h-50 items-center pl-10 text-16"
placeholder="admin"
:maxlength="20"
/>
</div>
@ -28,7 +27,6 @@
class="h-50 items-center pl-10 text-16"
type="password"
show-password-on="mousedown"
placeholder="123456"
:maxlength="20"
@keypress.enter="handleLogin"
/>

@ -0,0 +1,342 @@
<template>
<CommonPage show-footer title="快捷问题列表">
<template #action>
<NButton v-permission="'post/api/v1/question/create'" type="primary" @click="handleAdd">
<TheIcon icon="material-symbols:add" :size="18" class="mr-5" />新建快捷问题
</NButton>
</template>
<CrudTable
ref="$table"
v-model:query-items="queryItems"
:columns="columns"
:get-data="api.getQuestionList"
>
<template #queryBar>
<QueryBarItem label="问题标题" :label-width="80">
<NInput
v-model:value="queryItems.title"
clearable
type="text"
placeholder="请输入问题标题"
@keypress.enter="$table?.handleSearch()"
/>
</QueryBarItem>
</template>
</CrudTable>
<CrudModal
v-model:visible="modalVisible"
:title="modalTitle"
:loading="modalLoading"
@save="customHandleSave"
:style="{ width: '80%', maxWidth: '1000px', minHeight: '500px' }"
>
<NForm
ref="modalFormRef"
label-placement="left"
label-align="left"
:label-width="80"
:model="modalForm"
:disabled="modalAction === 'view'"
>
<NFormItem
label="问题标题"
path="title"
:rule="{
required: true,
message: '请输入问题标题',
trigger: ['input', 'blur'],
}"
>
<NInput v-model:value="modalForm.title" placeholder="请输入问题标题" />
</NFormItem>
<NFormItem label="显示顺序" path="order_num">
<NInput v-model:value="modalForm.order_num" type="number" placeholder="请输入显示顺序" />
</NFormItem>
<NFormItem label="状态" path="status">
<NSwitch
v-model:value="modalForm.status"
:checked-value="'1'"
:unchecked-value="'0'"
/>
<span class="ml-2">{{ modalForm.status === '1' ? '启用' : '停用' }}</span>
</NFormItem>
<NFormItem
label="问题内容"
path="content"
:rule="{
required: false, //
trigger: ['change', 'blur'],
}"
>
<div class="editor-container">
<Toolbar :editor="editorRef" :defaultConfig="toolbarConfig" :mode="'simple'" />
<Editor
v-model:value="modalForm.content"
:defaultConfig="editorConfig"
@onCreated="handleEditorCreated"
height="400px"
/>
</div>
</NFormItem>
</NForm>
</CrudModal>
</CommonPage>
</template>
<script setup>
import { h, onMounted, ref, resolveDirective, withDirectives, onUnmounted } from 'vue'
import {
NButton, NForm, NFormItem, NInput, NPopconfirm, NTag, NSwitch
} from 'naive-ui'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import '@wangeditor/editor/dist/css/style.css'
import CommonPage from '@/components/page/CommonPage.vue'
import QueryBarItem from '@/components/query-bar/QueryBarItem.vue'
import CrudModal from '@/components/table/CrudModal.vue'
import CrudTable from '@/components/table/CrudTable.vue'
import { formatDate, renderIcon } from '@/utils'
import { useCRUD } from '@/composables'
import api from '@/api'
import TheIcon from '@/components/icon/TheIcon.vue'
defineOptions({ name: '快捷问题管理' })
//
const editorRef = ref(null)
const toolbarConfig = ref({})
const editorConfig = ref({
placeholder: '请输入问题内容...',
MENU_CONF: {
uploadImage: {
server: '/api/upload/image', // 使
fieldName: 'file',
maxFileSize: 2 * 1024 * 1024, // 2MB
headers: {
'Authorization': `Bearer ${localStorage.getItem('token')}`
}
},
uploadVideo: {
server: '/api/upload/video', // 使
fieldName: 'file',
maxFileSize: 100 * 1024 * 1024, // 100MB
headers: {
'Authorization': `Bearer ${localStorage.getItem('token')}`
}
}
}
})
const handleEditorCreated = (editor) => {
editorRef.value = editor // editor
}
//
onUnmounted(() => {
const editor = editorRef.value
if (editor) {
editor.destroy()
}
})
const $table = ref(null)
const queryItems = ref({})
const vPermission = resolveDirective('permission')
const {
modalVisible,
modalAction,
modalTitle,
modalLoading,
handleAdd,
handleDelete,
handleEdit: originalHandleEdit,
handleSave,
modalForm,
modalFormRef,
} = useCRUD({
name: '快捷问题',
initForm: {
title: '',
order_num: 0,
status: '0',
content: ''
},
doCreate: api.createQuestion,
doDelete: api.deleteQuestion,
doUpdate: api.updateQuestion,
refresh: () => $table.value?.handleSearch(),
})
onMounted(() => {
$table.value?.handleSearch()
})
const columns = [
{
title: '问题标题',
key: 'title',
width: 180,
align: 'center',
ellipsis: { tooltip: true },
render(row) {
return h(NTag, { type: 'info' }, { default: () => row.title })
},
},
{
title: '显示顺序',
key: 'order_num',
width: 80,
align: 'center',
},
{
title: '状态',
key: 'status',
width: 80,
align: 'center',
render(row) {
return h(
NTag,
{ type: row.status === '0' ? 'success' : 'error' },
{ default: () => row.status === '0' ? '正常' : '停用' }
)
},
},
{
title: '创建时间',
key: 'create_time',
width: 120,
align: 'center',
render(row) {
return h('span', formatDate(row.create_time))
},
},
{
title: '操作',
key: 'actions',
width: 120,
align: 'center',
fixed: 'right',
render(row) {
return [
withDirectives(
h(
NButton,
{
size: 'small',
type: 'primary',
style: 'margin-right: 8px;',
onClick: () => {
handleEdit(row)
},
},
{
default: () => '编辑',
icon: renderIcon('material-symbols:edit-outline', { size: 16 }),
}
),
[[vPermission, 'post/api/v1/question/update']]
),
h(
NPopconfirm,
{
onPositiveClick: () => handleDelete({ question_id: row.id }, false),
onNegativeClick: () => {},
},
{
trigger: () =>
withDirectives(
h(
NButton,
{
size: 'small',
type: 'error',
style: 'margin-right: 8px;',
},
{
default: () => '删除',
icon: renderIcon('material-symbols:delete-outline', { size: 16 }),
}
),
[[vPermission, 'delete/api/v1/question/delete']]
),
default: () => h('div', {}, '确定删除该快捷问题吗?'),
}
),
]
},
},
]
// handleSave
const originalHandleSave = handleSave
// handleSave
const customHandleSave = async () => {
if (modalFormRef.value) {
try {
//
if (editorRef.value) {
modalForm.value.content = editorRef.value.getHtml()
}
await modalFormRef.value.validate()
originalHandleSave()
} catch (error) {
//
console.error('验证失败:', error)
}
}
}
// watch
watch(
() => modalForm.content,
(newValue) => {
if (modalFormRef.value) {
// newValue
//
setTimeout(() => {
modalFormRef.value.validateField('content')
}, 100)
}
},
// immediate
{ immediate: true }
)
// handleEditAPI
const handleEdit = async (row) => {
originalHandleEdit(row);
try {
modalLoading.value = true;
// getQuestion API
const res = await api.getQuestion({ question_id: row.id });
if (res && res.data) {
// modalForm
modalForm.value = { ...res.data };
//
if (editorRef.value) {
//
editorRef.value.setHtml(res.data.content || '');
}
}
} catch (error) {
console.error('获取问题详情失败:', error);
} finally {
modalLoading.value = false;
}
}
</script>
<style scoped>
.editor-container {
border: 1px solid #e5e7eb;
border-radius: 4px;
width: 100%;
/* 增加最小高度和高度设置 */
min-height: 300px;
height: 50vh; /* 使用视口高度单位,确保编辑器随页面大小调整 */
overflow: hidden;
}
</style>

@ -31,6 +31,11 @@ export default defineConfig(({ command, mode }) => {
proxy: VITE_USE_PROXY
? {
[VITE_BASE_API]: PROXY_CONFIG[VITE_BASE_API],
// 添加对/api/upload路径的代理配置
'/api/upload': {
target: 'http://127.0.0.1:8111',
changeOrigin: true,
},
}
: undefined,
},

Loading…
Cancel
Save