Browse Source

资料归集入口

MaiXinRong 2 years ago
parent
commit
35a81d9688

+ 37 - 0
app/controller/file_controller.js

@@ -0,0 +1,37 @@
+'use strict';
+
+/**
+ *
+ *
+ * @author Mai
+ * @date 2021/10/27
+ * @version
+ */
+const auditConst = require('../const/audit');
+module.exports = app => {
+    class BudgetController extends app.BaseController {
+
+        /**
+         * 概算投资
+         *
+         * @param ctx
+         * @returns {Promise<void>}
+         */
+        async index(ctx) {
+            try {
+                const renderData = {
+                    jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.file.index),
+                    auditConst,
+                };
+                renderData.projectList = await ctx.service.subProject.getFileProject(ctx.session.sessionProject.id, ctx.session.sessionUser.accountId, ctx.session.sessionUser.is_admin);
+                renderData.tenderList = await ctx.service.tender.getList4Select('stage');
+                renderData.categoryData = await this.ctx.service.category.getAllCategory(this.ctx.session.sessionProject.id);
+                await this.layout('file/index.ejs', renderData, 'file/modal.ejs');
+            } catch (err) {
+                ctx.log(err);
+            }
+        }
+    }
+
+    return BudgetController;
+};

+ 181 - 0
app/public/js/file.js

@@ -0,0 +1,181 @@
+'use strict';
+
+/**
+ *
+ *
+ * @author Mai
+ * @date
+ * @version
+ */
+let curProject = {};
+
+const showModal = function (obj) {
+    const tr = obj.parentNode.parentNode;
+    curProject.id = tr.getAttribute('tree_id');
+    curProject.name = tr.getAttribute('pname');
+    curProject.rela_tender = tr.getAttribute('rela-tender');
+    $(obj.getAttribute('data-target')).modal('show');
+};
+
+$(document).ready(() => {
+    autoFlashHeight();
+    const projectTreeObj = (function(setting){
+        const projectTree = createDragTree(setting.treeSetting);
+        projectTree.loadDatas(setting.source);
+        const TableObj = $(setting.table);
+
+        const Utils = {
+            getRowTdHtml: function (node, tree) {
+                const html = [];
+                // 名称
+                html.push('<td width="20%" class="in-' + node.tree_level + '">');
+                if (node.is_folder) {
+                    if (node.children.length > 0) {
+                        html.push('<span onselectstart="return false" style="{-moz-user-select:none}" class="fold-switch mr-1" title="收起" cid="'+ node.sort_id +'"><i class="fa fa-minus-square-o"></i></span> <i class="fa fa-folder-o"></i> ', node.name);
+                    } else {
+                        html.push('<i class="fa fa-folder-o"></i> ', node.name);
+                    }
+                } else {
+                    html.push(`<span class="text-muted mr-2">${tree.isLastSibling(node) ? '└' : '├'}</span>`);
+                    html.push(`<a href="/file/${node.id}/compare" name="name" id="${node.id}">`, node.name, '</a>');
+                }
+                html.push('</td>');
+                // 管理单位
+                html.push(`<td class="text-center">${node.management}</td>`);
+                // 创建时间
+                if (node.is_folder) {
+                    html.push(`<td class="text-center"></td>`);
+                } else {
+                    html.push(`<td class="text-center">${moment(node.create_time).format('YYYY-MM-DD')}</td>`);
+                }
+                // 操作
+                if (node.is_folder) {
+                    html.push(`<td></td>`);
+                } else {
+                    html.push(`<td>`);
+                    html.push('<button class="btn btn-outline-primary btn-sm" data-target="#select-rela" name="del" onclick="showModal(this);">关联标段</button>');
+                    html.push('</td>');
+                }
+                return html.join('');
+            },
+            getNodeTrHtml: function (node, tree) {
+                const html = [];
+                html.push(`<tr tree_id="${node.id}" pname="${node.name}" rela-tender="${node.rela_tender}">`);
+                html.push(Utils.getRowTdHtml(node, tree));
+                html.push(`</tr>`);
+                return html.join('');
+            },
+            reloadTable: function () {
+                const html = [];
+                for (const node of projectTree.nodes) {
+                    html.push(Utils.getNodeTrHtml(node, projectTree));
+                }
+                TableObj.html(html.join(''));
+            },
+            getSelectNode: function() {
+                const selectId = $('tr.table-active').attr('tree_id');
+                return selectId ? projectTree.getItems(selectId) : null;
+            },
+            getSelectNodeId: function() {
+                const selectId = $('tr.table-active').attr('tree_id');
+                return selectId || setting.treeSetting.rootId;
+            },
+        };
+
+        Utils.reloadTable();
+        return { projectTree, TableObj, ...Utils };
+    })({
+        treeSetting: { id: 'id', pid: 'tree_pid', level: 'tree_level', order: 'tree_order', rootId: '-1' },
+        source: projectList,
+        table: '#projectList',
+    });
+
+    class srObject {
+        constructor() {
+            const self = this;
+            this.selectTree = null;
+            const srSpreadSetting = {
+                cols: [
+                    {title: '选择', field: 'selected', hAlign: 1, width: 40, formatter: '@', cellType: 'checkbox'},
+                    {title: '名称', field: 'name', hAlign: 0, width: 180, formatter: '@', cellType: 'tree'},
+                    {title: '期数', field: 'lastStageOrder', hAlign: 1, width: 60, formatter: '@'},
+                    {title: '审批状态', field: 'lastStageStatus', hAlign: 1, width: 60, formatter: '@'},
+                ],
+                emptyRows: 0,
+                headRows: 1,
+                headRowHeight: [32],
+                defaultRowHeight: 21,
+                headerFont: '12px 微软雅黑',
+                font: '12px 微软雅黑',
+                headColWidth: [30],
+                selectedBackColor: '#fffacd',
+                readOnly: true,
+            };
+            this.spread = SpreadJsObj.createNewSpread($('#sr-spread')[0]);
+            this.sheet = this.spread.getActiveSheet();
+            SpreadJsObj.initSheet(this.sheet, srSpreadSetting);
+
+            this.spread.bind(spreadNS.Events.ButtonClicked, function (e, info) {
+                if (!info.sheet.zh_setting) return;
+
+                const col = info.sheet.zh_setting.cols[info.col];
+                if (col.field !== 'selected') return;
+
+                const node = SpreadJsObj.getSelectObject(info.sheet);
+                self.selectNode(node, !node[col.field]);
+                SpreadJsObj.reloadColData(info.sheet, 0);
+            });
+
+
+
+            $('#sr-select-all').click(function () {
+                if (!self.selectTree) return;
+                for (const n of self.selectTree.nodes) {
+                    n.selected = this.checked;
+                }
+                SpreadJsObj.reloadColData(self.sheet, 0);
+            });
+            $('#select-rela-ok').click(() => {
+                const rela = self.getSelects();
+                postData('/subproj/save', { id: curProject.id, rela_tender: rela.join(',') }, function () {
+                    $(`[tree_id=${curProject.id}]`)[0].setAttribute('rela-tender', rela.join(','));
+                    $('#select-rela').modal('hide');
+                });
+            });
+        }
+        selectNode(node, select) {
+            const posterity = this.selectTree.getPosterity(node);
+            posterity.unshift(node);
+            for (const p of posterity) {
+                p.selected = select;
+            }
+        }
+        getSelects() {
+            const select = [];
+            for (const n of this.selectTree.nodes) {
+                if ((!n.children || n.children.length === 0) && n.selected) select.push(n.tid);
+            }
+            return select;
+        }
+        init() {
+            $('#sr-select-all')[0].checked = false;
+            const self = this;
+            postData(`/subproj/rela?id=${curProject.id}`, {}, tenders => {
+                const rela = curProject.rela_tender ? curProject.rela_tender.split(',') : [];
+                self.selectTree = Tender2Tree.convert(category, tenders, null, null, function (node, source) {
+                    node.lastStageOrder = `第${source.lastStageOrder}期`;
+                    node.lastStageStatus = source.lastStageStatus;
+                });
+                for (const node of self.selectTree.nodes) {
+                    node.selected = rela.indexOf(node.tid + '') >= 0;
+                }
+                SpreadJsObj.loadSheetData(this.sheet, SpreadJsObj.DataType.Tree, this.selectTree);
+            });
+        }
+    }
+    let srSelect;
+    $('#select-rela').on('shown.bs.modal', () => {
+        if (!srSelect) srSelect = new srObject();
+        srSelect.init();
+    });
+});

+ 2 - 1
app/public/js/tender_list_manage.js

@@ -31,7 +31,8 @@ const tenderListSpec = (function(){
         html.push('<td style="width: 20%" tid="' + node.id + '">');
         if (!node.cid) {
             html.push('<a href="javascript: void(0)" name="edit" class="btn btn-outline-primary btn-sm">编辑</a>');
-            if (node.lastStage === null || node.lastStage === undefined) {
+            const hasStage = node.progress ? node.stage_count > 0 : !!node.lastStage;
+            if (!hasStage) {
                 html.push('<a href="javascript: void(0)" name="del" class="btn btn-outline-danger btn-sm ml-1">删除</a>');
             } else {
                 html.push('<button class="btn btn-outline-secondary btn-sm ml-1" data-toggle="tooltip" data-placement="top" title="请先删除所有期">删除</button>');

+ 2 - 0
app/router.js

@@ -712,6 +712,8 @@ module.exports = app => {
     app.post('/budget/:id/:btype/update', sessionAuth, budgetCheck, 'budgetController.detailUpdate');
     app.post('/budget/:id/:btype/upload-excel/:ueType', sessionAuth, budgetCheck, 'budgetController.detailUploadExcel');
     app.post('/budget/:id/decimal', sessionAuth, budgetCheck, 'budgetController.decimal');
+    // 电子档案
+    app.get('/file', sessionAuth, 'fileController.index');
 
     // 支付审批
     app.get('/payment', sessionAuth, 'paymentController.index');

+ 28 - 0
app/view/file/index.ejs

@@ -0,0 +1,28 @@
+<div class="panel-content">
+    <div class="panel-title fluid">
+        <div class="title-main  d-flex justify-content-between">
+            <div>资料归集</div>
+        </div>
+    </div>
+    <div class="content-wrap">
+        <div class="sjs-height-0" style="background-color: #fff">
+            <div class="c-body">
+                <% if (!projectList || projectList.length === 0) { %>
+                <div class="jumbotron">
+                    <h3 class="display-6">还没有项目数据</h3>
+                </div>
+                <% } else { %>
+                <table class="table table-hover table-bordered">
+                    <tr class="text-center"><th style="min-width: 200px">项目名称</th><th>管理单位</th><th>创建时间</th><th>操作</th></tr>
+                    <tbody id="projectList">
+                    </tbody>
+                </table>
+                <% } %>
+            </div>
+        </div>
+    </div>
+</div>
+<script>
+    const projectList = JSON.parse(unescape('<%- escape(JSON.stringify(projectList)) %>'));
+    const category = JSON.parse(unescape('<%- escape(JSON.stringify(categoryData)) %>'));
+</script>

+ 22 - 0
app/view/file/modal.ejs

@@ -0,0 +1,22 @@
+<!--弹出关联标段-->
+<div class="modal fade" id="select-rela" 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">
+                <h5>可选标段</h5>
+                <div id="sr-spread" style="height: 300px"></div>
+            </div>
+            <div class="modal-footer">
+                <div class="form-check form-check-inline">
+                    <input class="form-check-input" type="checkbox" id="sr-select-all">
+                    <label class="form-check-label" for="sr-select-all">全选</label>
+                </div>
+                <button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">取消</button>
+                <button type="button" class="btn btn-sm btn-primary" id="select-rela-ok">确定</button>
+            </div>
+        </div>
+    </div>
+</div>

+ 3 - 3
config/menu.js

@@ -42,12 +42,12 @@ const menu = {
         caption: '项目管理',
     },
     file: {
-        name: '电子档案',
-        icon: 'fa-file',
+        name: '资料归集',
+        icon: 'fa-credit-card',
         display: true,
         url: '/file',
         children: null,
-        caption: '电子档案',
+        caption: '资料归集',
     },
     budget: {
         name: '动态投资',

+ 16 - 0
config/web.js

@@ -1039,6 +1039,22 @@ const JsFiles = {
                 mergeFile: 'sub_project',
             },
         },
+        file: {
+            index: {
+                files: [
+                    '/public/js/moment/moment.min.js',
+                    '/public/js/spreadjs/sheets/v11/gc.spread.sheets.all.11.2.2.min.js',
+                ],
+                mergeFiles: [
+                    '/public/js/shares/drag_tree.js',
+                    '/public/js/path_tree.js',
+                    '/public/js/shares/tenders2tree.js',
+                    '/public/js/spreadjs_rela/spreadjs_zh.js',
+                    '/public/js/file.js',
+                ],
+                mergeFile: 'file',
+            },
+        },
         budget: {
             list: {
                 files: [