feat: expand EasyCode software factory workflows
This commit is contained in:
148
RuoYi-Vue/docs/superpowers/plans/2026-07-08-ai-usage-cny-cost.md
Normal file
148
RuoYi-Vue/docs/superpowers/plans/2026-07-08-ai-usage-cny-cost.md
Normal file
@@ -0,0 +1,148 @@
|
||||
# AI Usage CNY Cost Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** Make AI usage fees calculated and displayed as Chinese yuan.
|
||||
|
||||
**Architecture:** Keep the existing AI usage ledger API and database compatibility fields. Update `AiCostCalculator` to use CNY model rates while preserving cache-hit, cache-miss, and completion token calculation. Update the admin Vue page label and formatter to present CNY.
|
||||
|
||||
**Tech Stack:** Java, JUnit 4, Spring/MyBatis, Vue 2, Element UI.
|
||||
|
||||
---
|
||||
|
||||
### File Structure
|
||||
|
||||
- Modify: `ruoyi-generator/src/test/java/com/ruoyi/generator/service/front/AiCostCalculatorTest.java`
|
||||
- Owns pricing expectations for Flash, Pro, default DeepSeek models, missing usage, and cent rounding.
|
||||
- Modify: `ruoyi-generator/src/test/java/com/ruoyi/generator/service/front/AiUsageRecorderTest.java`
|
||||
- Verifies recorded ledger/scope costs reflect the calculator's CNY amount.
|
||||
- Modify: `ruoyi-generator/src/main/java/com/ruoyi/generator/service/front/AiCostCalculator.java`
|
||||
- Owns token-to-money calculation and model rate selection.
|
||||
- Modify: `ruoyi-ui/src/views/generator/aiUsage/index.vue`
|
||||
- Owns AI usage fee labels and currency formatting.
|
||||
|
||||
### Task 1: Backend Pricing Tests
|
||||
|
||||
- [ ] **Step 1: Write failing calculator expectations**
|
||||
|
||||
Update expected values in `AiCostCalculatorTest`:
|
||||
|
||||
```java
|
||||
assertEquals(300, calculator.estimateCostCents("deepseek", "deepseek-chat", 1_000_000, 1_000_000));
|
||||
assertEquals(new BigDecimal("2.90200000"),
|
||||
calculator.estimateCostUsd("deepseek", "deepseek-v4-flash", usage));
|
||||
assertEquals(new BigDecimal("9.02500000"),
|
||||
calculator.estimateCostUsd("deepseek", "deepseek-v4-pro", usage));
|
||||
assertEquals(new BigDecimal("3.00000000"),
|
||||
calculator.estimateCostUsd("deepseek", "deepseek-chat", usage));
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Verify tests fail under old USD rates**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
mvn -pl ruoyi-generator -Dtest=AiCostCalculatorTest test
|
||||
```
|
||||
|
||||
Expected: failures show old USD amounts such as `0.40628000` where CNY amounts are expected.
|
||||
|
||||
- [ ] **Step 3: Update recorder expectation**
|
||||
|
||||
In `AiUsageRecorderTest`, replace `0.40628000` expectations with `2.90200000`.
|
||||
|
||||
- [ ] **Step 4: Verify recorder test fails under old USD rates**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
mvn -pl ruoyi-generator -Dtest=AiUsageRecorderTest test
|
||||
```
|
||||
|
||||
Expected: failures show old USD amount `0.40628000` instead of `2.90000000`.
|
||||
|
||||
### Task 2: Backend CNY Implementation
|
||||
|
||||
- [ ] **Step 1: Replace calculator rate constants**
|
||||
|
||||
In `AiCostCalculator`, replace USD constants with CNY constants:
|
||||
|
||||
```java
|
||||
private static final BigDecimal FLASH_CACHE_HIT_CNY_PER_1M = new BigDecimal("0.02");
|
||||
private static final BigDecimal FLASH_CACHE_MISS_CNY_PER_1M = new BigDecimal("1");
|
||||
private static final BigDecimal FLASH_OUTPUT_CNY_PER_1M = new BigDecimal("2");
|
||||
private static final BigDecimal PRO_CACHE_HIT_CNY_PER_1M = new BigDecimal("0.025");
|
||||
private static final BigDecimal PRO_CACHE_MISS_CNY_PER_1M = new BigDecimal("3");
|
||||
private static final BigDecimal PRO_OUTPUT_CNY_PER_1M = new BigDecimal("6");
|
||||
```
|
||||
|
||||
Keep public method names unchanged for compatibility.
|
||||
|
||||
- [ ] **Step 2: Update internal variable names where local only**
|
||||
|
||||
Rename local variables and `Rate` fields from `Usd` to neutral `Amount` or `Cny` inside `AiCostCalculator`. Do not rename public methods or domain fields in this task.
|
||||
|
||||
- [ ] **Step 3: Verify backend tests pass**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
mvn -pl ruoyi-generator -Dtest=AiCostCalculatorTest,AiUsageRecorderTest test
|
||||
```
|
||||
|
||||
Expected: both test classes pass.
|
||||
|
||||
### Task 3: Admin UI CNY Display
|
||||
|
||||
- [ ] **Step 1: Update label and formatter**
|
||||
|
||||
In `ruoyi-ui/src/views/generator/aiUsage/index.vue`:
|
||||
|
||||
```vue
|
||||
<div class="metric-label">费用 CNY</div>
|
||||
<div class="metric-value">{{ formatCny(summary.costUsd) }}</div>
|
||||
```
|
||||
|
||||
Use `formatCny` for row values and return a yuan-prefixed string:
|
||||
|
||||
```js
|
||||
formatCny(value, cents) {
|
||||
let amount = Number(value || 0)
|
||||
if (!amount && cents) {
|
||||
amount = Number(cents || 0) / 100
|
||||
}
|
||||
return `¥${amount.toFixed(8).replace(/0+$/, '').replace(/\.$/, '') || '0'}`
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Verify UI references**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
rg -n "formatUsd|费用 USD|\\$[0-9]" ruoyi-ui/src/views/generator/aiUsage/index.vue
|
||||
```
|
||||
|
||||
Expected: no matches.
|
||||
|
||||
### Task 4: Final Verification
|
||||
|
||||
- [ ] **Step 1: Run targeted backend tests**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
mvn -pl ruoyi-generator -Dtest=AiCostCalculatorTest,AiUsageRecorderTest test
|
||||
```
|
||||
|
||||
Expected: exit code 0.
|
||||
|
||||
- [ ] **Step 2: Check changed file diff**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
git diff -- ruoyi-generator/src/main/java/com/ruoyi/generator/service/front/AiCostCalculator.java ruoyi-generator/src/test/java/com/ruoyi/generator/service/front/AiCostCalculatorTest.java ruoyi-generator/src/test/java/com/ruoyi/generator/service/front/AiUsageRecorderTest.java ruoyi-ui/src/views/generator/aiUsage/index.vue
|
||||
```
|
||||
|
||||
Expected: diff only changes pricing tests, CNY rates, and UI CNY formatter/labels.
|
||||
Reference in New Issue
Block a user