MaiXinRong 5 месяцев назад
Родитель
Сommit
fd422ee5a1
5 измененных файлов с 198 добавлено и 2 удалено
  1. 11 0
      app/controller/file_controller.js
  2. 135 1
      app/public/js/file_detail.js
  3. 1 0
      app/router.js
  4. 22 0
      app/service/file.js
  5. 29 1
      app/view/file/file_modal.ejs

+ 11 - 0
app/controller/file_controller.js

@@ -242,6 +242,17 @@ module.exports = app => {
                 ctx.ajaxErrorBody(error, '编辑附件失败');
             }
         }
+        async moveFile(ctx) {
+            try {
+                const data = JSON.parse(ctx.request.body.data);
+                if (!data.id || !data.filingId) throw '缺少参数';
+                const result = await ctx.service.file.moveFile(data.id, data.filingId);
+                ctx.body = { err: 0, msg: '', data: result };
+            } catch (error) {
+                this.log(error);
+                ctx.ajaxErrorBody(error, '编辑附件失败');
+            }
+        }
         async uploadBigFile(ctx) {
             try {
                 await this.checkCanUpload(ctx);

+ 135 - 1
app/public/js/file_detail.js

@@ -91,11 +91,12 @@ $(document).ready(function() {
             this.loadFiling();
         }
         _getFileNameHtml(file) {
+            const moveHtml = file.canEdit ? `<a href="javascript: void(0);" class="mr-1" name="move-file" fid="${file.id}"><i class="fa fa-exchange fa-fw"></i></a>` : '';
             const editHtml = file.canEdit ? `<a href="javascript: void(0);" class="mr-1" name="edit-file" fid="${file.id}"><i class="fa fa-pencil fa-fw"></i></a>` : '';
             const viewHtml = file.viewpath ? `<a href="${file.viewpath}" class="mr-1" target="_blank"><i class="fa fa-eye fa-fw"></i></a>` : '';
             const downHtml = `<a href="javascript: void(0);" onclick="AliOss.downloadFile('${file.filepath}', '${file.filename + file.fileext}')" class="mr-1"><i class="fa fa-download fa-fw"></i></a>`;
             const delHtml = file.canEdit ? `<a href="javascript: void(0);" class="mr-1 text-danger" name="del-file" fid="${file.id}"><i class="fa fa-trash-o fa-fw"></i></a>` : '';
-            return `<div class="d-flex justify-content-between align-items-center table-file"><div name="filename" fid="${file.id}">${file.filename}${file.fileext}</div><div class="btn-group-table" style="display: none;">${editHtml}${viewHtml}${downHtml}${delHtml}</div></div>`;
+            return `<div class="d-flex justify-content-between align-items-center table-file"><div name="filename" fid="${file.id}">${file.filename}${file.fileext}</div><div class="btn-group-table" style="display: none;">${moveHtml}${editHtml}${viewHtml}${downHtml}${delHtml}</div></div>`;
         }
         _getEditFileNameHtml(file) {
             const inputHtml = `<input type="text" class="form-control form-control-sm form-control-width" maxlength="100" value="${file.filename + file.fileext}" fid="${file.id}">`;
@@ -330,6 +331,26 @@ $(document).ready(function() {
                 if (callback) callback();
             });
         }
+        moveFile(file, filingId, callback) {
+            if (file.filing_id === filingId) {
+                callback();
+                return;
+            }
+            postData('file/move', { id: file.id, filingId: filingId }, function(data) {
+                const orgFiling = filingObj.findFiling(file.filing_id);
+                filingObj.updateFilingFileCount(orgFiling, orgFiling.source_node.file_count - 1);
+                const fIndex = orgFiling.source_node.files.findIndex(x => { return x.id === file.id });
+                if (fIndex >= 0) orgFiling.source_node.files.splice(fIndex, 1);
+                const targetFiling = filingObj.findFiling(filingId);
+                filingObj.updateFilingFileCount(targetFiling, targetFiling.source_node.file_count + 1);
+                if (file.filing_id === filingObj.curFiling.source_node.id) {
+                    filingObj.refreshPages();
+                    filingObj.refreshFilesTable();
+                }
+                fileSearch.refreshSearchFile(data.file);
+                callback();
+            });
+        }
         async setCurFiling(node) {
             filingObj.curFiling = node;
             filingObj.curPage = 1;
@@ -726,6 +747,110 @@ $(document).ready(function() {
 
         td.html(filingObj._getFileNameHtml(file));
     });
+    class MoveFileObj {
+        constructor() {
+            const self = this;
+            this.setting = {
+                treeId: 'moveTree',
+                view: {
+                    selectedMulti: false,
+                    showTitle: true,
+                },
+                data: {
+                    simpleData: {
+                        idKey: 'id',
+                        pIdKey: 'tree_pid',
+                        rootPId: '-1',
+                        enable: true,
+                    },
+                    key: { title: 'tips' },
+                },
+                edit: {
+                    enable: false,
+                },
+            };
+            this.moveTree = null;
+            $('#move-file2-ok').click(function() {
+                const targetFiling = self.moveTree.getSelectedNodes()[0];
+                if (!targetFiling) {
+                    toastr.warning('请选择目标分类');
+                    return;
+                }
+                if (targetFiling.children && targetFiling.children.length > 0) {
+                    toastr.warning('请选择最底层目标分类');
+                    return;
+                }
+                filingObj.moveFile(self.file, targetFiling.id, function() {
+                    $('#move-file2').modal('hide');
+                });
+            });
+            // 显示层次
+            (function (select) {
+                $(select).click(function () {
+                    const tag = $(this).attr('tag');
+                    setTimeout(() => {
+                        showWaitingView();
+                        switch (tag) {
+                            case "1":
+                            case "2":
+                            case "3":
+                            case "4":
+                                self.expandByLevel(parseInt(tag));
+                                break;
+                            case "last":
+                                self.expandByCustom(() => { return true; });
+                                break;
+                        }
+                        closeWaitingView();
+                    }, 100);
+                });
+            })('a[name=mf2-showLevel]');
+        }
+        expandByLevel(level) {
+            this.expandByCustom(x => {
+                return x.level + 1 < level;
+            })
+        }
+        expandByCustom(fun) {
+            const self = this;
+            const expandChildren = function(children) {
+                for (const child of children) {
+                    if (!child.children || child.children.length === 0) continue;
+                    const expand = fun(child);
+                    self.moveTree.expandNode(child, expand, false, false);
+                    expandChildren(child.children);
+                }
+            };
+            const nodes = this.moveTree.getNodes();
+            expandChildren(nodes);
+        }
+        initMoveTree() {
+            if (this.moveTree) $.fn.zTree.destroy(this.setting.treeId);
+            const sortNodes = filingObj.dragTree.nodes.map(x => {
+                const result = {
+                    id: x.id,
+                    tree_pid: x.tree_pid,
+                    name: x.name,
+                    spid: x.spid,
+                    tips: x.tips || '',
+                };
+                if (x.is_fixed) result.isParent = true;
+                return result;
+            });
+            this.moveTree = $.fn.zTree.init($('#moveFile'), this.setting, sortNodes);
+        }
+        show (file) {
+            this.file = file;
+            this.initMoveTree();
+            $('#move-file2').modal('show');
+        }
+    }
+    const moveFileObj = new MoveFileObj();
+    $('body').on('click', "a[name=move-file]", function() {
+        const id = this.getAttribute('fid');
+        const file = filingObj.curFiling.source_node.files.find(x => { return x.id === id });
+        moveFileObj.show(file);
+    });
     // $('body').on('blur', "[name=filename] input[fid]", function() {
     //     filingObj.renameFile(this.getAttribute('fid'), this.value);
     // });
@@ -1325,6 +1450,15 @@ $(document).ready(function() {
                 $('#search-list').html(fileSearch.getResultHtml(result.list));
             });
         }
+        refreshSearchFile(file) {
+            const sfile = this.searchResult.find(x => { return x.id === file.id; });
+            if (sfile) {
+                for (const prop in file) {
+                    if (prop === 'id') continue;
+                    sfile[prop] = file[prop];
+                }
+            }
+        }
         removeSearchFile(fid){
             $(`tr[fid=search_${fid}]`, '#search').remove();
             const index = this.searchResult.findIndex(x => { return x.id === fid; });

+ 1 - 0
app/router.js

@@ -911,6 +911,7 @@ module.exports = app => {
     app.post('/sp/:id/file/upload/big', sessionAuth, subProjectCheck, 'fileController.uploadBigFile');
     app.post('/sp/:id/file/del', sessionAuth, subProjectCheck, 'fileController.delFile');
     app.post('/sp/:id/file/save', sessionAuth, subProjectCheck, 'fileController.saveFile');
+    app.post('/sp/:id/file/move', sessionAuth, subProjectCheck, 'fileController.moveFile');
     app.post('/sp/:id/file/rela', sessionAuth, subProjectCheck, 'fileController.relaFile');
     app.post('/sp/:id/file/rela/tender', sessionAuth, subProjectCheck, 'fileController.loadValidRelaTender');
     app.post('/sp/:id/file/rela/files', sessionAuth, subProjectCheck, 'fileController.loadRelaFiles');

+ 22 - 0
app/service/file.js

@@ -135,6 +135,28 @@ module.exports = app => {
             return updateData;
         }
 
+        async moveFile(id, filing_id) {
+            const file = await this.getDataById(id);
+            if (!file) throw '文件不存在';
+            if (file.user_id !== this.ctx.session.sessionUser.accountId) throw '您无权编辑该文件';
+            const orgFiling = await this.ctx.service.filing.getDataById(file.filing_id);
+            const filing = await this.ctx.service.filing.getDataById(filing_id);
+            if (!filing) throw '目标分类不存在';
+
+            const conn = await this.db.beginTransaction();
+            try {
+                const updateFile = { id: file.id, filing_type: filing.filing_type, filing_id: filing.id };
+                await conn.update(this.tableName, updateFile);
+                const updateFiling = [{id: orgFiling.id, file_count: orgFiling.file_count - 1}, {id: filing.id, file_count: filing.file_count + 1}];
+                await conn.updateRows(this.ctx.service.filing.tableName, updateFiling);
+                await conn.commit();
+                return {file: updateFile, filing: updateFiling};
+            } catch(err) {
+                await conn.rollback();
+                throw err;
+            }
+        }
+
         async search(filing_type, keyword, limit = 1000) {
             if (!filing_type || filing_type.length === 0 || !keyword) return [];
             const sql = `SELECT * FROM ${this.tableName}` +

+ 29 - 1
app/view/file/file_modal.ejs

@@ -203,4 +203,32 @@
         </div>
     </div>
 </div>
-<% } %>
+<% } %>
+<div class="modal fade" id="move-file2" data-backdrop="static">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">选择分类</h5>
+            </div>
+            <div class="modal-body">
+                <div class="btn-group">
+                    <button type="button" class="btn btn-sm  text-primary dropdown-toggle" data-toggle="dropdown" id="mf2-zhankai" aria-expanded="false">显示层级</button>
+                    <div class="dropdown-menu" aria-labelledby="mf2-zhankai" x-placement="bottom-start" style="position: absolute; transform: translate3d(0px, 21px, 0px); top: 0px; left: 0px; will-change: transform;">
+                        <a class="dropdown-item" name="mf2-showLevel" tag="1" href="javascript: void(0);">第一层</a>
+                        <a class="dropdown-item" name="mf2-showLevel" tag="2" href="javascript: void(0);">第二层</a>
+                        <a class="dropdown-item" name="mf2-showLevel" tag="3" href="javascript: void(0);">第三层</a>
+                        <a class="dropdown-item" name="mf2-showLevel" tag="4" href="javascript: void(0);">第四层</a>
+                        <a class="dropdown-item" name="mf2-showLevel" tag="last" href="javascript: void(0);">最底层</a>
+                    </div>
+                </div>
+                <div class="modal-height-300">
+                    <ul id="moveFile" class="ztree"></ul>
+                </div>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary btn-sm" data-dismiss="modal">关闭</button>
+                <button type="button" class="btn btn-primary btn-sm" id="move-file2-ok">确定添加</button>
+            </div>
+        </div>
+    </div>
+</div>