vps-work 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.well-known/skills/index.json +203 -0
- package/README.md +315 -0
- package/USAGE.md +289 -0
- package/dist/vps-work.cjs +64206 -0
- package/examples/README.md +94 -0
- package/package.json +76 -0
- package/scripts/install-onboard-skill.ps1 +77 -0
- package/scripts/install-onboard-skill.sh +66 -0
- package/scripts/test-local-tenant-services.mjs +21 -0
- package/skills/README.md +53 -0
- package/skills/sale-performance-query/SKILL.md +210 -0
- package/skills/sale-performance-query/references/vps-sales-account-orders.md +48 -0
- package/skills/sale-performance-query/references/vps-sales-agent-five-suite.md +55 -0
- package/skills/sale-performance-query/references/vps-sales-customer-mix.md +47 -0
- package/skills/sale-performance-query/references/vps-sales-customer-region.md +70 -0
- package/skills/sale-performance-query/references/vps-sales-daily-trend.md +44 -0
- package/skills/sale-performance-query/references/vps-sales-dealer-orders.md +47 -0
- package/skills/sale-performance-query/references/vps-sales-dealer-performance.md +49 -0
- package/skills/sale-performance-query/references/vps-sales-deposit-breakdown.md +16 -0
- package/skills/sale-performance-query/references/vps-sales-dept-breakdown.md +32 -0
- package/skills/sale-performance-query/references/vps-sales-dept-comparison.md +24 -0
- package/skills/sale-performance-query/references/vps-sales-entities.md +25 -0
- package/skills/sale-performance-query/references/vps-sales-headline-kpi.md +26 -0
- package/skills/sale-performance-query/references/vps-sales-invoice-attachments.md +37 -0
- package/skills/sale-performance-query/references/vps-sales-invoice-status.md +37 -0
- package/skills/sale-performance-query/references/vps-sales-order-finance.md +29 -0
- package/skills/sale-performance-query/references/vps-sales-order-logistics.md +50 -0
- package/skills/sale-performance-query/references/vps-sales-per-person-kpi.md +24 -0
- package/skills/sale-performance-query/references/vps-sales-personal-okr.md +40 -0
- package/skills/sale-performance-query/references/vps-sales-ranking.md +25 -0
- package/skills/sale-performance-query/references/vps-sales-reconciled-receipts.md +46 -0
- package/skills/sale-performance-query/references/vps-sales-refund-summary.md +20 -0
- package/skills/sale-performance-query/references/vps-sales-service-sales.md +23 -0
- package/skills/sale-performance-query/references/vps-sales-shared-params.md +68 -0
- package/skills/sale-performance-query/references/vps-sales-target-achievement.md +47 -0
- package/skills/sale-performance-query/references/vps-sales-team-pk.md +23 -0
- package/skills/vps-approval/SKILL.md +20 -0
- package/skills/vps-calendar/SKILL.md +64 -0
- package/skills/vps-calendar/agents/openai.yaml +4 -0
- package/skills/vps-corporate/SKILL.md +84 -0
- package/skills/vps-creative/SKILL.md +66 -0
- package/skills/vps-current-user-identity/SKILL.md +138 -0
- package/skills/vps-current-user-identity/reference.md +79 -0
- package/skills/vps-daily-report-assistant/SKILL.md +180 -0
- package/skills/vps-daily-sales-report/SKILL.md +124 -0
- package/skills/vps-daily-sales-report/reference.md +188 -0
- package/skills/vps-device-abnormal-statistics/SKILL.md +52 -0
- package/skills/vps-device-abnormal-statistics/agents/openai.yaml +4 -0
- package/skills/vps-device-abnormal-statistics/references/api.md +134 -0
- package/skills/vps-documents/SKILL.md +77 -0
- package/skills/vps-documents/agents/openai.yaml +4 -0
- package/skills/vps-documents/references/api.md +106 -0
- package/skills/vps-hr/SKILL.md +50 -0
- package/skills/vps-hr-compensation-documents/SKILL.md +61 -0
- package/skills/vps-hr-compensation-documents/reference.md +68 -0
- package/skills/vps-hr-compensation-documents/references/+payslip.md +29 -0
- package/skills/vps-hr-compensation-documents/references/runtime-and-helpers.md +24 -0
- package/skills/vps-im/SKILL.md +154 -0
- package/skills/vps-im/references/vps-im-bots.md +25 -0
- package/skills/vps-im/references/vps-im-calls.md +28 -0
- package/skills/vps-im/references/vps-im-channels.md +32 -0
- package/skills/vps-im/references/vps-im-read.md +105 -0
- package/skills/vps-im/references/vps-im-send.md +57 -0
- package/skills/vps-im/references/vps-im-shared-params.md +42 -0
- package/skills/vps-mail/SKILL.md +17 -0
- package/skills/vps-meeting/SKILL.md +42 -0
- package/skills/vps-okr/SKILL.md +22 -0
- package/skills/vps-okr-management-assistant/SKILL.md +45 -0
- package/skills/vps-okr-management-assistant/reference.md +84 -0
- package/skills/vps-pending-approval-assistant/SKILL.md +66 -0
- package/skills/vps-pending-approval-assistant/reference.md +55 -0
- package/skills/vps-product/SKILL.md +221 -0
- package/skills/vps-sale-personnel-efficiency/SKILL.md +124 -0
- package/skills/vps-sale-personnel-efficiency/reference.md +139 -0
- package/skills/vps-shared/SKILL.md +72 -0
- package/skills/vps-store-management/SKILL.md +35 -0
- package/skills/vps-store-management/references/store-reception.md +40 -0
- package/skills/vps-task-management-assistant/SKILL.md +140 -0
- package/skills/vps-tools/SKILL.md +73 -0
- package/skills/vps-tools/agents/openai.yaml +4 -0
- package/skills/vps-v-drive/SKILL.md +82 -0
- package/skills/vps-vemory/SKILL.md +33 -0
- package/skills/vps-work/SKILL.md +366 -0
- package/skills/vps-work-onboard/SKILL.md +53 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# vps-work - quickstart walkthrough
|
|
2
|
+
|
|
3
|
+
End-to-end demonstration of using `vps-work` against Vertu business APIs, then
|
|
4
|
+
propagating the bundled public skills to Cursor / Claude Code / Trae / Hermes.
|
|
5
|
+
|
|
6
|
+
## 0. Build (or `npm link`) the CLI
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
cd vps-cli
|
|
10
|
+
cd packages/vps-work
|
|
11
|
+
npm install
|
|
12
|
+
npm run build
|
|
13
|
+
node dist/vps-work.cjs --help
|
|
14
|
+
# or, for a globally callable binary while developing:
|
|
15
|
+
npm link
|
|
16
|
+
vps-work --help
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## 1. Login once per deployment
|
|
20
|
+
|
|
21
|
+
This password login is for a human operator in an interactive terminal only. Agent/Bot/Hermes must use host-injected app_key credentials and must not request or pass a user password.
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
vps-work auth login
|
|
25
|
+
# → prompts for login + password, then stores the session in the OS keychain
|
|
26
|
+
# (falls back to ~/.vps-work/config.json with mode 0600 if keytar is unavailable)
|
|
27
|
+
|
|
28
|
+
vps-work auth status
|
|
29
|
+
# Service : Vertu
|
|
30
|
+
# Auth mode : user
|
|
31
|
+
# User : alice@example.com (uid=7)
|
|
32
|
+
# Session src : keychain
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## 2. Run domain shortcuts
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
vps-work sales --help
|
|
39
|
+
vps-work sales +headline-kpi
|
|
40
|
+
vps-work sales +dept-breakdown --period this_month --group-by dept_l1
|
|
41
|
+
vps-work sales +target-achievement --period this_month --params '{"group_by":"dept_l1","limit":500}'
|
|
42
|
+
vps-work sales +dept-breakdown --period this_month --group-by salesperson --limit 10
|
|
43
|
+
|
|
44
|
+
vps-work hr +me
|
|
45
|
+
vps-work product +inventory --product-name "AGENT Q"
|
|
46
|
+
vps-work product +inventory --product-subcategory "VERTU ALPHAFOLD" --product-material 小牛皮 --product-color 黑色 --group-by store_detail
|
|
47
|
+
vps-work product +price --product-subcategory "VERTU ALPHAFOLD" --product-material 鳄鱼皮 --price-region overseas
|
|
48
|
+
|
|
49
|
+
# manage the same local V Drive files as VPS Desktop
|
|
50
|
+
vps-work drive +list --recursive
|
|
51
|
+
vps-work drive +upload --source ./方案.pdf
|
|
52
|
+
|
|
53
|
+
# preview the payload without executing
|
|
54
|
+
vps-work sales +headline-kpi --validate-only
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## 3. Install bundled public skills (no login required)
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
vps-work skill list # list all bundled public skills
|
|
61
|
+
vps-work skill install --all --agent all # cursor / claude-code / trae / hermes / ...
|
|
62
|
+
vps-work skill install sale-performance-query vps-im --agent cursor
|
|
63
|
+
vps-work skill install --all --dir ~/work/my-agent/skills # custom dir for a non-builtin agent
|
|
64
|
+
|
|
65
|
+
vps-work skill update # overwrite-resync after upgrading the CLI
|
|
66
|
+
vps-work skill uninstall sale-performance-query --agent cursor
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## 4. Where things land on disk
|
|
70
|
+
|
|
71
|
+
| Agent | Directory | Notes |
|
|
72
|
+
|-------|-----------|-------|
|
|
73
|
+
| Cursor (user-level) | `~/.cursor/skills/<skill_key>/` | Adds `disable-model-invocation: false` to frontmatter |
|
|
74
|
+
| Claude Code (user-level) | `~/.claude/skills/<skill_key>/` | Adds `allowed-tools: [Bash]` so the model may invoke `vps-work` |
|
|
75
|
+
| Trae international | `~/.trae/skills/<skill_key>/` | International edition only |
|
|
76
|
+
| Trae China | `~/.trae-cn/skills/<skill_key>/` | CN edition uses a separate `.trae-cn` user folder |
|
|
77
|
+
| OpenClaw | `~/.openclaw/skills/<skill_key>/` | Managed/local skill root |
|
|
78
|
+
| Hermes (Nous Research) | `~/.hermes/skills/<skill_key>/` | Hermes Agent's source-of-truth skills root |
|
|
79
|
+
| Custom (`--dir`) | `<path>/<skill_key>/` | Any not-yet-builtin agent |
|
|
80
|
+
|
|
81
|
+
Skills are static files copied recursively from the package `skills/` directory —
|
|
82
|
+
no remote fetch, no cache, no manifest. `vps-work skill update` simply re-copies
|
|
83
|
+
the bundled files (overwrite).
|
|
84
|
+
|
|
85
|
+
## 5. CI / non-interactive use (Bot Bearer)
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
export VERTU_BOT_INBOUND_KEY=<inbound_api_key>
|
|
89
|
+
vps-work auth status
|
|
90
|
+
vps-work sales +headline-kpi
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
When `VERTU_BOT_INBOUND_KEY` is set the CLI sends `Authorization: Bearer ...`.
|
|
94
|
+
Agent integrations can instead set `VERTU_APP_ID` / `VERTU_APP_KEY`.
|
package/package.json
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "vps-work",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "VPS Work CLI - tenant-aware domain shortcuts and bundled agent skills for Cursor / Claude Code / Trae.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "he-linyan",
|
|
7
|
+
"homepage": "https://gitee.com/he-linyan/vps-cli#readme",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://gitee.com/he-linyan/vps-cli.git",
|
|
11
|
+
"directory": "packages/vps-work"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://gitee.com/he-linyan/vps-cli/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"odoo",
|
|
18
|
+
"cli",
|
|
19
|
+
"ai-skills",
|
|
20
|
+
"ai-cli",
|
|
21
|
+
"agent",
|
|
22
|
+
"cursor",
|
|
23
|
+
"claude-code",
|
|
24
|
+
"trae",
|
|
25
|
+
"vps-work"
|
|
26
|
+
],
|
|
27
|
+
"type": "module",
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=20"
|
|
30
|
+
},
|
|
31
|
+
"bin": {
|
|
32
|
+
"vps-work": "dist/vps-work.cjs"
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"dist",
|
|
36
|
+
"skills",
|
|
37
|
+
".well-known",
|
|
38
|
+
"scripts",
|
|
39
|
+
"README.md",
|
|
40
|
+
"USAGE.md",
|
|
41
|
+
"examples/README.md"
|
|
42
|
+
],
|
|
43
|
+
"publishConfig": {
|
|
44
|
+
"access": "public",
|
|
45
|
+
"registry": "https://registry.npmjs.org/"
|
|
46
|
+
},
|
|
47
|
+
"scripts": {
|
|
48
|
+
"dev": "tsx src/bin/vps-work.ts",
|
|
49
|
+
"build": "tsup",
|
|
50
|
+
"lint": "eslint \"src/**/*.ts\" \"tests/**/*.ts\"",
|
|
51
|
+
"typecheck": "tsc --noEmit",
|
|
52
|
+
"test": "vitest run",
|
|
53
|
+
"test:watch": "vitest",
|
|
54
|
+
"prepublishOnly": "npm test && npm run build"
|
|
55
|
+
},
|
|
56
|
+
"dependencies": {
|
|
57
|
+
"@inquirer/prompts": "^7.2.0",
|
|
58
|
+
"commander": "^13.0.0",
|
|
59
|
+
"undici": "^7.2.0",
|
|
60
|
+
"yaml": "^2.6.1",
|
|
61
|
+
"zod": "^3.24.1"
|
|
62
|
+
},
|
|
63
|
+
"optionalDependencies": {
|
|
64
|
+
"keytar": "^7.9.0"
|
|
65
|
+
},
|
|
66
|
+
"devDependencies": {
|
|
67
|
+
"@types/node": "^22.10.5",
|
|
68
|
+
"@typescript-eslint/eslint-plugin": "^8.20.0",
|
|
69
|
+
"@typescript-eslint/parser": "^8.20.0",
|
|
70
|
+
"eslint": "^9.18.0",
|
|
71
|
+
"tsup": "^8.3.5",
|
|
72
|
+
"tsx": "^4.19.2",
|
|
73
|
+
"typescript": "^5.7.3",
|
|
74
|
+
"vitest": "^3.0.0"
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# vps-work-onboard skill installer (PowerShell)
|
|
2
|
+
# Usage:
|
|
3
|
+
# irm https://unpkg.com/vps-work@latest/scripts/install-onboard-skill.ps1 | iex
|
|
4
|
+
#
|
|
5
|
+
# Behavior:
|
|
6
|
+
# - Downloads vps-work-onboard/SKILL.md from the npm package on unpkg (override via $env:VERTU_ONBOARD_RAW)
|
|
7
|
+
# - Detects which AI agent root directories already exist under $HOME and writes
|
|
8
|
+
# <agent>/skills/vps-work-onboard/SKILL.md into each
|
|
9
|
+
# - Falls back to ~/.cursor/skills/vps-work-onboard/ when no agent root is detected
|
|
10
|
+
# - Idempotent: re-running just rewrites the SKILL.md (whatever was on disk is overwritten)
|
|
11
|
+
#
|
|
12
|
+
# After running, tell your AI agent (Cursor / Claude Code / Trae / ...) something like:
|
|
13
|
+
# "Use the vps-work-onboard skill to install vps-work on this machine."
|
|
14
|
+
|
|
15
|
+
$ErrorActionPreference = 'Stop'
|
|
16
|
+
|
|
17
|
+
$Raw = if ($env:VERTU_ONBOARD_RAW) {
|
|
18
|
+
$env:VERTU_ONBOARD_RAW
|
|
19
|
+
} else {
|
|
20
|
+
'https://unpkg.com/vps-work@latest/skills/vps-work-onboard/SKILL.md'
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
# Critical: use Invoke-WebRequest -OutFile to preserve raw bytes. Invoke-RestMethod +
|
|
24
|
+
# Set-Content -Encoding UTF8 mangles non-ASCII (Chinese) on Windows PowerShell 5.x
|
|
25
|
+
# because IRM decodes the response into a .NET string under the current console codepage,
|
|
26
|
+
# and Set-Content -Encoding UTF8 then writes a BOM. Streaming bytes side-steps both.
|
|
27
|
+
Write-Host "[vps-work-onboard] fetching SKILL.md from $Raw"
|
|
28
|
+
$tmpFile = [System.IO.Path]::GetTempFileName()
|
|
29
|
+
try {
|
|
30
|
+
try {
|
|
31
|
+
Invoke-WebRequest -Uri $Raw -OutFile $tmpFile -UseBasicParsing -TimeoutSec 30 | Out-Null
|
|
32
|
+
} catch {
|
|
33
|
+
Write-Error "Failed to fetch SKILL.md from $Raw : $($_.Exception.Message)"
|
|
34
|
+
exit 1
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
# Map: agent id => root dir under $HOME (also the marker that proves the agent is in use)
|
|
38
|
+
$agents = @(
|
|
39
|
+
@{ Id = 'cursor'; Root = '.cursor' },
|
|
40
|
+
@{ Id = 'claude'; Root = '.claude' },
|
|
41
|
+
@{ Id = 'trae'; Root = '.trae' },
|
|
42
|
+
@{ Id = 'trae-cn'; Root = '.trae-cn' },
|
|
43
|
+
@{ Id = 'openclaw'; Root = '.openclaw' },
|
|
44
|
+
@{ Id = 'hermes'; Root = '.hermes' }
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
$homeDir = [Environment]::GetFolderPath('UserProfile')
|
|
48
|
+
$written = New-Object System.Collections.Generic.List[string]
|
|
49
|
+
|
|
50
|
+
foreach ($a in $agents) {
|
|
51
|
+
$markerPath = Join-Path $homeDir $a.Root
|
|
52
|
+
if (-not (Test-Path -LiteralPath $markerPath -PathType Container)) { continue }
|
|
53
|
+
$destDir = Join-Path (Join-Path $markerPath 'skills') 'vps-work-onboard'
|
|
54
|
+
New-Item -ItemType Directory -Path $destDir -Force | Out-Null
|
|
55
|
+
$destFile = Join-Path $destDir 'SKILL.md'
|
|
56
|
+
Copy-Item -LiteralPath $tmpFile -Destination $destFile -Force
|
|
57
|
+
$written.Add("$($a.Id) -> $destFile")
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if ($written.Count -eq 0) {
|
|
61
|
+
Write-Host "[vps-work-onboard] no AI agent root detected under $homeDir ; falling back to Cursor."
|
|
62
|
+
$destDir = Join-Path $homeDir '.cursor\skills\vps-work-onboard'
|
|
63
|
+
New-Item -ItemType Directory -Path $destDir -Force | Out-Null
|
|
64
|
+
$destFile = Join-Path $destDir 'SKILL.md'
|
|
65
|
+
Copy-Item -LiteralPath $tmpFile -Destination $destFile -Force
|
|
66
|
+
$written.Add("cursor (fallback) -> $destFile")
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
Write-Host ""
|
|
70
|
+
Write-Host "[vps-work-onboard] installed to:"
|
|
71
|
+
foreach ($w in $written) { Write-Host " $w" }
|
|
72
|
+
Write-Host ""
|
|
73
|
+
Write-Host "Next: open your AI agent and say:"
|
|
74
|
+
Write-Host ' "Use the vps-work-onboard skill to install vps-work on this machine."'
|
|
75
|
+
} finally {
|
|
76
|
+
Remove-Item -LiteralPath $tmpFile -Force -ErrorAction SilentlyContinue
|
|
77
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# vps-work-onboard skill installer (POSIX bash)
|
|
3
|
+
# Usage:
|
|
4
|
+
# curl -fsSL https://unpkg.com/vps-work@latest/scripts/install-onboard-skill.sh | bash
|
|
5
|
+
#
|
|
6
|
+
# Behavior:
|
|
7
|
+
# - Downloads vps-work-onboard/SKILL.md from the npm package on unpkg (override via VERTU_ONBOARD_RAW)
|
|
8
|
+
# - Detects which AI agent root directories already exist under $HOME and writes
|
|
9
|
+
# <agent>/skills/vps-work-onboard/SKILL.md into each
|
|
10
|
+
# - Falls back to ~/.cursor/skills/vps-work-onboard/ when no agent root is detected
|
|
11
|
+
# - Idempotent: re-running just rewrites the SKILL.md
|
|
12
|
+
#
|
|
13
|
+
# After running, tell your AI agent (Cursor / Claude Code / Trae / ...) something like:
|
|
14
|
+
# "Use the vps-work-onboard skill to install vps-work on this machine."
|
|
15
|
+
|
|
16
|
+
set -euo pipefail
|
|
17
|
+
|
|
18
|
+
RAW="${VERTU_ONBOARD_RAW:-https://unpkg.com/vps-work@latest/skills/vps-work-onboard/SKILL.md}"
|
|
19
|
+
|
|
20
|
+
echo "[vps-work-onboard] fetching SKILL.md from $RAW"
|
|
21
|
+
TMP="$(mktemp)"
|
|
22
|
+
trap 'rm -f "$TMP"' EXIT
|
|
23
|
+
if ! curl -fsSL --max-time 30 "$RAW" -o "$TMP"; then
|
|
24
|
+
echo "Failed to fetch SKILL.md from $RAW" >&2
|
|
25
|
+
exit 1
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
# Pairs of "<agent_id>:<root_dir_under_home>" — root_dir is also the marker that
|
|
29
|
+
# proves the user actually uses that agent. We write into <home>/<root>/skills/vps-work-onboard/.
|
|
30
|
+
AGENTS=(
|
|
31
|
+
"cursor:.cursor"
|
|
32
|
+
"claude:.claude"
|
|
33
|
+
"trae:.trae"
|
|
34
|
+
"trae-cn:.trae-cn"
|
|
35
|
+
"openclaw:.openclaw"
|
|
36
|
+
"hermes:.hermes"
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
HOME_DIR="${HOME:?HOME not set}"
|
|
40
|
+
written=()
|
|
41
|
+
|
|
42
|
+
for entry in "${AGENTS[@]}"; do
|
|
43
|
+
id="${entry%%:*}"
|
|
44
|
+
root="${entry##*:}"
|
|
45
|
+
marker="$HOME_DIR/$root"
|
|
46
|
+
[ -d "$marker" ] || continue
|
|
47
|
+
dest_dir="$marker/skills/vps-work-onboard"
|
|
48
|
+
mkdir -p "$dest_dir"
|
|
49
|
+
cp "$TMP" "$dest_dir/SKILL.md"
|
|
50
|
+
written+=("$id → $dest_dir/SKILL.md")
|
|
51
|
+
done
|
|
52
|
+
|
|
53
|
+
if [ "${#written[@]}" -eq 0 ]; then
|
|
54
|
+
echo "[vps-work-onboard] no AI agent root detected under $HOME_DIR ; falling back to Cursor."
|
|
55
|
+
dest_dir="$HOME_DIR/.cursor/skills/vps-work-onboard"
|
|
56
|
+
mkdir -p "$dest_dir"
|
|
57
|
+
cp "$TMP" "$dest_dir/SKILL.md"
|
|
58
|
+
written+=("cursor (fallback) → $dest_dir/SKILL.md")
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
echo
|
|
62
|
+
echo "[vps-work-onboard] installed to:"
|
|
63
|
+
for w in "${written[@]}"; do echo " $w"; done
|
|
64
|
+
echo
|
|
65
|
+
echo "Next: open your AI agent and say:"
|
|
66
|
+
echo ' "Use the vps-work-onboard skill to install vps-work on this machine."'
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import {execFile} from 'node:child_process';
|
|
3
|
+
import {promisify} from 'node:util';
|
|
4
|
+
import {fileURLToPath} from 'node:url';
|
|
5
|
+
const base='http://127.0.0.1:3928';
|
|
6
|
+
const tenants=[process.env.VPS_TEST_TENANT_A,process.env.VPS_TEST_TENANT_B];
|
|
7
|
+
if(tenants.some(id=>!id))throw Error('Specify isolated acceptance tenants');
|
|
8
|
+
const bin=process.env.VPS_TEST_CLI_BIN||fileURLToPath(new URL('../dist/vps-work.cjs',import.meta.url));
|
|
9
|
+
async function post(path,body,token){const r=await fetch(base+path,{method:'POST',headers:{'Content-Type':'application/json',...(token?{Authorization:`Bearer ${token}`}:{})},body:JSON.stringify(body)});assert.equal(r.status,200);return r.json();}
|
|
10
|
+
for(const tenant of tenants){
|
|
11
|
+
const initial=await post('/v1/auth/login',{login:'19900000011',password:'LocalAcceptance-2026!'});
|
|
12
|
+
const session=await post('/v1/auth/tenant/switch',{tenant_id:tenant},initial.token);
|
|
13
|
+
assert.equal(session.user.tenantId,tenant);
|
|
14
|
+
for(const args of [['im','+me'],['im','+users','--limit','100'],['im','+channels'],['task','+tc-tasks']]){
|
|
15
|
+
const {stdout}=await promisify(execFile)(process.execPath,[bin,...args],{env:{...process.env,VERTU_VPS_SERVICE_URL:base,VERTU_ACCESS_TOKEN:session.token,VERTU_EXPECTED_USER_ID:String(session.user.userId),VERTU_USER_LOGIN:session.user.login},timeout:60000,maxBuffer:4*1024*1024});
|
|
16
|
+
const result=JSON.parse(stdout);assert.ok(result&&typeof result==='object');
|
|
17
|
+
if(args[1]==='+me')assert.ok(stdout.includes(tenant),'CLI response must carry the selected tenant');
|
|
18
|
+
console.log(`PASS ${args.slice(0,2).join(' ')} for isolated tenant ${tenant}`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
console.log('Built CLI read-only smoke passed. No global CLI credentials were changed; no SMS or paid model request was sent.');
|
package/skills/README.md
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Agent Skills
|
|
2
|
+
|
|
3
|
+
布局对齐 [larksuite/cli/skills](https://github.com/larksuite/cli/tree/main/skills):`skills/<skill_key>/SKILL.md`,域级聚合 skill 提供 `+` 快捷表并指向 `references/` 或子 skill 契约。
|
|
4
|
+
|
|
5
|
+
## 域聚合(与 `vps-work <域>` 一一对应)
|
|
6
|
+
|
|
7
|
+
| CLI 域 | 聚合 skill | 说明 |
|
|
8
|
+
|--------|------------|------|
|
|
9
|
+
| (共用) | `vps-shared` | 登录、身份、`+` 约定 |
|
|
10
|
+
| `sales` | `sale-performance-query` | 总销日报、部门 OKR 达成、销售人效 |
|
|
11
|
+
| `store` | `vps-store-management` | 门店接待、进店转化与客户过程数据 |
|
|
12
|
+
| `hr` | `vps-hr` | 薪酬单据、工资条 |
|
|
13
|
+
| `product` | `vps-product` | 库存、商品价格、发货、齐套物料、机头库存 |
|
|
14
|
+
| `task` | `vps-task-management-assistant` | 任务中心项目 / 任务 / 待办 / PDCA 协助人 / OKR |
|
|
15
|
+
| `approval` | `vps-approval` | 审批队列 |
|
|
16
|
+
| `report` | `vps-daily-report-assistant` | 我的日报 / 提交 / 同步 |
|
|
17
|
+
| `okr` | `vps-okr` | OKR |
|
|
18
|
+
| `calendar` | `vps-calendar` | 查询、创建和修改日程,指定日历与多人忙闲 |
|
|
19
|
+
| `docs` | `vps-documents` | 查询、创建、整理、导出、共享企业云文档,并发送文档卡片到 VPS IM |
|
|
20
|
+
| `drive` | `vps-v-drive` | 管理账号级 OSS V盘普通文件、文件夹、传输记录与回收站 |
|
|
21
|
+
| `creative` | `vps-creative` | 内容创作画布:AI 生图、生视频、文字转语音、音乐生成与模型列表 |
|
|
22
|
+
| `tools` | `vps-tools` | 平台公共工具:OSS 上传、公开地址与限时签名地址 |
|
|
23
|
+
| `im` / `mail` / `meeting` | `vps-im` / `vps-mail` / `vps-meeting` | IM 消息与会话附件下载、站内信和会议协作(`vemory` 保留兼容) |
|
|
24
|
+
|
|
25
|
+
细粒度 `vps-*` skill(如 `vps-daily-sales-report`)承载 script_key 与参数说明;Agent 优先读域聚合 skill,再按需下钻子 skill。
|
|
26
|
+
|
|
27
|
+
- `vps-device-abnormal-statistics`:按仓位查询在库激活、库存/在途与异常 IMEI,并按 IMEI 下钻未处理异常原因;仅授权中心已分配“VPS 设备异常分析”角色的员工可访问,入口 `vps-work product +abnormal-…`。
|
|
28
|
+
|
|
29
|
+
## 业务技能(随包静态分发,完全公开)
|
|
30
|
+
|
|
31
|
+
所有 `vps-*` 业务 skill 都随 npm 包分发于本仓库 `skills/<skill_key>/`,**无需登录、不连服务端**。安装到各 Agent 目录:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
vps-work skill list # 列出全部公开 skill
|
|
35
|
+
vps-work skill install --all --agent all # 铺到 cursor / claude-code / hermes 等
|
|
36
|
+
vps-work skill update # 覆盖式重同步
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
当前 Agent 使用宿主 app_key 管理用户自己的技能时,使用 `skill +create-personal`、
|
|
40
|
+
`+update-personal`、`+change-category`、`+request-publication`、`+delete-personal`。
|
|
41
|
+
新建和更新命令会自动补齐、校正 `SKILL.md` YAML frontmatter;详见
|
|
42
|
+
[`vps-work/SKILL.md`](./vps-work/SKILL.md#51-agent-管理当前用户自己的技能)。
|
|
43
|
+
|
|
44
|
+
`.well-known/skills/index.json` 为仓库内发现索引。
|
|
45
|
+
|
|
46
|
+
**命名**:仓库与文案统一 `vps-*`。
|
|
47
|
+
|
|
48
|
+
## 仓库内自举 skill
|
|
49
|
+
|
|
50
|
+
| Skill | 说明 |
|
|
51
|
+
|-------|------|
|
|
52
|
+
| `vps-work-onboard` | 安装 / 登录 / skill 铺设引导 |
|
|
53
|
+
| `vps-work` | CLI 自身说明 |
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sale-performance-query
|
|
3
|
+
description: "使用 `vps-work sales +…` 查询 Vertu 销售业绩和订单。用于公司、部门、销售员的销售额、销量、普通销售订单、订单关联的开票申请、正式发票、会计凭证与付款状态、已对账销售收款、JXSD 经销商订单、代理商 Sell-in/Sell-out、代理商五件套来源和 Walk-in、经销商库存与终销、客户画像、新老客占比、环比同比、部门下钻、目标达成、定金退款、人效、个人 OKR、团队 PK,以及按商品系列、款式或 IOT 分析销量销额。除经销商默认仓库库存外,通用商品库存、价格、发货与商品主数据改用 vps-product。"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 业绩查询
|
|
7
|
+
|
|
8
|
+
**CRITICAL — 开始前 MUST 先用 Read 工具读取 [`../vps-shared/SKILL.md`](../vps-shared/SKILL.md),其中包含认证、当前用户与 `+` 快捷约定**
|
|
9
|
+
|
|
10
|
+
## 工作原则
|
|
11
|
+
|
|
12
|
+
- 优先使用 `vps-work sales +…`;不要绕过业务封装查未文档化汇总视图。
|
|
13
|
+
- 查询前确认用户要的时间、部门层级、是否含定金;不明确时采用 Shortcut 默认值,但回答必须说明口径。
|
|
14
|
+
- 如果用户要求本地服务或刚改过 CLI,先 `npm run build`,并显式传 `--base-url http://127.0.0.1:3920` 或确认 `vps-work auth status --json` 指向本地。
|
|
15
|
+
- 引用结果前先看返回的 `filter`:必须核对 `period/start_date/end_date/include_deposit/dept_l1/dept_l2/dept_l3/dept_l4/dept_l5`;商品查询还必须核对 `product_subcategory/product_style/product_style_details/smart_wearable`,趋势查询继续核对 `grain/group_by/breakdown_by`。
|
|
16
|
+
- 返回含 `pagination` 的列表必须检查 `pagination.has_more` / `next_page`,不要把第一页 `rows` 当作全量;需要完整清单时持续翻页直到 `has_more=false`。
|
|
17
|
+
- 空结果先检查权限、过滤条件、姓名/工号拼写、是否默认剔除了定金;不要直接断言全公司为 0。
|
|
18
|
+
|
|
19
|
+
## Shortcuts(推荐优先使用)
|
|
20
|
+
|
|
21
|
+
Shortcut 是对常用销售经营查询的高级封装(`vps-work sales +<verb> [flags]`)。有 Shortcut 的操作优先使用,不要绕过业务口径直接查汇总视图。
|
|
22
|
+
|
|
23
|
+
| Shortcut | 说明 |
|
|
24
|
+
|----------|------|
|
|
25
|
+
| [`+headline-kpi`](references/vps-sales-headline-kpi.md) | 获取公司/部门核心 KPI:销售额、销量、订单 |
|
|
26
|
+
| `+orders` / `+order-list` | 查询订单明细;订单结果已带 `商品码`、分摊比例、客户来源、二级客户来源、最新发货日期和物流单号摘要,支持 `--logistics-no` 反查订单 |
|
|
27
|
+
| [`+order-finance`](references/vps-sales-order-finance.md) / `+finance-detail` | 按销售单号一次查看订单、开票申请、正式发票、过账/付款状态和关联会计凭证摘要 |
|
|
28
|
+
| [`+reconciled-receipts`](references/vps-sales-reconciled-receipts.md) / `+sales-receipts` | 查询最近 30 个自然日内已对账销售单据的收款明细;按单据、收款方式和收款主体聚合 |
|
|
29
|
+
| [`+invoice-status`](references/vps-sales-invoice-status.md) / `+invoice-applications` | 按一个或多个销售单号精确查询开票申请,区分未找到、未申请、草稿、审批中、已完成和已取消 |
|
|
30
|
+
| [`+account-orders`](references/vps-sales-account-orders.md) / `+account-sales-detail` | 按会计科目穿透已过账凭证关联的销售订单行;区分直接关联与同凭证关联 |
|
|
31
|
+
| [`+invoice-attachments`](references/vps-sales-invoice-attachments.md) | 按销售单号查询已过账客户发票/退款单附件;可由本地服务安全下载,不返回存储签名 URL |
|
|
32
|
+
| [`+dealer-orders`](references/vps-sales-dealer-orders.md) / `+dealer-order-list` | 查询独立的 `dealer.sale.order` 经销商订单;仅返回 `JXSD` 前缀,支持经销商、商品和 VSN/IMEI 筛选 |
|
|
33
|
+
| [`+dealer-inventory`](references/vps-sales-dealer-performance.md) | 按经销商默认仓库统计当前正库存数量、标准价金额、SKU 和未定价库存 |
|
|
34
|
+
| [`+dealer-final-sales`](references/vps-sales-dealer-performance.md) | 按经销商和五件套客户类型统计已完成 JXSD 终销数量、含税金额、订单数 |
|
|
35
|
+
| [`+dealer-customer-portrait`](references/vps-sales-dealer-performance.md) / `+dealer-portrait` | 统计终销单客户背景、年龄、购买原因及订单占比 |
|
|
36
|
+
| [`+agent-sell-in-out`](references/vps-sales-agent-five-suite.md) / `+sell-in-out` | 对比国内代理 Sell-in 与经销商销售订单 Sell-out;支持按代理商精确筛选 |
|
|
37
|
+
| [`+agent-sell-in-out-details`](references/vps-sales-agent-five-suite.md) | 返回 Sell-in 销售业绩行与 Sell-out 经销商订单明细 |
|
|
38
|
+
| [`+agent-five-source`](references/vps-sales-agent-five-suite.md) / `+agent-wujiantao` | 返回代理商五件套来源目标、真实 Sell-out、占比与完成率 |
|
|
39
|
+
| [`+agent-five-source-half-year`](references/vps-sales-agent-five-suite.md) | 返回上/下半年五件套 Sell-out 真实业绩 |
|
|
40
|
+
| [`+agent-walkin`](references/vps-sales-agent-five-suite.md) | 查询客户类型为自然进店/Walk-in 的国内经销商销售订单 |
|
|
41
|
+
| [`+agent-list`](references/vps-sales-agent-five-suite.md) | 返回与 `vps-ep` 代理商组织树同期间、同国内代理范围的代理商名单 |
|
|
42
|
+
| [`+agent-top-metrics`](references/vps-sales-agent-five-suite.md) · `+agent-performance` · `+agent-performance-detail` | 查询代理商看板顶部指标、目标业绩及环比同比明细 |
|
|
43
|
+
| [`+agent-delivery`](references/vps-sales-agent-five-suite.md) · `+agent-product-sales` · `+agent-product-ranking` · `+agent-sku-ranking` · `+agent-product-material-ranking` | 查询代理商提货、产品层级及排名 |
|
|
44
|
+
| [`+agent-phone-sales-proportion`](references/vps-sales-agent-five-suite.md) · `+agent-iot-sales-proportion` · `+agent-price-distribution` | 查询代理商手机/IOT 占比和价格区间 |
|
|
45
|
+
| [`+order-logistics`](references/vps-sales-order-logistics.md) | 仅在明确要看某订单/物流单号/出库单号的发货明细时使用 |
|
|
46
|
+
| [`+dept-breakdown`](references/vps-sales-dept-breakdown.md) | 按部门、销售员、产品线等维度拆解销售排名 |
|
|
47
|
+
| [`+customer-region`](references/vps-sales-customer-region.md) / `+customer-region-summary` | 按客户国家/地区查询全公司订单数、营业额及占比 |
|
|
48
|
+
| [`+customer-mix`](references/vps-sales-customer-mix.md) | 按 `customer_source.customer_category` 查询新客、老客及未分类销售额占比 |
|
|
49
|
+
| [`+dept-comparison`](references/vps-sales-dept-comparison.md) | 获取环比、同比对比结果 |
|
|
50
|
+
| [`+target-achievement`](references/vps-sales-target-achievement.md) | 获取部门或公司 OKR / 目标达成率 |
|
|
51
|
+
| `+dept-monthly-okr` | 获取部门月度 OKR 明细,用于核对目标来源;默认与管理端“部门业绩目标”页面一致,需要核对新表时传 `--okr-source postgres` |
|
|
52
|
+
| [`+deposit-breakdown`](references/vps-sales-deposit-breakdown.md) | 获取含定金、不含定金、定金金额三类口径 |
|
|
53
|
+
| [`+refund-summary`](references/vps-sales-refund-summary.md) | 获取退款、退换货汇总与部门 Top |
|
|
54
|
+
| [`+service-sales`](references/vps-sales-service-sales.md) | 获取权益部、服务部销售业绩 |
|
|
55
|
+
| [`+daily-trend`](references/vps-sales-daily-trend.md) / `+trend` | 获取按日/周/月销售趋势、环比、累计、同比及渠道 × 款式明细 |
|
|
56
|
+
| [`+ranking`](references/vps-sales-ranking.md) | 获取销售员 TOP / BOTTOM 红黑榜 |
|
|
57
|
+
| [`+per-person-kpi`](references/vps-sales-per-person-kpi.md) | 获取销售人员个人 KPI(人效) |
|
|
58
|
+
| [`+personal-okr`](references/vps-sales-personal-okr.md) | 获取销售人员个人 OKR 达成 |
|
|
59
|
+
| `+personal-monthly-okr` | 获取个人月度 OKR 明细,用于核对个人目标来源;默认 Postgres,旧 PMS/BI 口径传 `--okr-source legacy` |
|
|
60
|
+
| [`+team-pk`](references/vps-sales-team-pk.md) | 获取团队 PK 排名 |
|
|
61
|
+
|
|
62
|
+
## 需要读取的参考
|
|
63
|
+
|
|
64
|
+
- [`销售域业务实体`](references/vps-sales-entities.md) — 三条能力线、商品分类、定金口径。
|
|
65
|
+
- [`共享时间/部门参数`](references/vps-sales-shared-params.md) — 各 Shortcut 共用的 CLI 与 execute 字段。
|
|
66
|
+
- 处理具体 Shortcut 前读取上表对应的参考文档;人员业绩与 PK 的完整参数可继续读取 [`vps-sale-personnel-efficiency/reference.md`](../vps-sale-personnel-efficiency/reference.md)。
|
|
67
|
+
|
|
68
|
+
## 订单与物流
|
|
69
|
+
|
|
70
|
+
- 用户提到“经销商订单 / 经销商销售单 / JXSD 单号”时必须用 `+dealer-orders`,不要用普通 `+orders`;两者数据模型和金额口径不同。
|
|
71
|
+
- `+dealer-orders` 默认本月,订单号、经销商、商品或 VSN 筛选后仍需检查 `filter.order_prefix=JXSD`、`filter.access` 和分页状态。
|
|
72
|
+
- 用户问“经销商库存数量/金额”时用 `+dealer-inventory`;这是经销商默认仓库专用口径,不用通用商品库存替代。
|
|
73
|
+
- 用户问“经销商终销/五件套客户类型”时用 `+dealer-final-sales`;用户问终销单内的客户背景、年龄或购买原因时用 `+dealer-customer-portrait`。两个终销入口默认本月,必须说明只含 `JXSD + done + so + 非退货明细`。
|
|
74
|
+
- 用户问“代理商 Sell-in/Sell-out 对比”时用 `+agent-sell-in-out`,追明细用 `+agent-sell-in-out-details`。Sell-in 来自国内代理部门子树销售业绩;Sell-out 来自国内经销商已完成销售单。此处为 `vps-ep` 个性化看板口径,不额外限制 `JXSD` 或 `doc_type=so`。
|
|
75
|
+
- 用户问“代理商五件套/五大来源/来源完成率”时用 `+agent-five-source`;问半年结构时用 `+agent-five-source-half-year`;问自然进店订单时用 `+agent-walkin`。
|
|
76
|
+
- 用户问 `vps-ep` 代理商个性化页面的其他模块时,使用同名 `+agent-*` 看板命令;先用 `+agent-list` 获取完整名称,再向相关命令传 `--agent-name <完整名称>`。
|
|
77
|
+
- 选择单个代理商优先用 `--agent-name <完整名称>` 标准化中英文括号后精确匹配;`--dealer` 是兼容参数,在代理商看板命令中同样按精确名称处理。检查有 `filter` 的返回时同时核对 `filter.agent_name`、`nature=domestic` 和权限范围。
|
|
78
|
+
- 代理商目标来自 `线下代理OKR` 且严格按请求日期范围取数;结果为 `0` 时先区分“当期无目标记录”和“存在目标记录但值为零”,不得自行回退上月目标。
|
|
79
|
+
- 查“订单、订单明细、某商品订单、某客户订单、物流单号对应哪个订单”优先用 `+orders`。订单列表返回 `商品码`、`分摊比例`、`客户来源`、`二级客户来源`、`最新发货日期`、`物流单号`、`物流单号数`,一般不需要再查物流明细。
|
|
80
|
+
- 查“某销售单的开票申请、正式发票、会计凭证、过账和付款状态”优先使用 `+order-finance --order-no ...`,避免拼接多个局部查询。
|
|
81
|
+
- 查“已对账销售收款、某销售单收款方式/主体/金额”使用 `+reconciled-receipts`。其时间范围固定为最近 30 个自然日,即使指定单号也不放宽;结果默认排除“京东自营”和“商场代收”收款方式。
|
|
82
|
+
- 查“某销售单有没有申请开票、申请到哪一步、销售单与开票申请如何关联”使用 `+invoice-status --order-names ...`。禁止用 `+reconciled-receipts` 的“已开票”布尔值代替真实申请状态。
|
|
83
|
+
- 查“某会计科目对应哪些销售单/销售明细”使用 `+account-orders`。必须至少传 `--account-code` 或 `--account-name`,并区分会计行金额、发票行金额与销售订单行金额。
|
|
84
|
+
- 查“某销售单的发票附件”使用 `+invoice-attachments --order-no <销售单号>`;只查询当前用户销售数据范围内的订单。需要文件时加 `--download-dir <目录>`,附件由 Vertu 服务代理下载,不直接展示对象存储 URL。
|
|
85
|
+
- 订单列表客户信息默认按常用规则脱敏:手机号保留前三后四,客户名称保留首字;有 `sales.pii:read` 时才返回明文。
|
|
86
|
+
- 用户明确给出物流单号并要求“物流情况/发货明细/收货信息”时,先运行 `vps-work sales +order-logistics --help`,再传入用户提供的真实物流单号。
|
|
87
|
+
- 不要为了“某部门物流/某销售员物流”优先跑物流明细查询;先运行 `vps-work sales +orders --help`,按帮助中的部门或销售员参数筛选订单,再对具体订单或物流单号精查。
|
|
88
|
+
|
|
89
|
+
## 新老客销售占比
|
|
90
|
+
|
|
91
|
+
- 用户问“新老客销售占比 / 新客老客结构”时使用 `+customer-mix`,不要通过客户手机号或首次下单时间自行推断。
|
|
92
|
+
- 分类固定读取销售订单的客户来源关联:`sale_order.customer_source = customer_source.id`,再取 `customer_source.customer_category`。
|
|
93
|
+
- 分类值映射:`new=新客`、`old=老客`、NULL/空值=`未分类`;未知扩展值保留原值,不并入新客或老客。
|
|
94
|
+
- `sales_share` 的分母包含未分类,适合与总销售额对账;`classified_sales_share` 只在新客与老客之间计算;必须同时说明 `classified_coverage_rate`,不能隐藏未分类销售额。
|
|
95
|
+
- 默认不含定金,时间默认本月;部门过滤、商品细类过滤和数据权限与其他销售 KPI 一致。
|
|
96
|
+
|
|
97
|
+
## 客户地区业绩
|
|
98
|
+
|
|
99
|
+
- 用户问“客户地区分布 / 某国家来源的业绩 / 马来西亚本月订单数和营业额”时使用 `+customer-region`。
|
|
100
|
+
- 该命令固定为全公司汇总,必须具备 `sales.customer_region.all:read`;缺少权限时不得改用 `+orders`、`+headline-kpi` 或本人范围数据猜测。
|
|
101
|
+
- 地区来自订单国家/国区字段,不是销售部门、门店东西南北区或收货地址文本。
|
|
102
|
+
- 默认本月、不含定金;营业额复用公司 KPI 实际业绩口径,退货/退差价作负数冲减。
|
|
103
|
+
|
|
104
|
+
## 商品与系列查询口径
|
|
105
|
+
|
|
106
|
+
- “大折叠”必须先限定 `--product-subcategory "VERTU ALPHAFOLD"`,但这只限定商品细类,不能区分黄金3、黄金4、金钻等款式。
|
|
107
|
+
- “高定销售”使用精确条件 `--product-style 高定`。该口径已与 `vps-ep` 高定销售保持一致,不要改用商品名称模糊搜索。
|
|
108
|
+
- “黄金3 / 黄金4 / 金钻”使用 `--product-style-details "黄金3,黄金4,金钻"`;服务端会把“金钻”“4金3钻”规范化为商品维表的精确值 `4金/3钻`。需要限定大折叠时必须同时传 `--product-subcategory "VERTU ALPHAFOLD"`。
|
|
109
|
+
- “智能穿戴”使用 `--smart-wearable`。它同时限定商品大类为戒指/手链,并使用与 `vps-ep` 一致的系列白名单:智能健康戒指、AI钻戒2代、VERTU AI 水晶智能戒指、VERTU AI 智能戒指、VERTU关心智能手链。
|
|
110
|
+
- “IOT / IOT配件”使用 `--product-category IOT配件`;IOT 分类包含手链。商品趋势同时返回去重销售单数 `orders` 和与 vps-ep 商品页一致的明细行数 `product_order_count`,二者不能混报。含/不含代理折扣、置换排除及库存口径读取 `vps-product`。
|
|
111
|
+
- 聚合查询不要用 `+orders --product <词>` 代替上述精确过滤;`--product` 会在名称、编码和分类上做模糊搜索,只适合找订单明细。
|
|
112
|
+
- 必须检查响应 `filter` 是否原样返回上述商品条件;缺失任一条件时,不得把结果称为该系列或款式的业绩。
|
|
113
|
+
|
|
114
|
+
### 大折叠高定趋势标准调用
|
|
115
|
+
|
|
116
|
+
周维度:最新组织渠道 × 款式1,含销量、销额和周环比:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
vps-work sales +trend --period this_year --grain week \
|
|
120
|
+
--group-by org_channel --breakdown-by product_style1 \
|
|
121
|
+
--product-subcategory "VERTU ALPHAFOLD" --product-style 高定 \
|
|
122
|
+
--product-style-details "黄金3,黄金4,金钻"
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
月维度:最新组织渠道 × 款式1,含销量、销额和月环比:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
vps-work sales +trend --period this_year --grain month \
|
|
129
|
+
--group-by org_channel --breakdown-by product_style1 \
|
|
130
|
+
--product-subcategory "VERTU ALPHAFOLD" --product-style 高定 \
|
|
131
|
+
--product-style-details "黄金3,黄金4,金钻"
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
结果中的 `qty/amount` 是当期销量/销额,`previous_qty/previous_amount` 是上个周/月,`wow_*` 或 `mom_*` 是对应环比。明细必须保留 `bucket_start/bucket_end/group_name/breakdown_name`。
|
|
135
|
+
|
|
136
|
+
## 部门层级
|
|
137
|
+
|
|
138
|
+
- 销售查询只接受 `dept_l1` / `dept_l2` / `dept_l3` / `dept_l4` / `dept_l5`。不要传 `dept`、`department`、`dept_name`、`department_name`,也不要把用户说的“部门”静默猜成一级或二级。
|
|
139
|
+
- 用户说“按一级部门”时使用 `+dept-breakdown --group-by dept_l1`。
|
|
140
|
+
- 用户说“继续到二级部门”或“一级部门和二级部门一起”时,不要只查 `dept_l2`。先查 `dept_l1`,再对每个一级部门执行 `+dept-breakdown --group-by dept_l2 --dept-l1 <一级部门>`,最后按“一级部门 / 二级部门 / 小计”展示。
|
|
141
|
+
- 二级部门的订单数子项相加可能大于一级小计,因为同一销售单可能跨二级部门分摊;展示时需要提示这个口径。
|
|
142
|
+
- 当前在线 Odoo 销售脚本没有额外“匹配部门规则”;忽略历史特例后,`匹配部门` 字段等同业绩所属门店(`hdn1.current_name`)。业务业绩、目标达成默认仍可用 `department_mode=matched` 表示按 `匹配部门` 字段汇总;用户明确说“原始组织/组织架构/一级二级三级部门”才用 `department_mode=raw`。
|
|
143
|
+
- 用户说“全公司渠道 / 按最新组织架构渠道”时使用 `group_by=org_channel`,它按当前一级部门归为 `AI渠道 / 国内渠道 / 海外渠道 / 其它部门`。不要使用 `group_by=channel`;后者是销售订单的渠道字段,不是组织架构渠道。
|
|
144
|
+
|
|
145
|
+
## OKR 合并
|
|
146
|
+
|
|
147
|
+
- `+target-achievement`、`+dept-monthly-okr` 默认读取管理端“部门业绩目标”相同的 `部门OKR_1` 数据;显式传 `--okr-source postgres` / `okr_source=postgres` 才读取迁移后的部门目标表。`+personal-okr`、`+personal-monthly-okr` 仍默认使用 Postgres 的个人目标表。
|
|
148
|
+
- `+target-achievement` 默认 `group_by=match_dept`,不适合直接合并到一级/二级部门层级表。
|
|
149
|
+
- 要一级部门 OKR,传高级参数:`--params '{"group_by":"dept_l1","limit":500}'`。
|
|
150
|
+
- 要二级部门 OKR,传高级参数:`--params '{"group_by":"dept_l2","limit":500}'`。
|
|
151
|
+
- 用户要“一级 + 二级 + OKR + 达成率”时,先用 `+dept-breakdown` 生成实际业绩层级,再分别拉 `dept_l1/dept_l2` 的目标达成,按部门名合并;展示列至少包含 `实际业绩`、`OKR`、`达成率`。
|
|
152
|
+
- 如果 OKR 明细和销售层级不一致,读取 `+dept-monthly-okr --limit 500` 核对目标来源;回答只合并可匹配到当前展示层级的目标,不把无实绩的门店/小组混进业绩表。
|
|
153
|
+
- 计算“公司整体目标”时必须汇总返回的全部部门目标,包括 `sales_amount=0` 但 `target_amount>0` 的部门;不得把“本期无实绩”当作默认排除条件。如果用户明确要求排除,必须同时披露被排除的部门、数量、目标金额及排除前后的合计。
|
|
154
|
+
- 说明 `target_grain`。本月/月度目标通常是“月度目标整月累加”,不是按当前日期进度折算。
|
|
155
|
+
- OKR 明细与目标达成返回 `pagination`;当 `has_more=true` 时用 `--page <next_page>` 继续查。`total_rows/total_pages` 有值时,回答可说明“共 N 条,仅展示第 X 页”。
|
|
156
|
+
|
|
157
|
+
## 人员业绩归属
|
|
158
|
+
|
|
159
|
+
- 查某个人实际业绩优先用 `+headline-kpi --name <姓名>` 或 `+personal-okr --params '{"salesperson_like":"<姓名>"}'`;能确定工号时用 `--work-id` / `work_id` 更稳。
|
|
160
|
+
- 实际业绩归属来自销售行口径:Odoo 在线订单使用 `apportionment_ratio_line.user_id/department_id`,没有分摊时回落 `sale_order.user_id/department_id`;一级/二级部门来自这个“业绩部门”关联后的组织树。
|
|
161
|
+
- `+personal-okr` 展示人员部门时优先取人员视图,再回落销售行部门。若该人在查询窗口没有销售行,显示的部门主要来自人员视图,不代表该窗口有业绩归属。
|
|
162
|
+
- 回答“是否按视图查询”时区分:实际金额按销售视图/代码化销售行口径;人员展示部门可能来自人员视图。
|
|
163
|
+
|
|
164
|
+
## 回答格式
|
|
165
|
+
|
|
166
|
+
- 金额用 `¥` 和两位小数;达成率用百分比两位小数。
|
|
167
|
+
- 部门下钻优先用层级表:一级部门小计加粗,下面列二级部门。
|
|
168
|
+
- 汇总时说明:时间窗口、是否含定金、部门层级、商品细类/款式条件、权限范围。
|
|
169
|
+
- **排除项必须披露**:凡结果使用了默认或显式排除(例如不含定金、排除部门/人员、仅统计有实绩行、商品过滤),回答必须逐项说明;分页、Top N、权限范围造成的非全量覆盖也必须说明。禁止把排除后的数字表述为未加限定的“全公司/整体/全部”。
|
|
170
|
+
- 对负数量、退款、订单数分摊导致的合计差异,直接说明口径,不要自行修正数据。
|
|
171
|
+
|
|
172
|
+
## Skill Resources
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
vps-work sales --help
|
|
176
|
+
vps-work sales +headline-kpi --help
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### 业绩汇总脚本
|
|
180
|
+
|
|
181
|
+
底层 `/v1/execute` 为兼容现有客户端仍使用 `vps-daily-sales-report` 作为 `skill_key`;这只是后端路由键,不是另一个应优先触发的业务 Skill。
|
|
182
|
+
|
|
183
|
+
- `headline_kpi` · `order_list` · `order_finance` · `sales_invoice_status` · `reconciled_sales_receipts` · `account_sales_detail` · `dealer_order_list` · `dealer_inventory_summary` · `dealer_final_sales_summary` · `dealer_customer_portrait`
|
|
184
|
+
- `agent_list` · `agent_sell_in_out_summary` · `agent_sell_in_out_details` · `agent_walkin_orders` · `agent_five_source_metrics` · `agent_five_source_half_year`
|
|
185
|
+
- `agent_top_metrics` · `agent_performance` · `agent_delivery` · `agent_product_ranking` · `agent_sku_ranking` · `agent_product_material_ranking` · `agent_performance_detail`
|
|
186
|
+
- `agent_product_sales` · `agent_phone_sales_proportion` · `agent_iot_sales_proportion` · `agent_price_distribution`
|
|
187
|
+
- 兼容旧代理商五件套脚本键:`agent_wujiantao_completion_rate` · `agent_wujiantao_five_source_metrics` · `agent_wujiantao_half_year_forecast`
|
|
188
|
+
- `dept_breakdown` · `customer_region_summary` · `customer_sales_mix` · `dept_comparison` · `dept_target_achievement` · `dept_monthly_okr`
|
|
189
|
+
- `with_without_deposit_breakdown` · `refund_summary` · `service_dept_sales_summary`
|
|
190
|
+
- `monthly_daily_trend` · `employee_ranking_top_bottom`
|
|
191
|
+
|
|
192
|
+
### vps-sale-personnel-efficiency
|
|
193
|
+
|
|
194
|
+
- `per_person_kpi` · `personal_okr_achievement` · `personal_monthly_okr` · `team_pk_ranking`
|
|
195
|
+
|
|
196
|
+
## 权限与限制
|
|
197
|
+
|
|
198
|
+
| 能力 | 说明 |
|
|
199
|
+
|------|------|
|
|
200
|
+
| 登录 | 使用 `vps-work auth status --json` 确认已登录;执行类接口还需要 `execute:read` |
|
|
201
|
+
| 数据范围 | 返回结果会按当前用户数据权限裁剪;用返回 `filter` 检查 `dept_l1/dept_l2/dept_l3/dept_l4/dept_l5/dept_ids/salespersons/barcodes/any_of` |
|
|
202
|
+
| 基础销售 KPI 与订单 | `+headline-kpi`、`+orders`、`+dealer-orders`、`+dealer-inventory`、`+dealer-final-sales`、`+dealer-customer-portrait`、`+agent-sell-in-out`、`+agent-five-source`、`+agent-walkin`、`+dept-breakdown`、`+customer-mix`、`+dept-comparison`、`+deposit-breakdown`、`+refund-summary`、`+service-sales`、`+daily-trend` 需要 `sales.headline_kpi:read` |
|
|
203
|
+
| 全域客户地区业绩 | `+customer-region` 需要独立 `sales.customer_region.all:read`;授权中心角色为 `vps_sales_region_analyst`,只返回地区汇总 |
|
|
204
|
+
| 财务销售查询与发票附件 | `+order-finance`、`+account-orders`、`+invoice-status`、`+reconciled-receipts`、`+invoice-attachments` 需要 `sales.account_orders:read`;开票状态与已对账收款按接口固定 SQL 口径查询,其他能力按各自返回的数据范围说明 |
|
|
205
|
+
| 部门目标达成 | `+target-achievement` 需要 `sales.dept_target:read` |
|
|
206
|
+
| 部门 OKR 明细 | `+dept-monthly-okr` 需要 `sales.dept_monthly_okr:read` |
|
|
207
|
+
| 排名/PK | `+ranking`、`+team-pk` 需要 `sales.team_pk:read` |
|
|
208
|
+
| 人效 | `+per-person-kpi` 需要 `sales.per_person_kpi:read` |
|
|
209
|
+
| 个人 OKR 达成 | `+personal-okr` 需要 `sales.personal_okr_achievement:read` |
|
|
210
|
+
| 个人 OKR 明细 | `+personal-monthly-okr` 需要 `okr.personal_monthly:read` |
|