@alipay/alipay-aipay 1.2.2 → 1.5.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/README.md +5 -0
- package/dist/commands/install.d.ts.map +1 -1
- package/dist/commands/install.js +13 -12
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/uninstall.d.ts.map +1 -1
- package/dist/commands/uninstall.js +17 -9
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +5 -5
- package/dist/commands/update.js.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/dist/utils/config.d.ts +5 -3
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +34 -12
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/file.d.ts +8 -0
- package/dist/utils/file.d.ts.map +1 -1
- package/dist/utils/file.js +161 -9
- package/dist/utils/file.js.map +1 -1
- package/dist/utils/jq.d.ts.map +1 -1
- package/dist/utils/jq.js +8 -0
- package/dist/utils/jq.js.map +1 -1
- package/package.json +9 -5
- package/skill/SKILL.md +15 -169
- package/skill/VERSION +1 -1
- package/skill/references/integration/flow.md +388 -291
- package/skill/references/integration/modules/alipay-sdk-reminder.md +5 -3
- package/skill/references/integration/modules/checklist.md +54 -32
- package/skill/references/integration/modules/code-examples/csharp/1-/351/200/232/347/224/250/346/216/245/345/217/243//345/274/202/346/255/245/351/200/232/347/237/245/345/244/204/347/220/206/344/273/243/347/240/201/347/244/272/344/276/213.md +199 -0
- package/skill/references/integration/modules/code-examples/csharp/2-/347/275/221/347/253/231/346/224/257/344/273/230//347/273/237/344/270/200/346/224/266/345/215/225/344/270/213/345/215/225/345/271/266/346/224/257/344/273/230/351/241/265/351/235/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +8 -4
- package/skill/references/integration/modules/code-examples/csharp/3-APP/346/224/257/344/273/230/APP/346/224/257/344/273/230/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +6 -2
- package/skill/references/integration/modules/code-examples/csharp/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemo.cs +3 -1
- package/skill/references/integration/modules/code-examples/java/1-/351/200/232/347/224/250/346/216/245/345/217/243//345/274/202/346/255/245/351/200/232/347/237/245/345/244/204/347/220/206/344/273/243/347/240/201/347/244/272/344/276/213.md +184 -0
- package/skill/references/integration/modules/code-examples/java/2-/347/275/221/347/253/231/346/224/257/344/273/230//347/273/237/344/270/200/346/224/266/345/215/225/344/270/213/345/215/225/345/271/266/346/224/257/344/273/230/351/241/265/351/235/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +4 -1
- package/skill/references/integration/modules/code-examples/java/3-APP/346/224/257/344/273/230/APP/346/224/257/344/273/230/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +5 -2
- package/skill/references/integration/modules/code-examples/java/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemoController.java +3 -1
- package/skill/references/integration/modules/code-examples/nodejs/1-/351/200/232/347/224/250/346/216/245/345/217/243//345/274/202/346/255/245/351/200/232/347/237/245/345/244/204/347/220/206/344/273/243/347/240/201/347/244/272/344/276/213.md +135 -0
- package/skill/references/integration/modules/code-examples/nodejs/2-/347/275/221/347/253/231/346/224/257/344/273/230//347/273/237/344/270/200/346/224/266/345/215/225/344/270/213/345/215/225/345/271/266/346/224/257/344/273/230/351/241/265/351/235/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +16 -10
- package/skill/references/integration/modules/code-examples/nodejs/3-APP/346/224/257/344/273/230/APP/346/224/257/344/273/230/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +10 -4
- package/skill/references/integration/modules/code-examples/nodejs/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemo.js +2 -1
- package/skill/references/integration/modules/code-examples/php/1-/351/200/232/347/224/250/346/216/245/345/217/243//345/274/202/346/255/245/351/200/232/347/237/245/345/244/204/347/220/206/344/273/243/347/240/201/347/244/272/344/276/213.md +157 -0
- package/skill/references/integration/modules/code-examples/php/2-/347/275/221/347/253/231/346/224/257/344/273/230//347/273/237/344/270/200/346/224/266/345/215/225/344/270/213/345/215/225/345/271/266/346/224/257/344/273/230/351/241/265/351/235/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +4 -1
- package/skill/references/integration/modules/code-examples/php/3-APP/346/224/257/344/273/230/APP/346/224/257/344/273/230/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +5 -2
- package/skill/references/integration/modules/code-examples/php/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemo.php +2 -1
- package/skill/references/integration/modules/code-examples/python/1-/351/200/232/347/224/250/346/216/245/345/217/243//345/274/202/346/255/245/351/200/232/347/237/245/345/244/204/347/220/206/344/273/243/347/240/201/347/244/272/344/276/213.md +128 -0
- package/skill/references/integration/modules/code-examples/python/2-/347/275/221/347/253/231/346/224/257/344/273/230//347/273/237/344/270/200/346/224/266/345/215/225/344/270/213/345/215/225/345/271/266/346/224/257/344/273/230/351/241/265/351/235/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +4 -1
- package/skill/references/integration/modules/code-examples/python/3-APP/346/224/257/344/273/230/APP/346/224/257/344/273/230/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +5 -1
- package/skill/references/integration/modules/code-examples/python/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemo.py +4 -2
- package/skill/references/integration/modules/interface-contract/aipay-interface-contract.md +52 -0
- package/skill/references/integration/modules/interface-contract/apppay-interface-contract.md +45 -0
- package/skill/references/integration/modules/interface-contract/common-trade-contract.md +42 -0
- package/skill/references/integration/modules/interface-contract/notify-url-contract.md +68 -0
- package/skill/references/integration/modules/interface-contract/webpay-interface-contract.md +44 -0
- package/skill/references/integration/modules/interface-guide.md +38 -71
- package/skill/references/integration/modules/product-decision.md +18 -35
- package/skill/references/integration/modules/sandbox/a2m-sandbox-test.md +62 -94
- package/skill/references/integration/modules/sandbox/alipay-sandbox-tool.md +43 -40
- package/skill/references/integration/modules/sandbox/sandbox-setup-guide.md +93 -114
- package/skill/references/integration/modules/scripts/local_402_sandbox_pay.py +358 -148
- package/skill/references/integration/modules/scripts/sandbox_config.sh +299 -0
- package/skill/references/integration/modules/troubleshooting-flow.md +28 -0
- package/skill/references/normal/alipay-cli-env.md +15 -5
- package/skill/references/normal/full-process-routing.md +82 -0
- package/skill/references/normal/json/customer-messages.json +942 -0
- package/skill/references/normal/json/policy-rules.json +179 -0
- package/skill/references/normal/rejection-guide.md +12 -7
- package/skill/references/normal/scripts/alipay_cli_env.mjs +33 -0
- package/skill/references/normal/scripts/alipay_cli_env.sh +55 -0
- package/skill/references/normal/scripts/common.sh +151 -0
- package/skill/references/normal/scripts/detect_dev_tool.sh +5 -1
- package/skill/references/normal/scripts/flow_loader.mjs +241 -0
- package/skill/references/normal/scripts/integration_context_runner.mjs +166 -0
- package/skill/references/normal/scripts/integration_message_runner.mjs +1023 -0
- package/skill/references/normal/scripts/interaction_reply.mjs +133 -0
- package/skill/references/normal/scripts/onboarding_discovery_runner.mjs +224 -0
- package/skill/references/normal/scripts/onboarding_message_runner.mjs +451 -0
- package/skill/references/normal/scripts/onboarding_recovery_runner.mjs +96 -0
- package/skill/references/normal/scripts/open_official_url.sh +82 -0
- package/skill/references/normal/scripts/platform_compat.mjs +39 -0
- package/skill/references/normal/scripts/project_route_inspector.sh +132 -0
- package/skill/references/normal/scripts/python_script_runner.mjs +56 -0
- package/skill/references/normal/scripts/render_customer_message.mjs +1288 -0
- package/skill/references/normal/scripts/self_update.mjs +160 -0
- package/skill/references/normal/scripts/telemetry.mjs +1327 -0
- package/skill/references/normal/self-update.md +18 -51
- package/skill/references/normal/telemetry.md +26 -0
- package/skill/references/onboarding/flow.md +421 -309
- package/skill/references/onboarding/modules/app-release.md +44 -438
- package/skill/references/onboarding/modules/authorization.md +25 -281
- package/skill/references/onboarding/modules/error-handling.md +31 -237
- package/skill/references/onboarding/modules/product-sign.md +25 -294
- package/skill/references/onboarding/modules/scripts/app.sh +445 -169
- package/skill/references/onboarding/modules/scripts/ar_sign_apply.sh +47 -28
- package/skill/references/onboarding/modules/scripts/auth.sh +484 -167
- package/skill/references/onboarding/modules/scripts/download_key_tool.sh +157 -0
- package/skill/references/onboarding/modules/scripts/error_handler.sh +101 -130
- package/skill/references/onboarding/modules/scripts/network_retry.sh +96 -0
- package/skill/references/onboarding/modules/scripts/query_sign_status.sh +20 -71
- package/skill/references/onboarding/modules/scripts/service.sh +154 -89
- package/skill/references/onboarding/modules/scripts/sign_status_parser.sh +58 -0
- package/skill/references/onboarding/modules/scripts/upload_screenshots.sh +34 -20
- package/skill/references/onboarding/modules/service-registration.md +20 -317
- package/skill/references/runtime-entry.md +63 -0
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
# 脚本名称: query_sign_status.sh
|
|
4
4
|
# 功能描述: 查询签约状态并根据结果判断后续流程
|
|
5
5
|
# 调用位置: Step 3.1 状态与资源查询
|
|
6
|
-
# 调用前置: 脚本通过 error_handler.sh 间接初始化 DEV_TOOL_NAME;需传入 --sales-code,或兼容使用 SALES_CODE 环境变量
|
|
6
|
+
# 调用前置: 脚本通过 error_handler.sh 间接初始化 DEV_TOOL_NAME/PLATFORM_ID;需传入 --sales-code,或兼容使用 SALES_CODE 环境变量
|
|
7
7
|
# 用法: bash query_sign_status.sh --sales-code <code> [--product-type aipay|webpay|apppay]
|
|
8
|
-
# 返回值:
|
|
8
|
+
# 返回值: 在 stderr 输出签约状态控制信号;stdout 只保留受控错误正文
|
|
9
9
|
# SIGN_STATUS=NOT_SIGNED | SIGN_STATUS=SIGNED_EFFECTIVE | SIGN_STATUS=SIGN_SUBMITTED | SIGN_STATUS=OTHER_STATUS
|
|
10
|
-
# 按量付费: FLOW:AI_PAY_NOT_SIGNED | FLOW:AI_PAY_SIGNED
|
|
11
|
-
#
|
|
12
|
-
#
|
|
10
|
+
# AI 按量付费: FLOW:AI_PAY_NOT_SIGNED | FLOW:AI_PAY_SIGNED
|
|
11
|
+
# AI 网页应用收款: FLOW:PC_WEB_NOT_SIGNED | FLOW:PC_WEB_SIGNED
|
|
12
|
+
# AI 移动应用收款: FLOW:APP_NOT_SIGNED | FLOW:APP_SIGNED
|
|
13
13
|
#=============================================================================
|
|
14
14
|
|
|
15
15
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
@@ -21,6 +21,8 @@ else
|
|
|
21
21
|
echo "❌ 缺少错误处理脚本: ${SCRIPT_DIR}/error_handler.sh"
|
|
22
22
|
exit 1
|
|
23
23
|
fi
|
|
24
|
+
source "${SCRIPT_DIR}/network_retry.sh"
|
|
25
|
+
source "${SCRIPT_DIR}/sign_status_parser.sh"
|
|
24
26
|
|
|
25
27
|
require_command jq || exit 1
|
|
26
28
|
require_command alipay-cli || exit 1
|
|
@@ -69,27 +71,18 @@ if [ "$PRODUCT_TYPE" != "unknown" ] && [ "$PRODUCT_TYPE" != "$EXPECTED_PRODUCT_T
|
|
|
69
71
|
exit 1
|
|
70
72
|
fi
|
|
71
73
|
|
|
72
|
-
|
|
73
|
-
case "$SALES_CODE" in
|
|
74
|
-
"I1080300001000041203")
|
|
75
|
-
echo "FLOW:PC_WEB_SIGNED"
|
|
76
|
-
# 网站支付已生效或已提交:Step 4 只处理应用决策,Step 5 跳过签约提交
|
|
77
|
-
;;
|
|
78
|
-
"I1080300001000041313")
|
|
79
|
-
echo "FLOW:APP_SIGNED"
|
|
80
|
-
# APP支付已生效或已提交:Step 4 只处理应用决策,Step 5 跳过签约提交
|
|
81
|
-
;;
|
|
82
|
-
"I1080300001000160457")
|
|
83
|
-
echo "FLOW:AI_PAY_SIGNED"
|
|
84
|
-
# 按量付费已生效或已提交:Step 4 处理服务/应用决策,Step 5 跳过签约提交
|
|
85
|
-
;;
|
|
86
|
-
esac
|
|
87
|
-
}
|
|
74
|
+
init_alipay_cli_product "$EXPECTED_PRODUCT_TYPE" || exit 1
|
|
88
75
|
|
|
89
76
|
# 查询签约状态
|
|
90
|
-
|
|
77
|
+
export PLATFORM="${DEV_TOOL_NAME}" PLATFORM_ID="${PLATFORM_ID:-}"
|
|
78
|
+
run_network_retry RESULT read query_sign_status -- alipay-cli mcp call ar-query.queryArInfosBySalesProd \
|
|
91
79
|
-d "{\"request\":{\"salesProductCodes\":[\"${SALES_CODE}\"]},\"ctx\":{}}" \
|
|
92
|
-
--json
|
|
80
|
+
--json
|
|
81
|
+
RETRY_RC=$?
|
|
82
|
+
if [ "$RETRY_RC" -ne 0 ]; then
|
|
83
|
+
echo "❌ 签约状态查询因网络或服务异常在自动重试两次后仍未恢复"
|
|
84
|
+
exit 1
|
|
85
|
+
fi
|
|
93
86
|
|
|
94
87
|
# 错误检测
|
|
95
88
|
if ! handle_error "$RESULT"; then
|
|
@@ -99,54 +92,10 @@ fi
|
|
|
99
92
|
# 解包 MCP 信封后解析业务字段
|
|
100
93
|
BUSINESS=$(unwrap_mcp "$RESULT")
|
|
101
94
|
|
|
102
|
-
#
|
|
103
|
-
|
|
104
|
-
if (.resultObj | type) == "object" and (.resultObj.arInfoList | type) == "array" then
|
|
105
|
-
.resultObj.arInfoList
|
|
106
|
-
else
|
|
107
|
-
null
|
|
108
|
-
end
|
|
109
|
-
' 2>/dev/null)
|
|
110
|
-
if [ -z "$AR_LIST" ] || ! echo "$AR_LIST" | jq -e 'type == "array"' >/dev/null 2>&1; then
|
|
95
|
+
# 只有明确返回数组才可判断签约状态;缺少字段必须阻断,避免误判为未签约。
|
|
96
|
+
if ! SIGN_STATUS_OUTPUT=$(emit_sign_status_from_business "$BUSINESS" "$SALES_CODE"); then
|
|
111
97
|
echo "❌ 签约状态返回结构异常,无法解析 arInfoList"
|
|
112
98
|
exit 1
|
|
113
99
|
fi
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
if [ "$AR_COUNT" -eq 0 ]; then
|
|
117
|
-
echo "📋 签约状态: 未签约 (NOT_SIGNED);继续 Step 4 一次性资料与资源决策"
|
|
118
|
-
echo "SIGN_STATUS=NOT_SIGNED"
|
|
119
|
-
|
|
120
|
-
case "$SALES_CODE" in
|
|
121
|
-
"I1080300001000041203")
|
|
122
|
-
echo "FLOW:PC_WEB_NOT_SIGNED"
|
|
123
|
-
# 网站支付未签约:需先采集 3 张网站截图,再进入 Step 5 签约
|
|
124
|
-
;;
|
|
125
|
-
"I1080300001000041313")
|
|
126
|
-
echo "FLOW:APP_NOT_SIGNED"
|
|
127
|
-
# APP支付未签约:需先采集 APP 名称和 3 张APP界面截图,再进入 Step 5 签约
|
|
128
|
-
;;
|
|
129
|
-
"I1080300001000160457")
|
|
130
|
-
echo "FLOW:AI_PAY_NOT_SIGNED"
|
|
131
|
-
# 按量付费未签约:Step 4 无需页面图片,但仍完成服务/应用决策
|
|
132
|
-
;;
|
|
133
|
-
esac
|
|
134
|
-
else
|
|
135
|
-
# AR_LIST 已在上方确认为数组
|
|
136
|
-
HAS_EFFECTIVE=$(echo "$AR_LIST" | jq -r '[.[] | select(.arStatus == "02")] | length')
|
|
137
|
-
HAS_SUBMITTED=$(echo "$AR_LIST" | jq -r '[.[] | select(.arStatus == "01")] | length')
|
|
138
|
-
|
|
139
|
-
if [ "$HAS_EFFECTIVE" -gt 0 ]; then
|
|
140
|
-
echo "✅ 签约已生效;无需签约材料,继续 Step 4 资源决策"
|
|
141
|
-
echo "SIGN_STATUS=SIGNED_EFFECTIVE"
|
|
142
|
-
emit_signed_flow
|
|
143
|
-
elif [ "$HAS_SUBMITTED" -gt 0 ]; then
|
|
144
|
-
echo "📋 已提交签约(待生效),无需重复提交签约,继续推进后续步骤"
|
|
145
|
-
echo "SIGN_STATUS=SIGN_SUBMITTED"
|
|
146
|
-
emit_signed_flow
|
|
147
|
-
else
|
|
148
|
-
echo "📋 其他签约状态;保留已取得的只读结果并将签约分支标记为待核验"
|
|
149
|
-
echo "SIGN_STATUS=OTHER_STATUS"
|
|
150
|
-
echo "FLOW:OTHER_STATUS"
|
|
151
|
-
fi
|
|
152
|
-
fi
|
|
100
|
+
printf '%s\n' "$SIGN_STATUS_OUTPUT" \
|
|
101
|
+
| while IFS= read -r marker; do emit_control "$marker"; done
|
|
@@ -3,18 +3,19 @@
|
|
|
3
3
|
# 脚本名称: service.sh
|
|
4
4
|
# 功能描述: 服务市场注册 - 查询已有服务 + 创建/修改服务
|
|
5
5
|
# 调用位置: list 用于 Step 3.1 前置资源查询;save/validate 用于 Step 5.2 服务市场注册
|
|
6
|
-
# 调用前置: 脚本通过 error_handler.sh 间接初始化 DEV_TOOL_NAME;必要时可用 DEV_TOOL_NAME 环境变量覆盖
|
|
6
|
+
# 调用前置: 脚本通过 error_handler.sh 间接初始化 DEV_TOOL_NAME/PLATFORM_ID;必要时可用 DEV_TOOL_NAME 环境变量覆盖
|
|
7
7
|
# 用法:
|
|
8
8
|
# service list - 查询已有服务列表
|
|
9
9
|
# service save --name <n> --desc <d> --url <u> --pricing <p> --schema <json> [--service-id <id>]
|
|
10
10
|
# service validate --name <n> --desc <d> --url <u> --pricing <p> --schema <json>
|
|
11
11
|
# 返回值:
|
|
12
|
-
# list:
|
|
13
|
-
# save:
|
|
14
|
-
# validate:
|
|
12
|
+
# list: stdout 成功时为空;stderr 输出带统一内部前缀的候选 JSON、SERVICE_CANDIDATE_ID 和 FLOW
|
|
13
|
+
# save: stderr 输出实际解析到的 SERVICE_ID(不接受 Agent 自填)
|
|
14
|
+
# validate: stderr 输出规范化结果(退出码 0=通过, 1=失败)
|
|
15
15
|
#=============================================================================
|
|
16
16
|
|
|
17
17
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
18
|
+
CANDIDATE_RUNNER="${SCRIPT_DIR}/../../../normal/scripts/onboarding_message_runner.mjs"
|
|
18
19
|
|
|
19
20
|
# 一次性 source error_handler(含 unwrap_mcp)
|
|
20
21
|
if [ -f "${SCRIPT_DIR}/error_handler.sh" ]; then
|
|
@@ -23,10 +24,67 @@ else
|
|
|
23
24
|
echo "❌ 缺少错误处理脚本: ${SCRIPT_DIR}/error_handler.sh"
|
|
24
25
|
exit 1
|
|
25
26
|
fi
|
|
27
|
+
source "${SCRIPT_DIR}/network_retry.sh"
|
|
26
28
|
|
|
27
29
|
require_command jq || exit 1
|
|
28
30
|
require_command alipay-cli || exit 1
|
|
29
31
|
require_command awk || exit 1
|
|
32
|
+
require_command node || exit 1
|
|
33
|
+
init_alipay_cli_product aipay || exit 1
|
|
34
|
+
|
|
35
|
+
SERVICE_LIST_PAGE_LIMIT=10
|
|
36
|
+
SERVICE_CREATE_LIMIT=10
|
|
37
|
+
|
|
38
|
+
normalize_service_pricing() {
|
|
39
|
+
local raw="$1"
|
|
40
|
+
local pricing_pattern='^ *([0-9]+([.][0-9]+)?) *(元(/次)?)? *$'
|
|
41
|
+
SERVICE_PRICING_NORMALIZED=""
|
|
42
|
+
case "$raw" in *$'\n'*|*$'\r'*|*$'\t'*) return 1 ;; esac
|
|
43
|
+
if [[ "$raw" =~ $pricing_pattern ]]; then
|
|
44
|
+
SERVICE_PRICING_NORMALIZED="${BASH_REMATCH[1]}"
|
|
45
|
+
return 0
|
|
46
|
+
fi
|
|
47
|
+
return 1
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
validate_service_fields() {
|
|
51
|
+
# 1. 服务名称:长度 1-50 字符
|
|
52
|
+
if [ -z "$SERVICE_NAME" ] || [ ${#SERVICE_NAME} -gt 50 ]; then
|
|
53
|
+
echo "❌ 服务名称长度需在 1-50 字符之间(当前长度: ${#SERVICE_NAME})"
|
|
54
|
+
exit 1
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
# 2. 服务描述:长度 1-500 字符
|
|
58
|
+
if [ -z "$SERVICE_DESC" ] || [ ${#SERVICE_DESC} -gt 500 ]; then
|
|
59
|
+
echo "❌ 服务描述长度需在 1-500 字符之间(当前长度: ${#SERVICE_DESC})"
|
|
60
|
+
exit 1
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
# 3. 服务地址:有效 URL
|
|
64
|
+
if [ -z "$RESOURCE_URL" ] || ! [[ "$RESOURCE_URL" =~ ^https?:// ]]; then
|
|
65
|
+
echo "❌ 请提供有效的 URL 地址(以 http:// 或 https:// 开头)"
|
|
66
|
+
exit 1
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
# 4. 服务单价:提交值统一规范化为纯数字,模板负责追加“元/次”。
|
|
70
|
+
if [ -z "$PRICING" ] || ! normalize_service_pricing "$PRICING"; then
|
|
71
|
+
echo "❌ 服务单价格式不正确,请输入金额(如 0.03、0.03元或 0.03 元/次)"
|
|
72
|
+
exit 1
|
|
73
|
+
fi
|
|
74
|
+
PRICING="$SERVICE_PRICING_NORMALIZED"
|
|
75
|
+
PRICING_VALID=$(awk -v p="$PRICING" 'BEGIN { if (p + 0 >= 0.01) print "true"; else print "false" }')
|
|
76
|
+
if [ "$PRICING_VALID" = "false" ]; then
|
|
77
|
+
echo "❌ 服务单价最低为 0.01 元"
|
|
78
|
+
exit 1
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
# 5. schemaUrl 在本流程中承载序列化后的 JSON 请求示例,不是 URL。
|
|
82
|
+
# CLI 接收原始 JSON;save 分支通过 jq --arg 将其安全写入字符串字段。
|
|
83
|
+
if [ -z "$SCHEMA_URL" ] || ! echo "$SCHEMA_URL" | jq . >/dev/null 2>&1; then
|
|
84
|
+
echo "❌ 请提供有效的 JSON 格式请求示例"
|
|
85
|
+
exit 1
|
|
86
|
+
fi
|
|
87
|
+
}
|
|
30
88
|
|
|
31
89
|
# ─── service list: 查询已有服务 ──────────────────────────────────────────────
|
|
32
90
|
fetch_service_page() {
|
|
@@ -39,9 +97,15 @@ fetch_service_page() {
|
|
|
39
97
|
--argjson offset "$OFFSET" \
|
|
40
98
|
'{request:{limit:$limit,offset:$offset}}')
|
|
41
99
|
|
|
42
|
-
|
|
100
|
+
export PLATFORM="${DEV_TOOL_NAME}" PLATFORM_ID="${PLATFORM_ID:-}"
|
|
101
|
+
run_network_retry RESULT read service_list_page -- alipay-cli mcp call a2a-pay-service.discoverBazaarServicesForMcp \
|
|
43
102
|
-d "$REQUEST_JSON" \
|
|
44
|
-
--json
|
|
103
|
+
--json
|
|
104
|
+
RETRY_RC=$?
|
|
105
|
+
if [ "$RETRY_RC" -ne 0 ]; then
|
|
106
|
+
echo "❌ 服务列表当前分页因网络或服务异常在自动重试两次后仍未恢复"
|
|
107
|
+
return 1
|
|
108
|
+
fi
|
|
45
109
|
|
|
46
110
|
if ! handle_error "$RESULT"; then
|
|
47
111
|
return 1
|
|
@@ -54,6 +118,7 @@ fetch_service_page() {
|
|
|
54
118
|
BUSINESS_MESSAGE=$(echo "$BUSINESS" | jq -r '
|
|
55
119
|
.subMsg // .data.subMsg // .msg // .data.msg // "未知错误"
|
|
56
120
|
' 2>/dev/null)
|
|
121
|
+
BUSINESS_MESSAGE=$(sanitize_customer_error_text "$BUSINESS_MESSAGE")
|
|
57
122
|
echo "❌ 查询服务列表失败: ${BUSINESS_CODE} / ${BUSINESS_MESSAGE}"
|
|
58
123
|
return 1
|
|
59
124
|
fi
|
|
@@ -103,7 +168,7 @@ fetch_service_page() {
|
|
|
103
168
|
}
|
|
104
169
|
|
|
105
170
|
fetch_service_list() {
|
|
106
|
-
local LIMIT=
|
|
171
|
+
local LIMIT="$SERVICE_LIST_PAGE_LIMIT"
|
|
107
172
|
local OFFSET=0
|
|
108
173
|
local EXPECTED_TOTAL=""
|
|
109
174
|
local PAGE_COUNT
|
|
@@ -155,9 +220,13 @@ fetch_service_list() {
|
|
|
155
220
|
done
|
|
156
221
|
|
|
157
222
|
if ! echo "$SERVICE_LIST" | jq -e '
|
|
158
|
-
all(.[];
|
|
223
|
+
all(.[];
|
|
224
|
+
((.serviceId | type) == "string") and
|
|
225
|
+
(.serviceId | length > 0) and
|
|
226
|
+
((.serviceId | test("[\u0000-\u001f\u007f]") | not))
|
|
227
|
+
)
|
|
159
228
|
' >/dev/null 2>&1; then
|
|
160
|
-
echo "❌
|
|
229
|
+
echo "❌ 服务列表返回结构异常:候选 serviceId 缺失或包含控制字符"
|
|
161
230
|
return 1
|
|
162
231
|
fi
|
|
163
232
|
|
|
@@ -169,40 +238,31 @@ service_list() {
|
|
|
169
238
|
exit 1
|
|
170
239
|
fi
|
|
171
240
|
|
|
241
|
+
SERVICE_CANDIDATES=$(echo "$SERVICE_LIST" | jq -c '[.[] | {
|
|
242
|
+
serviceId: .serviceId,
|
|
243
|
+
serviceName: ((.serviceName // "未知") | tostring),
|
|
244
|
+
serviceDesc: ((.serviceDesc // "无描述") | tostring),
|
|
245
|
+
pricing: ((.metadata.pricing // .pricing // "未知") | tostring),
|
|
246
|
+
serviceStatus: ((.serviceStatus // .status // "未知") | tostring),
|
|
247
|
+
resourceUrl: ((.resourceUrl // "未知") | tostring)
|
|
248
|
+
}]')
|
|
249
|
+
if ! printf '%s' "$SERVICE_CANDIDATES" | node "$CANDIDATE_RUNNER" service-candidates >/dev/null 2>&1; then
|
|
250
|
+
echo "❌ 服务候选事实安全校验失败"
|
|
251
|
+
emit_control "FLOW:ERROR"
|
|
252
|
+
exit 1
|
|
253
|
+
fi
|
|
254
|
+
if ! emit_control_field "SERVICE_CANDIDATES_JSON" "$SERVICE_CANDIDATES"; then
|
|
255
|
+
echo "❌ 服务候选事实包含非法控制字符"
|
|
256
|
+
emit_control "FLOW:ERROR"
|
|
257
|
+
exit 1
|
|
258
|
+
fi
|
|
259
|
+
|
|
172
260
|
if [ "$SERVICE_COUNT" -eq 0 ] || [ "$SERVICE_LIST" = "[]" ] || [ -z "$SERVICE_LIST" ]; then
|
|
173
|
-
|
|
174
|
-
echo "FLOW:CREATE_NEW"
|
|
261
|
+
emit_control "FLOW:CREATE_NEW"
|
|
175
262
|
else
|
|
176
|
-
echo "
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
echo "|------|--------|----------|------|------|----------|----------|"
|
|
180
|
-
|
|
181
|
-
for i in $(seq 0 $((SERVICE_COUNT-1))); do
|
|
182
|
-
SERVICE=$(echo "$SERVICE_LIST" | jq ".[$i]")
|
|
183
|
-
SERVICE_ID=$(echo "$SERVICE" | jq -r '.serviceId // "未知"')
|
|
184
|
-
SERVICE_NAME=$(echo "$SERVICE" | jq -r '.serviceName // "未知"')
|
|
185
|
-
SERVICE_DESC=$(echo "$SERVICE" | jq -r '.serviceDesc // "无描述"')
|
|
186
|
-
PRICING=$(echo "$SERVICE" | jq -r '.pricing // "未知"')
|
|
187
|
-
SERVICE_STATUS=$(echo "$SERVICE" | jq -r '.serviceStatus // .status // "未知"')
|
|
188
|
-
RESOURCE_URL=$(echo "$SERVICE" | jq -r '.resourceUrl // "未知"')
|
|
189
|
-
|
|
190
|
-
case "$SERVICE_STATUS" in
|
|
191
|
-
"ACTIVE") STATUS_CN="已上线" ;;
|
|
192
|
-
"PENDING") STATUS_CN="审核中" ;;
|
|
193
|
-
"REJECTED") STATUS_CN="审核拒绝" ;;
|
|
194
|
-
*) STATUS_CN="$SERVICE_STATUS" ;;
|
|
195
|
-
esac
|
|
196
|
-
|
|
197
|
-
echo "| $((i+1)) | $SERVICE_ID | $SERVICE_NAME | $SERVICE_DESC | ${PRICING}元/次 | $STATUS_CN | $RESOURCE_URL |"
|
|
198
|
-
done
|
|
199
|
-
|
|
200
|
-
echo ""
|
|
201
|
-
echo "请选择:"
|
|
202
|
-
echo " • 输入序号 (1-${SERVICE_COUNT}) 复用对应服务"
|
|
203
|
-
echo " • 输入\"新建\"创建新服务"
|
|
204
|
-
echo " • 输入\"修改 + serviceId\"修改已有服务"
|
|
205
|
-
echo "FLOW:SELECT"
|
|
263
|
+
echo "$SERVICE_LIST" | jq -r '.[] | "SERVICE_CANDIDATE_ID=" + .serviceId' \
|
|
264
|
+
| while IFS= read -r marker; do emit_control "$marker"; done
|
|
265
|
+
emit_control "FLOW:SELECT"
|
|
206
266
|
fi
|
|
207
267
|
}
|
|
208
268
|
|
|
@@ -245,14 +305,19 @@ service_save() {
|
|
|
245
305
|
echo "用法(修改): bash service.sh save --service-id <id> --name <name> --desc <desc> --url <url> --pricing <pricing> --schema <json>"
|
|
246
306
|
exit 1
|
|
247
307
|
fi
|
|
308
|
+
if [ -n "$SERVICE_ID" ] && ! validate_control_value "$SERVICE_ID"; then
|
|
309
|
+
echo "❌ serviceId 包含非法控制字符"
|
|
310
|
+
exit 1
|
|
311
|
+
fi
|
|
312
|
+
validate_service_fields
|
|
248
313
|
|
|
249
314
|
if [ -z "$SERVICE_ID" ]; then
|
|
250
315
|
# 创建新服务(不传 serviceId)
|
|
251
316
|
if ! fetch_service_list; then
|
|
252
317
|
exit 1
|
|
253
318
|
fi
|
|
254
|
-
if [ "$SERVICE_COUNT" -ge
|
|
255
|
-
echo "❌
|
|
319
|
+
if [ "$SERVICE_COUNT" -ge "$SERVICE_CREATE_LIMIT" ]; then
|
|
320
|
+
echo "❌ 已达到服务数量上限(${SERVICE_CREATE_LIMIT}个),无法创建新服务"
|
|
256
321
|
echo "📋 您当前已有 $SERVICE_COUNT 个服务,请选择复用已有服务或修改已有服务"
|
|
257
322
|
exit 1
|
|
258
323
|
fi
|
|
@@ -265,9 +330,6 @@ service_save() {
|
|
|
265
330
|
--arg schemaUrl "$SCHEMA_URL" \
|
|
266
331
|
'{request:{serviceName:$serviceName,serviceDesc:$serviceDesc,resourceUrl:$resourceUrl,pricing:$pricing,schemaUrl:$schemaUrl}}')
|
|
267
332
|
|
|
268
|
-
RESULT=$(export PLATFORM=${DEV_TOOL_NAME} && alipay-cli mcp call a2a-pay-service.saveBazaarServiceForMcp \
|
|
269
|
-
-d "$REQUEST_JSON" \
|
|
270
|
-
--json 2>/dev/null)
|
|
271
333
|
else
|
|
272
334
|
# 修改已有服务(必须传入 serviceId + 所有字段)
|
|
273
335
|
REQUEST_JSON=$(jq -n \
|
|
@@ -279,9 +341,43 @@ service_save() {
|
|
|
279
341
|
--arg schemaUrl "$SCHEMA_URL" \
|
|
280
342
|
'{request:{serviceId:$serviceId,serviceName:$serviceName,serviceDesc:$serviceDesc,resourceUrl:$resourceUrl,pricing:$pricing,schemaUrl:$schemaUrl}}')
|
|
281
343
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
344
|
+
fi
|
|
345
|
+
|
|
346
|
+
export PLATFORM="${DEV_TOOL_NAME}" PLATFORM_ID="${PLATFORM_ID:-}"
|
|
347
|
+
run_network_retry RESULT write service_save -- alipay-cli mcp call a2a-pay-service.saveBazaarServiceForMcp \
|
|
348
|
+
-d "$REQUEST_JSON" \
|
|
349
|
+
--json
|
|
350
|
+
RETRY_RC=$?
|
|
351
|
+
if [ "$RETRY_RC" -eq 75 ]; then
|
|
352
|
+
if [ -z "$SERVICE_ID" ]; then
|
|
353
|
+
echo "❌ 服务创建响应不明;现有查询无法把同名候选唯一归属于本次创建,结果标记为 UNKNOWN,禁止自动重复创建"
|
|
354
|
+
exit 1
|
|
355
|
+
fi
|
|
356
|
+
if fetch_service_list; then
|
|
357
|
+
MATCH_COUNT=$(echo "$SERVICE_LIST" | jq --arg id "$SERVICE_ID" --arg name "$SERVICE_NAME" --arg desc "$SERVICE_DESC" --arg url "$RESOURCE_URL" --arg pricing "$PRICING" --arg schema "$SCHEMA_URL" '
|
|
358
|
+
[.[] | select(
|
|
359
|
+
.serviceId == $id and .serviceName == $name and .serviceDesc == $desc and
|
|
360
|
+
.resourceUrl == $url and
|
|
361
|
+
((.metadata.pricing // .pricing) | tostring) == $pricing and
|
|
362
|
+
(.metadata.schema_url // .schemaUrl) == $schema
|
|
363
|
+
)] | length
|
|
364
|
+
')
|
|
365
|
+
if [ "$MATCH_COUNT" -eq 1 ]; then
|
|
366
|
+
emit_control "✅ 服务修改已由列表查询核验成功"
|
|
367
|
+
emit_control "📋 服务ID: $SERVICE_ID"
|
|
368
|
+
emit_control_field "SERVICE_ID" "$SERVICE_ID" || return 1
|
|
369
|
+
return 0
|
|
370
|
+
fi
|
|
371
|
+
fi
|
|
372
|
+
echo "❌ 服务修改响应不明且现有列表无法排除传播延迟,结果标记为 UNKNOWN,禁止自动重复修改"
|
|
373
|
+
exit 1
|
|
374
|
+
elif [ "$RETRY_RC" -ne 0 ]; then
|
|
375
|
+
if [ -z "$SERVICE_ID" ]; then
|
|
376
|
+
echo "❌ 服务创建因明确未发送的网络异常在自动重试两次后仍未恢复"
|
|
377
|
+
else
|
|
378
|
+
echo "❌ 服务修改因明确未发送的网络异常在自动重试两次后仍未恢复"
|
|
379
|
+
fi
|
|
380
|
+
exit 1
|
|
285
381
|
fi
|
|
286
382
|
|
|
287
383
|
# 错误检测
|
|
@@ -320,12 +416,13 @@ service_save() {
|
|
|
320
416
|
')
|
|
321
417
|
fi
|
|
322
418
|
|
|
323
|
-
if
|
|
419
|
+
if ! validate_control_value "$NEW_SERVICE_ID"; then
|
|
324
420
|
echo "❌ 服务创建返回成功,但未解析到 serviceId,禁止继续后续流程"
|
|
325
421
|
exit 1
|
|
326
422
|
fi
|
|
327
|
-
|
|
328
|
-
|
|
423
|
+
emit_control "✅ 服务${OPERATION}成功"
|
|
424
|
+
emit_control "📋 服务ID: $NEW_SERVICE_ID"
|
|
425
|
+
emit_control_field "SERVICE_ID" "$NEW_SERVICE_ID" || exit 1
|
|
329
426
|
else
|
|
330
427
|
OPERATION="创建"
|
|
331
428
|
if [ -n "$SERVICE_ID" ]; then
|
|
@@ -338,7 +435,8 @@ service_save() {
|
|
|
338
435
|
.data.subMsg // .data.msg // .subMsg // .msg //
|
|
339
436
|
.error.message // .errorMessage // "未知错误"
|
|
340
437
|
' 2>/dev/null)
|
|
341
|
-
|
|
438
|
+
ERROR_MSG=$(sanitize_customer_error_text "$ERROR_MSG")
|
|
439
|
+
echo "❌ 服务${OPERATION}失败: ${BUSINESS_CODE} / ${ERROR_MSG}"
|
|
342
440
|
else
|
|
343
441
|
echo "❌ 服务${OPERATION}返回结构异常,无法确认操作结果"
|
|
344
442
|
fi
|
|
@@ -375,43 +473,10 @@ service_validate() {
|
|
|
375
473
|
esac
|
|
376
474
|
done
|
|
377
475
|
|
|
378
|
-
|
|
379
|
-
if [ -z "$SERVICE_NAME" ] || [ ${#SERVICE_NAME} -gt 50 ]; then
|
|
380
|
-
echo "❌ 服务名称长度需在 1-50 字符之间(当前长度: ${#SERVICE_NAME})"
|
|
381
|
-
exit 1
|
|
382
|
-
fi
|
|
383
|
-
|
|
384
|
-
# 2. 服务描述:长度 1-500 字符
|
|
385
|
-
if [ -z "$SERVICE_DESC" ] || [ ${#SERVICE_DESC} -gt 500 ]; then
|
|
386
|
-
echo "❌ 服务描述长度需在 1-500 字符之间(当前长度: ${#SERVICE_DESC})"
|
|
387
|
-
exit 1
|
|
388
|
-
fi
|
|
389
|
-
|
|
390
|
-
# 3. 服务地址:有效 URL
|
|
391
|
-
if [ -z "$RESOURCE_URL" ] || ! [[ "$RESOURCE_URL" =~ ^https?:// ]]; then
|
|
392
|
-
echo "❌ 请提供有效的 URL 地址(以 http:// 或 https:// 开头)"
|
|
393
|
-
exit 1
|
|
394
|
-
fi
|
|
395
|
-
|
|
396
|
-
# 4. 服务单价:数字格式,>= 0.01
|
|
397
|
-
if [ -z "$PRICING" ] || ! [[ "$PRICING" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
|
|
398
|
-
echo "❌ 服务单价格式不正确,请输入数字(如 0.01、1.00)"
|
|
399
|
-
exit 1
|
|
400
|
-
fi
|
|
401
|
-
PRICING_VALID=$(awk -v p="$PRICING" 'BEGIN { if (p + 0 >= 0.01) print "true"; else print "false" }')
|
|
402
|
-
if [ "$PRICING_VALID" = "false" ]; then
|
|
403
|
-
echo "❌ 服务单价最低为 0.01 元"
|
|
404
|
-
exit 1
|
|
405
|
-
fi
|
|
406
|
-
|
|
407
|
-
# 5. schemaUrl 在本流程中承载序列化后的 JSON 请求示例,不是 URL。
|
|
408
|
-
# CLI 接收原始 JSON;save 分支通过 jq --arg 将其安全写入字符串字段。
|
|
409
|
-
if [ -z "$SCHEMA_URL" ] || ! echo "$SCHEMA_URL" | jq . >/dev/null 2>&1; then
|
|
410
|
-
echo "❌ 请提供有效的 JSON 格式请求示例"
|
|
411
|
-
exit 1
|
|
412
|
-
fi
|
|
476
|
+
validate_service_fields
|
|
413
477
|
|
|
414
|
-
|
|
478
|
+
emit_control "✅ 服务信息校验通过"
|
|
479
|
+
emit_control_field "SERVICE_PRICING" "$PRICING" || exit 1
|
|
415
480
|
}
|
|
416
481
|
|
|
417
482
|
# ─── 入口分发 ────────────────────────────────────────────────────────────────
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
emit_signed_flow() {
|
|
4
|
+
case "$1" in
|
|
5
|
+
"I1080300001000041203") echo "FLOW:PC_WEB_SIGNED" ;;
|
|
6
|
+
"I1080300001000041313") echo "FLOW:APP_SIGNED" ;;
|
|
7
|
+
"I1080300001000160457") echo "FLOW:AI_PAY_SIGNED" ;;
|
|
8
|
+
*) return 1 ;;
|
|
9
|
+
esac
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
emit_sign_status_from_business() {
|
|
13
|
+
local business="$1"
|
|
14
|
+
local sales_code="$2"
|
|
15
|
+
local ar_list ar_count has_effective has_submitted
|
|
16
|
+
|
|
17
|
+
case "$sales_code" in
|
|
18
|
+
"I1080300001000041203"|"I1080300001000041313"|"I1080300001000160457") ;;
|
|
19
|
+
*) return 1 ;;
|
|
20
|
+
esac
|
|
21
|
+
|
|
22
|
+
ar_list=$(printf '%s' "$business" | jq -c '
|
|
23
|
+
if (.resultObj | type) == "object" and (.resultObj.arInfoList | type) == "array" then
|
|
24
|
+
.resultObj.arInfoList
|
|
25
|
+
else
|
|
26
|
+
null
|
|
27
|
+
end
|
|
28
|
+
' 2>/dev/null) || return 1
|
|
29
|
+
[ -n "$ar_list" ] && printf '%s' "$ar_list" | jq -e 'type == "array"' >/dev/null 2>&1 || return 1
|
|
30
|
+
ar_count=$(printf '%s' "$ar_list" | jq 'length') || return 1
|
|
31
|
+
|
|
32
|
+
if [ "$ar_count" -eq 0 ]; then
|
|
33
|
+
echo "📋 签约状态: 未签约 (NOT_SIGNED);进入 Step 4 签约材料类别"
|
|
34
|
+
echo "SIGN_STATUS=NOT_SIGNED"
|
|
35
|
+
case "$sales_code" in
|
|
36
|
+
"I1080300001000041203") echo "FLOW:PC_WEB_NOT_SIGNED" ;;
|
|
37
|
+
"I1080300001000041313") echo "FLOW:APP_NOT_SIGNED" ;;
|
|
38
|
+
"I1080300001000160457") echo "FLOW:AI_PAY_NOT_SIGNED" ;;
|
|
39
|
+
esac
|
|
40
|
+
return 0
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
has_effective=$(printf '%s' "$ar_list" | jq -r '[.[] | select(.arStatus == "02")] | length') || return 1
|
|
44
|
+
has_submitted=$(printf '%s' "$ar_list" | jq -r '[.[] | select(.arStatus == "01")] | length') || return 1
|
|
45
|
+
if [ "$has_effective" -gt 0 ]; then
|
|
46
|
+
echo "✅ 签约已生效;无需签约材料,继续 Step 4 资源决策"
|
|
47
|
+
echo "SIGN_STATUS=SIGNED_EFFECTIVE"
|
|
48
|
+
emit_signed_flow "$sales_code"
|
|
49
|
+
elif [ "$has_submitted" -gt 0 ]; then
|
|
50
|
+
echo "📋 已提交签约(待生效),无需重复提交签约,继续推进后续步骤"
|
|
51
|
+
echo "SIGN_STATUS=SIGN_SUBMITTED"
|
|
52
|
+
emit_signed_flow "$sales_code"
|
|
53
|
+
else
|
|
54
|
+
echo "📋 其他签约状态;保留已取得的只读结果并将签约分支标记为待核验"
|
|
55
|
+
echo "SIGN_STATUS=OTHER_STATUS"
|
|
56
|
+
echo "FLOW:OTHER_STATUS"
|
|
57
|
+
fi
|
|
58
|
+
}
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
#=============================================================================
|
|
3
3
|
# 脚本名称: upload_screenshots.sh
|
|
4
4
|
# 功能描述: 并行上传截图文件并解析可用于签约的图片引用值
|
|
5
|
-
# 调用位置: Step 4
|
|
6
|
-
# 调用前置: 脚本通过 error_handler.sh 间接初始化 DEV_TOOL_NAME
|
|
7
|
-
# 用法: bash upload_screenshots.sh "$HOME_IMG" "$SHOP_IMG" "$PAY_IMG"
|
|
8
|
-
# 返回值:
|
|
5
|
+
# 调用位置: Step 4 签约材料类别
|
|
6
|
+
# 调用前置: 脚本通过 error_handler.sh 间接初始化 DEV_TOOL_NAME/PLATFORM_ID;需传入产品类型和3个文件路径
|
|
7
|
+
# 用法: bash upload_screenshots.sh --product-type <webpay|apppay> "$HOME_IMG" "$SHOP_IMG" "$PAY_IMG"
|
|
8
|
+
# 返回值: stdout 仅输出上传结果;stderr 输出图片引用值控制信号
|
|
9
9
|
#=============================================================================
|
|
10
10
|
|
|
11
11
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
@@ -22,16 +22,28 @@ require_command jq || exit 1
|
|
|
22
22
|
require_command alipay-cli || exit 1
|
|
23
23
|
require_command mktemp || exit 1
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
if [ "${1:-}" != "--product-type" ] || [ "$#" -lt 5 ]; then
|
|
26
|
+
echo "❌ 请先传入 --product-type webpay|apppay"
|
|
27
|
+
exit 1
|
|
28
|
+
fi
|
|
29
|
+
PRODUCT_TYPE="$2"
|
|
30
|
+
shift 2
|
|
31
|
+
case "$PRODUCT_TYPE" in
|
|
32
|
+
webpay|apppay) ;;
|
|
33
|
+
*) echo "❌ 截图上传仅支持 webpay|apppay"; exit 1 ;;
|
|
34
|
+
esac
|
|
35
|
+
init_alipay_cli_product "$PRODUCT_TYPE" || exit 1
|
|
36
|
+
|
|
37
|
+
HOME_IMG="${1:-}"
|
|
38
|
+
SHOP_IMG="${2:-}"
|
|
39
|
+
PAY_IMG="${3:-}"
|
|
28
40
|
|
|
29
41
|
# 校验参数
|
|
30
42
|
if [ -z "$HOME_IMG" ] || [ -z "$SHOP_IMG" ] || [ -z "$PAY_IMG" ]; then
|
|
31
43
|
echo "❌ 请提供 3 个截图文件路径"
|
|
32
|
-
echo "用法: bash upload_screenshots.sh <首页截图> <商品页截图> <支付页截图>"
|
|
33
|
-
echo "
|
|
34
|
-
echo " APP
|
|
44
|
+
echo "用法: bash upload_screenshots.sh --product-type <webpay|apppay> <首页截图> <商品页截图> <支付页截图>"
|
|
45
|
+
echo " AI 网页应用收款:传入网站首页、商品页、支付页截图"
|
|
46
|
+
echo " AI 移动应用收款:传入 APP 首页、商品页、支付页截图"
|
|
35
47
|
exit 1
|
|
36
48
|
fi
|
|
37
49
|
|
|
@@ -62,10 +74,10 @@ cleanup_upload_tmp() {
|
|
|
62
74
|
}
|
|
63
75
|
trap cleanup_upload_tmp EXIT
|
|
64
76
|
|
|
65
|
-
# 并行上传 3
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
77
|
+
# 并行上传 3 张截图。PLATFORM_ID 与 PRODUCT 均由公共上下文初始化。
|
|
78
|
+
PLATFORM="${DEV_TOOL_NAME:-unknown}" PLATFORM_ID="${PLATFORM_ID:-}" PRODUCT="${PRODUCT:-}" alipay-cli file upload "$HOME_IMG" -s payMerchantcodeSkill --json 2>/dev/null > "$TMP_HOME" &
|
|
79
|
+
PLATFORM="${DEV_TOOL_NAME:-unknown}" PLATFORM_ID="${PLATFORM_ID:-}" PRODUCT="${PRODUCT:-}" alipay-cli file upload "$SHOP_IMG" -s payMerchantcodeSkill --json 2>/dev/null > "$TMP_SHOP" &
|
|
80
|
+
PLATFORM="${DEV_TOOL_NAME:-unknown}" PLATFORM_ID="${PLATFORM_ID:-}" PRODUCT="${PRODUCT:-}" alipay-cli file upload "$PAY_IMG" -s payMerchantcodeSkill --json 2>/dev/null > "$TMP_PAY" &
|
|
69
81
|
wait
|
|
70
82
|
|
|
71
83
|
# 解析图片引用值(兼容 file upload 返回 fileKey 或 URL 字段)
|
|
@@ -143,10 +155,12 @@ if [ -n "$ERRORS" ]; then
|
|
|
143
155
|
exit 1
|
|
144
156
|
fi
|
|
145
157
|
|
|
158
|
+
if ! validate_control_value "$HOME_REF" || ! validate_control_value "$SHOP_REF" || ! validate_control_value "$PAY_REF"; then
|
|
159
|
+
echo "❌ 截图上传返回的图片引用包含非法控制字符"
|
|
160
|
+
exit 1
|
|
161
|
+
fi
|
|
162
|
+
|
|
146
163
|
echo "✅ 截图上传成功"
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
echo ""
|
|
151
|
-
echo "# 更新对话上下文状态:"
|
|
152
|
-
echo "# collect_information = {\"screenshot\":[\"$HOME_REF\",\"$SHOP_REF\",\"$PAY_REF\"]}"
|
|
164
|
+
emit_control_field "SCREENSHOT_HOME_REF" "$HOME_REF" || exit 1
|
|
165
|
+
emit_control_field "SCREENSHOT_SHOP_REF" "$SHOP_REF" || exit 1
|
|
166
|
+
emit_control_field "SCREENSHOT_PAY_REF" "$PAY_REF" || exit 1
|