Node.js 切近实战(八) 之Excel在线(文件权限)
2019獨角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
最近美國又他媽的皮癢了,在南海找事,還說什么中國必須接受南海仲裁結(jié)果,我去你大爺?shù)?#xff0c;你以為你是誰啊。說實話只要我們要決一死戰(zhàn)的勇氣,還管什么華盛頓航母,佛吉尼亞潛艇,大不了大家一起死,不,全世界一起死。怎么個死法,中國惹急了先給俄羅斯來幾顆核彈,然后俄羅斯反擊中國的同時,也會給歐洲扔幾顆核彈,給美國扔很多核彈,然后歐洲英法會給其他國家扔核彈,美國給世界扔核彈,俄羅斯只給北冰洋扔就行了,中國給美國和太平洋扔就行了,這樣世界就不復(fù)存在了。
?
今天我們來看一下文件權(quán)限管理,這個其實是對共享出去的文件的一個簡單的權(quán)限管理demo。在上節(jié)我寫過的界面中,可以查詢自己共享出去的文件。
勾選Shared,我們查出自己共享出去的文件。或者我們可以通過點擊ToolBar上面的SHARE按鈕,實現(xiàn)共享文件。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | $(".k-grid-share",?"#file_list").bind("click",?function?(ev)?{ ????var?selIds?=?[]; ????$("#file_list?table:eq(1)").find("tr").each(function?()?{ ????????var?chkElement?=?$(this).children("td:first").find("input[type='checkbox']").first(); ????????if?(chkElement.prop('checked'))?{ ????????????selIds.push(chkElement.val()); ????????} ????}); ????? ????if?(selIds.length?==?0)?{ ????????showMsg('info',?'Please?select?at?least?one?file?to?share!'); ????????return; ????} ????? ????sharedUpdate(selIds,?true); }); |
首先是找到選中的文件的_id,然后調(diào)用shareUpdate方法去共享。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | function?sharedUpdate(selIds,?shared)?{ ????msg?=?Messenger().post({ ????????message:?"Do?you?want?to?"?+?(shared??'share':'unshare')?+?"?these?file?", ????????actions:?{ ????????????delete:?{ ????????????????label:?'Yes', ????????????????delay:?10, ????????????????action:?function?()?{ ????????????????????var?postData?=?{ ????????????????????????ids:?selIds, ????????????????????????isShared:?shared ????????????????????}; ????????????????????? ????????????????????$.ajax({ ????????????????????????url:?'/file/share',? ????????????????????????type:?'PUT',? ????????????????????????dataType:?'json', ????????????????????????data:?{?postData:?JSON.stringify(postData)?}, ????????????????????????success:?function?(res)?{ ????????????????????????????if?(!res.isSuc)?{ ????????????????????????????????showMsg('error',?res.msg); ????????????????????????????????return; ????????????????????????????} ????????????????????????????? ????????????????????????????getFilelist(selGroupId); ????????????????????????} ????????????????????}); ????????????????????msg.hide(); ????????????????} ????????????}, ????????????cancel:?{ ????????????????label:?"No", ????????????????action:?function?()?{ ????????????????????msg.hide(); ????????????????} ????????????} ????????} ????}); } |
發(fā)送一個ajax請求,去修改傳入文件的共享屬性,看一下效果
先會彈出確認(rèn),點擊Yes,調(diào)用api file/share去修改共享屬性,看一下后臺。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | router.put('/file/share',?fileRoutes.fileShare); exports.fileShare?=?function?(req,?res)?{ ????var?data?=?JSON.parse(req.body.postData); ????var?idArray?=?data.ids; ????? ????if?(!idArray?||?idArray?==?0)?{ ????????res.status(403).json(commonMsgRes.buildJsonErrorRes('NoRecord')); ????????return; ????} ????? ????fileModel.update({?_id:?{?$in:?idArray?}?},?{?$set:?{?isshared:?data.isShared?}?},?{?multi:?true?} ,?function?(error,?result)?{ ????????if?(error)?{ ????????????res.json({?isSuc:?false,?msg:?error.message?}); ????????} ????????else?{ ????????????res.json({?isSuc:?true?}); ????????} ????}); } |
在后臺,先把json字符串轉(zhuǎn)化成js對象,然后用mongoose提供的update方法去批量更新數(shù)據(jù)。注意這里的$in,其實是和sqlServer中的in一個意思,$set意思是需要修改的屬性,你可以在這里寫多個屬性進(jìn)行修改,并不一定只是一個isshared屬性,然后最后的multi:true,意思是更新多個doc。所以整個修改的意思就是找到_id在idArray中的file docs,然后將其isshared屬性全部修改為傳入的值。當(dāng)然在這里你也可以使用mongoose中的findAndUpdate方法去做批量更新。
?
文件share好之后,我們看一下共享文件權(quán)限設(shè)置界面。
?
查詢出數(shù)據(jù)后,每個文件都可以設(shè)置權(quán)限,這里很簡單的三個,要真做權(quán)限,還是買吉日嘎啦的走火入魔權(quán)限管理系統(tǒng)好了,自己不要瞎折騰。OK,那么這三個權(quán)限使我們mongodb數(shù)據(jù)庫中配置的。
?
我們在界面可以選擇一個或者多個。
選擇完成后,點擊Save,如果不想修改了,點擊cancel,可以回到初始狀態(tài),我們來看一下js代碼。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | $("#file_list").kendoGrid({ ????scrollable:?true, ????allowCopy:?true, ????resizable:?false, ????sortable:?true, ????height:?800, ????pageable:?{ ????????refresh:?true, ????????pageSizes:?[10,?20,?50,?100], ????????buttonCount:?5, ????},? ????toolbar:?[{?name:?'authSet',?text:?"Batch?Setup"?,?imageClass:?'k-icon?k-i-lock'?}], ????columns:?[{ ????????????template:?"<div?class='center-align-text'>"?+ ????????????????"<input?id='chkId_#=_id#'?type='checkbox'?class='k-checkbox'?value='#=_id#'?onclick='chkHeader_cl ????????????????+?"<label?class='k-checkbox-label'?for='chkId_#=_id#'></label></div>", ????????????field:?"", ????????????title:?"<div?class='center-align-text'>"?+ ????????????????"<input?type='checkbox'?class='k-checkbox'?id='chk_all'/>"? ????????????????+?"<label?class='k-checkbox-label'?for='chk_all'></label></div>", ????????????width:?45, ????????????sortable:?false ????????}, ????????{ ????????????field:?"fullname",? ????????????title:?"File?Name" ????????}, ????????{ ????????????field:?"isshared",? ????????????title:?"Shared"?, ????????????template:?'<select?id="ddl_auth#=_id#"?name="auth"?multiple="multiple"></select>', ????????????sortable:?false ????????},?{ ????????????command:?[ ????????????????{ ????????????????????name:?"authUpdate", ????????????????????text:?"Save", ????????????????????imageClass:?"k-icon?k-i-tick", ????????????????????click:?updateFileAuth ????????????????},?{ ????????????????????name:?"authCancel", ????????????????????text:?"Cancel", ????????????????????imageClass:?"k-icon?k-i-undo", ????????????????????click:?cancelUpdateFileAuth ????????????????} ????????????],? ????????????width:?230, ????????????title:?"Operation" ????????}],?dataBound:?function?(rowBoundEvent)?{ ????????$("#file_list?select[name='auth']").each(function?(index,?element)?{ ????????????$(element).kendoMultiSelect({ ????????????????valuePrimitive:?true, ????????????????placeholder:?"---Please?Select---", ????????????????ignoreCase:?true, ????????????????dataSource:?authArray.length?>?0??authArray:dataSource, ????????????????dataTextField:?"name", ????????????????dataValueField:?"_id", ????????????????headerTemplate:?'<div?class="multi-select-header">'? ????????????????????????????+?'Choose?File?Auth?Below:</div>', ????????????????dataBound:?function?(e)?{ ????????????????????var?dataItem?=?$("#file_list").data('kendoGrid').dataItem($(element).closest("tr")); ????????????????????if?(dataItem.auth?&&?dataItem.auth.length?>?0)?{ ????????????????????????var?authArray?=?[]; ????????????????????????dataItem.auth.forEach(function?(v)?{ ????????????????????????????authArray.push(v._id); ????????????????????????}); ????????????????????????? ????????????????????????this.value(authArray); ????????????????????} ????????????????????? ????????????????} ????????????}); ????????}); ????} }); |
大家注意isShared這一列,是個下拉列表,支持多選,然后在數(shù)據(jù)綁定完成以后,循環(huán)里面的下拉列表,將其渲染成kendoMultiSelect,注意這里的dataSource參數(shù),如果authArray已經(jīng)取到了,則使用,否則調(diào)用后臺api獲取。
| 1 2 3 4 5 6 7 8 | var?dataSource?=?new?kendo.data.DataSource({ ????transport:?{ ????????read:?{ ????????????url:?"/file/auth", ????????????dataType:?"json" ????????} ????} }); |
如果在這里直接使用每次請求的話,會存在很多問題,性能問題,界面渲染也會出現(xiàn)一些重復(fù)渲染的問題。因為大家的auth都是一樣的,所以我們先取到再說。
| 1 2 3 4 | var?authArray?=?[]; $.get('/file/auth',?function?(result)?{ ????authArray?=?result; }); |
OK,接下來我們看一下Save功能,在grid的定義中,我們可以看到save調(diào)用的是updateFileAuth方法。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | function?updateFileAuth(e)?{ ????var?dataItem?=?this.dataItem($(e.currentTarget).closest("tr")); ????var?fileId?=?dataItem._id; ????var?authArray?=?$("#ddl_auth"?+?dataItem._id).data("kendoMultiSelect").value() ????? ????if?(!authArray?||?authArray.length?==?0)?{ ????????showMsg('info',?'Please?select?at?least?one?auth!'); ????????return; ????} ????? ????var?postData?=?{ ????????fileId:?dataItem._id, ????????fileAuth:?authArray ????}; ????? ????$.post('/file/auth',?postData,?function?(res)?{ ????????if?(!res.isSuc)?{ ????????????showMsg('error',?res.msg); ????????????return; ????????} ????????? ????????showMsg('success',?'Saved?successfully!'); ????????$("#btn_searchShared").click(); ????}); } |
根據(jù)當(dāng)前行拿到id,再根據(jù)id拿到下拉選中的值,kendoMultiSelect的value方法返回的就是一個數(shù)組。
最后我們將得到的數(shù)組傳遞到api去修改權(quán)限,看一下后臺。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | router.post('/file/auth',?fileAuthRoutes.updateFileAuth); exports.updateFileAuth?=?function?(req,?res)?{ ????var?fileId?=?req.body.fileId; ????var?fileAuth?=?req.body.fileAuth; ????var?fileAuths?=?[]; ????? ????fileAuth.forEach(function?(v)?{ ????????fileAuths.push(mongoose.Types.ObjectId(v)); ????}); ????? ????fileModel.findByIdAndUpdate(fileId,?{?'$set':?{?auth:?fileAuths?}?} ????????,?function?(error,?doc)?{ ????????console.log(error); ????????if?(error)?{ ????????????res.json({?isSuc:?false,?msg:?error.message?}); ????????} ????????else?{ ????????????res.json({?isSuc:?true?}); ????????} ????}); } |
在這里我們先將權(quán)限的id轉(zhuǎn)化成ObjectId,再根據(jù)傳入的文件id進(jìn)行修改,ok,save就說完了。
再看一下cancel,其實就是將該行的權(quán)限id再賦給下拉列表。
| 1 2 3 4 5 6 7 8 9 10 11 | function?cancelUpdateFileAuth(e)?{ ????var?dataItem?=?this.dataItem($(e.currentTarget).closest("tr")); ????var?fileId?=?dataItem._id; ????var?authArray?=?[]; ????if?(dataItem?!=?null?&&?dataItem.auth.length?>?0)?{ ????????dataItem.auth.forEach(function?(v)?{ ????????????authArray.push(v._id); ????????}); ????} ????$("#ddl_auth"?+?dataItem._id).data("kendoMultiSelect").value(authArray); } |
ok,最后就是batch批量設(shè)置,勾選數(shù)據(jù),點擊ToolBar上的BATCH SETUP,我們先看頁面的代碼。
這里的fileAuth_Window就是批量設(shè)置界面,在這里大家發(fā)現(xiàn)了一個循環(huán)的寫法,不錯,這就是jade模板中的語法,類似于razor視圖引擎一樣。看到這樣的循環(huán),我們在后臺必須有代碼要給頁面這些值,類似于asp.NET?mvc中頁面綁定的Model。
| 1 2 3 | fileAuthSchemas.authModel.find({},?function?(error,?doc)?{ ????res.render('authorization/docauth',?{?authArray:?doc?}); }); |
看到了吧,在向客戶端輸出頁面時,同時傳了一個對象,對象中的authArray的值為doc。這樣的話,我們就可以在頁面直接使用這個變量authArray。
我們選擇三個,點擊SETUP,AJAX調(diào)用后臺api批量設(shè)置。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | $("#btn_setup").click(function?()?{ ????var?selAuthIdArray?=?getSelAuthId(); ????if?(selAuthIdArray.length?==?0)?{ ????????showMsg('info',?'Please?select?at?least?one?auth!'); ????????return; ????} ????? ????var?selIds?=?getSelFileId(); ????if?(selIds.length?==?0)?{ ????????showMsg('info',?'Please?select?at?least?one?file?to?setup!'); ????????return; ????} ????? ????showConfirm(updateFileAuthBatch); }); ? function?updateFileAuthBatch()?{ ????var?selIds?=?getSelFileId(); ????if?(selIds.length?==?0)?{ ????????showMsg('info',?'Please?select?at?least?one?file?to?setup!'); ????????return; ????} ????? ????var?postBody?=?{ ????????fileIdArray:?selIds, ????????fileAuth:?getSelAuthId() ????}; ????? ????$.post('/file/auth/batch',?postBody,?function?(result)?{ ????????if?(!result.isSuc)?{ ????????????showMsg('error',?result.msg); ????????????return; ????????} ? ????????fileAuthWindow.data("kendoWindow").close(); ????????$("#btn_searchShared").click(); ????}); } ? function?showConfirm(action)?{ ????msg?=?Messenger().post({ ????????message:?"Do?you?want?to?setup?", ????????actions:?{ ????????????save:?{ ????????????????label:?'Yes', ????????????????delay:?10, ????????????????action:?function?()?{ ????????????????????action(); ????????????????????msg.hide(); ????????????????} ????????????}, ????????????cancel:?{ ????????????????label:?"No", ????????????????action:?function?()?{ ????????????????????msg.hide(); ????????????????} ????????????} ????????} ????}); } |
上面這段代碼有沒有很像C#中的委托呢?有點。最后我們看一下后臺的批量設(shè)置api代碼。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | exports.batchUpdateFileAuth?=?function?(req,?res)?{ ????var?fileIdArray?=?req.body.fileIdArray; ????var?fileAuth?=?req.body.fileAuth; ????var?fileAuths?=?[]; ????? ????if?(!fileIdArray?||?fileIdArray.length?==?0)?{ ????????res.json(commonMsgRes.buildJsonErrorRes('NoRecord')); ????????return; ????} ????? ????fileAuth.forEach(function?(v)?{ ????????fileAuths.push(mongoose.Types.ObjectId(v)); ????}); ????? ????fileModel.update({?_id:?{?$in:?fileIdArray?}?},?{?$set:?{?auth:?fileAuths?}?},?{?multi:?true?} ????????,?function?(error,?doc)?{ ????????if?(error)?{ ????????????res.json({?isSuc:?false,?msg:?error.message?}); ????????} ????????else?{ ????????????res.json({?isSuc:?true?}); ????????} ????}); } |
這樣就設(shè)置成功了,我們來看一下效果。
?
好了,下節(jié)進(jìn)入我們的關(guān)鍵點,Excel在線保存,編輯。
?
結(jié)束語
?
免費學(xué)習(xí)更多精品課程,登錄樂搏學(xué)院官網(wǎng)http://h.learnbo.cn/
或關(guān)注我們的官方微博微信,還有更多驚喜哦~
?
本文出自 “技術(shù)創(chuàng)造價值” 博客,請務(wù)必保留此出處http://leelei.blog.51cto.com/856755/1812777
轉(zhuǎn)載于:https://my.oschina.net/learnbo/blog/776341
總結(jié)
以上是生活随笔為你收集整理的Node.js 切近实战(八) 之Excel在线(文件权限)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ASP.NET Core 中文文档 第四
- 下一篇: nginx的反向代理以及负载均衡模块的使