manage_list.tpl 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="utf-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1">
  7. <title>我的文章 - Powered by MinDoc</title>
  8. <!-- Bootstrap -->
  9. <link href="{{cdncss "/static/bootstrap/css/bootstrap.min.css"}}" rel="stylesheet" type="text/css">
  10. <link href="{{cdncss "/static/font-awesome/css/font-awesome.min.css"}}" rel="stylesheet" type="text/css">
  11. <link href="{{cdncss "/static/bootstrap/plugins/bootstrap-fileinput/4.4.7/css/fileinput.min.css"}}" rel="stylesheet" type="text/css">
  12. <link href="{{cdncss "/static/bootstrap/plugins/bootstrap-fileinput/4.4.7/themes/explorer-fa/theme.css"}}" rel="stylesheet" type="text/css">
  13. <link href="{{cdncss "/static/css/main.css"}}" rel="stylesheet">
  14. <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
  15. <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
  16. <!--[if lt IE 9]>
  17. <script src="/static/html5shiv/3.7.3/html5shiv.min.js"></script>
  18. <script src="/static/respond.js/1.4.2/respond.min.js"></script>
  19. <![endif]-->
  20. </head>
  21. <body>
  22. <div class="manual-reader">
  23. {{template "widgets/header.tpl" .}}
  24. <div class="container manual-body">
  25. <div class="row">
  26. <div class="page-left">
  27. <ul class="menu">
  28. <li {{if eq .ControllerName "BookController"}}class="active"{{end}}><a href="{{urlfor "BookController.Index"}}" class="item"><i class="fa fa-sitemap" aria-hidden="true"></i> 我的项目</a> </li>
  29. <li {{if eq .ControllerName "BlogController"}}class="active"{{end}}><a href="{{urlfor "BlogController.ManageList"}}" class="item"><i class="fa fa-file" aria-hidden="true"></i> 我的文章</a> </li>
  30. </ul>
  31. </div>
  32. <div class="page-right">
  33. <div class="m-box">
  34. <div class="box-head">
  35. <strong class="box-title">文章列表</strong>
  36. &nbsp;
  37. <button type="button" data-toggle="modal" data-target="#addBlogDialogModal" class="btn btn-success btn-sm pull-right">添加文章</button>
  38. </div>
  39. </div>
  40. <div class="box-body" id="bookList">
  41. <div class="book-list">
  42. <template v-if="lists.length <= 0">
  43. <div class="text-center">暂无数据</div>
  44. </template>
  45. <template v-else>
  46. <div class="list-item" v-for="item in lists">
  47. <div class="book-title">
  48. <div class="pull-left">
  49. <a :href="'{{.BaseUrl}}/book/' + item.identify + '/dashboard'" title="项目概要" data-toggle="tooltip">
  50. <template v-if="item.privately_owned == 0">
  51. <i class="fa fa-unlock" aria-hidden="true"></i>
  52. </template>
  53. <template v-else-if="item.privately_owned == 1">
  54. <i class="fa fa-lock" aria-hidden="true"></i>
  55. </template>
  56. ${item.book_name}
  57. </a>
  58. </div>
  59. <div class="pull-right">
  60. <div class="btn-group">
  61. <a :href="'{{.BaseUrl}}/book/' + item.identify + '/dashboard'" class="btn btn-default">设置</a>
  62. <a href="javascript:;" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
  63. <span class="caret"></span>
  64. <span class="sr-only">Toggle Dropdown</span>
  65. </a>
  66. <ul class="dropdown-menu">
  67. <li><a :href="'{{urlfor "DocumentController.Index" ":key" ""}}' + item.identify" target="_blank">阅读</a></li>
  68. <template v-if="item.role_id != 3">
  69. <li><a :href="'{{.BaseUrl}}/api/' + item.identify + '/edit'" target="_blank">编辑</a></li>
  70. </template>
  71. <template v-if="item.role_id == 0">
  72. <li><a :href="'javascript:deleteBook(\''+item.identify+'\');'">删除</a></li>
  73. <li><a :href="'javascript:copyBook(\''+item.identify+'\');'">复制</a></li>
  74. </template>
  75. </ul>
  76. </div>
  77. {{/*<a :href="'{{urlfor "DocumentController.Index" ":key" ""}}' + item.identify" title="查看文档" data-toggle="tooltip" target="_blank"><i class="fa fa-eye"></i> 查看文档</a>*/}}
  78. {{/*<template v-if="item.role_id != 3">*/}}
  79. {{/*<a :href="'/api/' + item.identify + '/edit'" title="编辑文档" data-toggle="tooltip" target="_blank"><i class="fa fa-edit" aria-hidden="true"></i> 编辑文档</a>*/}}
  80. {{/*</template>*/}}
  81. </div>
  82. <div class="clearfix"></div>
  83. </div>
  84. <div class="desc-text">
  85. <template v-if="item.description === ''">
  86. &nbsp;
  87. </template>
  88. <template v-else="">
  89. <a :href="'{{.BaseUrl}}/book/' + item.identify + '/dashboard'" title="项目概要" style="font-size: 12px;">
  90. ${item.description}
  91. </a>
  92. </template>
  93. </div>
  94. <div class="info">
  95. <span title="创建时间" data-toggle="tooltip" data-placement="bottom"><i class="fa fa-clock-o"></i>
  96. ${(new Date(item.create_time)).format("yyyy-MM-dd hh:mm:ss")}
  97. </span>
  98. <span title="创建者" data-toggle="tooltip" data-placement="bottom"><i class="fa fa-user"></i> ${item.create_name}</span>
  99. <span title="文档数量" data-toggle="tooltip" data-placement="bottom"><i class="fa fa-pie-chart"></i> ${item.doc_count}</span>
  100. <span title="项目角色" data-toggle="tooltip" data-placement="bottom"><i class="fa fa-user-secret"></i> ${item.role_name}</span>
  101. <template v-if="item.last_modify_text !== ''">
  102. <span title="最后编辑" data-toggle="tooltip" data-placement="bottom"><i class="fa fa-pencil"></i> 最后编辑: ${item.last_modify_text}</span>
  103. </template>
  104. </div>
  105. </div>
  106. </template>
  107. </div>
  108. <template v-if="lists.length >= 0">
  109. <nav class="pagination-container">
  110. {{.PageHtml}}
  111. </nav>
  112. </template>
  113. </div>
  114. </div>
  115. </div>
  116. </div>
  117. {{template "widgets/footer.tpl" .}}
  118. </div>
  119. <!-- Modal -->
  120. <div class="modal fade" id="addBlogDialogModal" tabindex="-1" role="dialog" aria-labelledby="addBlogDialogModalLabel">
  121. <div class="modal-dialog modal-lg" role="document" style="min-width: 900px;">
  122. <form method="post" autocomplete="off" action="{{urlfor "BookController.Create"}}" id="addBookDialogForm" enctype="multipart/form-data">
  123. <div class="modal-content">
  124. <div class="modal-header">
  125. <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
  126. <h4 class="modal-title" id="myModalLabel">添加文章</h4>
  127. </div>
  128. <div class="modal-body">
  129. <div class="form-group">
  130. <div class="pull-left">
  131. <div class="form-group">
  132. <input type="text" class="form-control" placeholder="标题(不超过100字)" name="book_name" id="bookName">
  133. </div>
  134. <div class="form-group">
  135. <div class="pull-left" style="padding: 7px 5px 6px 0">
  136. {{urlfor "DocumentController.Index" ":key" ""}}
  137. </div>
  138. <input type="text" class="form-control pull-left" style="width: 410px;vertical-align: middle" placeholder="项目唯一标识(不超过50字)" name="identify" id="identify">
  139. <div class="clearfix"></div>
  140. <p class="text" style="font-size: 12px;color: #999;margin-top: 6px;">文档标识只能包含小写字母、数字,以及“-”、“.”和“_”符号.</p>
  141. </div>
  142. <div class="form-group">
  143. <textarea name="description" id="description" class="form-control" placeholder="描述信息不超过500个字符" style="height: 90px;"></textarea>
  144. </div>
  145. <div class="form-group">
  146. <div class="col-lg-6">
  147. <label>
  148. <input type="radio" name="privately_owned" value="0" checked> 公开<span class="text">(任何人都可以访问)</span>
  149. </label>
  150. </div>
  151. <div class="col-lg-6">
  152. <label>
  153. <input type="radio" name="privately_owned" value="1"> 私有<span class="text">(只要参与者或使用令牌才能访问)</span>
  154. </label>
  155. </div>
  156. <div class="clearfix"></div>
  157. </div>
  158. </div>
  159. </div>
  160. <div class="clearfix"></div>
  161. </div>
  162. <div class="modal-footer">
  163. <span id="form-error-message"></span>
  164. <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
  165. <button type="button" class="btn btn-success" id="btnSaveDocument" data-loading-text="保存中...">保存</button>
  166. </div>
  167. </div>
  168. </form>
  169. </div>
  170. </div>
  171. <!--END Modal-->
  172. <!-- Delete Book Modal -->
  173. <div class="modal fade" id="deleteBookModal" tabindex="-1" role="dialog" aria-labelledby="deleteBookModalLabel">
  174. <div class="modal-dialog" role="document">
  175. <form method="post" id="deleteBookForm" action="{{urlfor "BookController.Delete"}}">
  176. <input type="hidden" name="identify" value="">
  177. <div class="modal-content">
  178. <div class="modal-header">
  179. <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
  180. <h4 class="modal-title">删除项目</h4>
  181. </div>
  182. <div class="modal-body">
  183. <span style="font-size: 14px;font-weight: 400;">确定删除项目吗?</span>
  184. <p></p>
  185. <p class="text error-message">删除项目后将无法找回。</p>
  186. </div>
  187. <div class="modal-footer">
  188. <span id="form-error-message2" class="error-message"></span>
  189. <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
  190. <button type="submit" id="btnDeleteBook" class="btn btn-primary" data-loading-text="删除中...">确定删除</button>
  191. </div>
  192. </div>
  193. </form>
  194. </div>
  195. </div>
  196. <script src="{{cdnjs "/static/jquery/1.12.4/jquery.min.js"}}" type="text/javascript"></script>
  197. <script src="{{cdnjs "/static/bootstrap/js/bootstrap.min.js"}}" type="text/javascript"></script>
  198. <script src="{{cdnjs "/static/vuejs/vue.min.js"}}" type="text/javascript"></script>
  199. <script src="{{cdnjs "/static/js/jquery.form.js"}}" type="text/javascript"></script>
  200. <script src="{{cdnjs "/static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/fileinput.min.js"}}"></script>
  201. <script src="{{cdnjs "/static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/zh.js"}}"></script>
  202. <script src="{{cdnjs "/static/layer/layer.js"}}" type="text/javascript" ></script>
  203. <script src="{{cdnjs "/static/js/main.js"}}" type="text/javascript"></script>
  204. <script type="text/javascript">
  205. /**
  206. * 绘制项目封面
  207. * @param $id
  208. * @param $font
  209. */
  210. function drawBookCover($id,$font) {
  211. var draw = document.getElementById($id);
  212. //确认浏览器是否支持<canvas>元素
  213. if (draw.getContext) {
  214. var context = draw.getContext('2d');
  215. //绘制红色矩形,绿色描边
  216. context.fillStyle = '#eee';
  217. context.strokeStyle = '#d4d4d5';
  218. context.strokeRect(0,0,170,230);
  219. context.fillRect(0,0,170,230);
  220. //设置字体样式
  221. context.font = "bold 20px SimSun";
  222. context.textAlign = "left";
  223. //设置字体填充颜色
  224. context.fillStyle = "#3E403E";
  225. var font = $font;
  226. var lineWidth = 0; //当前行的绘制的宽度
  227. var lastTextIndex = 0; //已经绘制上canvas最后的一个字符的下标
  228. var drawWidth = 155,lineHeight = 25,drawStartX = 15,drawStartY=65;
  229. //由于改变canvas 的高度会导致绘制的纹理被清空,所以,不预先绘制,先放入到一个数组当中
  230. var arr = [];
  231. for(var i = 0; i<font.length; i++){
  232. //获取当前的截取的字符串的宽度
  233. lineWidth = context.measureText(font.substr(lastTextIndex,i-lastTextIndex)).width;
  234. if(lineWidth > drawWidth){
  235. //判断最后一位是否是标点符号
  236. if(judgePunctuationMarks(font[i-1])){
  237. arr.push(font.substr(lastTextIndex,i-lastTextIndex));
  238. lastTextIndex = i;
  239. }else{
  240. arr.push(font.substr(lastTextIndex,i-lastTextIndex-1));
  241. lastTextIndex = i-1;
  242. }
  243. }
  244. //将最后多余的一部分添加到数组
  245. if(i === font.length - 1){
  246. arr.push(font.substr(lastTextIndex,i-lastTextIndex+1));
  247. }
  248. }
  249. for(var i =0; i<arr.length; i++){
  250. context.fillText(arr[i],drawStartX,drawStartY+i*lineHeight);
  251. }
  252. //判断是否是需要避开的标签符号
  253. function judgePunctuationMarks(value) {
  254. var arr = [".",",",";","?","!",":","\"",",","。","?","!",";",":","、"];
  255. for(var i = 0; i< arr.length; i++){
  256. if(value === arr[i]){
  257. return true;
  258. }
  259. }
  260. return false;
  261. }
  262. }else{
  263. console.log("浏览器不支持")
  264. }
  265. }
  266. /**
  267. * 将base64格式的图片转换为二进制
  268. * @param dataURI
  269. * @returns {Blob}
  270. */
  271. function dataURItoBlob(dataURI) {
  272. var byteString = atob(dataURI.split(',')[1]);
  273. var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
  274. var ab = new ArrayBuffer(byteString.length);
  275. var ia = new Uint8Array(ab);
  276. for (var i = 0; i < byteString.length; i++) {
  277. ia[i] = byteString.charCodeAt(i);
  278. }
  279. return new Blob([ab], {type: mimeString});
  280. }
  281. /**
  282. * 删除项目
  283. */
  284. function deleteBook($id) {
  285. $("#deleteBookModal").find("input[name='identify']").val($id);
  286. $("#deleteBookModal").modal("show");
  287. }
  288. function copyBook($id){
  289. var index = layer.load()
  290. $.ajax({
  291. url : "{{urlfor "BookController.Copy"}}" ,
  292. data : {"identify":$id},
  293. type : "POST",
  294. dataType : "json",
  295. success : function ($res) {
  296. layer.close(index);
  297. if ($res.errcode === 0) {
  298. window.app.lists.splice(0, 0, $res.data);
  299. $("#addBookDialogModal").modal("hide");
  300. } else {
  301. layer.msg($res.message);
  302. }
  303. },
  304. error : function () {
  305. layer.close(index);
  306. layer.msg('服务器异常');
  307. }
  308. });
  309. }
  310. $(function () {
  311. $("#addBookDialogModal").on("show.bs.modal",function () {
  312. window.bookDialogModal = $(this).find("#addBookDialogForm").html();
  313. drawBookCover("bookCover","默认封面");
  314. }).on("hidden.bs.modal",function () {
  315. $(this).find("#addBookDialogForm").html(window.bookDialogModal);
  316. });
  317. /**
  318. * 创建项目
  319. */
  320. $("body").on("click","#btnSaveDocument",function () {
  321. var $this = $(this);
  322. var bookName = $.trim($("#bookName").val());
  323. if (bookName === "") {
  324. return showError("项目标题不能为空")
  325. }
  326. if (bookName.length > 100) {
  327. return showError("项目标题必须小于100字符");
  328. }
  329. var identify = $.trim($("#identify").val());
  330. if (identify === "") {
  331. return showError("项目标识不能为空");
  332. }
  333. if (identify.length > 50) {
  334. return showError("项目标识必须小于50字符");
  335. }
  336. var description = $.trim($("#description").val());
  337. if (description.length > 500) {
  338. return showError("描述信息不超过500个字符");
  339. }
  340. $this.button("loading");
  341. var draw = document.getElementById("bookCover");
  342. var form = document.getElementById("addBookDialogForm");
  343. var fd = new FormData(form);
  344. if (draw.getContext) {
  345. var dataURL = draw.toDataURL("png", 100);
  346. var blob = dataURItoBlob(dataURL);
  347. fd.append('image-file', blob,(new Date()).valueOf() + ".png");
  348. }
  349. $.ajax({
  350. url : "{{urlfor "BookController.Create"}}",
  351. data: fd,
  352. type: "POST",
  353. dataType :"json",
  354. processData: false,
  355. contentType: false
  356. }).success(function (res) {
  357. $this.button("reset");
  358. if (res.errcode === 0) {
  359. window.app.lists.splice(0, 0, res.data);
  360. $("#addBookDialogModal").modal("hide");
  361. } else {
  362. showError(res.message);
  363. }
  364. $this.button("reset");
  365. }).error(function () {
  366. $this.button("reset");
  367. return showError("服务器异常");
  368. });
  369. return false;
  370. });
  371. /**
  372. * 当填写项目标题后,绘制项目封面
  373. */
  374. $("#bookName").on("blur",function () {
  375. var txt = $(this).val();
  376. if(txt !== ""){
  377. drawBookCover("bookCover",txt);
  378. }
  379. });
  380. /**
  381. * 删除项目
  382. */
  383. $("#deleteBookForm").ajaxForm({
  384. beforeSubmit : function () {
  385. $("#btnDeleteBook").button("loading");
  386. },
  387. success : function (res) {
  388. if(res.errcode === 0){
  389. window.location = window.location.href;
  390. }else{
  391. showError(res.message,"#form-error-message2");
  392. }
  393. $("#btnDeleteBook").button("reset");
  394. },
  395. error : function () {
  396. showError("服务器异常","#form-error-message2");
  397. $("#btnDeleteBook").button("reset");
  398. }
  399. });
  400. $("#btnImportBook").on("click",function () {
  401. var $this = $(this);
  402. var $then = $(this).parents("#importBookDialogForm");
  403. var bookName = $.trim($then.find("input[name='book_name']").val());
  404. if (bookName === "") {
  405. return showError("项目标题不能为空","#import-book-form-error-message");
  406. }
  407. if (bookName.length > 100) {
  408. return showError("项目标题必须小于100字符","#import-book-form-error-message");
  409. }
  410. var identify = $.trim($then.find("input[name='identify']").val());
  411. if (identify === "") {
  412. return showError("项目标识不能为空","#import-book-form-error-message");
  413. }
  414. var description = $.trim($then.find('textarea[name="description"]').val());
  415. if (description.length > 500) {
  416. return showError("描述信息不超过500个字符","#import-book-form-error-message");
  417. }
  418. var filesCount = $('#import-book-upload').fileinput('getFilesCount');
  419. console.log(filesCount)
  420. if (filesCount <= 0) {
  421. return showError("请选择需要上传的文件","#import-book-form-error-message");
  422. }
  423. //$("#importBookDialogForm").submit();
  424. $("#btnImportBook").button("loading");
  425. $('#import-book-upload').fileinput('upload');
  426. });
  427. window.app = new Vue({
  428. el : "#bookList",
  429. data : {
  430. lists : {{.Result}}
  431. },
  432. delimiters : ['${','}'],
  433. methods : {
  434. }
  435. });
  436. Vue.nextTick(function () {
  437. $("[data-toggle='tooltip']").tooltip();
  438. });
  439. $("#import-book-upload").fileinput({
  440. 'uploadUrl':"{{urlfor "BookController.Import"}}",
  441. 'theme': 'fa',
  442. 'showPreview': false,
  443. 'showUpload' : false,
  444. 'required': true,
  445. 'validateInitialCount': true,
  446. "language" : "zh",
  447. 'allowedFileExtensions': ['zip'],
  448. 'msgPlaceholder' : '请选择Zip文件',
  449. 'elErrorContainer' : "#import-book-form-error-message",
  450. 'uploadExtraData' : function () {
  451. var book = {};
  452. var $then = $("#importBookDialogForm");
  453. book.book_name = $then.find("input[name='book_name']").val();
  454. book.identify = $then.find("input[name='identify']").val();
  455. book.description = $then.find('textarea[name="description"]').val()
  456. return book;
  457. }
  458. });
  459. $("#import-book-upload").on("fileuploaded",function (event, data, previewId, index){
  460. if(data.response.errcode === 0 || data.response.errcode === '0'){
  461. showSuccess(data.response.message,"#import-book-form-error-message");
  462. }else{
  463. showError(data.response.message,"#import-book-form-error-message");
  464. }
  465. $("#btnImportBook").button("reset");
  466. return true;
  467. });
  468. });
  469. </script>
  470. </body>
  471. </html>