BtoBtoC(BtoBtoBでも可)向けのアプリの場合、そのアプリを提供している会社向けに管理画面を提供したいと考えることがあります。その管理画面では、利用企業が自分たちのデータについてだけメンテナンスできるようになります。
そのための管理画面を作成していきます。今回は前回のベースを踏まえて、画像アップロード処理を作っていきます。
ファイルデータにはフィールドの追加ができません
これまで契約企業ごとにフィールドでデータの区別をしていましたが、ファイルストアでは追加のフィールド設定ができません。そこで、ファイル名に特徴を持たせることにします。
// AAA社のファイル AAA_001.png // BBB社のファイル BBB_002.jpg
といった具合に契約企業のロール名をプリフィックスに付けることにします。そして、ファイルの一覧を取得する際には次のように正規表現を使います。
ncmb.File .where({'fileName': {"$regex": `${user.Company}_.*`}}) .fetchAll() .then(files => { res.render('files/index', {user: user, files: files}); })
なお、公式SDKの中で正規表現検索をサポートしているのは執筆時点ではJavaScript SDKのみになります。
HTTPSによるファイル公開設定を有効にする
今回は写真をアップロードする前提とし、アップロードされたデータは一覧画面で内容が確認できるようにします。そのため、ファイルストアの設定でHTTPSによるファイル公開を有効にします。これを有効にすると、次のようなURLでコンテンツが取得できます。
https://mb.api.cloud.nifty.com/2013-09-01/applications/APPLICATION_ID/publicFiles/FILE_NAME
このAPPLICATION_IDはアプリケーションごとに異なるものになります。そこで config.jsonの中に設定を書いておきます。
{ "application_key": "YOUR_APPLICATION_KEY", "client_key": "YOUR_CLIENT_KEY", "secret": "yoursecret", "application_id": "YOUR_APPLICATION_ID" }
ログイン後のページからリンク追加
views/index.jade にファイルアップロード画面へのリンクを追加します。パスは /files とします。
p a.btn.btn-info(href='/files') ファイルアップロード
ファイルアップロード画面の作成
ファイルアップロード画面は views/files/index.jade として作成します。画像のURLについては若干複雑なものになります。
extends ../layout block content h1 ファイル管理 form(action='/files',method='post',enctype='multipart/form-data') div.form-group label(for='inputAppName') ファイルを指定 input.form-control(type='file',name='photo') button.btn.btn-default(type='submit') 登録 - for (i in files) { - var file = files[i]; p div.row div.col-xs-9.col-md-offset-3 img.img-rounded(width='100%',src='https://mb.api.cloud.nifty.com/2013-09-01/applications/'+config.application_id+'/publicFiles/'+file.fileName) - }
ファイルハンドリング機能の追加
デフォルトのExpressではファイルハンドリング機能がありません。そこで、express-fileuploadをインストールします。
npm install --save express-fileupload
使い方としては app.js に次のように追記します。
const fileUpload = require('express-fileupload'); app.use(fileUpload());
これで req.filesでアップロードされるファイルの内容が扱えるようになります。
ファイルアップロード処理の作成
ではファイルアップロード処理を作ります。全体の概要は次の通りです。
let express = require('express'); let router = express.Router(); let config = require('../config'); let ncmb = require('../libs/ncmb'); let user = null; // 認証済みかチェック router.all('*', (req, res, next) => { user = req.session.user || null; if (!user) { return res.redirect('/'); }else{ ncmb.sessionToken = user.sessionToken; next(); } }); // 画面表示 router.get('/', (req, res, next) => { }); // ファイルをアップロードする router.post('/', (req, res, next) => { }); module.exports = router;
画面表示
画面表示の際にはファイルストアを検索し、データがあれば表示に使います。この時、前述のように正規表現でファイル名を絞り込みます。
// 画面表示 router.get('/', (req, res, next) => { ncmb.File .where({'fileName': {"$regex": `${user.Company}_.*`}}) .fetchAll() .then(files => { res.render('files/index', {user: user, files: files, config: config}); }) });
画像表示用のアプリケーションIDを格納した config を一緒に渡していることに注意してください。
ファイルアップロード処理
ファイルアップロード処理はとても簡単です。req.filesにファイルデータが入ってきますのでそれを使います。また、ACLを適切にセットし、アップロード時に適用します。ファイル名は前述の通り、ロール名をプリフィックスとして適用します。
// ファイルをアップロードする router.post('/', (req, res, next) => { let acl = new ncmb.Acl; acl.setRoleWriteAccess(user.Company, true) .setRoleWriteAccess('Admin', true) .setPublicReadAccess(true); ncmb.File.upload(`${user.Company}_${req.files.photo.name}`, req.files.photo.data, acl) .then(file => { res.redirect('/files'); }) .catch(error => { res.status(401).render('error', {error: error}); }) });
masters.jsをapp.jsに登録
最後にルーティング情報をapp.jsに追加します。
var files = require('./routes/files'); app.use('/files', files);
ここまでの処理でファイルをアップロードする機能ができあがりました。ファイルを選択してアップロードすると、一覧に表示されるのが確認できるはずです。
今回までのコードはNCMBMania/BtoB_Management at v0.4にて確認できます。実装時の参考にしてください。