fix(#758): 请修复 Bug #758(诸葛亮分析完成,分配给你)
根因:
- Bug #请修复 Bug #758(诸葛亮分析完成,分配给你) 存在的问题
修复:
- 文件 1** — `core-common/.../DictUtils.java:39`
- `getDictCache()` 方法增加三层防御:
- 外层 `try-catch` 捕获所有异常,异常时自动清除损坏缓存并返回 null(降级为空字典,不报错)
- 支持 `JSONArray` 和普通 `List<?>` 两种 Redis 反序列化结果,兼容不同序列化格式
- 缓存数据类型异常时自动清除,下次读取会重建
- 文件 2** — `healthlink-his-common/.../DictAspect.java:128`
- `processDict()` 中 `queryDictLabel()` 调用增加字段级 `try-catch`:
- 单个字段字典翻译失败不再影响其他字段的处理
- 异常降级为 debug 日志,前端不受影响
- ### 验证
- `mvn compile -DskipTests` → **BUILD SUCCESS** ✅
- 无新增编译错误,WARNING 均为已有 unchecked cast
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
# HealthLink-HIS 代码模块索引
|
# HealthLink-HIS 代码模块索引
|
||||||
|
|
||||||
> 供 LLM 快速定位代码。每个模块列出 Controller → Service → Mapper 关键文件。
|
> 供 LLM 快速定位代码。每个模块列出 Controller → Service → Mapper 关键文件。
|
||||||
> 最后更新: 2026-06-12 18:00 (298 个 Controller)
|
> 最后更新: 2026-06-13 12:00 (298 个 Controller)
|
||||||
|
|
||||||
## 关键词 → 模块速查
|
## 关键词 → 模块速查
|
||||||
|
|
||||||
|
|||||||
@@ -1,62 +0,0 @@
|
|||||||
# ============================================================
|
|
||||||
# OpenHIS 前端部署脚本 (Windows PowerShell)
|
|
||||||
# 用法: .\deploy-frontend.ps1 [-Env prod|test|staging|dev]
|
|
||||||
# ============================================================
|
|
||||||
param(
|
|
||||||
[ValidateSet("prod","test","staging","dev")]
|
|
||||||
[string]$Env = "prod"
|
|
||||||
)
|
|
||||||
|
|
||||||
$ErrorActionPreference = "Stop"
|
|
||||||
$ProjectDir = Split-Path -Parent (Split-Path -Parent $MyInvocation.MyCommand.Path)
|
|
||||||
$UiDir = "$ProjectDir\openhis-ui-vue3"
|
|
||||||
$DistDir = "$UiDir\dist"
|
|
||||||
|
|
||||||
Write-Host "==========================================" -ForegroundColor Cyan
|
|
||||||
Write-Host " OpenHIS 前端部署" -ForegroundColor Cyan
|
|
||||||
Write-Host " 环境: $Env" -ForegroundColor Cyan
|
|
||||||
Write-Host " 目录: $UiDir" -ForegroundColor Cyan
|
|
||||||
Write-Host "==========================================" -ForegroundColor Cyan
|
|
||||||
|
|
||||||
# ---------- 1. 环境检查 ----------
|
|
||||||
Write-Host "`n[1/5] 环境检查..." -ForegroundColor Yellow
|
|
||||||
|
|
||||||
try { $nodeVer = node -v } catch { Write-Host "错误: 未找到 node" -ForegroundColor Red; exit 1 }
|
|
||||||
try { $npmVer = npm -v } catch { Write-Host "错误: 未找到 npm" -ForegroundColor Red; exit 1 }
|
|
||||||
|
|
||||||
$nodeMajor = [int]($nodeVer -replace 'v','' -split '\.')[0]
|
|
||||||
if ($nodeMajor -lt 18) {
|
|
||||||
Write-Host "错误: Node.js >= 18,当前 $nodeVer" -ForegroundColor Red
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
Write-Host " Node.js: $nodeVer ✓"
|
|
||||||
Write-Host " npm: $npmVer ✓"
|
|
||||||
|
|
||||||
# ---------- 2. 安装依赖 ----------
|
|
||||||
Write-Host "`n[2/5] 安装依赖..." -ForegroundColor Yellow
|
|
||||||
Set-Location $UiDir
|
|
||||||
npm install --legacy-peer-deps
|
|
||||||
Write-Host " 依赖安装完成 ✓" -ForegroundColor Green
|
|
||||||
|
|
||||||
# ---------- 3. 构建 ----------
|
|
||||||
Write-Host "`n[3/5] 构建 ($Env)..." -ForegroundColor Yellow
|
|
||||||
npm run "build:$Env"
|
|
||||||
Write-Host " 构建完成 ✓" -ForegroundColor Green
|
|
||||||
|
|
||||||
# ---------- 4. 产物信息 ----------
|
|
||||||
Write-Host "`n[4/5] 构建产物:" -ForegroundColor Yellow
|
|
||||||
$totalSize = (Get-ChildItem $DistDir -Recurse -File | Measure-Object -Property Length -Sum).Sum
|
|
||||||
$fileCount = (Get-ChildItem $DistDir -Recurse -File).Count
|
|
||||||
Write-Host " 路径: $DistDir"
|
|
||||||
Write-Host " 大小: $([math]::Round($totalSize/1MB, 2)) MB"
|
|
||||||
Write-Host " 文件: $fileCount 个"
|
|
||||||
|
|
||||||
# ---------- 5. 部署提示 ----------
|
|
||||||
Write-Host "`n[5/5] 后续操作:" -ForegroundColor Yellow
|
|
||||||
Write-Host ""
|
|
||||||
Write-Host " 将 $DistDir 目录内容上传到服务器 Nginx 根目录"
|
|
||||||
Write-Host " 然后在服务器执行: nginx -s reload"
|
|
||||||
Write-Host ""
|
|
||||||
Write-Host "==========================================" -ForegroundColor Cyan
|
|
||||||
Write-Host " 构建完成!" -ForegroundColor Green
|
|
||||||
Write-Host "==========================================" -ForegroundColor Cyan
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# ============================================================
|
|
||||||
# HealthLink-HIS 前端部署脚本
|
|
||||||
# 用法: bash deploy-frontend.sh [prod|test|staging|dev]
|
|
||||||
# 默认: prod
|
|
||||||
# ============================================================
|
|
||||||
set -e
|
|
||||||
|
|
||||||
MODE=${1:-prod}
|
|
||||||
PROJECT_DIR=$(cd "$(dirname "$0")/.." && pwd)
|
|
||||||
UI_DIR="$PROJECT_DIR/healthlink-his-ui"
|
|
||||||
DIST_DIR="$UI_DIR/dist"
|
|
||||||
|
|
||||||
echo "=========================================="
|
|
||||||
echo " HealthLink-HIS 前端部署"
|
|
||||||
echo " 环境: $MODE"
|
|
||||||
echo " 目录: $UI_DIR"
|
|
||||||
echo "=========================================="
|
|
||||||
|
|
||||||
# ---------- 1. 环境检查 ----------
|
|
||||||
echo ""
|
|
||||||
echo "[1/5] 环境检查..."
|
|
||||||
|
|
||||||
check_cmd() {
|
|
||||||
if ! command -v "$1" &> /dev/null; then
|
|
||||||
echo "错误: 未找到 $1,请先安装"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
check_cmd node
|
|
||||||
check_cmd npm
|
|
||||||
|
|
||||||
NODE_VER=$(node -v | sed 's/v//' | cut -d. -f1)
|
|
||||||
if [ "$NODE_VER" -lt 18 ]; then
|
|
||||||
echo "错误: Node.js 版本需要 >= 18,当前: $(node -v)"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo " Node.js: $(node -v) ✓"
|
|
||||||
echo " npm: $(npm -v) ✓"
|
|
||||||
|
|
||||||
# ---------- 2. 安装依赖 ----------
|
|
||||||
echo ""
|
|
||||||
echo "[2/5] 安装依赖..."
|
|
||||||
cd "$UI_DIR"
|
|
||||||
|
|
||||||
# 清理旧的 node_modules(可选,取消注释启用)
|
|
||||||
# echo " 清理旧依赖..."
|
|
||||||
# rm -rf node_modules package-lock.json
|
|
||||||
|
|
||||||
npm install --production=false --legacy-peer-deps
|
|
||||||
echo " 依赖安装完成 ✓"
|
|
||||||
|
|
||||||
# ---------- 3. 构建 ----------
|
|
||||||
echo ""
|
|
||||||
echo "[3/5] 构建 ($MODE)..."
|
|
||||||
npm run "build:$MODE"
|
|
||||||
echo " 构建完成 ✓"
|
|
||||||
|
|
||||||
# ---------- 4. 产物信息 ----------
|
|
||||||
echo ""
|
|
||||||
echo "[4/5] 构建产物:"
|
|
||||||
TOTAL_SIZE=$(du -sh "$DIST_DIR" 2>/dev/null | cut -f1)
|
|
||||||
FILE_COUNT=$(find "$DIST_DIR" -type f | wc -l)
|
|
||||||
echo " 路径: $DIST_DIR"
|
|
||||||
echo " 大小: $TOTAL_SIZE"
|
|
||||||
echo " 文件: $FILE_COUNT 个"
|
|
||||||
|
|
||||||
# ---------- 5. 部署提示 ----------
|
|
||||||
echo ""
|
|
||||||
echo "[5/5] 部署方式:"
|
|
||||||
echo ""
|
|
||||||
echo " 方式一: 复制到 Nginx"
|
|
||||||
echo " cp -r $DIST_DIR/* /usr/share/nginx/html/healthlink-his/"
|
|
||||||
echo " nginx -s reload"
|
|
||||||
echo ""
|
|
||||||
echo " 方式二: 软链接(推荐,方便更新)"
|
|
||||||
echo " ln -sfn $DIST_DIR /usr/share/nginx/html/healthlink-his"
|
|
||||||
echo " nginx -s reload"
|
|
||||||
echo ""
|
|
||||||
echo "=========================================="
|
|
||||||
echo " 部署完成!"
|
|
||||||
echo "=========================================="
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
# ============================================================
|
|
||||||
# HealthLink-HIS 前端依赖问题排查与修复脚本
|
|
||||||
# 用法: bash fix-deps.sh
|
|
||||||
# ============================================================
|
|
||||||
set -e
|
|
||||||
|
|
||||||
PROJECT_DIR=$(cd "$(dirname "$0")/.." && pwd)
|
|
||||||
UI_DIR="$PROJECT_DIR/healthlink-his-ui"
|
|
||||||
|
|
||||||
cd "$UI_DIR"
|
|
||||||
|
|
||||||
echo "=========================================="
|
|
||||||
echo " HealthLink-HIS 前端依赖诊断"
|
|
||||||
echo "=========================================="
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# 检查 node_modules 是否存在
|
|
||||||
if [ ! -d "node_modules" ]; then
|
|
||||||
echo "[!] node_modules 不存在,执行 npm install..."
|
|
||||||
npm install --legacy-peer-deps
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 检查 package-lock.json 是否存在
|
|
||||||
if [ ! -f "package-lock.json" ]; then
|
|
||||||
echo "[!] package-lock.json 缺失,重新生成..."
|
|
||||||
npm install --legacy-peer-deps
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 检查关键依赖
|
|
||||||
echo "检查关键依赖:"
|
|
||||||
DEPS=("vue" "vite" "vxe-table" "element-plus" "pinia" "vue-router" "axios" "dayjs")
|
|
||||||
for dep in "${DEPS[@]}"; do
|
|
||||||
if [ -d "node_modules/$dep" ]; then
|
|
||||||
VER=$(node -p "require('./node_modules/$dep/package.json').version" 2>/dev/null || echo "未知")
|
|
||||||
echo " ✓ $dep@$VER"
|
|
||||||
else
|
|
||||||
echo " ✗ $dep 缺失!"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# 检查过时依赖
|
|
||||||
echo "检查过时依赖 (可选升级):"
|
|
||||||
npm outdated 2>/dev/null || true
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# 常见问题修复菜单
|
|
||||||
echo "=========================================="
|
|
||||||
echo " 修复选项:"
|
|
||||||
echo " 1) 重新安装依赖 (rm node_modules + npm install)"
|
|
||||||
echo " 2) 清理缓存并重装 (npm cache clean + 重装)"
|
|
||||||
echo " 3) 修复 peer 依赖冲突 (npm install --legacy-peer-deps)"
|
|
||||||
echo " 4) 退出"
|
|
||||||
echo "=========================================="
|
|
||||||
read -p "选择 [1-4]: " choice
|
|
||||||
|
|
||||||
case $choice in
|
|
||||||
1)
|
|
||||||
echo "清理 node_modules..."
|
|
||||||
rm -rf node_modules package-lock.json
|
|
||||||
npm install --legacy-peer-deps
|
|
||||||
;;
|
|
||||||
2)
|
|
||||||
echo "清理缓存..."
|
|
||||||
npm cache clean --force
|
|
||||||
rm -rf node_modules package-lock.json
|
|
||||||
npm install --legacy-peer-deps
|
|
||||||
;;
|
|
||||||
3)
|
|
||||||
npm install --legacy-peer-deps
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "退出"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "完成 ✓"
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
# ============================================================
|
|
||||||
# HealthLink-HIS 前端 Nginx 配置
|
|
||||||
# 放到 /etc/nginx/conf.d/openhis.conf 或 include 到 nginx.conf
|
|
||||||
# ============================================================
|
|
||||||
|
|
||||||
server {
|
|
||||||
listen 80;
|
|
||||||
server_name healthlink-his.local; # 改成实际域名或 IP
|
|
||||||
|
|
||||||
# 前端静态文件
|
|
||||||
location / {
|
|
||||||
root /usr/share/nginx/html/healthlink-his;
|
|
||||||
index index.html;
|
|
||||||
try_files $uri $uri/ /index.html; # SPA 路由回退
|
|
||||||
}
|
|
||||||
|
|
||||||
# 后端 API 代理
|
|
||||||
location /prd-api/ {
|
|
||||||
proxy_pass http://127.0.0.1:18082/healthlink-his/;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
proxy_connect_timeout 300;
|
|
||||||
proxy_read_timeout 300;
|
|
||||||
client_max_body_size 50m;
|
|
||||||
}
|
|
||||||
|
|
||||||
# gzip 压缩(Vite 构建已生成 .gz 文件,Nginx 直接发送)
|
|
||||||
gzip on;
|
|
||||||
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;
|
|
||||||
gzip_min_length 1024;
|
|
||||||
gzip_comp_level 6;
|
|
||||||
gzip_vary on;
|
|
||||||
|
|
||||||
# 静态资源缓存(带 hash 的文件长期缓存)
|
|
||||||
location ~* /assets/.*\.(js|css|woff2?|ttf|eot|png|jpg|jpeg|gif|svg|ico)$ {
|
|
||||||
root /usr/share/nginx/html/healthlink-his;
|
|
||||||
expires 365d;
|
|
||||||
add_header Cache-Control "public, immutable";
|
|
||||||
}
|
|
||||||
|
|
||||||
# index.html 不缓存(保证更新及时生效)
|
|
||||||
location = /index.html {
|
|
||||||
root /usr/share/nginx/html/healthlink-his;
|
|
||||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -6,6 +6,9 @@ import com.core.common.core.domain.entity.SysDictData;
|
|||||||
import com.core.common.core.redis.RedisCache;
|
import com.core.common.core.redis.RedisCache;
|
||||||
import com.core.common.utils.spring.SpringUtils;
|
import com.core.common.utils.spring.SpringUtils;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -15,6 +18,7 @@ import java.util.List;
|
|||||||
* @author system
|
* @author system
|
||||||
*/
|
*/
|
||||||
public class DictUtils {
|
public class DictUtils {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(DictUtils.class);
|
||||||
/**
|
/**
|
||||||
* 分隔符
|
* 分隔符
|
||||||
*/
|
*/
|
||||||
@@ -37,11 +41,39 @@ public class DictUtils {
|
|||||||
* @return dictDatas 字典数据列表
|
* @return dictDatas 字典数据列表
|
||||||
*/
|
*/
|
||||||
public static List<SysDictData> getDictCache(String key) {
|
public static List<SysDictData> getDictCache(String key) {
|
||||||
JSONArray arrayCache = SpringUtils.getBean(RedisCache.class).getCacheObject(getCacheKey(key));
|
try {
|
||||||
if (StringUtils.isNotNull(arrayCache)) {
|
Object cached = SpringUtils.getBean(RedisCache.class).getCacheObject(getCacheKey(key));
|
||||||
return arrayCache.toList(SysDictData.class);
|
if (cached == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (cached instanceof JSONArray arrayCache) {
|
||||||
|
return arrayCache.toList(SysDictData.class);
|
||||||
|
}
|
||||||
|
if (cached instanceof List<?> list) {
|
||||||
|
// Redis缓存可能已反序列化为List,尝试逐个转换
|
||||||
|
java.util.ArrayList<SysDictData> result = new java.util.ArrayList<>(list.size());
|
||||||
|
for (Object item : list) {
|
||||||
|
if (item instanceof SysDictData dictData) {
|
||||||
|
result.add(dictData);
|
||||||
|
} else {
|
||||||
|
// 尝试通过JSON转换
|
||||||
|
String json = com.alibaba.fastjson2.JSON.toJSONString(item);
|
||||||
|
result.add(com.alibaba.fastjson2.JSON.parseObject(json, SysDictData.class));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
log.warn("字典缓存key={}的数据类型异常: {}, 清除缓存", key, cached.getClass().getName());
|
||||||
|
removeDictCache(key);
|
||||||
|
return null;
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("获取字典缓存异常key={}, 清除缓存: {}", key, e.getMessage());
|
||||||
|
try {
|
||||||
|
removeDictCache(key);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -125,15 +125,19 @@ public class DictAspect {
|
|||||||
// _dictText field not present, proceed normally
|
// _dictText field not present, proceed normally
|
||||||
}
|
}
|
||||||
|
|
||||||
String dictLabel = queryDictLabel(dictTable, dictCode, dictText, deleteFlag, fieldValue.toString());
|
try {
|
||||||
if (dictLabel != null && !dictLabel.isEmpty()) {
|
String dictLabel = queryDictLabel(dictTable, dictCode, dictText, deleteFlag, fieldValue.toString());
|
||||||
try {
|
if (dictLabel != null && !dictLabel.isEmpty()) {
|
||||||
Field textField = clazz.getDeclaredField(textFieldName);
|
try {
|
||||||
textField.setAccessible(true);
|
Field textField = clazz.getDeclaredField(textFieldName);
|
||||||
textField.set(dto, dictLabel);
|
textField.setAccessible(true);
|
||||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
textField.set(dto, dictLabel);
|
||||||
log.debug("字段 {} 不存在或无法访问,跳过字典翻译", textFieldName);
|
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||||
|
log.debug("字段 {} 不存在或无法访问,跳过字典翻译", textFieldName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.debug("字典翻译异常, 字段={}, dictCode={}, 跳过: {}", field.getName(), dictCode, e.getMessage());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
processDict(fieldValue, visited);
|
processDict(fieldValue, visited);
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
# 页面标题
|
|
||||||
VITE_APP_TITLE =医院信息管理系统
|
|
||||||
|
|
||||||
# 开发环境配置
|
|
||||||
VITE_APP_ENV = 'development'
|
|
||||||
|
|
||||||
# HealthLink-HIS管理系统/开发环境
|
|
||||||
VITE_APP_BASE_API = '/dev-api'
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
# 页面标题
|
|
||||||
VITE_APP_TITLE=医院信息管理系统
|
|
||||||
|
|
||||||
# 生产环境配置
|
|
||||||
VITE_APP_ENV= 'prod'
|
|
||||||
|
|
||||||
# HealthLink-HIS管理系统/生产环境
|
|
||||||
VITE_APP_BASE_API= '/prd-api'
|
|
||||||
|
|
||||||
# 租户ID配置
|
|
||||||
VITE_APP_TENANT_ID= '1'
|
|
||||||
|
|
||||||
# 是否在打包时开启压缩,支持 gzip 和 brotli
|
|
||||||
VITE_BUILD_COMPRESS = gzip
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
# 开发环境:本地只启动前端项目,依赖开发环境(后端、APP)
|
|
||||||
# 生产环境配置
|
|
||||||
VITE_APP_ENV = 'spug'
|
|
||||||
|
|
||||||
VITE_DEV=true
|
|
||||||
|
|
||||||
# 请求路径
|
|
||||||
VITE_BASE_URL='http://192.168.110.252'
|
|
||||||
|
|
||||||
# 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持S3服务
|
|
||||||
VITE_UPLOAD_TYPE=server
|
|
||||||
|
|
||||||
# HealthLink-HIS管理系统/SPUG环境
|
|
||||||
VITE_APP_BASE_API = '/admin-api'
|
|
||||||
|
|
||||||
# 租户ID配置
|
|
||||||
VITE_APP_TENANT_ID=1
|
|
||||||
|
|
||||||
# 是否删除debugger
|
|
||||||
VITE_DROP_DEBUGGER=false
|
|
||||||
|
|
||||||
# 是否删除console.log
|
|
||||||
VITE_DROP_CONSOLE=false
|
|
||||||
|
|
||||||
# 是否sourcemap
|
|
||||||
VITE_SOURCEMAP=true
|
|
||||||
|
|
||||||
# 打包路径
|
|
||||||
VITE_BASE_PATH=/
|
|
||||||
|
|
||||||
# 商城H5会员端域名
|
|
||||||
VITE_MALL_H5_DOMAIN='http://mall.yudao.iocoder.cn'
|
|
||||||
|
|
||||||
# 验证码的开关
|
|
||||||
VITE_APP_CAPTCHA_ENABLE=false
|
|
||||||
|
|
||||||
# GoView域名
|
|
||||||
VITE_GOVIEW_URL='http://127.0.0.1:3000'
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
# 页面标题
|
|
||||||
VITE_APP_TITLE = OpenHIS管理系统
|
|
||||||
|
|
||||||
# 生产环境配置
|
|
||||||
VITE_APP_ENV = 'staging'
|
|
||||||
|
|
||||||
# OpenHIS管理系统/生产环境
|
|
||||||
VITE_APP_BASE_API = '/stage-api'
|
|
||||||
|
|
||||||
# 租户ID配置
|
|
||||||
VITE_APP_TENANT_ID=1
|
|
||||||
|
|
||||||
# 是否在打包时开启压缩,支持 gzip 和 brotli
|
|
||||||
VITE_BUILD_COMPRESS = gzip
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
# Playwright E2E 测试环境变量
|
|
||||||
# 注意:此文件仅用于本地开发,生产环境使用CI Secret管理
|
|
||||||
TEST_BASE_URL=http://localhost:80
|
|
||||||
TEST_USERNAME=admin
|
|
||||||
TEST_PASSWORD=changeme_in_local_env
|
|
||||||
381
package-lock.json
generated
381
package-lock.json
generated
@@ -1,381 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "his",
|
|
||||||
"lockfileVersion": 3,
|
|
||||||
"requires": true,
|
|
||||||
"packages": {
|
|
||||||
"": {
|
|
||||||
"dependencies": {
|
|
||||||
"axios": "^1.13.2",
|
|
||||||
"json-bigint": "^1.0.0"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"husky": "^9.1.7"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/agent-base": {
|
|
||||||
"version": "6.0.2",
|
|
||||||
"resolved": "https://registry.npmmirror.com/agent-base/-/agent-base-6.0.2.tgz",
|
|
||||||
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"debug": "4"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 6.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/asynckit": {
|
|
||||||
"version": "0.4.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
|
|
||||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/axios": {
|
|
||||||
"version": "1.17.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/axios/-/axios-1.17.0.tgz",
|
|
||||||
"integrity": "sha512-J8SwNxprqqpbfenehxWYXE7CW+wM1BB4w3+N+g+/Wx40xM4rsLrfPmHHxSWIxJLYDgSY/HqlFPIYb2/S3rxafw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"follow-redirects": "^1.16.0",
|
|
||||||
"form-data": "^4.0.5",
|
|
||||||
"https-proxy-agent": "^5.0.1",
|
|
||||||
"proxy-from-env": "^2.1.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/bignumber.js": {
|
|
||||||
"version": "9.3.1",
|
|
||||||
"resolved": "https://registry.npmmirror.com/bignumber.js/-/bignumber.js-9.3.1.tgz",
|
|
||||||
"integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/call-bind-apply-helpers": {
|
|
||||||
"version": "1.0.2",
|
|
||||||
"resolved": "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
|
|
||||||
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"es-errors": "^1.3.0",
|
|
||||||
"function-bind": "^1.1.2"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/combined-stream": {
|
|
||||||
"version": "1.0.8",
|
|
||||||
"resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz",
|
|
||||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"delayed-stream": "~1.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/debug": {
|
|
||||||
"version": "4.4.3",
|
|
||||||
"resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.3.tgz",
|
|
||||||
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"ms": "^2.1.3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6.0"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"supports-color": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/delayed-stream": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
|
||||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.4.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/dunder-proto": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"call-bind-apply-helpers": "^1.0.1",
|
|
||||||
"es-errors": "^1.3.0",
|
|
||||||
"gopd": "^1.2.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/es-define-property": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/es-errors": {
|
|
||||||
"version": "1.3.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz",
|
|
||||||
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/es-object-atoms": {
|
|
||||||
"version": "1.1.2",
|
|
||||||
"resolved": "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.1.2.tgz",
|
|
||||||
"integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"es-errors": "^1.3.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/es-set-tostringtag": {
|
|
||||||
"version": "2.1.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
|
|
||||||
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"es-errors": "^1.3.0",
|
|
||||||
"get-intrinsic": "^1.2.6",
|
|
||||||
"has-tostringtag": "^1.0.2",
|
|
||||||
"hasown": "^2.0.2"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/follow-redirects": {
|
|
||||||
"version": "1.16.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.16.0.tgz",
|
|
||||||
"integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==",
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"type": "individual",
|
|
||||||
"url": "https://github.com/sponsors/RubenVerborgh"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=4.0"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"debug": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/form-data": {
|
|
||||||
"version": "4.0.5",
|
|
||||||
"resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.5.tgz",
|
|
||||||
"integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"asynckit": "^0.4.0",
|
|
||||||
"combined-stream": "^1.0.8",
|
|
||||||
"es-set-tostringtag": "^2.1.0",
|
|
||||||
"hasown": "^2.0.2",
|
|
||||||
"mime-types": "^2.1.12"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/function-bind": {
|
|
||||||
"version": "1.1.2",
|
|
||||||
"resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz",
|
|
||||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/get-intrinsic": {
|
|
||||||
"version": "1.3.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
|
|
||||||
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"call-bind-apply-helpers": "^1.0.2",
|
|
||||||
"es-define-property": "^1.0.1",
|
|
||||||
"es-errors": "^1.3.0",
|
|
||||||
"es-object-atoms": "^1.1.1",
|
|
||||||
"function-bind": "^1.1.2",
|
|
||||||
"get-proto": "^1.0.1",
|
|
||||||
"gopd": "^1.2.0",
|
|
||||||
"has-symbols": "^1.1.0",
|
|
||||||
"hasown": "^2.0.2",
|
|
||||||
"math-intrinsics": "^1.1.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.4"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/get-proto": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmmirror.com/get-proto/-/get-proto-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"dunder-proto": "^1.0.1",
|
|
||||||
"es-object-atoms": "^1.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/gopd": {
|
|
||||||
"version": "1.2.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz",
|
|
||||||
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.4"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/has-symbols": {
|
|
||||||
"version": "1.1.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz",
|
|
||||||
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.4"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/has-tostringtag": {
|
|
||||||
"version": "1.0.2",
|
|
||||||
"resolved": "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
|
|
||||||
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"has-symbols": "^1.0.3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.4"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/hasown": {
|
|
||||||
"version": "2.0.4",
|
|
||||||
"resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.4.tgz",
|
|
||||||
"integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"function-bind": "^1.1.2"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/https-proxy-agent": {
|
|
||||||
"version": "5.0.1",
|
|
||||||
"resolved": "https://registry.npmmirror.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
|
|
||||||
"integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"agent-base": "6",
|
|
||||||
"debug": "4"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/husky": {
|
|
||||||
"version": "9.1.7",
|
|
||||||
"resolved": "https://registry.npmmirror.com/husky/-/husky-9.1.7.tgz",
|
|
||||||
"integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"bin": {
|
|
||||||
"husky": "bin.js"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/typicode"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/json-bigint": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/json-bigint/-/json-bigint-1.0.0.tgz",
|
|
||||||
"integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"bignumber.js": "^9.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/math-intrinsics": {
|
|
||||||
"version": "1.1.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
|
||||||
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/mime-db": {
|
|
||||||
"version": "1.52.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
|
|
||||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/mime-types": {
|
|
||||||
"version": "2.1.35",
|
|
||||||
"resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz",
|
|
||||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"mime-db": "1.52.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/ms": {
|
|
||||||
"version": "2.1.3",
|
|
||||||
"resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz",
|
|
||||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/proxy-from-env": {
|
|
||||||
"version": "2.1.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-2.1.0.tgz",
|
|
||||||
"integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,351 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""
|
|
||||||
Bug #318 历史数据修复脚本
|
|
||||||
为已存在但未生成手术医嘱的手术申请单补齐数据
|
|
||||||
"""
|
|
||||||
|
|
||||||
import psycopg2
|
|
||||||
import json
|
|
||||||
import random
|
|
||||||
import string
|
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
# 数据库连接配置
|
|
||||||
DB_CONFIG = {
|
|
||||||
"host": "47.116.196.11",
|
|
||||||
"port": 15432,
|
|
||||||
"database": "postgresql",
|
|
||||||
"user": "postgresql",
|
|
||||||
"password": "postgresql", # 请根据实际情况修改
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def generate_bus_no():
|
|
||||||
"""生成4位随机bus_no"""
|
|
||||||
return "".join(random.choices(string.digits, k=4))
|
|
||||||
|
|
||||||
|
|
||||||
def check_repair_needed(conn):
|
|
||||||
"""检查需要修复的记录数"""
|
|
||||||
cursor = conn.cursor()
|
|
||||||
sql = """
|
|
||||||
SELECT COUNT(*)
|
|
||||||
FROM doc_request_form rf
|
|
||||||
LEFT JOIN wor_service_request sr ON sr.prescription_no = rf.prescription_no
|
|
||||||
AND sr.delete_flag = '0'
|
|
||||||
WHERE rf.type_code = 'PROCEDURE'
|
|
||||||
AND rf.delete_flag = '0'
|
|
||||||
AND sr.id IS NULL
|
|
||||||
"""
|
|
||||||
cursor.execute(sql)
|
|
||||||
count = cursor.fetchone()[0]
|
|
||||||
cursor.close()
|
|
||||||
return count
|
|
||||||
|
|
||||||
|
|
||||||
def get_repair_list(conn):
|
|
||||||
"""获取需要修复的手术申请单列表"""
|
|
||||||
cursor = conn.cursor()
|
|
||||||
sql = """
|
|
||||||
SELECT
|
|
||||||
rf.id,
|
|
||||||
rf.prescription_no,
|
|
||||||
rf.encounter_id,
|
|
||||||
rf.patient_id,
|
|
||||||
rf.requester_id,
|
|
||||||
rf.create_time,
|
|
||||||
rf.org_id,
|
|
||||||
rf.desc_json
|
|
||||||
FROM doc_request_form rf
|
|
||||||
LEFT JOIN wor_service_request sr ON sr.prescription_no = rf.prescription_no
|
|
||||||
AND sr.delete_flag = '0'
|
|
||||||
WHERE rf.type_code = 'PROCEDURE'
|
|
||||||
AND rf.delete_flag = '0'
|
|
||||||
AND sr.id IS NULL
|
|
||||||
ORDER BY rf.create_time DESC
|
|
||||||
"""
|
|
||||||
cursor.execute(sql)
|
|
||||||
results = cursor.fetchall()
|
|
||||||
cursor.close()
|
|
||||||
return results
|
|
||||||
|
|
||||||
|
|
||||||
def parse_surgery_info(desc_json):
|
|
||||||
"""解析手术信息"""
|
|
||||||
if not desc_json:
|
|
||||||
return {}
|
|
||||||
try:
|
|
||||||
if isinstance(desc_json, str):
|
|
||||||
return json.loads(desc_json)
|
|
||||||
return desc_json
|
|
||||||
except:
|
|
||||||
return {}
|
|
||||||
|
|
||||||
|
|
||||||
def repair_service_request(conn, repair_list):
|
|
||||||
"""修复手术医嘱(ServiceRequest)"""
|
|
||||||
cursor = conn.cursor()
|
|
||||||
|
|
||||||
insert_sql = """
|
|
||||||
INSERT INTO wor_service_request (
|
|
||||||
bus_no, prescription_no, status_enum, generate_source_enum,
|
|
||||||
therapy_enum, quantity, unit_code, category_enum,
|
|
||||||
patient_id, requester_id, encounter_id, authored_time,
|
|
||||||
org_id, content_json, delete_flag, create_time, create_by, tenant_id
|
|
||||||
) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
|
|
||||||
RETURNING id
|
|
||||||
"""
|
|
||||||
|
|
||||||
new_requests = []
|
|
||||||
for record in repair_list:
|
|
||||||
(
|
|
||||||
rf_id,
|
|
||||||
prescription_no,
|
|
||||||
encounter_id,
|
|
||||||
patient_id,
|
|
||||||
requester_id,
|
|
||||||
create_time,
|
|
||||||
org_id,
|
|
||||||
desc_json,
|
|
||||||
) = record
|
|
||||||
|
|
||||||
# 解析手术信息
|
|
||||||
surgery_info = parse_surgery_info(desc_json)
|
|
||||||
content_json = (
|
|
||||||
json.dumps(surgery_info, ensure_ascii=False) if surgery_info else None
|
|
||||||
)
|
|
||||||
|
|
||||||
# 生成bus_no
|
|
||||||
bus_no = generate_bus_no()
|
|
||||||
|
|
||||||
# 插入ServiceRequest
|
|
||||||
cursor.execute(
|
|
||||||
insert_sql,
|
|
||||||
(
|
|
||||||
bus_no, # bus_no
|
|
||||||
prescription_no, # prescription_no
|
|
||||||
1, # status_enum: 1-待签发
|
|
||||||
1, # generate_source_enum: 1-医生处方
|
|
||||||
2, # therapy_enum: 2-临时医嘱
|
|
||||||
1, # quantity
|
|
||||||
"次", # unit_code
|
|
||||||
4, # category_enum: 4-手术
|
|
||||||
patient_id, # patient_id
|
|
||||||
requester_id, # requester_id
|
|
||||||
encounter_id, # encounter_id
|
|
||||||
create_time, # authored_time
|
|
||||||
org_id, # org_id
|
|
||||||
content_json, # content_json
|
|
||||||
"0", # delete_flag
|
|
||||||
create_time, # create_time
|
|
||||||
requester_id, # create_by
|
|
||||||
1, # tenant_id
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
service_request_id = cursor.fetchone()[0]
|
|
||||||
new_requests.append(
|
|
||||||
{
|
|
||||||
"service_request_id": service_request_id,
|
|
||||||
"bus_no": bus_no,
|
|
||||||
"prescription_no": prescription_no,
|
|
||||||
"patient_id": patient_id,
|
|
||||||
"encounter_id": encounter_id,
|
|
||||||
"requester_id": requester_id,
|
|
||||||
"create_time": create_time,
|
|
||||||
"org_id": org_id,
|
|
||||||
"surgery_info": surgery_info,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
conn.commit()
|
|
||||||
cursor.close()
|
|
||||||
return new_requests
|
|
||||||
|
|
||||||
|
|
||||||
def repair_charge_items(conn, new_requests):
|
|
||||||
"""修复收费项目(ChargeItem)"""
|
|
||||||
cursor = conn.cursor()
|
|
||||||
|
|
||||||
insert_sql = """
|
|
||||||
INSERT INTO adm_charge_item (
|
|
||||||
bus_no, status_enum, generate_source_enum, patient_id,
|
|
||||||
context_enum, encounter_id, enterer_id, entered_date,
|
|
||||||
service_table, service_id, product_table, requesting_org_id,
|
|
||||||
quantity_value, quantity_unit, unit_price, total_price,
|
|
||||||
delete_flag, create_time, create_by, tenant_id
|
|
||||||
) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
|
|
||||||
"""
|
|
||||||
|
|
||||||
for req in new_requests:
|
|
||||||
surgery_info = req["surgery_info"]
|
|
||||||
|
|
||||||
# 手术费用
|
|
||||||
surgery_fee = 0
|
|
||||||
if surgery_info and "surgeryFee" in surgery_info:
|
|
||||||
try:
|
|
||||||
surgery_fee = float(surgery_info["surgeryFee"])
|
|
||||||
except:
|
|
||||||
surgery_fee = 0
|
|
||||||
|
|
||||||
# 插入手术费用收费项目
|
|
||||||
cursor.execute(
|
|
||||||
insert_sql,
|
|
||||||
(
|
|
||||||
"CI" + req["bus_no"], # bus_no
|
|
||||||
1, # status_enum: 1-草稿
|
|
||||||
1, # generate_source_enum: 1-医生处方
|
|
||||||
req["patient_id"], # patient_id
|
|
||||||
3, # context_enum: 3-诊疗
|
|
||||||
req["encounter_id"], # encounter_id
|
|
||||||
req["requester_id"], # enterer_id
|
|
||||||
req["create_time"], # entered_date
|
|
||||||
"wor_service_request", # service_table
|
|
||||||
req["service_request_id"], # service_id
|
|
||||||
"wor_activity_definition", # product_table
|
|
||||||
req["org_id"], # requesting_org_id
|
|
||||||
1, # quantity_value
|
|
||||||
"次", # quantity_unit
|
|
||||||
surgery_fee, # unit_price
|
|
||||||
surgery_fee, # total_price
|
|
||||||
"0", # delete_flag
|
|
||||||
req["create_time"], # create_time
|
|
||||||
req["requester_id"], # create_by
|
|
||||||
1, # tenant_id
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
# 麻醉费用(如果存在且大于0)
|
|
||||||
anesthesia_fee = 0
|
|
||||||
if surgery_info and "anesthesiaFee" in surgery_info:
|
|
||||||
try:
|
|
||||||
anesthesia_fee = float(surgery_info["anesthesiaFee"])
|
|
||||||
except:
|
|
||||||
anesthesia_fee = 0
|
|
||||||
|
|
||||||
if anesthesia_fee > 0:
|
|
||||||
cursor.execute(
|
|
||||||
insert_sql,
|
|
||||||
(
|
|
||||||
"CI" + req["bus_no"] + "_A", # bus_no
|
|
||||||
1, # status_enum
|
|
||||||
1, # generate_source_enum
|
|
||||||
req["patient_id"], # patient_id
|
|
||||||
3, # context_enum
|
|
||||||
req["encounter_id"], # encounter_id
|
|
||||||
req["requester_id"], # enterer_id
|
|
||||||
req["create_time"], # entered_date
|
|
||||||
"wor_service_request", # service_table
|
|
||||||
req["service_request_id"], # service_id
|
|
||||||
"wor_activity_definition", # product_table
|
|
||||||
req["org_id"], # requesting_org_id
|
|
||||||
1, # quantity_value
|
|
||||||
"次", # quantity_unit
|
|
||||||
anesthesia_fee, # unit_price
|
|
||||||
anesthesia_fee, # total_price
|
|
||||||
"0", # delete_flag
|
|
||||||
req["create_time"], # create_time
|
|
||||||
req["requester_id"], # create_by
|
|
||||||
1, # tenant_id
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
conn.commit()
|
|
||||||
cursor.close()
|
|
||||||
|
|
||||||
|
|
||||||
def verify_repair(conn):
|
|
||||||
"""验证修复结果"""
|
|
||||||
cursor = conn.cursor()
|
|
||||||
|
|
||||||
# 统计手术医嘱数量
|
|
||||||
cursor.execute("""
|
|
||||||
SELECT COUNT(*)
|
|
||||||
FROM wor_service_request
|
|
||||||
WHERE category_enum = 4 AND delete_flag = '0'
|
|
||||||
""")
|
|
||||||
service_request_count = cursor.fetchone()[0]
|
|
||||||
|
|
||||||
# 统计收费项目数量
|
|
||||||
cursor.execute("""
|
|
||||||
SELECT COUNT(*)
|
|
||||||
FROM adm_charge_item ci
|
|
||||||
WHERE ci.service_table = 'wor_service_request'
|
|
||||||
AND EXISTS (
|
|
||||||
SELECT 1 FROM wor_service_request sr
|
|
||||||
WHERE sr.id = ci.service_id AND sr.category_enum = 4
|
|
||||||
)
|
|
||||||
""")
|
|
||||||
charge_item_count = cursor.fetchone()[0]
|
|
||||||
|
|
||||||
cursor.close()
|
|
||||||
return service_request_count, charge_item_count
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
"""主函数"""
|
|
||||||
print("=" * 60)
|
|
||||||
print("Bug #318 历史数据修复脚本")
|
|
||||||
print("=" * 60)
|
|
||||||
print()
|
|
||||||
|
|
||||||
try:
|
|
||||||
# 连接数据库
|
|
||||||
print("正在连接数据库...")
|
|
||||||
conn = psycopg2.connect(**DB_CONFIG)
|
|
||||||
print("✓ 数据库连接成功")
|
|
||||||
print()
|
|
||||||
|
|
||||||
# 步骤1:检查需要修复的记录数
|
|
||||||
print("步骤1: 检查需要修复的记录...")
|
|
||||||
need_repair_count = check_repair_needed(conn)
|
|
||||||
print(f"✓ 发现 {need_repair_count} 条需要修复的手术申请单")
|
|
||||||
print()
|
|
||||||
|
|
||||||
if need_repair_count == 0:
|
|
||||||
print("没有需要修复的数据,退出")
|
|
||||||
return
|
|
||||||
|
|
||||||
# 步骤2:获取修复列表
|
|
||||||
print("步骤2: 获取修复列表...")
|
|
||||||
repair_list = get_repair_list(conn)
|
|
||||||
print(f"✓ 获取到 {len(repair_list)} 条记录")
|
|
||||||
print()
|
|
||||||
|
|
||||||
# 步骤3:修复ServiceRequest
|
|
||||||
print("步骤3: 生成手术医嘱(ServiceRequest)...")
|
|
||||||
new_requests = repair_service_request(conn, repair_list)
|
|
||||||
print(f"✓ 成功生成 {len(new_requests)} 条手术医嘱")
|
|
||||||
print()
|
|
||||||
|
|
||||||
# 步骤4:修复ChargeItem
|
|
||||||
print("步骤4: 生成收费项目(ChargeItem)...")
|
|
||||||
repair_charge_items(conn, new_requests)
|
|
||||||
print(f"✓ 成功生成收费项目")
|
|
||||||
print()
|
|
||||||
|
|
||||||
# 步骤5:验证修复结果
|
|
||||||
print("步骤5: 验证修复结果...")
|
|
||||||
service_count, charge_count = verify_repair(conn)
|
|
||||||
print(f"✓ 当前手术医嘱总数: {service_count}")
|
|
||||||
print(f"✓ 当前手术收费项目总数: {charge_count}")
|
|
||||||
print()
|
|
||||||
|
|
||||||
print("=" * 60)
|
|
||||||
print("✓ 修复完成!")
|
|
||||||
print("=" * 60)
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"✗ 错误: {e}")
|
|
||||||
import traceback
|
|
||||||
|
|
||||||
traceback.print_exc()
|
|
||||||
finally:
|
|
||||||
if "conn" in locals():
|
|
||||||
conn.close()
|
|
||||||
print("\n数据库连接已关闭")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
@@ -1,156 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# ============================================================
|
|
||||||
# sync-ai-rules.sh — 将 RULES.md 完整内容同步到所有 AI 工具配置文件
|
|
||||||
#
|
|
||||||
# 用法: bash scripts/sync-ai-rules.sh
|
|
||||||
#
|
|
||||||
# 设计原则:
|
|
||||||
# RULES.md 是唯一信源,本脚本将其内容嵌入到各工具配置文件
|
|
||||||
# 开发者只需编辑 RULES.md,然后运行本脚本即可同步所有工具
|
|
||||||
# ============================================================
|
|
||||||
|
|
||||||
set -euo pipefail
|
|
||||||
cd "$(dirname "$0")/.."
|
|
||||||
|
|
||||||
RULES_FILE="RULES.md"
|
|
||||||
if [ ! -f "$RULES_FILE" ]; then
|
|
||||||
echo "❌ $RULES_FILE not found"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
RULES_CONTENT=$(cat "$RULES_FILE")
|
|
||||||
TIMESTAMP=$(date '+%Y-%m-%d %H:%M')
|
|
||||||
|
|
||||||
echo "📝 Syncing RULES.md → AI tool configs..."
|
|
||||||
|
|
||||||
# ============================================================
|
|
||||||
# 1. AGENTS.md (Codex CLI / Claude Code)
|
|
||||||
# ============================================================
|
|
||||||
cat > AGENTS.md << HEREDOC
|
|
||||||
# HealthLink-HIS — AI 开发规范
|
|
||||||
|
|
||||||
> 🤖 本文件由 Codex CLI、Claude Code 等工具自动读取。
|
|
||||||
> 工具进入项目目录时会自动加载此文件作为开发规范上下文。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
${RULES_CONTENT}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
> 📅 最后同步: ${TIMESTAMP} | 源文件: RULES.md | 重新同步: \`bash scripts/sync-ai-rules.sh\`
|
|
||||||
HEREDOC
|
|
||||||
echo " ✅ AGENTS.md"
|
|
||||||
|
|
||||||
# ============================================================
|
|
||||||
# 2. .cursorrules (Cursor IDE / Codeium Windsurf)
|
|
||||||
# ============================================================
|
|
||||||
cat > .cursorrules << HEREDOC
|
|
||||||
# HealthLink-HIS — AI 开发规范 (Cursor)
|
|
||||||
|
|
||||||
> 🤖 Cursor IDE 打开本项目时自动加载此文件。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
${RULES_CONTENT}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
> 📅 最后同步: ${TIMESTAMP} | 源文件: RULES.md | 重新同步: \`bash scripts/sync-ai-rules.sh\`
|
|
||||||
HEREDOC
|
|
||||||
echo " ✅ .cursorrules"
|
|
||||||
|
|
||||||
# ============================================================
|
|
||||||
# 3. .github/copilot-instructions.md (GitHub Copilot)
|
|
||||||
# ============================================================
|
|
||||||
mkdir -p .github
|
|
||||||
cat > .github/copilot-instructions.md << HEREDOC
|
|
||||||
# HealthLink-HIS — AI 开发规范 (GitHub Copilot)
|
|
||||||
|
|
||||||
> 🤖 GitHub Copilot 打开本项目时自动加载此文件。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
${RULES_CONTENT}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
> 📅 最后同步: ${TIMESTAMP} | 源文件: RULES.md | 重新同步: \`bash scripts/sync-ai-rules.sh\`
|
|
||||||
HEREDOC
|
|
||||||
echo " ✅ .github/copilot-instructions.md"
|
|
||||||
|
|
||||||
# ============================================================
|
|
||||||
# 4. .windsurfrules (Windsurf / Codeium)
|
|
||||||
# ============================================================
|
|
||||||
cat > .windsurfrules << HEREDOC
|
|
||||||
# HealthLink-HIS — AI 开发规范 (Windsurf)
|
|
||||||
|
|
||||||
> 🤖 Windsurf 打开本项目时自动加载此文件。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
${RULES_CONTENT}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
> 📅 最后同步: ${TIMESTAMP} | 源文件: RULES.md | 重新同步: \`bash scripts/sync-ai-rules.sh\`
|
|
||||||
HEREDOC
|
|
||||||
echo " ✅ .windsurfrules"
|
|
||||||
|
|
||||||
# ============================================================
|
|
||||||
# 5. .clinerules (Cline)
|
|
||||||
# ============================================================
|
|
||||||
cat > .clinerules << HEREDOC
|
|
||||||
# HealthLink-HIS — AI 开发规范 (Cline)
|
|
||||||
|
|
||||||
> 🤖 Cline 打开本项目时自动加载此文件。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
${RULES_CONTENT}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
> 📅 最后同步: ${TIMESTAMP} | 源文件: RULES.md | 重新同步: \`bash scripts/sync-ai-rules.sh\`
|
|
||||||
HEREDOC
|
|
||||||
echo " ✅ .clinerules"
|
|
||||||
|
|
||||||
# ============================================================
|
|
||||||
# 6. .qwenrules (Qwen Coder / 通义灵码)
|
|
||||||
# ============================================================
|
|
||||||
cat > .qwenrules << HEREDOC
|
|
||||||
# HealthLink-HIS — AI 开发规范 (Qwen Coder)
|
|
||||||
|
|
||||||
> 🤖 通义灵码 / Qwen Coder 打开本项目时自动加载此文件。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
${RULES_CONTENT}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
> 📅 最后同步: ${TIMESTAMP} | 源文件: RULES.md | 重新同步: \`bash scripts/sync-ai-rules.sh\`
|
|
||||||
HEREDOC
|
|
||||||
echo " ✅ .qwenrules"
|
|
||||||
|
|
||||||
# ============================================================
|
|
||||||
# 7. .aider.conf.yml (Aider) — YAML格式,嵌入指令
|
|
||||||
# ============================================================
|
|
||||||
# Aider 支持 instruction-files 指向文件,同时也支持直接在 .aider.conf.yml 中写 instructions
|
|
||||||
# 这里用 instructions 指令把内容内联
|
|
||||||
cat > .aider.conf.yml << HEREDOC
|
|
||||||
# Aider configuration for HealthLink-HIS
|
|
||||||
# Aider 自动读取此文件获取开发规范
|
|
||||||
|
|
||||||
instructions: |
|
|
||||||
$(echo "$RULES_CONTENT" | sed 's/^/ /')
|
|
||||||
HEREDOC
|
|
||||||
echo " ✅ .aider.conf.yml"
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "🎉 All 7 AI tool configs synced from RULES.md"
|
|
||||||
echo " 文件大小:"
|
|
||||||
for f in AGENTS.md .cursorrules .github/copilot-instructions.md .windsurfrules .clinerules .qwenrules .aider.conf.yml; do
|
|
||||||
size=$(wc -c < "$f" 2>/dev/null || echo "0")
|
|
||||||
echo " $f: ${size} bytes"
|
|
||||||
done
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="outpatient-record">
|
|
||||||
<el-table :data="records" style="width: 100%">
|
|
||||||
<el-table-column prop="date" label="就诊日期" width="180"/>
|
|
||||||
<el-table-column prop="doctor" label="医生" width="180"/>
|
|
||||||
<el-table-column prop="status" label="状态" width="120">
|
|
||||||
<!-- 修复:当 status 为 null、undefined、空字符串时统一显示为 “未确认” 并使用已选中样式 -->
|
|
||||||
<template #default="{ row }">
|
|
||||||
<el-checkbox
|
|
||||||
v-model="row._statusChecked"
|
|
||||||
:true-label="'已确认'"
|
|
||||||
:false-label="'未确认'"
|
|
||||||
:disabled="true"
|
|
||||||
@change="onStatusChange(row)">
|
|
||||||
{{ row._statusChecked ? '已确认' : '未确认' }}
|
|
||||||
</el-checkbox>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="操作" width="120">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<el-button type="text" size="small" @click="viewDetail(row)">查看</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: 'OutpatientRecord',
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
records: [] // [{ date, doctor, status }]
|
|
||||||
};
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.fetchRecords();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
/** 获取就诊记录 */
|
|
||||||
async fetchRecords() {
|
|
||||||
const res = await this.$api.getOutpatientRecords();
|
|
||||||
// 这里统一把 status 转换为布尔值,避免出现空方框
|
|
||||||
this.records = res.data.map(item => ({
|
|
||||||
...item,
|
|
||||||
// status 可能为 null、undefined、'',统一映射为 false(未确认)
|
|
||||||
_statusChecked: !!item.status
|
|
||||||
}));
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 当状态复选框变化时(理论上只读,这里保留以防后续业务需要) */
|
|
||||||
onStatusChange(row) {
|
|
||||||
// 只在前端展示,不向后端提交,防止误改
|
|
||||||
// 如需持久化,请在此调用对应的 API
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 查看详情 */
|
|
||||||
viewDetail(row) {
|
|
||||||
this.$router.push({ name: 'OutpatientDetail', params: { id: row.id } });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.outpatient-record {
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
153
zentao_api.sh
153
zentao_api.sh
@@ -1,153 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# 禅道 API 命令行工具
|
|
||||||
# 使用前需要设置环境变量:
|
|
||||||
# export ZENTAO_URL="http://your-zentao-domain.com"
|
|
||||||
# export ZENTAO_ACCOUNT="your_username"
|
|
||||||
# export ZENTAO_PASSWORD="your_password"
|
|
||||||
|
|
||||||
# 颜色输出
|
|
||||||
RED='\033[0;31m'
|
|
||||||
GREEN='\033[0;32m'
|
|
||||||
YELLOW='\033[1;33m'
|
|
||||||
NC='\033[0m' # No Color
|
|
||||||
|
|
||||||
# 检查依赖
|
|
||||||
check_dependencies() {
|
|
||||||
if ! command -v curl &> /dev/null; then
|
|
||||||
echo -e "${RED}错误: 请安装 curl${NC}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! command -v jq &> /dev/null; then
|
|
||||||
echo -e "${RED}错误: 请安装 jq${NC}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# 获取 Token
|
|
||||||
get_token() {
|
|
||||||
check_dependencies
|
|
||||||
|
|
||||||
if [[ -z "$ZENTAO_URL" || -z "$ZENTAO_ACCOUNT" || -z "$ZENTAO_PASSWORD" ]]; then
|
|
||||||
echo -e "${RED}错误: 请设置环境变量 ZENTAO_URL, ZENTAO_ACCOUNT, ZENTAO_PASSWORD${NC}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
local url="${ZENTAO_URL}/api.php/v1/tokens"
|
|
||||||
|
|
||||||
local response=$(curl -s -X POST "$url" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d "{\"account\":\"$ZENTAO_ACCOUNT\",\"password\":\"$ZENTAO_PASSWORD\"}")
|
|
||||||
|
|
||||||
local token=$(echo "$response" | jq -r '.data.token // empty')
|
|
||||||
|
|
||||||
if [[ -n "$token" ]]; then
|
|
||||||
echo "$token"
|
|
||||||
else
|
|
||||||
echo -e "${RED}获取 Token 失败:${NC}"
|
|
||||||
echo "$response" | jq .
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# 创建 Bug
|
|
||||||
create_bug() {
|
|
||||||
local token="$1"
|
|
||||||
local product_id="$2"
|
|
||||||
local title="$3"
|
|
||||||
local steps="$4"
|
|
||||||
local severity="${5:-2}"
|
|
||||||
local priority="${6:-2}"
|
|
||||||
local module="${7:-}"
|
|
||||||
local assigned_to="${8:-}"
|
|
||||||
|
|
||||||
if [[ -z "$token" || -z "$product_id" || -z "$title" || -z "$steps" ]]; then
|
|
||||||
echo -e "${YELLOW}用法:${NC} $0 create_bug <token> <product_id> <title> <steps> [severity] [priority] [module] [assigned_to]"
|
|
||||||
echo ""
|
|
||||||
echo "参数说明:"
|
|
||||||
echo " token - API Token"
|
|
||||||
echo " product_id - 产品ID"
|
|
||||||
echo " title - Bug标题"
|
|
||||||
echo " steps - 重现步骤"
|
|
||||||
echo " severity - 严重程度 (1-4, 默认2: 一般)"
|
|
||||||
echo " priority - 优先级 (1-4, 默认2: 中等)"
|
|
||||||
echo " module - 模块ID (可选)"
|
|
||||||
echo " assigned_to- 指派给谁 (可选)"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
local url="${ZENTAO_URL}/api.php/v1/products/${product_id}/bugs"
|
|
||||||
|
|
||||||
# 构建 JSON 数据
|
|
||||||
local data="{"
|
|
||||||
data+="\"product\":${product_id},"
|
|
||||||
if [[ -n "$module" ]]; then
|
|
||||||
data+="\"module\":${module},"
|
|
||||||
fi
|
|
||||||
data+="\"title\":\"${title}\","
|
|
||||||
data+="\"steps\":\"${steps}\","
|
|
||||||
data+="\"severity\":${severity},"
|
|
||||||
data+="\"priority\":${priority}"
|
|
||||||
if [[ -n "$assigned_to" ]]; then
|
|
||||||
data+=",\"assignedTo\":\"${assigned_to}\""
|
|
||||||
fi
|
|
||||||
data+="}"
|
|
||||||
|
|
||||||
local response=$(curl -s -X POST "$url" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-H "Authorization:${token}" \
|
|
||||||
-d "$data")
|
|
||||||
|
|
||||||
echo "$response" | jq .
|
|
||||||
}
|
|
||||||
|
|
||||||
# 显示使用帮助
|
|
||||||
show_help() {
|
|
||||||
echo -e "${GREEN}禅道 API 命令行工具${NC}"
|
|
||||||
echo ""
|
|
||||||
echo "用法: $0 <command> [arguments]"
|
|
||||||
echo ""
|
|
||||||
echo "命令:"
|
|
||||||
echo " token 获取 API Token"
|
|
||||||
echo " create_bug 创建 Bug"
|
|
||||||
echo " list_bugs 列出 Bugs"
|
|
||||||
echo " get_bug 获取单个 Bug"
|
|
||||||
echo " update_bug 更新 Bug"
|
|
||||||
echo " resolve_bug 解决 Bug"
|
|
||||||
echo ""
|
|
||||||
echo "示例:"
|
|
||||||
echo " $0 token # 获取 Token"
|
|
||||||
echo " $0 create_bug <token> 100 '测试Bug' '步骤...' # 创建 Bug"
|
|
||||||
}
|
|
||||||
|
|
||||||
# 主函数
|
|
||||||
main() {
|
|
||||||
local command="$1"
|
|
||||||
shift || true
|
|
||||||
|
|
||||||
case "$command" in
|
|
||||||
token)
|
|
||||||
get_token
|
|
||||||
;;
|
|
||||||
create_bug)
|
|
||||||
create_bug "$@"
|
|
||||||
;;
|
|
||||||
list_bugs|get_bug|update_bug|resolve_bug)
|
|
||||||
# 其他功能待实现
|
|
||||||
echo -e "${YELLOW}功能待实现${NC}"
|
|
||||||
;;
|
|
||||||
help|--help|-h)
|
|
||||||
show_help
|
|
||||||
;;
|
|
||||||
"")
|
|
||||||
show_help
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo -e "${RED}未知命令: $command${NC}"
|
|
||||||
show_help
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
main "$@"
|
|
||||||
@@ -1,100 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""
|
|
||||||
禅道 API 示例脚本 - 创建 Bug
|
|
||||||
"""
|
|
||||||
|
|
||||||
import requests
|
|
||||||
import json
|
|
||||||
|
|
||||||
# 禅道配置(需要根据实际情况修改)
|
|
||||||
ZENTAO_URL = "http://your-zentao-domain.com" # 禅道地址
|
|
||||||
ZENTAO_ACCOUNT = "your_username" # 禅道账号
|
|
||||||
ZENTAO_PASSWORD = "your_password" # 禅道密码
|
|
||||||
|
|
||||||
def get_token():
|
|
||||||
"""获取禅道 API Token"""
|
|
||||||
url = f"{ZENTAO_URL}/api.php/v1/tokens"
|
|
||||||
headers = {
|
|
||||||
"Content-Type": "application/json"
|
|
||||||
}
|
|
||||||
data = {
|
|
||||||
"account": ZENTAO_ACCOUNT,
|
|
||||||
"password": ZENTAO_PASSWORD
|
|
||||||
}
|
|
||||||
|
|
||||||
response = requests.post(url, headers=headers, json=data)
|
|
||||||
result = response.json()
|
|
||||||
|
|
||||||
if response.status_code == 200 and result.get("status") == "success":
|
|
||||||
return result.get("token")
|
|
||||||
else:
|
|
||||||
raise Exception(f"获取 Token 失败: {result}")
|
|
||||||
|
|
||||||
def create_bug(token, product_id, title, steps, severity=2, priority=2, module='', assigned_to=''):
|
|
||||||
"""
|
|
||||||
创建Bug
|
|
||||||
|
|
||||||
参数:
|
|
||||||
token: API Token
|
|
||||||
product_id: 产品ID
|
|
||||||
title: Bug标题
|
|
||||||
steps: 重现步骤
|
|
||||||
severity: 严重程度 (1-4, 默认2: 一般)
|
|
||||||
priority: 优先级 (1-4, 默认2: 中等)
|
|
||||||
module: 模块ID (可选)
|
|
||||||
assigned_to: 指派给谁 (可选)
|
|
||||||
"""
|
|
||||||
url = f"{ZENTAO_URL}/api.php/v1/products/{product_id}/bugs"
|
|
||||||
headers = {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"Authorization": token
|
|
||||||
}
|
|
||||||
|
|
||||||
data = {
|
|
||||||
"product": product_id,
|
|
||||||
"module": module,
|
|
||||||
"title": title,
|
|
||||||
"steps": steps,
|
|
||||||
"severity": severity,
|
|
||||||
"priority": priority,
|
|
||||||
"assignedTo": assigned_to
|
|
||||||
}
|
|
||||||
|
|
||||||
# 移除值为空的字段
|
|
||||||
data = {k: v for k, v in data.items() if v}
|
|
||||||
|
|
||||||
response = requests.post(url, headers=headers, json=data)
|
|
||||||
result = response.json()
|
|
||||||
|
|
||||||
if response.status_code == 200 and result.get("status") == "success":
|
|
||||||
print(f"✅ Bug 创建成功!Bug ID: {result.get('data', {}).get('id')}")
|
|
||||||
return result
|
|
||||||
else:
|
|
||||||
print(f"❌ Bug 创建失败: {result}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
def main():
|
|
||||||
try:
|
|
||||||
# 1. 获取 Token
|
|
||||||
print("正在获取 Token...")
|
|
||||||
token = get_token()
|
|
||||||
print(f"✓ Token 获取成功: {token[:10]}...")
|
|
||||||
|
|
||||||
# 2. 创建 Bug 示例
|
|
||||||
# TODO: 请根据实际情况修改以下参数
|
|
||||||
product_id = 100 # 产品ID,需要在禅道中查询
|
|
||||||
title = "【测试】API 创建 Bug 示例"
|
|
||||||
steps = """1. 登录系统
|
|
||||||
2. 进入某个模块
|
|
||||||
3. 执行某个操作
|
|
||||||
4. 观察结果"""
|
|
||||||
|
|
||||||
print("\n正在创建 Bug...")
|
|
||||||
create_bug(token, product_id, title, steps)
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"❌ 发生错误: {e}")
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
Reference in New Issue
Block a user