注意事項

1. 請求方式: HTTP + JSON + POST / GET

2. 字段名均為小寫

3. 統一使用UTF-8編碼

4. 春雨測試服務地址 https://test.chunyutianxia.com/,正式服務地址 http://www.lcstp.com/

5. 第三方用戶可以使用管理后臺進行自測,該管理賬戶請聯系相關春雨人員開通

6. 春雨所有環境的機房出口IP,如需增加到白名單,請使用:

  • 所有云主機默認外網(natgw): 123.59.151.95
  • 物理機外網(代理vpn), 123.59.151.126
  • 云主機重要線上業務,117.50.107.208/28,即117.50.107.208-117.50.107.223共16個ip地址

7. 合作方需按照跟春雨商定的合作方式來開發,不能接入未合作的問診方式

8. 關于醫生總結:API渠道圖文問題關閉后,醫生仍可以發送總結消息(以醫生文字回復形式)來通知患者(關閉后患者不可復),如存在醫生在問題關閉后發總結情況,請確保可以接收到春雨推送信息并及時通知患者;

9. 相關服務開通權限后方可使用

簽名校驗機制

雙方進行通信時,使用加密密鑰(partner_key)進行安全校驗, 簽名密鑰值用sign標識,需嚴格保密。

簽名生成規則按使用場景分為兩類:

  • 非回調類型:使用key、atime、user_id生成sign值
  • 回調接口類型:使用key、atime、problem_id生成sign值(電話類服務使用service_id替換掉problem_id)

非回調類型生成方式示例如下:

# PYTHON 版本 生成方法
                import hashlib
                # 合作方 partner_key,注意不是 partner
                partner_key = 'XKBP1Oqut0r2LiGV'
                # UNIX TIMESTAMP 最小單位為秒
                atime = '1467098815'
                # 第三方用戶唯一標識,可以為字母與數字組合的字符串
                user_id = 'A800130'
                # 獲得簽名: md5的32位結果取中間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";
                // 第三方用戶唯一標識,可以為字母與數字組合的字符串。
                $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";
                            // 第三方用戶唯一標識,可以為字母與數字組合的字符串。
                            String user_id = "A800130";
                            // 計算sign結果為: 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";
                        // 第三方用戶唯一標識,可以為字母與數字組合的字符串
                        string user_id = "A800130";
                        // 獲得簽名: md5的32位結果取中間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);
                    }
                }
                

提問數據結構

JSONArray集合,格式: [contentItem 1, contentItem 2,..., contentItem n]

contentItem含義:

  • 文字內容 {'type': 'text', 'text': '這是一段文本形式的內容'}
  • 圖片內容 {'type': 'image', 'file': '這是圖片形式的內容,這里是圖片的 url'}
  • 音頻內容 {'type': 'audio', 'file': '這是語音形式的內容,這里是音頻文件的 url'}
  • 視頻內容 {'type': 'video', 'file': '這是視頻形式的內容,這里是視頻文件的 url','duration':10, 'partner_cover_image':'視頻封面圖url'}
  • 病人資料 {'type': 'patient_meta', 'age': '15 歲', 'sex': '男', 'name': '張三'}

生成content代碼示例如下:

說明:

  • 眾包服務為確保分診準確性,患者首問字數請限制在10-500字;且務必傳給春雨提問患者姓別、年齡字段;
  • 創建問題時首問請務必提問醫療問題,非醫療問題會被舉報;
  • 圖片文件要求為JPG或PNG,單張最大不超過5M,每次最多可同時上傳9張,多張圖片時使用多個contentItem;
  • 音頻文件格式要求是MP3,最長兩分鐘;
  • 視頻文件要求為.mp4格式,時長不超過1分鐘。duration單位為秒;
  • 提交的文件URL,春雨目前不會下載保存,請確保提交的文件URL可以長期穩定訪問
  • 使用JSON POST時,請注意content類型為string而不是嵌套的json類型
# PYTHON 版本 生成方法
import json
# 創建對話內容
content = [
    {"type": "text","text": "這是一段文本形式的內容"},
    {"type": "image","file": "這是圖片形式的內容,這里是圖片的 url'"},
    {"type": "audio","file": "這是語音形式的內容,這里是音頻文件的 url"},
    {"type": "video","file": "這是視頻形式的內容,這里是視頻文件的 url","duration": 10,"partner_cover_image": "視頻封面圖url"},
    {"type": "patient_meta","age": "15歲","sex": "男","name": "張三"}
]
# 獲得json string 格式結果,接口中content字段使用該結果
content = json.dumps(content)
// 創建對話內容
import json
// 創建對話內容
$content_list = array(
    array ('type'=>'text','text'=>'這是一段文本形式的內容'),
    array ('type'=>'image','file'=>'這是圖片形式的內容,這里是圖片的 url'),
    array ('type'=>'audio','file'=>'這是語音形式的內容,這里是音頻文件的 url'),
    array ('type'=>'video','file'=>'這是視頻形式的內容,這里是視頻文件的 url','duration':10'),
    array ('type'=>'patient_meta','age'=>'15 歲', 'sex'=>'男'),
);
// 獲得json string 格式結果,接口中content字段使用該結果
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();
        // 添加文本內容
        Map c_text = new HashMap();
        c_text.put("type", "text");
        c_text.put("text", "這是一段文本形式的內容");
        content_list.add(c_text);
        // 添加圖片內容
        Map c_image = new HashMap();
        c_image.put("type", "image");
        c_image.put("file", "這是圖片形式的內容,這里是圖片的 url");
        content_list.add(c_image);
        // 添加音頻內容
        Map c_audio = new HashMap();
        c_audio.put("type", "audio");
        c_audio.put("file", "這是一段文本形式的內容,這里是音頻文件的 url");
        content_list.add(c_audio);
        // 添加視頻內容
        Map c_video = new HashMap();
        c_video.put("type", "video");
        c_video.put("file", "這是視頻形式的內容,這里是視頻文件的 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);

        // 輸出結果
        JSONArray content_json = JSONArray.fromObject(content_list);
        String content = content_json.toString();
        System.out.println(content);
    }
}

科室劃分

一級科室編碼 具體科室 二級科室編碼 具體科室
1 婦科 婦科
2 兒科 fb 新生兒科
fa 小兒科
3 內科 ai 感染科
ah 血液病科
ag 風濕免疫科
af 內分泌與代謝科
ae 腎內科
ad 消化內科
ac 神經內科
ab 心血管內科
aa 呼吸內科
4 皮膚性病科 hb 性病科
ha 皮膚科
6 營養科 營養科
7 骨傷科 cc 創傷科
cb 關節科
ca 脊柱科
8 男科 男科
9 外科 bj 甲狀腺乳腺外科
bi 普外科
bh 肛腸科
bg 泌尿外科
bf 康復科
be 燒傷科
bd 肝膽外科
bc 神經外科
bb 心臟與血管外科
ba 胸外科
11 腫瘤及防治科 md 腫瘤中醫科
mc 介入與放療中心
mb 腫瘤外科
ma 腫瘤內科
12 中醫科 oe 中醫兒科
od 中醫男科
oc 中醫婦科
ob 中醫外科
oa 中醫內科
13 口腔頜面科 口腔頜面科
14 耳鼻咽喉科 jc 咽喉科
jb 鼻科
ja 耳科
15 眼科
16 整型美容科
17 精神心理科 nb 心理科
na 精神科
21 產科
22 報告解讀科 qi 預防保健科
qh 體檢中心
qg 麻醉科
qf 超聲科
qe 心電圖科
qd 病理科
qc 內鏡科
qb 放射科
qa 檢驗科

Postman調試工具

Postman接口測試套件使用說明

使用此工具,可以在開發未完成狀態下,驗證接口服務狀態和業務的接入流程,同時在開發過程中,如果遇到問題,報錯等,可以快速幫助定位問題。只需要考慮業務參數,而不需要關注簽名,時間戳等。

注意:雖然可配置線上的請求,但請慎重使用,如隨意測試線上接口可能會導致用戶id被拉黑,多扣費等情況。

使用和配置

1.下載Postman > 7.0版本

2.下載Postman_config.zip并解壓

3.Import->Folder 選擇文件夾導入

在環境變量配置(1)->全局配置(2)中修改partner

在環境變量配置中的test(3)、online(4)中配置測試環境、線上環境的partner_key和當前環境的測試用戶。

注意:線上測試必須添加user_id至白名單

在選擇好測試環境后,選擇需要測試的接口進行請求即可,測試過程中只需要修改業務參數如partner_order_id,problem_id等。不需要再關注簽名、時間戳等驗證字段

業務問題

1、問題交互次數定義

答:患者連續追問直至醫生回答定義為一次交互。示意圖(以下三種情況均定義為一次交互):

問題交互次數定義

2、服務自動關閉邏輯?

圖文問題醫生首次答復后會重新計算時間,后續答復則不再重新計算。

問題類型 已回復自動關閉邏輯 未回復自動關閉邏輯 測試環境自動關閉時間 關閉后的問題狀態
眾包服務 20次交互或醫生首次回復24h后問題關閉 24h自動關閉 已回復/未回復均為1h 關閉狀態
眾包升級 20次交互或醫生首次回復24h后問題關閉 1h自動關閉 已回復/未回復均為1h 關閉狀態
定向圖文 30次交互或醫生首次回復48h后問題關閉 24h自動關閉 已回復/未回復均為1h 關閉狀態
名醫咨詢 10次交互或醫生首次回復48h后問題關閉 24h自動關閉 已回復/未回復均為1h 關閉狀態
圖文急診 20次交互或醫生首次回復30min后問題關閉 30min自動關閉 已回復/未回復均為30min 關閉狀態

3、健康檔案需要提供哪些字段信息?

答:API對接方式下,健康檔案包括:性別、年齡。具體可參考 開發前必讀->提問數據結構

4、春雨平臺側能否提供科室信息?

答:目前春雨平臺側可以提供一級/二級科室信息,科室列表信息請參見:API接口->定向圖文服務->找醫生接口。

5、H5和API的對接方式下,收款流程都是什么樣的?

答:如以H5形式對接,春雨直接收費。如以API形式對接,用戶直接支付給合作方,合作方再和春雨平臺定期結算。

6、API接入眾包服務:用戶提交問題后,用戶對系統分配到的科室可以修改嗎?

答:不可以修改。

7、允許用戶進行評價的觸發條件是什么?

答:醫患交互后即可評價醫生。

8、針對醫生評價功能,不滿意的原因是必填項么?

答:必填。

9、針對舉報功能:被醫生或系統舉報的功能,有專門的接口么?用戶被舉報后,如何通知到合作方?

答:被醫生或系統舉報,無專門的接口通知。會通過【通用接口】的【問題關閉通知】發close或refund通知。春雨會返回對應的被舉報文案,請參見【退款及舉報邏輯】部分。同時被舉報后會以特殊的問題狀態進行標識,參見【問題詳情接口】。

10、針對黑名單功能:當用戶被列入黑名單時,用戶再提問時,會如何提示?

答:用戶被加入黑名單后,當該用戶提問時,春雨平臺會返回錯誤碼12003來進行標識。具體請參見【黑名單邏輯】和【錯誤碼】中的對應內容。

技術問題

1、為何在安卓客戶端的webview中點擊上傳圖片控件沒反應?

答: 由于安全因素android webview屏蔽了文件上傳控件,具體參考:?
https://www.oschina.net/question/23880_50205
安卓5.0及以上版本中,有修改,具體參考:
http://blog.csdn.net/u012912435/article/details/51484211
在在Android5.0及以上版本中使用WebView加載https資源文件時,
如果認證證書不被Android認可,那么會出現無法成功加載對應資源問題。
具體解決參考:
https://www.cnblogs.com/zhengshiqiang47/p/6220295.html

2、為何在H5頁面點擊創建問題無效?

答: H5頁面不能在PC瀏覽器環境下直接使用,需要在手機或手機模擬器環境下使用。

3、為何在加載H5頁面時候樣式丟失?

答: H5頁面所有資源URL為相對URL,請確認當前加載環境是否支持獲取該資源。

4、什么是atime?

答: atime 為時間戳,是指格林威治時間1970年01月01日00時00分00秒(北京時間1970年01月01日08時00分00秒)起至現在的總秒數;atime需實時獲取,前后15min有效。

5、為何在回調通知里面查不到相關參數?

答: 春雨發送第三方回調通知時采用POST方式,data為json格式,請確保接口符合要求。如果仍然未獲取到相關參數,建議增加request請求內容的完整打印消息來排查原因。

6、每次API接口 創建/追問 問題前都需要先請求賬號同步接口嗎?

答: 不需要,新用戶只要同步過一次即可。

7、H5不能直接返回到上級頁面嗎?

答: 由于H5是嵌入第三方APP的,所以返回欄需要由第三方來實現。

8、API付費款項是怎樣處理的?

答: 第三方需要先在春雨服務器創建付費問診記錄,然后引導用戶付費至第三方平臺,成功后通知春雨服務器更新訂單,后續問診交互同API免費問診一致。春雨公司定期與第三方公司結算相關款項。

9、接口返回"invalid_user"是為什么?

答: 首先 user_id 只可以包含大小寫字母與數字、下劃線的組合,其次在確認 user_id 符合格式時請檢查是否是由于構建的數據類型(content或者assess_info)格式錯誤,導致參數亂碼(可通過抓包的方式確認發出的數據是否正確)。

10、H5接入方式下,針對Android系統,填寫病情描述后不能點擊下一步的解決辦法?

答: 參考如下代碼進行解決
webSettings.setJavaScriptEnabled(true);
webSettings.setDomStorageEnabled(true);
// 前面倆個必須同時在
webView.setWebChromeClient(new MyWebChromeClient());
webSettings.setAllowFileAccess(true)

11、API對接眾包升級服務:可以使用哪些接口?。

答:請查看【開發文檔】中,【眾包升級服務】目錄下的所有接口,【通用接口】下的所有接口,和【第三方回調管理】的所有接口。