Преглед изворни кода

Merge branch 'dev' of http://192.168.1.41:3000/maixinrong/Calculation into dev

Tony Kang пре 10 месеци
родитељ
комит
92f89c5214

+ 10 - 2
app/controller/tender_controller.js

@@ -55,6 +55,7 @@ module.exports = app => {
                 const tenderList = await this.ctx.service.tender.getBuildList('', userPermission, this.ctx.session.sessionUser.is_admin);
                 for (const t of tenderList) {
                     await this.ctx.service.tenderCache.loadTenderCache(t, this.ctx.session.sessionUser.accountId);
+                    t.canFinish = await this.ctx.service.tender.checkTenderCanFinish(t);
                 }
                 const categoryData = await this.ctx.service.category.getAllCategory(this.ctx.session.sessionProject.id);
                 const valuations = await this.ctx.service.valuation.getProjectValidValuation(this.ctx.session.sessionProject.id);
@@ -73,6 +74,7 @@ module.exports = app => {
                     pid: this.ctx.session.sessionProject.id,
                     colSet: this.colSet,
                     subProject,
+                    buildStatus: tenderConst.buildStatus,
                 };
                 renderData.selfCategoryLevel = await this.ctx.service.projectAccount.getSelfCategoryLevel(this.ctx.session.sessionUser.accountId);
                 renderData.is_finish = false;
@@ -92,6 +94,7 @@ module.exports = app => {
                 const tenderList = await this.ctx.service.tender.getFinishList('', userPermission, this.ctx.session.sessionUser.is_admin);
                 for (const t of tenderList) {
                     await this.ctx.service.tenderCache.loadTenderCache(t, this.ctx.session.sessionUser.accountId);
+                    t.canFinish = await this.ctx.service.tender.checkTenderCanFinish(t);
                 }
                 const categoryData = await this.ctx.service.category.getAllCategory(this.ctx.session.sessionProject.id);
                 const valuations = await this.ctx.service.valuation.getProjectValidValuation(this.ctx.session.sessionProject.id);
@@ -110,6 +113,7 @@ module.exports = app => {
                     pid: this.ctx.session.sessionProject.id,
                     colSet: this.colSet,
                     subProject,
+                    buildStatus: tenderConst.buildStatus,
                 };
                 renderData.selfCategoryLevel = await this.ctx.service.projectAccount.getSelfCategoryLevel(this.ctx.session.sessionUser.accountId);
                 renderData.is_finish = true;
@@ -127,6 +131,7 @@ module.exports = app => {
                 for (const t of renderData.tenderList) {
                     t.visitor = (await this.ctx.service.tenderTourist.getTourists(t.id)).map(x => { return x.user_name; });
                     await this.ctx.service.tenderCache.loadTenderCache(t, this.ctx.session.sessionUser.accountId);
+                    t.canFinish = await this.ctx.service.tender.checkTenderCanFinish(t);
                 }
                 renderData.categoryData = await this.ctx.service.category.getAllCategory(this.ctx.session.sessionProject.id);
                 renderData.valuations = await this.ctx.service.valuation.getProjectValidValuation(this.ctx.session.sessionProject.id);
@@ -140,6 +145,7 @@ module.exports = app => {
                 renderData.selfCategoryLevel = await this.ctx.service.projectAccount.getSelfCategoryLevel(this.ctx.session.sessionUser.accountId);
                 renderData.is_finish = false;
                 renderData.colSet = this.colSet;
+                renderData.buildStatus = tenderConst.buildStatus;
                 renderData.subProject = await this.ctx.service.subProject.getSubProject(this.ctx.session.sessionProject.id, this.ctx.session.sessionUser.accountId, this.ctx.session.sessionUser.is_admin, true);
                 await this.layout(view, renderData, modal);
             } catch (err) {
@@ -155,6 +161,7 @@ module.exports = app => {
                 for (const t of renderData.tenderList) {
                     t.visitor = (await this.ctx.service.tenderTourist.getTourists(t.id)).map(x => { return x.user_name; });
                     await this.ctx.service.tenderCache.loadTenderCache(t, this.ctx.session.sessionUser.accountId);
+                    t.canFinish = await this.ctx.service.tender.checkTenderCanFinish(t);
                 }
                 renderData.categoryData = await this.ctx.service.category.getAllCategory(this.ctx.session.sessionProject.id);
                 renderData.valuations = await this.ctx.service.valuation.getProjectValidValuation(this.ctx.session.sessionProject.id);
@@ -168,6 +175,7 @@ module.exports = app => {
                 renderData.selfCategoryLevel = await this.ctx.service.projectAccount.getSelfCategoryLevel(this.ctx.session.sessionUser.accountId);
                 renderData.is_finish = true;
                 renderData.colSet = this.colSet;
+                renderData.buildStatus = tenderConst.buildStatus;
                 renderData.subProject = await this.ctx.service.subProject.getSubProject(this.ctx.session.sessionProject.id, this.ctx.session.sessionUser.accountId, this.ctx.session.sessionUser.is_admin, true);
                 await this.layout(view, renderData, modal);
             } catch (err) {
@@ -690,13 +698,13 @@ module.exports = app => {
         }
         async saveBuildStatus(ctx) {
             try {
-                const status = parseInt(ctx.query.status);
+                const status = parseInt(ctx.query.status || ctx.request.body.status);
                 await ctx.service.tender.saveBuildStatus(ctx.tender.data, status);
             } catch (err) {
                 this.log(err);
                 this.postError(err, '修改在建状态失败');
             }
-            ctx.redirect('/tender/' + ctx.params.id);
+            ctx.redirect(ctx.request.header.referer);
         }
 
 

+ 24 - 18
app/public/js/shenpi.js

@@ -681,30 +681,36 @@ $(document).ready(function () {
     $('body').on('click', '.set-otherShenpi', function () {
         let canSetOther = true;
         const this_code = $(this).data('code');
-        if (['stage', 'change'].indexOf(this_code) !== -1) {
-            const select = $(this).siblings('.lc-show').find('select[class*="audit-type-key"]');
-            select.each((i, s) => {
-                if (s.value !== '1') canSetOther = false;
-            });
-        }
-        if (!canSetOther) {
-            toastr.warning('该流程含有会签或签,不可同步至其他流程');
-            $('#batch2').modal('hide');
-            return;
-        }
+        // if (['stage', 'change'].indexOf(this_code) !== -1) {
+        //     const select = $(this).siblings('.lc-show').find('select[class*="audit-type-key"]');
+        //     select.each((i, s) => {
+        //         if (s.value !== '1') canSetOther = false;
+        //     });
+        // }
+        // if (!canSetOther) {
+        //     toastr.warning('该流程含有会签或签,不可同步至其他流程');
+        //     $('#batch2').modal('hide');
+        //     return;
+        // }
 
         const this_status = parseInt($(this).siblings('.lc-show').siblings('.form-group').find('input:checked').val());
-        const aid_num = $(this).siblings('.lc-show').children('ul').find('.remove-audit').length;
-        const aidList = [];
-        for (let i = 0; i < aid_num; i++) {
-            const aid = parseInt($(this).siblings('.lc-show').children('ul').find('.remove-audit').eq(i).data('id'));
-            aidList.push(aid);
+        const copyFlow = [];
+        const flow = $('li.d-flex', $(this).siblings('.lc-show'));
+        for (const f of flow) {
+            const audit_type = $('select', f).val();
+            const auditors = $('.remove-audit', f);
+            if (auditors.length === 0) continue;
+            const aid = [];
+            for (const a of auditors) {
+                aid.push(a.getAttribute('data-id'));
+            }
+            copyFlow.push(`${audit_type}:${aid.join(',')}`);
         }
         const html = getShenpiHtml(this_code);
         $('#shenpi-name2').text($(this).data('name'));
         $('#shenpi_code2').val(this_code);
         $('#shenpi_status2').val(this_status);
-        $('#shenpi_auditors2').val(aidList.join(','));
+        $('#shenpi_auditors2').val(copyFlow.join(';'));
         $('#shenpi-list').html(html);
         setTimeout(function () { $("#shenpi-list [data-toggle='tooltip']").tooltip(); },800);
         $('#batch2').modal('show');
@@ -724,7 +730,7 @@ $(document).ready(function () {
             code: $('#shenpi_code2').val(),
         };
         if(data.status !== shenpi_status.gdspl) {
-            data.aidList = $('#shenpi_auditors2').val();
+            data.flowList = $('#shenpi_auditors2').val();
         }
         // 获取已选中的标段
         const shenpiList = [];

+ 15 - 0
app/public/js/tender_list_manage.js

@@ -1,3 +1,17 @@
+const modStatus = function(tid) {
+    const tender = tenders.find(x => { return x.id === tid});
+    if (tender.status === 1) {
+        if (tender.canFinish) {
+            $('form', '#mod-status2finish').attr('action', `/tender/${tid}/build`);
+            $('#mod-status2finish').modal('show');
+        } else {
+            $('#mod-status-hint').modal('show');
+        }
+    } else {
+        $('form', '#mod-status2build').attr('action', `/tender/${tid}/build`);
+        $('#mod-status2build').modal('show');
+    }
+};
 const tenderListSpec = (function(){
     function getTenderNodeHtml(node, arr, pid) {
         const html = [];
@@ -39,6 +53,7 @@ const tenderListSpec = (function(){
                 html.push('<button class="btn btn-outline-secondary btn-sm ml-1" data-toggle="tooltip" data-placement="top" title="请先删除所有期">删除</button>');
             }
             if (cache) html.push(`<a href="/list/refreshCache?tid=${node.id}" class="btn btn-outline-primary btn-sm ml-1">更新缓存</a>`);
+            html.push(`<a href="javascript: void(0)" class="btn btn-outline-primary btn-sm ml-1" onclick="modStatus(${node.id});">修改状态</a>`);
         }
         html.push('</td>');
         html.push('</tr>');

+ 19 - 10
app/service/shenpi_audit.js

@@ -291,17 +291,26 @@ module.exports = app => {
                             }
                         }
                         await transaction.delete(this.tableName, { tid: this.ctx.tender.id, sp_type: shenpiConst.sp_type[code], sp_status: shenpiInfo[code] });
-                        for (const aid of data.aidList.split(',')) {
-                            if (aid && parseInt(aid) !== this.ctx.tender.data.user_id || (parseInt(aid) === this.ctx.tender.data.user_id && needYB.indexOf(code) !== -1)) {
-                                const insertData = {
-                                    tid: this.ctx.tender.id,
-                                    sp_type: shenpiConst.sp_type[code],
-                                    sp_status: shenpi_status,
-                                    audit_id: parseInt(aid),
-                                    audit_order: insertList.length + 1,
-                                };
-                                insertList.push(insertData);
+                        const flows = data.flowList.split(';');
+                        let audit_order = 1;
+                        for (const f of flows) {
+                            const audit_type = parseInt(f.split(':')[0]);
+                            const auditTypeInfo = auditType.info[audit_type];
+                            const auditTypeValid = !auditTypeInfo.valid || auditTypeInfo.valid.indexOf(code) >= 0;
+                            const auditIds = f.split(':')[1].split(',').map(x => { return parseInt(x)});
+                            for (const aid of auditIds) {
+                                if (aid !== this.ctx.tender.data.user_id || needYB.indexOf(code) >= 0) {
+                                    insertList.push({
+                                        tid: this.ctx.tender.id,
+                                        sp_type: shenpiConst.sp_type[code], sp_status: shenpi_status,
+                                        audit_id: aid,
+                                        audit_type: auditTypeValid ? audit_type : auditType.key.common,
+                                        audit_order: audit_order,
+                                    });
+                                    if (!auditTypeValid) audit_order++;
+                                }
                             }
+                            if (auditTypeValid) audit_order++;
                         }
                     }
                 }

+ 1 - 1
app/service/tender.js

@@ -91,7 +91,7 @@ module.exports = app => {
             let sql = '';
             let sqlParam = [];
             if (listStatus === 'manage') {
-                const userFilter = getAll ? '' : this.db.format('And t.user_id = ?', [session.sessionUser.accountId]);
+                const userFilter = getAll ? '' : this.db.format(' And t.user_id = ? ', [session.sessionUser.accountId]);
                 // 管理页面只取属于自己创建的标段
                 sql = 'SELECT t.`id`, t.`project_id`, t.`name`, t.`status`, t.`category`, t.`ledger_times`, t.`ledger_status`, t.`measure_type`, t.`user_id`, t.`create_time`, t.`total_price`, t.`deal_tp`, t.`spid`,' +
                     '    pa.`name` As `user_name`, pa.`role` As `user_role`, pa.`company` As `user_company` ' +

+ 54 - 0
app/view/tender/manage_modal.ejs

@@ -135,3 +135,57 @@
         </div>
     </div>
 </div>
+
+<!--在建状态-->
+<div class="modal fade" id="mod-status2finish" data-backdrop="static" aria-hidden="true" style="display: none;">
+    <form class="modal-dialog" role="document" method="POST" action="">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">修改在建状态</h5>
+            </div>
+            <div class="modal-body">
+                <h6>确认修改标段状态为「已完工」?</h6>
+                <h6>修改后,将<strong class="text-danger">无法</strong>再进行任一审批流程,且标段会被移至已完工页面。</h6>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">关闭</button>
+                <input type="hidden" name="_csrf_j" value="<%= ctx.csrf %>" />
+                <input type="hidden" name="status" value="<%= buildStatus.status.finish %>" />
+                <button type="submit" class="btn btn-sm btn-primary">确定修改</button>
+            </div>
+        </div>
+    </form>
+</div>
+<div class="modal fade" id="mod-status-hint" data-backdrop="static" style="display: none;" aria-hidden="true">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">修改在建状态</h5>
+            </div>
+            <div class="modal-body">
+                <h6>存在未审批完成的流程,请审批完成后再修改状态。</h6>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">关闭</button>
+            </div>
+        </div>
+    </div>
+</div>
+<div class="modal fade" id="mod-status2build" data-backdrop="static" aria-hidden="true" style="display: none;">
+    <form class="modal-dialog" role="document" method="POST" action="">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">修改在建状态</h5>
+            </div>
+            <div class="modal-body">
+                <h6>确认修改标段状态为「在建中」?</h6>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">关闭</button>
+                <input type="hidden" name="_csrf_j" value="<%= ctx.csrf %>" />
+                <input type="hidden" name="status" value="<%- buildStatus.status.build %>" />
+                <button type="submit" class="btn btn-sm btn-primary">确定修改</button>
+            </div>
+        </div>
+    </form>
+</div>