前戲
上一周是我到現(xiàn)公司來最忙碌的(最有意思的)一周了备恤,為什么這么說呢诬烹?因?yàn)轫?xiàng)目中需要提供服務(wù)端對(duì)用戶病人信息的一個(gè)匯總并以email的形式分享信息的接口溪胶,在幾天的時(shí)間里調(diào)研處理一套實(shí)施方案阔拳。我們服務(wù)端是Node.js實(shí)現(xiàn)的(其中的npm中有很多豐富的第三方庫來解放你重新造輪子的尷尬)
配方
pug
->html-pdf
->pdf2png
->s3
->sendgrid
pug 中在phantom中字體無效的解決方案
在開發(fā)pug時(shí)遇到一個(gè)比較棘手的問題壶唤,設(shè)計(jì)定的字體在瀏覽器上是有效果的嘁傀,但是通過Phantom.js(服務(wù)器端的 JavaScript API 的 WebKit)進(jìn)行網(wǎng)頁截圖時(shí),字體卻都使用了默認(rèn)字體视粮,后來只有通過自定義字體文件才解決這個(gè)問題。
style.
@font-face {
font-family: CustomFont;
src: url('./views/fonts/HelveticaNeue.otf');
}
.gender {
display: inline;
color: rgb(102, 102, 102);
font-family: CustomFont;
}
嗯橙凳,模板文件算是搞定了蕾殴,接下來就是具體代碼的實(shí)現(xiàn)了笑撞。
準(zhǔn)備數(shù)據(jù)材料
要做某件事情肯定都會(huì)先把需要的材料先搞到手把!(感覺編程和現(xiàn)實(shí)生活中解決問題的思路很多都是想通的)
我是受到某人的啟發(fā)說通過一個(gè)匯總鏈表查詢钓觉,把N張表的數(shù)據(jù)都通過一個(gè)查詢搞出來茴肥,最后把它變成View,也方便服務(wù)端的開發(fā)荡灾,我這么一聽感覺是很有道理啊瓤狐,那就做吧(我感覺我執(zhí)行力好強(qiáng)?)
在我們的系統(tǒng)有些表的設(shè)置是字段可以方便增加字段類型,但在查詢時(shí)就必須要考慮行轉(zhuǎn)列批幌,或是列轉(zhuǎn)行(這在我之前都是未知領(lǐng)域)
select patient_id, max(IF(contact_type = 'email',value,null)) as 'email', max(IF(contact_type = 'address',value,null)) as 'address', group_concat(case when contact_type='mobile' then contacts.value end) as 'mobiles'
from contacts where contacts.is_deleted = 0 group by patient_id
max(IF(contact_type = 'email',value,null) 可以將列中符合contact_type='email' 的提出來單獨(dú)作為一列础锐;group_concat(case when contact_type='mobile' then contacts.value end) 則可以將多個(gè)類型的通過拼接放在一個(gè)單元格中。不過最后遇到一個(gè)問題荧缘,就是無法將多個(gè)mobile很好的區(qū)分出來皆警。所以只好老實(shí)的在Node.js中分批的查詢其中的數(shù)據(jù)。放一張截圖截粗,肯定能體會(huì)出我心中N多的XX馬(留意下文件名)
分批次取數(shù)據(jù)
先講解下前提信姓,customDiagnoses和patientDiagnoses表是1->N的關(guān)系。
const customDiagnoses = await Promise.all(
patientDiagnoses.map(item =>
CustomDiagnosis.findById(item.sourceId)
)
)
Promise.all()是需要等待其中的所有的方法都完全處理完后再執(zhí)行后面的語句
這里可以補(bǔ)充一個(gè)《如何把一個(gè)異步的方法搞成一個(gè)看似同步的方法》
static async exportPDF(html, options, filePath) {
const promise = new Promise((reslove, reject) => {
const callback = (err, res) => {
if (err) {
reject(err)
return
}
reslove(res)
}
pdf.create(html, options).toFile(filePath, callback)
})
return promise
}
Promise顧名思義就是當(dāng)你達(dá)成某種成就了绸罗,我就會(huì)幫你干某件事意推。
寫一個(gè)Promise最有變化就是對(duì)callback的處理,其他的基本都跟這個(gè)差不多珊蟀,使用Promise也很簡單菊值,直接在調(diào)用的地方前面加上一個(gè)await即可。
有人會(huì)問了為什么要寫Promise跋德濉俊性?Node.js 不是都是有callback的嗎?干嘛還要我多次一舉描扯?
起始也不完全都要把異步方法用Promise封裝起來定页,但是if 你的一個(gè)方法中有N個(gè)異步的 && 根據(jù)上一個(gè)方法的結(jié)果來干下一件事 {
那么你的代碼就會(huì)變成一個(gè)階梯狀,一層嵌套一層绽诚,不移維護(hù)也不易閱讀
}
最后附上典徊,我心情勞動(dòng)后,上天也被感動(dòng)恩够,給力我一個(gè)超可愛的喵星人卒落,也要感謝在開發(fā)過程支持和幫助我的某某人!7渫啊儡毕!
下部預(yù)告,《測試達(dá)人帶飛,讓你裝逼讓你吹》