站长信息
jeffery.xu
jeffery.xu

软件工程师

欢迎访问我的个人笔记网站!我是一名热爱技术的开发者,专注于Web开发和技术分享。

811495111@qq.com
18521510875
筛选

个人笔记

MiniMax AI 项目结构与原理
编程技巧

## MiniMax AI 项目结构与原理

### 📁 文件结构

```
ForAI/
├── config.py          # 配置文件
├── main.py            # 命令行入口
├── minimax_client.py  # API 客户端封装
├── requirements.txt   # 依赖列表
└── .env.example       # 环境变量示例(已弃用)
```

### 🔧 各文件详解

**1. config.py - 配置管理**
```python
MINIMAX_API_KEY = "sk-cp-..."  # API 密钥(写死)
MINIMAX_BASE_URL = "https://api.minimaxi.com/anthropic"  # API 地址
DEFAULT_MODEL = "image-01"  # 默认模型
MAX_TOKENS = 4096  # 最大生成 token 数
TEMPERATURE = 1.0  # 随机性参数
```
原理:集中管理所有配置,简化其他文件的引用。

**2. minimax_client.py - 核心客户端**

```python
class MiniMaxClient:
    # __init__: 初始化 Anthropic SDK 客户端
    # chat(): 支持流式/非流式文字对话
    # simple_chat(): 简易单轮对话
    # generate_image(): 调用 /v1/image_generation 生成图片
```

原理:
- 使用 `anthropic` 官方 SDK 进行文字对话
- 使用 `requests` 库直接调用图像生成 API(因为 SDK 不支持)

**3. main.py - 命令行入口**

使用 `argparse` 解析命令行参数:
- `-m/--message`: 发送的消息
- `-s/--system`: 系统提示词
- `--stream`: 开启流式输出
- `--image/-i`: 图像生成模式
- `--width/--height`: 像素尺寸
- `--aspect-ratio`: 比例(如 16:9)
- `--n`: 生成数量

### 🔄 工作流程

```
用户输入命令
    ↓
main.py 解析参数
    ↓
创建 MiniMaxClient 实例
    ↓
调用相应方法
    ├── chat() / simple_chat() → 文字对话
    └── generate_image() → 图像生成
    ↓
API 返回响应
    ↓
解析并打印结果
```

### 📡 API 调用原理

**文字对话**(使用 Anthropic SDK):
```
client.messages.create(
    model="MiniMax-M2.7-highspeed",
    messages=[{"role": "user", "content": "..."}],
    system="你是一个助手"
)
```

**图像生成**(直接调用 REST API):
```python
requests.post(
    "https://api.minimaxi.com/v1/image_generation",
    headers={"Authorization": f"Bearer {api_key}"},
    json={
        "model": "image-01",
        "prompt": "...",
        "aspect_ratio": "1:1",
        "n": 1
    }
)
```

### 🔑 核心概念

| 参数 | 作用 |
|------|------|
| `temperature` | 控制输出随机性,1.0 为标准,较低值更确定 |
| `max_tokens` | 限制最大生成长度 |
| `stream` | 是否逐字输出(打字机效果) |
| `prompt_optimizer` | 是否让 AI 优化提示词 |
| `aspect_ratio` | 图像宽高比 |

### 🚀 运行示例

```bash
# 文字对话
python main.py -m "你好"

# 流式对话
python main.py -m "写一个故事" --stream

# 生成图片
python main.py -m "一只猫" --image --width 512 --height 512
```

医院补偿类型功能开发说明
工作笔记


一、需求背景
为支持补偿类型在医院维度上的精细化控制,本次在原有“经销商 / 产品 / 省市补偿类型”基础上,新增“医院补偿类型”能力,并同步打通总部维护侧与 DMS/SOI 应用侧逻辑。
本次改造目标为:
•    总部可维护医院补偿类型关系
•    支持医院补偿类型导入、导出
•    补偿申请选择补偿类型时,按医院规则进行过滤
•    补偿申请新增列表与补偿类型选择逻辑保持一致
---
二、提测范围
1. 总部侧-补偿类型维护
新增“医院”维度的补偿类型维护能力,支持:
•    新增
•    修改
•    查看
•    删除
•    导入
•    导出
2. DMS / SOI 应用侧
在补偿申请相关场景中增加医院维度筛选逻辑,涉及:
•    补偿类型选择弹窗
•    补偿申请新增可选数据列表
•    DMS 端
•    SOI 端
---
三、本次开发内容
1. 总部侧开发内容
1.1 医院补偿类型 CRUD
在补偿类型主档下新增“医院”页签,支持维护医院明细关系。
功能点
•    可选择医院
•    可维护“是否纳入补偿”
•    可查看医院补偿类型明细
•    同一补偿类型下支持多医院维护
•    增加重复校验
业务规则
是否纳入补偿 分两种模式:
•    是:表示当前补偿类型仅对配置的医院生效
•    否:表示当前补偿类型对配置的医院不生效
---
1.2 医院补偿类型一致性控制
同一个补偿类型下,所有医院记录的 是否纳入补偿 必须保持一致,不允许同一补偿类型同时出现“是”和“否”。
已实现
•    前端联动同步
•    后端保存前统一规范化处理
•    导入时一致性校验
---
1.3 医院补偿类型导入
新增医院补偿类型导入能力。
导入规则
•    医院代码必填,且必须存在
•    补偿类型代码必填,且必须存在
•    是否纳入补偿 必填,仅允许填写“是/否”
•    标识必填,仅允许填写“新增/覆盖”
•    同一补偿类型下,是否纳入补偿 必须一致
•    任意一条校验失败,则整批导入失败
标识说明
•    新增:保留原有医院关系,新增本次导入数据
•    覆盖:先清除该补偿类型历史医院数据,再导入本次数据
---
1.4 医院补偿类型导出
新增医院补偿类型导出能力,支持导出以下字段:
•    补偿名称
•    补偿代码
•    医院代码
•    医院名称
•    是否纳入补偿
•    创建时间/创建人
•    修改时间/修改人
---
2. DMS / SOI 应用侧开发内容
2.1 补偿类型选择增加医院筛选逻辑
在补偿申请中选择“补偿类型”时,除原有经销商、产品、省市规则外,新增医院规则过滤。
规则说明
医院条件与原有规则关系为 AND。
即在满足经销商 / 产品 / 省市逻辑的基础上,还需满足医院逻辑。
医院筛选规则
•    若补偿类型未配置医院关系:不限制医院
•    若补偿类型配置为 IsInclude = 1
•    当前医院必须存在于医院补偿配置中
•    若补偿类型配置为 IsInclude = 0
•    当前医院必须不存在于医院补偿配置中
---
2.2 补偿申请新增列表增加同样医院逻辑
为保证补偿申请入口行为一致,补偿申请新增列表同步增加同样的医院筛选逻辑。
已同步场景
•    DMS:CompensateApplicationADD
•    SOI:CompensateApplicationADD_SOI
目标
避免出现以下不一致问题:
•    列表中数据可选,但补偿类型不可选
•    补偿类型可选,但实际列表不应出现
---
四、影响模块
总部维护侧
•    补偿类型主档
•    医院补偿类型子表
•    医院补偿类型导入
•    医院补偿类型导出
应用侧
•    DMS 补偿申请
•    SOI 补偿申请
•    补偿类型选择弹窗
•    补偿申请新增列表
---
五、重点测试场景
1. 总部侧 CRUD 测试
场景 1:新增医院补偿类型
•    新增一个补偿类型
•    关联多个医院
•    是否纳入补偿 = 是
•    保存成功
场景 2:修改医院补偿类型
•    修改已有补偿类型的医院列表
•    修改后保存成功
•    查看明细正常
场景 3:一致性校验
•    同一补偿类型下尝试同时保存“是”和“否”
•    预期:不允许保存 / 系统统一规范化
场景 4:重复医院校验
•    同一补偿类型下重复选择同一家医院
•    预期:不允许重复
---
2. 导入测试
场景 5:正常导入-纳入补偿
•    同一补偿类型导入多个医院
•    是否纳入补偿 均为“是”
•    预期:导入成功
场景 6:正常导入-不纳入补偿
•    同一补偿类型导入多个医院
•    是否纳入补偿 均为“否”
•    预期:导入成功
场景 7:混合导入
•    同一补偿类型下同时导入“是”和“否”
•    预期:导入失败
场景 8:医院代码不存在
•    预期:导入失败
场景 9:补偿类型代码不存在
•    预期:导入失败
场景 10:覆盖导入
•    原有医院关系存在
•    使用“覆盖”重新导入
•    预期:旧数据被替换
---
3. 导出测试
场景 11:医院补偿类型导出
•    从补偿类型列表点击“医院导出”
•    预期:
•    成功下载
•    数据字段完整
•    内容与维护数据一致
---
4. DMS / SOI 应用侧测试
场景 12:未配置医院关系
•    某补偿类型只配置经销商/产品/省市,未配置医院
•    预期:该补偿类型不受医院限制
场景 13:医院纳入补偿
•    配置 IsInclude = 1
•    当前医院在配置内
•    预期:补偿类型可见 / 列表可查
场景 14:医院纳入补偿但不匹配
•    配置 IsInclude = 1
•    当前医院不在配置内
•    预期:补偿类型不可见 / 列表不可查
场景 15:医院不纳入补偿
•    配置 IsInclude = 0
•    当前医院在配置内
•    预期:补偿类型不可见 / 列表不可查
场景 16:医院不纳入补偿且不匹配
•    配置 IsInclude = 0
•    当前医院不在配置内
•    预期:补偿类型可见 / 列表可查
---
5. 联合规则测试
场景 17:省市通过,医院通过
•    预期:可选
场景 18:省市通过,医院不通过
•    预期:不可选
场景 19:省市不通过,医院通过
•    预期:不可选
场景 20:省市与医院都通过
•    预期:最终可用
说明:省市与医院关系为 AND
---
六、注意事项
1.    同一补偿类型下医院关系采用统一模式,不支持部分医院纳入、部分医院排除混用
2.    本次改造不影响现有补偿金额计算公式
3.    本次改造主要影响“补偿类型是否可选”和“申请数据是否可见”
4.    DMS 与 SOI 两侧已同步处理,需分别验证

wireguard配置笔记
人工智能学习

 


🧭 一、整体结构(先理解)

服务器(wg0)
  ↓
多个客户端(Peer)
  ↓
每个客户端 = 独立密钥 + 独立IP

🚀 二、首次搭建流程(完整)


1️⃣ 安装 WireGuard(服务器)

sudo apt update
sudo apt install wireguard qrencode -y

2️⃣ 生成服务器密钥

wg genkey | tee /etc/wireguard/server_private.key | wg pubkey > /etc/wireguard/server_public.key

查看:

cat /etc/wireguard/server_public.key

3️⃣ 创建服务器配置

sudo nano /etc/wireguard/wg0.conf

写入👇(替换私钥):

[Interface]
PrivateKey = 服务器私钥
Address = 10.0.0.1/24
ListenPort = 51820

PostUp = sysctl -w net.ipv4.ip_forward=1
PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

4️⃣ 启动服务器

sudo wg-quick up wg0
sudo systemctl enable wg-quick@wg0

查看状态:

sudo wg

📱 三、添加客户端(标准流程)


1️⃣ 客户端生成密钥(推荐)

👉 手机 / 电脑用 WireGuard 自动生成
或:

wg genkey | tee client_private.key | wg pubkey > client_public.key

2️⃣ 在服务器添加客户端

编辑:

sudo nano /etc/wireguard/wg0.conf

追加:

[Peer]
PublicKey = 客户端公钥
AllowedIPs = 10.0.0.2/32

应用(不用重启):

sudo wg syncconf wg0 <(wg-quick strip wg0)

3️⃣ 客户端配置

[Interface]
PrivateKey = 客户端私钥
Address = 10.0.0.2/24
DNS = 1.1.1.1

[Peer]
PublicKey = 服务器公钥
Endpoint = 服务器IP:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

4️⃣ (可选)生成二维码

qrencode -t ansiutf8 < client.conf

🔐 四、换 Key(重点!!!)


🧨 场景:服务器私钥泄露 / 想更换


1️⃣ 生成新服务器密钥

wg genkey | tee /etc/wireguard/new_server_private.key | wg pubkey > /etc/wireguard/new_server_public.key

2️⃣ 替换 wg0.conf

sudo nano /etc/wireguard/wg0.conf

改:

PrivateKey = 新私钥

3️⃣ 重启服务(必须)

sudo wg-quick down wg0
sudo wg-quick up wg0

4️⃣ 确认新公钥生效

sudo wg show wg0 public-key

👉 必须等于:

cat /etc/wireguard/new_server_public.key

5️⃣ 更新所有客户端(关键)

每个客户端改:

[Peer]
PublicKey = 新服务器公钥

6️⃣ 客户端重新连接

打开 VPN 即可


🔁 五、完全重置(更安全)

👉 如果怀疑泄露严重:


服务器

wg genkey | tee server_private.key | wg pubkey > server_public.key

每个客户端(全部重建)

wg genkey | tee client_private.key | wg pubkey > client_public.key

更新服务器

[Peer]
PublicKey = 新客户端公钥
AllowedIPs = 新IP

🧪 六、验证是否成功


服务器查看

sudo wg

重点看:

latest handshake: 刚刚

测试网络

客户端:

ping 10.0.0.1

⚡ 七、常用命令速查


查看状态

sudo wg

查看公钥

sudo wg show wg0 public-key

启动/停止

sudo wg-quick up wg0
sudo wg-quick down wg0

热更新配置

sudo wg syncconf wg0 <(wg-quick strip wg0)

🧠 八、关键记忆(超重要)

👉 WireGuard 核心就是:

私钥(身份) + 公钥(认证) + IP(唯一标识)

 

 

BusinessView的修改
工作笔记

1) 在模型层新增属性(ViewItem)
在 ..\Wicresoft\BusinessObject\ObjectView\BusinessObjectView.cs 的 ViewItem 中新增了 EndTimeInclude(并提供了对应构造函数),用于标记某个日期查询项是否要“按日期(yyyy-MM-dd)比较”。
---
2) 在查询控件生成阶段把属性下发到 UI 节点
在 ..\SOI\CustomControls\QueryProvider.ascx.cs 的 GenerateQueryItem(ViewItem vi, int rowIndex) 里,增加了:
•    queryItem.Attributes["EndTimeInclude"] = vi.EndTimeInclude.ToString().ToLower();
这样每一行查询项(__queryitem_x)都带上了这个标记。
GridView 的作用是通过 ucQueryProvider.InitQueryProvider(this.BusinessObjectView) 把 BusinessObjectView 传给 QueryProvider,因此 vi.EndTimeInclude 能被拿到并写入 queryItem.Attributes。
---
3) 在过滤拼接阶段按该属性走不同 SQL 逻辑
在 QueryProvider.GetBusinessFilter(...) 的 DateTime 分支中,读取:
•    queryItem.Attributes["EndTimeInclude"]
并做条件拼接分支:
•    非 true:沿用原逻辑(field <= endTime)。
•    true:对字段加 CONVERT(varchar(10), field, 23),确保按 yyyy-MM-dd 比较后再和结束日期拼接。

上线前调整
工作笔记


ADD DMS  经销商基准价功能:

1.列表及查询及导出去掉有效日期、失效日期、修改创建时间为创建日期、新增修改日期。

2.当前年份字段改成使用年份,列表、查询、导出都改掉。

3.价格字段放到产品编码后面。

4.查询条件增加经销商名称查询

5.导出都按照最新列表内容进行导出。

6.货号升级功能看下代码逻辑,做修改的时候,需要更新modifytime字段

一键脚本发布
编程技巧

.\scripts\deploy.ps1 -ServerHost "106.54.42.242" -ServerUser "ubuntu" -ServerComposePath "/home/ubuntu"

清空vscode记录
编程技巧

Write-Host "正在清理 VSCode 相关文件..." -ForegroundColor Yellow # 停止可能运行的 VSCode 进程 Get-Process "Code" -ErrorAction SilentlyContinue | Stop-Process -Force # 删除文件夹 $paths = @( "$env:APPDATA\Code", "$env:APPDATA\Code - Insiders", "$env:LOCALAPPDATA\Programs\Microsoft VS Code", "$env:LOCALAPPDATA\Programs\VS Code", "$HOME\.vscode" ) foreach ($path in $paths) { if (Test-Path $path) { Remove-Item -Recurse -Force $path Write-Host "已删除: $path" -ForegroundColor Green } } Write-Host "清理完成!" -ForegroundColor Green

UVX报错
编程技巧

在用 uvx 配置 MCP server 时,安装 amap-mcp-server==0.1.11 失败,报错是
The system cannot open the device or file specified (os error -2147024786),随后触发 MCP error -32000: Connection closed。


uvx 的独立安装/缓存链路在 Windows 上出问题。
机器里同时有两份 uv(pip 版 + standalone 版),导致 uv self update 初始失败。
解决方案总结:
1. 先解决 uv 冲突:卸载 pip 版或确保命中 standalone 版。

卸载 pip 版 uv

python -m pip uninstall -y uv

新开一个 PowerShell,确认命中的是 standalone

where uv
uv --version
uv self update
success: Upgraded uv from v0.10.10 to v0.10.12! https://github.com/astral-sh/uv/releases/tag/0.10.12
把 uv 升级到 0.10.12,说明这一步已完成。
若 uvx 仍报设备/文件错误,设置:
• UV_CACHE_DIR=C:\uv-cache
• UV_LINK_MODE=copy
然后重开终端再试。
高德地图MCP
编程技巧
"高德地图": {
      "url": "https://mcp.amap.com/sse?key="
    }
本地 `git push` 失败(GitHub 单文件上限 100MB)。
编程技巧

问题总结(可直接记录):

1. 现象  
本地 `git push` 失败,原因是提交历史里包含了 `DiaryWebsite.Web/logs/` 下超过 100MB 的 `.log` 文件(GitHub 单文件上限 100MB)。

2. 约束  
你已经有很多其他改动并且都 commit 了,不能简单回退提交。

3. 处理思路  
不回退业务改动,只把大日志文件从 Git 历史中移除,并防止未来再次被提交。

4. 关键操作  
- 在 `.gitignore` 中忽略日志文件(如 `DiaryWebsite.Web/logs/*.log`)。  
- 用历史清理工具(`git filter-repo`)删除历史中的日志文件记录。  
- 清理后发现远程 `origin` 丢失(报错:`'origin' does not appear to be a git repository`)。  
- 重新添加远程:`https://github.com/jy02542317/Diary.git`。  
- `git fetch origin --prune` 后,再执行  
  `git push -u origin main --force-with-lease` 成功。

5. 最终结果  
远程 `main` 已成功更新(forced update),仓库恢复可正常 push/pull。

6. 经验与预防  
- 日志、打包产物、大模型文件不要直接进 Git。  
- 通过 `.gitignore` 提前屏蔽 `logs/*.log`。  
- 大文件如需版本管理,使用 Git LFS。  
- 一旦做了历史重写并 force push,需通知协作者同步分支。

```bash
# 1) 先备份一个分支(防止误操作)
git branch backup-before-clean-large-file

# 2) 忽略日志文件
echo DiaryWebsite.Web/logs/*.log >> .gitignore
git add .gitignore
git commit -m "chore: ignore log files"

# 3) 安装历史清理工具(若未安装)
pip install git-filter-repo

# 4) 从历史中移除 logs 下的 .log 文件
git filter-repo --force --path-glob "DiaryWebsite.Web/logs/*.log" --invert-paths

# 5) 重新添加远程(filter-repo 后可能丢失)
git remote add origin https://github.com/jy02542317/Diary.git

# 6) 检查远程是否配置成功
git remote -v
git remote get-url origin

# 7) 拉取远端引用,避免 force-with-lease 的 stale info
git fetch origin --prune

# 8) 强制推送清理后的 main(保留 lease 保护)
git push -u origin main --force-with-lease
```

你这次实际成功推送时的关键输出是:
- `branch 'main' set up to track 'origin/main'.`
- `main -> main (forced update)`