Hi,大家好,又到了連續假期了,總算可以脫離幾天上班的生活了XD,昨天我們完成了附件上傳的機制,使用 dataURL 的機制,傳完之後,當然就是要可以在畫面上看到附件了,今天就讓我們來完成這項功能吧。
在這裡我們要先進行檔案架構的說明,因為是非正式性的專案,我們的附件是先放在程式碼的存放位置,並以 caseID 做為資料夾名稱,格式為 png 檔,另外因為我們會進行自動縮圖,因此必需安裝好縮圖用的程式,安裝方式如下
取得附件的方式是直接去掃指定資料夾中的 png 檔,因為我們之前已經完成了抓取詳細資料的功能,我們這次只要針對該功能加入抓取附件清單的機制即可,修正之程式碼如下
/**
* 取得客服案件詳細資料
* @param {string} guid 客服紀錄編號
*/
getSingleCase: async (guid) => {
//擴充原先的取得詳細資料的功能,加入取出圖檔清單之機制
let data = await cases.findOne({
where: {
caseid: guid
},
include: [circuit, casefile]
});
let result = {}
if (data) {
data.dataValues.casestatus_desc = getStatusDesc(data.dataValues.casestatus)
result = data.dataValues
for (let i = 0; i < result.circuits.length; i++) {
let obj = result.circuits[i].dataValues
obj.status_desc = getStatusDesc(obj.status)
}
//搜尋資料夾中的檔案
result.casefiles = []
let files = fs.readdirSync(path.join(__dirname, guid))
for (let i = 0; i < files.length; i++) {
//排除掉非png檔與檔名為 xxx.png.png 之檔案
if (path.extname(files[i]) != ".png" || path.basename(files[i]).indexOf(".png.png") >= 0) {
continue;
}
let obj = {}
//將檔名轉為 base64格式,做為搜尋網址列參數與檔案之依據
obj.fileid = new Buffer.from(path.join(guid, files[i])).toString("base64")
//縮圖網址
obj.thomb = "/saf/thomb/" + obj.fileid
//全圖大小網址
obj.url = "/saf/viewpic/" + obj.fileid
result.casefiles.push(obj)
}
}
return result
},
說明:
接下來要配合剛剛訂定的縮圖網址與原圖網址製作對應的 router,打開 routers/saf.js 後,加入下列程式
/**
* 顯示原圖
*/
router.get("/viewpic/:guid", async (req, res, next) => {
try {
let guid = req.params.guid
let file = await casedao.showfile(guid, false)
res.setHeader("Content-Type", mime.getType(file.filename))
res.send(file.buf)
} catch(err) {
res.status(500).send(err.message || err)
}
})
/**
* 顯示縮圖
*/
router.get("/thomb/:guid", async (req, res, next) => {
try {
let guid = req.params.guid
let file = await casedao.showfile(guid, true)
res.setHeader("Content-Type", "image/png")
res.send(file.buf)
} catch(err) {
res.status(500).send(err.message || err)
}
})
接下來撰寫讀檔與縮圖功能,打開 casedao.js 後,加上讀圖與縮圖之機制,在這邊我們需要先安裝好縮圖用的套件
const im = require('imagemagick');
/**
* 產生縮圖
* @param {string} src
*/
async function createThomb(src) {
return new Promise((resolve, reject) => {
im.resize({
srcPath: src + "[0]",
dstPath: src + ".png",
width: 150
}, function (err, stdout, stderr) {
if (err) {
reject(err);
} else {
resolve();
}
});
})
}
/**
* 讀取圖檔
* @param {string} guid 檔嬣編號
* @param {boolean} isthomb 是否為縮圖
*/
showfile: async (guid, isthomb) => {
let src = new Buffer.from(guid, "base64").toString("utf-8")
src = path.join(__dirname, src)
let result = {}
result.filename = path.basename(src)
if (!isthomb) {
result.buf = fs.readFileSync(src)
} else {
let thombfile = src + ".png"
try {
fs.accessSync(thombfile)
} catch (err) {
await createThomb(src)
}
result.buf = fs.readFileSync(thombfile)
}
return result
},
說明:
接下來打開之前的詳細資料頁面「case.ejs」,加上圖檔顯示之功能,程式碼如下
<div id="app" class="container">
<h3>問題描述</h3>
<div class="row dr tr">
<div class="col-2 title txtr">問題名稱:</div>
<div class="col-10 info">{{data.cases.casedesc}}</div>
</div>
<div class="row dr">
<div class="col-2 title txtr">問題描述:</div>
<div class="col-10 info">{{data.cases.caseinfo}}</div>
</div>
<div class="row dr">
<div class="col-12 info tc" v-if="data.cases.casefiles.length >= 1">附件</div>
</div>
<div class="row dr info" v-if="data.cases.casefiles.length >= 1">
<div class="col-2 tc" style="margin-top: 10px; margin-bottom: 10px;"
v-for="(file, index) in data.cases.casefiles">
<label>附件 {{index + 1}}</label><br />
<a v-bind:href="file.url" target="_blank">
<img v-bind:src="file.thomb" />
</a>
</div>
</div>
<div class="row dr">
<div class="col-2 title txtr">聯絡人:</div>
<div class="col-6 info">{{data.cases.fromper}} <a
href="mailto://{{data.cases.frommail}}">{{data.cases.frommail}}</a></div>
<div class="col-2 title txtr">聯絡電話:</div>
<div class="col-2 info">{{data.cases.fromtel}}</div>
</div>
<div class="row dr">
<div class="col-2 title txtr">登錄時間:</div>
<div class="col-8 info">{{data.cases.logdate}}</div>
<div class="col-2" v-bind:class="[data.casestatus == '10'? 'info': 'inpcc']">{{data.cases.casestatus_desc}}</div>
</div>
<hr />
以下省略…
說明:
完成畫面
今天完成了檔案檢視的功能,為了方便使用者快速瀏覽,我們還加上了縮圖的機制,透過 imagemagick,除了一般圖檔,還可以做出 pdf 的縮圖,是一個很強大的軟體。目前完成了資料的登錄、附件的上傳、瀏覽,明天要處理的是處理流程的輸入與通知,那麼,我們明天再繼續吧