注意事項
1. 請求方式: HTTP + JSON + POST / GET
2. 字段名均為小寫
3. 統(tǒng)一使用UTF-8編碼
4. 春雨測試服務(wù)地址 https://test.chunyutianxia.com/,正式服務(wù)地址 http://www.zpr9.com/
5. 第三方用戶可以使用管理后臺進(jìn)行自測,該管理賬戶請聯(lián)系相關(guān)春雨人員開通
6. 春雨所有環(huán)境的機(jī)房出口IP,如需增加到白名單,請使用:
- 所有云主機(jī)默認(rèn)外網(wǎng)(natgw): 123.59.151.95
- 物理機(jī)外網(wǎng)(代理vpn), 123.59.151.126
- 云主機(jī)重要線上業(yè)務(wù),117.50.107.208/28,即117.50.107.208-117.50.107.223共16個ip地址
7. 合作方需按照跟春雨商定的合作方式來開發(fā),不能接入未合作的問診方式
8. 關(guān)于醫(yī)生總結(jié):API渠道圖文問題關(guān)閉后,醫(yī)生仍可以發(fā)送總結(jié)消息(以醫(yī)生文字回復(fù)形式)來通知患者(關(guān)閉后患者不可復(fù)),如存在醫(yī)生在問題關(guān)閉后發(fā)總結(jié)情況,請確??梢越邮盏酱河晖扑托畔⒉⒓皶r通知患者;
9. 相關(guān)服務(wù)開通權(quán)限后方可使用
簽名校驗(yàn)機(jī)制
雙方進(jìn)行通信時,使用加密密鑰(partner_key)進(jìn)行安全校驗(yàn), 簽名密鑰值用sign標(biāo)識,需嚴(yán)格保密。
簽名生成規(guī)則按使用場景分為兩類:
- 非回調(diào)類型:使用key、atime、user_id生成sign值
- 回調(diào)接口類型:使用key、atime、problem_id生成sign值(電話類服務(wù)使用service_id替換掉problem_id)
非回調(diào)類型生成方式示例如下:
# PYTHON 版本 生成方法
import hashlib
# 合作方 partner_key,注意不是 partner
partner_key = 'XKBP1Oqut0r2LiGV'
# UNIX TIMESTAMP 最小單位為秒
atime = '1467098815'
# 第三方用戶唯一標(biāo)識,可以為字母與數(shù)字組合的字符串
user_id = 'A800130'
# 獲得簽名: md5的32位結(jié)果取中間16位
sign = hashlib.md5(partner_key + atime + user_id).hexdigest()[8:-8]
# 輸出sign:5afda19c5d65a7a7
print sign
// PHP 版本 生成方法
// 合作方 partner_key, 注意不是 partner
$partner_key = "XKBP1Oqut0r2LiGV";
// UNIX TIMESTAMP 最小單位為秒
$atime = "1467098815";
// 第三方用戶唯一標(biāo)識,可以為字母與數(shù)字組合的字符串。
$user_id = "A800130";
// 生成簽名 5afda19c5d65a7a7
$sign = substr(md5($partner_key.$atime.$user_id), 8, 16);
// 輸出sign:5afda19c5d65a7a7
echo "sign: ".$sign;
// JAVA 版本 生成方法
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import org.apache.commons.codec.binary.Hex;
public class SignTest {
// 計算 Sign
private static String getSign(String partner_key, String atime, String user_id)
throws NoSuchAlgorithmException{
String info = partner_key + atime + user_id;
MessageDigest md5 = MessageDigest.getInstance("MD5");
byte[] srcBytes = info.getBytes();
md5.update(srcBytes);
byte[] resultBytes = md5.digest();
String resultString = new String(new Hex().encode(resultBytes));
return resultString.substring(8, 24);
}
public static void main( final String[] args ){
try {
// 合作方 partner_key, 注意不是 partner
String partner_key = "XKBP1Oqut0r2LiGV";
// UNIX TIMESTAMP 最小單位為秒
String atime = "1467098815";
// 第三方用戶唯一標(biāo)識,可以為字母與數(shù)字組合的字符串。
String user_id = "A800130";
// 計算sign結(jié)果為: 5afda19c5d65a7a7
String sign = SignTest.getSign(partner_key, atime, user_id);
System.out.println(sign);
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
}
// C# 版本 生成方法
using System;
using System.Security.Cryptography;
using System.Text;
public class Test
{
public static void Main()
{
// C#版本生成方法
string partner_key = "XKBP1Oqut0r2LiGV";
// UNIX TIMESTAMP 最小單位為秒
string atime = "1467098815";
// 第三方用戶唯一標(biāo)識,可以為字母與數(shù)字組合的字符串
string user_id = "A800130";
// 獲得簽名: md5的32位結(jié)果取中間16位
MD5 md5 = new MD5CryptoServiceProvider();
byte[] output = md5.ComputeHash(Encoding.UTF8.GetBytes(partner_key+atime+user_id));
string sign = BitConverter.ToString(output).Replace("-","").Substring(8, 16).ToLower();
// 輸出sign:5afda19c5d65a7a7
Console.WriteLine(sign);
}
}
提問數(shù)據(jù)結(jié)構(gòu)
JSONArray集合,格式: [contentItem 1, contentItem 2,..., contentItem n]
contentItem含義:
文字內(nèi)容{'type': 'text', 'text': '這是一段文本形式的內(nèi)容'}圖片內(nèi)容{'type': 'image', 'file': '這是圖片形式的內(nèi)容,這里是圖片的 url'}音頻內(nèi)容{'type': 'audio', 'file': '這是語音形式的內(nèi)容,這里是音頻文件的 url'}視頻內(nèi)容{'type': 'video', 'file': '這是視頻形式的內(nèi)容,這里是視頻文件的 url','duration':10, 'partner_cover_image':'視頻封面圖url'}病人資料{'type': 'patient_meta', 'age': '15 歲', 'sex': '男', 'name': '張三'}
生成content代碼示例如下:
說明:
- 眾包服務(wù)為確保分診準(zhǔn)確性,患者首問字?jǐn)?shù)請限制在10-500字;且務(wù)必傳給春雨提問患者姓別、年齡字段;
- 創(chuàng)建問題時首問請務(wù)必提問醫(yī)療問題,非醫(yī)療問題會被舉報;
- 圖片文件要求為JPG或PNG,單張最大不超過5M,每次最多可同時上傳9張,多張圖片時使用多個contentItem;
- 音頻文件格式要求是MP3,最長兩分鐘;
- 視頻文件要求為.mp4格式,時長不超過1分鐘。duration單位為秒;
- 提交的文件URL,春雨目前不會下載保存,請確保提交的文件URL可以長期穩(wěn)定訪問
- 使用JSON POST時,請注意content類型為string而不是嵌套的json類型
# PYTHON 版本 生成方法
import json
# 創(chuàng)建對話內(nèi)容
content = [
{"type": "text","text": "這是一段文本形式的內(nèi)容"},
{"type": "image","file": "這是圖片形式的內(nèi)容,這里是圖片的 url'"},
{"type": "audio","file": "這是語音形式的內(nèi)容,這里是音頻文件的 url"},
{"type": "video","file": "這是視頻形式的內(nèi)容,這里是視頻文件的 url","duration": 10,"partner_cover_image": "視頻封面圖url"},
{"type": "patient_meta","age": "15歲","sex": "男","name": "張三"}
]
# 獲得json string 格式結(jié)果,接口中content字段使用該結(jié)果
content = json.dumps(content)
// 創(chuàng)建對話內(nèi)容
import json
// 創(chuàng)建對話內(nèi)容
$content_list = array(
array ('type'=>'text','text'=>'這是一段文本形式的內(nèi)容'),
array ('type'=>'image','file'=>'這是圖片形式的內(nèi)容,這里是圖片的 url'),
array ('type'=>'audio','file'=>'這是語音形式的內(nèi)容,這里是音頻文件的 url'),
array ('type'=>'video','file'=>'這是視頻形式的內(nèi)容,這里是視頻文件的 url','duration':10'),
array ('type'=>'patient_meta','age'=>'15 歲', 'sex'=>'男'),
);
// 獲得json string 格式結(jié)果,接口中content字段使用該結(jié)果
echo json_encode($content_list);
// JAVA 版本 生成方法
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import net.sf.json.JSONArray;
import net.sf.json.JSONException;
public class JsonTest {
public static void main(String[] args) throws JSONException, ParseException {
ArrayList content_list = new ArrayList();
// 添加文本內(nèi)容
Map c_text = new HashMap();
c_text.put("type", "text");
c_text.put("text", "這是一段文本形式的內(nèi)容");
content_list.add(c_text);
// 添加圖片內(nèi)容
Map c_image = new HashMap();
c_image.put("type", "image");
c_image.put("file", "這是圖片形式的內(nèi)容,這里是圖片的 url");
content_list.add(c_image);
// 添加音頻內(nèi)容
Map c_audio = new HashMap();
c_audio.put("type", "audio");
c_audio.put("file", "這是一段文本形式的內(nèi)容,這里是音頻文件的 url");
content_list.add(c_audio);
// 添加視頻內(nèi)容
Map c_video = new HashMap();
c_video.put("type", "video");
c_video.put("file", "這是視頻形式的內(nèi)容,這里是視頻文件的 url','duration':10'");
content_list.add(c_video);
// 添加患者信息
Map c_patient_meta = new HashMap();
c_patient_meta.put("type", "patient_meta");
c_patient_meta.put("age", "15 歲");
c_patient_meta.put("sex", "男");
content_list.add(c_patient_meta);
// 輸出結(jié)果
JSONArray content_json = JSONArray.fromObject(content_list);
String content = content_json.toString();
System.out.println(content);
}
}
科室劃分
| 一級科室編碼 | 具體科室 | 二級科室編碼 | 具體科室 |
|---|---|---|---|
| 1 | 婦科 | 婦科 | |
| 2 | 兒科 | fb | 新生兒科 |
| fa | 小兒科 | ||
| 3 | 內(nèi)科 | ai | 感染科 |
| ah | 血液病科 | ||
| ag | 風(fēng)濕免疫科 | ||
| af | 內(nèi)分泌與代謝科 | ||
| ae | 腎內(nèi)科 | ||
| ad | 消化內(nèi)科 | ||
| ac | 神經(jīng)內(nèi)科 | ||
| ab | 心血管內(nèi)科 | ||
| aa | 呼吸內(nèi)科 | ||
| 4 | 皮膚性病科 | hb | 性病科 |
| ha | 皮膚科 | ||
| 6 | 營養(yǎng)科 | 營養(yǎng)科 | |
| 7 | 骨傷科 | cc | 創(chuàng)傷科 |
| cb | 關(guān)節(jié)科 | ||
| ca | 脊柱科 | ||
| 8 | 男科 | 男科 | |
| 9 | 外科 | bj | 甲狀腺乳腺外科 |
| bi | 普外科 | ||
| bh | 肛腸科 | ||
| bg | 泌尿外科 | ||
| bf | 康復(fù)科 | ||
| be | 燒傷科 | ||
| bd | 肝膽外科 | ||
| bc | 神經(jīng)外科 | ||
| bb | 心臟與血管外科 | ||
| ba | 胸外科 | ||
| 11 | 腫瘤及防治科 | md | 腫瘤中醫(yī)科 |
| mc | 介入與放療中心 | ||
| mb | 腫瘤外科 | ||
| ma | 腫瘤內(nèi)科 | ||
| 12 | 中醫(yī)科 | oe | 中醫(yī)兒科 |
| od | 中醫(yī)男科 | ||
| oc | 中醫(yī)婦科 | ||
| ob | 中醫(yī)外科 | ||
| oa | 中醫(yī)內(nèi)科 | ||
| 13 | 口腔頜面科 | 口腔頜面科 | |
| 14 | 耳鼻咽喉科 | jc | 咽喉科 |
| jb | 鼻科 | ||
| ja | 耳科 | ||
| 15 | 眼科 | ||
| 16 | 整型美容科 | ||
| 17 | 精神心理科 | nb | 心理科 |
| na | 精神科 | ||
| 21 | 產(chǎn)科 | ||
| 22 | 報告解讀科 | qi | 預(yù)防保健科 |
| qh | 體檢中心 | ||
| qg | 麻醉科 | ||
| qf | 超聲科 | ||
| qe | 心電圖科 | ||
| qd | 病理科 | ||
| qc | 內(nèi)鏡科 | ||
| qb | 放射科 | ||
| qa | 檢驗(yàn)科 |
Postman調(diào)試工具
Postman接口測試套件使用說明
使用此工具,可以在開發(fā)未完成狀態(tài)下,驗(yàn)證接口服務(wù)狀態(tài)和業(yè)務(wù)的接入流程,同時在開發(fā)過程中,如果遇到問題,報錯等,可以快速幫助定位問題。只需要考慮業(yè)務(wù)參數(shù),而不需要關(guān)注簽名,時間戳等。
注意:雖然可配置線上的請求,但請慎重使用,如隨意測試線上接口可能會導(dǎo)致用戶id被拉黑,多扣費(fèi)等情況。
使用和配置
1.下載Postman > 7.0版本
2.下載Postman_config.zip并解壓
3.Import->Folder 選擇文件夾導(dǎo)入
在環(huán)境變量配置(1)->全局配置(2)中修改partner
在環(huán)境變量配置中的test(3)、online(4)中配置測試環(huán)境、線上環(huán)境的partner_key和當(dāng)前環(huán)境的測試用戶。
注意:線上測試必須添加user_id至白名單
在選擇好測試環(huán)境后,選擇需要測試的接口進(jìn)行請求即可,測試過程中只需要修改業(yè)務(wù)參數(shù)如partner_order_id,problem_id等。不需要再關(guān)注簽名、時間戳等驗(yàn)證字段
業(yè)務(wù)問題
1、問題交互次數(shù)定義
答:患者連續(xù)追問直至醫(yī)生回答定義為一次交互。示意圖(以下三種情況均定義為一次交互):
2、服務(wù)自動關(guān)閉邏輯?
圖文問題醫(yī)生首次答復(fù)后會重新計算時間,后續(xù)答復(fù)則不再重新計算。
| 問題類型 | 已回復(fù)自動關(guān)閉邏輯 | 未回復(fù)自動關(guān)閉邏輯 | 測試環(huán)境自動關(guān)閉時間 | 關(guān)閉后的問題狀態(tài) |
|---|---|---|---|---|
| 眾包服務(wù) | 20次交互或醫(yī)生首次回復(fù)24h后問題關(guān)閉 | 24h自動關(guān)閉 | 已回復(fù)/未回復(fù)均為1h | 關(guān)閉狀態(tài) |
| 眾包升級 | 20次交互或醫(yī)生首次回復(fù)24h后問題關(guān)閉 | 1h自動關(guān)閉 | 已回復(fù)/未回復(fù)均為1h | 關(guān)閉狀態(tài) |
| 定向圖文 | 30次交互或醫(yī)生首次回復(fù)48h后問題關(guān)閉 | 24h自動關(guān)閉 | 已回復(fù)/未回復(fù)均為1h | 關(guān)閉狀態(tài) |
| 名醫(yī)咨詢 | 10次交互或醫(yī)生首次回復(fù)48h后問題關(guān)閉 | 24h自動關(guān)閉 | 已回復(fù)/未回復(fù)均為1h | 關(guān)閉狀態(tài) |
| 圖文急診 | 20次交互或醫(yī)生首次回復(fù)30min后問題關(guān)閉 | 30min自動關(guān)閉 | 已回復(fù)/未回復(fù)均為30min | 關(guān)閉狀態(tài) |
3、健康檔案需要提供哪些字段信息?
答:API對接方式下,健康檔案包括:性別、年齡。具體可參考 開發(fā)前必讀->提問數(shù)據(jù)結(jié)構(gòu)
4、春雨平臺側(cè)能否提供科室信息?
答:目前春雨平臺側(cè)可以提供一級/二級科室信息,科室列表信息請參見:API接口->定向圖文服務(wù)->找醫(yī)生接口。
5、H5和API的對接方式下,收款流程都是什么樣的?
答:如以H5形式對接,春雨直接收費(fèi)。如以API形式對接,用戶直接支付給合作方,合作方再和春雨平臺定期結(jié)算。
6、API接入眾包服務(wù):用戶提交問題后,用戶對系統(tǒng)分配到的科室可以修改嗎?
答:不可以修改。
7、允許用戶進(jìn)行評價的觸發(fā)條件是什么?
答:醫(yī)患交互后即可評價醫(yī)生。
8、針對醫(yī)生評價功能,不滿意的原因是必填項么?
答:必填。
9、針對舉報功能:被醫(yī)生或系統(tǒng)舉報的功能,有專門的接口么?用戶被舉報后,如何通知到合作方?
答:被醫(yī)生或系統(tǒng)舉報,無專門的接口通知。會通過【通用接口】的【問題關(guān)閉通知】發(fā)close或refund通知。春雨會返回對應(yīng)的被舉報文案,請參見【退款及舉報邏輯】部分。同時被舉報后會以特殊的問題狀態(tài)進(jìn)行標(biāo)識,參見【問題詳情接口】。
10、針對黑名單功能:當(dāng)用戶被列入黑名單時,用戶再提問時,會如何提示?
答:用戶被加入黑名單后,當(dāng)該用戶提問時,春雨平臺會返回錯誤碼12003來進(jìn)行標(biāo)識。具體請參見【黑名單邏輯】和【錯誤碼】中的對應(yīng)內(nèi)容。
技術(shù)問題
1、為何在安卓客戶端的webview中點(diǎn)擊上傳圖片控件沒反應(yīng)?
答: 由于安全因素android webview屏蔽了文件上傳控件,具體參考:?
https://www.oschina.net/question/23880_50205
安卓5.0及以上版本中,有修改,具體參考:
http://blog.csdn.net/u012912435/article/details/51484211
在在Android5.0及以上版本中使用WebView加載https資源文件時,
如果認(rèn)證證書不被Android認(rèn)可,那么會出現(xiàn)無法成功加載對應(yīng)資源問題。
具體解決參考:
https://www.cnblogs.com/zhengshiqiang47/p/6220295.html
2、為何在H5頁面點(diǎn)擊創(chuàng)建問題無效?
答: H5頁面不能在PC瀏覽器環(huán)境下直接使用,需要在手機(jī)或手機(jī)模擬器環(huán)境下使用。
3、為何在加載H5頁面時候樣式丟失?
答: H5頁面所有資源URL為相對URL,請確認(rèn)當(dāng)前加載環(huán)境是否支持獲取該資源。
4、什么是atime?
答: atime 為時間戳,是指格林威治時間1970年01月01日00時00分00秒(北京時間1970年01月01日08時00分00秒)起至現(xiàn)在的總秒數(shù);atime需實(shí)時獲取,前后15min有效。
5、為何在回調(diào)通知里面查不到相關(guān)參數(shù)?
答: 春雨發(fā)送第三方回調(diào)通知時采用POST方式,data為json格式,請確保接口符合要求。如果仍然未獲取到相關(guān)參數(shù),建議增加request請求內(nèi)容的完整打印消息來排查原因。
6、每次API接口 創(chuàng)建/追問 問題前都需要先請求賬號同步接口嗎?
答: 不需要,新用戶只要同步過一次即可。
7、H5不能直接返回到上級頁面嗎?
答: 由于H5是嵌入第三方APP的,所以返回欄需要由第三方來實(shí)現(xiàn)。
8、API付費(fèi)款項是怎樣處理的?
答: 第三方需要先在春雨服務(wù)器創(chuàng)建付費(fèi)問診記錄,然后引導(dǎo)用戶付費(fèi)至第三方平臺,成功后通知春雨服務(wù)器更新訂單,后續(xù)問診交互同API免費(fèi)問診一致。春雨公司定期與第三方公司結(jié)算相關(guān)款項。
9、接口返回"invalid_user"是為什么?
答: 首先 user_id 只可以包含大小寫字母與數(shù)字、下劃線的組合,其次在確認(rèn) user_id 符合格式時請檢查是否是由于構(gòu)建的數(shù)據(jù)類型(content或者assess_info)格式錯誤,導(dǎo)致參數(shù)亂碼(可通過抓包的方式確認(rèn)發(fā)出的數(shù)據(jù)是否正確)。
10、H5接入方式下,針對Android系統(tǒng),填寫病情描述后不能點(diǎn)擊下一步的解決辦法?
答: 參考如下代碼進(jìn)行解決
webSettings.setJavaScriptEnabled(true);
webSettings.setDomStorageEnabled(true);
// 前面?zhèn)z個必須同時在
webView.setWebChromeClient(new MyWebChromeClient());
webSettings.setAllowFileAccess(true)
11、API對接眾包升級服務(wù):可以使用哪些接口?。
答:請查看【開發(fā)文檔】中,【眾包升級服務(wù)】目錄下的所有接口,【通用接口】下的所有接口,和【第三方回調(diào)管理】的所有接口。