瀏覽代碼

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

TonyKang 3 年之前
父節點
當前提交
6569f0b4a6

+ 5 - 1
app/const/account_group.js

@@ -14,16 +14,20 @@ const accountGroup = {
     SJDW: 4,
     DJDW: 5,
     GZSJ: 6,
+    ZBDW: 8,
+    FBDW: 9,
     QT: 7,
 };
 
 const group = [];
 group[accountGroup.JSDW] = '建设单位';
-group[accountGroup.DJDW] = '代建单位';
 group[accountGroup.JLDW] = '监理单位';
 group[accountGroup.SGDW] = '施工单位';
 group[accountGroup.SJDW] = '设计单位';
+group[accountGroup.DJDW] = '代建单位';
 group[accountGroup.GZSJ] = '跟踪审计';
+group[accountGroup.ZBDW] = '总包单位';
+group[accountGroup.FBDW] = '分包单位';
 group[accountGroup.QT] = '其他';
 
 module.exports = {

+ 6 - 6
app/const/change.js

@@ -12,22 +12,22 @@ module.exports = {
     // 变更类型
     type: {
         pos: {
-            value: 1, name: 'A.数量',
+            value: 1, name: '数量',
         },
         num: {
-            value: 2, name: 'B.位置',
+            value: 2, name: '位置',
         },
         structure: {
-            value: 3, name: 'C.结构',
+            value: 3, name: '结构',
         },
         add: {
-            value: 4, name: 'D.新增',
+            value: 4, name: '新增',
         },
         cancel: {
-            value: 5, name: 'E.取消',
+            value: 5, name: '取消',
         },
         correct: {
-            value: 6, name: 'F.纠错',
+            value: 6, name: '纠错',
         },
     },
     // 变更类别

+ 1 - 1
app/const/page_show.js

@@ -14,7 +14,7 @@ const pageStatus = {
 };
 
 // const pageControl = [
-//     { title: '开启「部位台」', name: 'bwtz', value: pageStatus.show, type: 'checkbox' },
+//     { title: '开启「部位台」', name: 'bwtz', value: pageStatus.show, type: 'checkbox' },
 //     { title: '开启「投资进度」功能', name: 'xxjd', value: pageStatus.show, type: 'checkbox' },
 //     { title: '开启「其他台账」功能', name: 'stageExtra', value: pageStatus.show, type: 'checkbox' },
 //     { title: '关闭报表「导出PDF」', name: 'closeExportPdf', value: pageStatus.show, type: 'checkbox' },

+ 0 - 4
app/controller/stage_controller.js

@@ -1535,10 +1535,6 @@ module.exports = app => {
                     const dirName = `app/public/upload/${this.ctx.tender.id}/stage`;
                     const fileName = 'fujian_' + create_time + fileInfo.ext;
 
-                    // 判断文件夹是否存在,不存在则直接创建文件夹
-                    if (!fs.existsSync(path.join(this.app.baseDir, dirName))) {
-                        await fs.mkdirSync(path.join(this.app.baseDir, dirName));
-                    }
                     // 保存文件
                     await ctx.helper.saveStreamFile(stream, path.join(this.app.baseDir, dirName, fileName));
                     // 保存数据到att表

+ 5 - 2
app/controller/tender_controller.js

@@ -499,7 +499,7 @@ module.exports = app => {
                     materialData.auditors = materialData.status === auditConst.material.status.uncheck ? [] : await ctx.service.materialAudit.getFinalAuditGroup(materialData.id, times);
                 }
                 // 修订完成数目
-                const reviseNum = await ctx.service.ledgerRevise.count({ tid: tender.id, status: auditConst.revise.status.checked });
+                // const reviseNum = await ctx.service.ledgerRevise.count({ tid: tender.id, status: auditConst.revise.status.checked });
                 // 计量完成概况
                 // tender.total_price
                 const stage_total = [
@@ -527,7 +527,7 @@ module.exports = app => {
                     change_status_total,
                     change_quality_total,
                     materialData,
-                    reviseNum,
+                    // reviseNum,
                     stage_total,
                     hadMap,
                     jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.tender.tenderInfo),
@@ -1247,6 +1247,9 @@ module.exports = app => {
                     case 'del-map':
                         await ctx.service.tenderMap.deleteById(data.id);
                         break;
+                    case 'save-map':
+                        await ctx.service.tenderMap.saveMap(data.mapData);
+                        break;
                     default:break;
                 }
                 ctx.body = { err: 0, msg: '', data: info };

+ 33 - 8
app/public/css/main.css

@@ -1293,31 +1293,56 @@ overflow-y: auto;
 .context-menu-icon.context-menu-hover.context-menu-icon--fa.fa-tag span{
     color: #fff;!important;
 }
+.auto-main-height{
+  height: calc(100vh - 34px);
+  display: flex;
+  flex-direction: column;
+}
+.auto-main-height .main-height-one{
+  flex-grow: 1;
+}
+.auto-main-height .main-height-two{
+  flex-grow: 18;
+}
+.bottom-height{
+  height:300px);
+}
+.bottom-height-two{
+  height: 300px;
+}
+.card-big-title{
+  font-size: 1.75rem;
+  margin-bottom: .30rem;
+}
+.card-big-title small{
+  margin-top: -15px;
+  margin-right: -10px;
+}
 .circle-box{
   float: left;
   position: relative;
 }
 .circle{
-  width: 42px; 
-  height: 42px;
+  width: 62px; 
+  height: 62px;
   border-radius: 50%;
   background: none; 
-  border: 3px solid #D7B014;
+  border: 4px solid #D7B014;
 }
 .circle-num{
   position: absolute;
   top: 50%;
-  margin-top: -16px;
-  width: 42px;
+  margin-top: -32px;
+  width: 62px;
   text-align: center;
-  font-size: 22px;
+  font-size: 42px;
   font-weight: 500;
 }
 .circle-text{
   float: right;
-  margin-left: 20px;
+  margin-right: 20px;
   margin-top: 10px;
-  font-size: 16px;
+  font-size: 24px;
 }
 .dropdown-wd{
   width: 80px;

文件差異過大導致無法顯示
+ 20 - 0
app/public/js/map/gcoord.js


文件差異過大導致無法顯示
+ 88 - 0
app/public/js/map/turf.min.js


+ 1 - 1
app/public/js/material_file.js

@@ -216,7 +216,7 @@ $(document).ready(function () {
             <td>${fileInfo.upload_time}</td>`
             if (fileInfo.showDel ) {
                 html += `<td>
-                <a href="/${fileInfo.filepath}" class="btn btn-light btn-sm" title="下载"><span class="fa fa-download text-primary"></span></a>
+                <a href="file/${fileInfo.id}/download" class="btn btn-light btn-sm" title="下载"><span class="fa fa-download text-primary"></span></a>
                 <a href="javascript:void(0);" class="btn btn-light btn-sm delete-file" data-attid="${fileInfo.id}" title="删除附件">
                 <span class="fa fa-trash text-danger"></span>
                 </a>

+ 2 - 2
app/public/js/shares/cs_tools.js

@@ -665,7 +665,7 @@ const showSelectTab = function(select, spread, afterShow) {
             // 参与人可见
             tagHtml.push('<div class="custom-control custom-switch mr-2">');
             tagHtml.push('<input type="checkbox" class="custom-control-input custom-control-warning-input" id="tag-share"', tag.share ? 'checked' : '', '>');
-            tagHtml.push('<label class="custom-control-label custom-control-warning-label" for="tag-share" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="所有参与台审批管理的用户都可以看到这条书签"><i class="fa fa-users"></i> 参与者可见</label>');
+            tagHtml.push('<label class="custom-control-label custom-control-warning-label" for="tag-share" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="所有参与台审批管理的用户都可以看到这条书签"><i class="fa fa-users"></i> 参与者可见</label>');
             tagHtml.push('</div>');
             // 编辑按钮
             tagHtml.push('<div>', '<button type="button" class="btn btn-sm btn-outline-danger mr-3" id="tag-del"><i class="fa fa-close"></i>  删除书签</button>',
@@ -688,7 +688,7 @@ const showSelectTab = function(select, spread, afterShow) {
             tagHtml.push('</div>');
             tag.node && tagHtml.push((tag.node.code || '') + (tag.node.b_code || ''), ' / ', tag.node.name || '');
             if (tag.share) {
-                tagHtml.push('<i class="fa fa-users pull-right text-warning" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="所有参与台审批管理的用户都可以看到这条书签"></i>')
+                tagHtml.push('<i class="fa fa-users pull-right text-warning" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="所有参与台审批管理的用户都可以看到这条书签"></i>')
             }
             tagHtml.push('<div class="pull-right edit-tag-btn">');
             const lid = tag.node ? tag.node.ledger_id : -1;

+ 1 - 1
app/service/project_account.js

@@ -401,7 +401,7 @@ module.exports = app => {
                     },
                 });
                 if (accountData.length > 0) {
-                    throw '已存在对应的户名';
+                    throw '已存在对应的户名';
                 }
 
                 // 加密密码

+ 9 - 1
app/service/tender_map.js

@@ -32,7 +32,15 @@ module.exports = app => {
             return await this.db.insert(this.tableName, data);
         }
 
-        async saveMap(id, updateData) {
+        async saveMap(mapData) {
+            const id = mapData.id;
+            const updateData = {
+                name: mapData.name,
+                color: mapData.color,
+                map_json: mapData.map_json,
+                center: mapData.center,
+                tips: mapData.tips,
+            };
             return await this.db.update(this.tableName, updateData, { where: { id } });
         }
     }

+ 1 - 1
app/view/schedule/index.ejs

@@ -7,7 +7,7 @@
                 <% if (planMonth) { %>计划至 <%- planMonth.split('-')[0] %>年<%- parseInt(planMonth.split('-')[1]) %>月 <% } %>
             </h2>
             <div class="ml-auto">
-                <a href="/tender/<%- ctx.tender.id %>/schedule/ledger" class="btn btn-sm btn-outline-primary">进度台</a>
+                <a href="/tender/<%- ctx.tender.id %>/schedule/ledger" class="btn btn-sm btn-outline-primary">进度台</a>
             </div>
         </div>
     </div>

+ 3 - 3
app/view/schedule/modal.ejs

@@ -4,7 +4,7 @@
     <div class="modal-dialog" role="document">
         <div class="modal-content">
             <div class="modal-header">
-                <h5 class="modal-title">进度台</h5>
+                <h5 class="modal-title">进度台</h5>
             </div>
             <% if (tender.user_id !== ctx.session.sessionUser.accountId) { %>
             <div class="modal-body">
@@ -15,7 +15,7 @@
             </div>
             <% } else { %>
             <div class="modal-body">
-                <h5>首次使用投资进度需要进行进度台初始化设置</h5>
+                <h5>首次使用投资进度需要进行进度台初始化设置</h5>
             </div>
             <div class="modal-footer">
                 <a href="/tender/<%- ctx.tender.id %>/schedule/ledger" class="btn btn-sm btn-primary">开始设置</a>
@@ -54,7 +54,7 @@
                 </div>
                 <div class="modal-body">
                     <% if (ctx.url === '/tender/' + ctx.tender.id + '/schedule/ledger') { %>
-                        <h5>正在更新台,请等待...</h5>
+                        <h5>正在更新台,请等待...</h5>
                         <div class="progress">
                             <div id="schedule-progress" class="progress-bar" role="progressbar" style="width: 0%;" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">0%</div>
                         </div>

+ 4 - 4
app/view/setting/user_modal.ejs

@@ -1,4 +1,4 @@
-<!--弹出添加号-->
+<!--弹出添加号-->
 <div class="modal fade" id="add-user" data-backdrop="static">
     <div class="modal-dialog" role="document">
         <div class="modal-content">
@@ -62,7 +62,7 @@
         </div>
     </div>
 </div>
-<!--弹出编辑号-->
+<!--弹出编辑号-->
 <div class="modal fade" id="edit-user" data-backdrop="static">
     <div class="modal-dialog" role="document">
         <div class="modal-content">
@@ -156,7 +156,7 @@
         </div>
     </div>
 </div>
-<!--弹出解绑号-->
+<!--弹出解绑号-->
 <div class="modal fade" id="unlink-user" data-backdrop="static">
     <div class="modal-dialog" role="document">
         <div class="modal-content">
@@ -175,7 +175,7 @@
         </div>
     </div>
 </div>
-<!--弹出修改号名-->
+<!--弹出修改号名-->
 <div class="modal" tabindex="-1" role="dialog" id="edit-password">
     <div class="modal-dialog" role="document">
         <form method="post" action="/setting/user/reset/password" class="modal-content" onsubmit="return checkPasswordForm();">

+ 1 - 1
app/view/setting/user_permission_modal.ejs

@@ -1,4 +1,4 @@
-<!--弹出添加号-->
+<!--弹出添加号-->
 <div class="modal fade" id="add-user" data-backdrop="static">
     <div class="modal-dialog" role="document">
         <div class="modal-content">

+ 1 - 1
app/view/sign/info.ejs

@@ -64,7 +64,7 @@
 <body>
 <div id="app">
     <% if (error !== undefined && error) { %>
-    <div>参数有误, 无法访问本页.</div>
+    <div>token已更新,请重新登录并再次扫码。</div>
     <% } else { %>
     <div class="container">
         <div id="canvasBox" :style="getHorizontalStyle" v-show="!showBox">

文件差異過大導致無法顯示
+ 608 - 393
app/view/tender/detail.ejs


+ 368 - 30
app/view/tender/detail_modal.ejs

@@ -2025,8 +2025,9 @@
             </div>
             <div class="modal-footer">
                 <button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">关闭</button>
-                <!--<button type="button" class="btn btn-sm btn-primary" >确认修改</button>-->
-                <button type="button" class="btn btn-sm btn-success" >刷新显示</button>
+                <% if (hadMap) { %>
+                <button type="button" class="btn btn-sm btn-success" onclick="window.location.reload()" >刷新显示</button>
+                <% } %>
             </div>
         </div>
     </div>
@@ -2038,26 +2039,20 @@
                 <h5 class="modal-title">地图路线</h5>
             </div>
             <div class="modal-body">
-                <input class="form-control form-control-sm mb-1" type="text" value="路线1" placeholder="请输入路线名称">
-                <input class="form-control form-control-sm mb-1" type="text" id="color-select" value="#ff0000" placeholder="请选择路线颜色">
-                <!--<table class="table table-bordered table-sm">-->
-                    <!--<tr><th>坐标/备注</th><th>N(X)</th><th>E(Y)</th><th>色值(选填)</th></tr>-->
-                    <!--<tr><td>K0+000</td><td>324234.22</td><td>121212.09</td><td>#ff6501</td></tr>-->
-                    <!--<tr><td>K1+356</td><td>9861253.22</td><td>28234234.09</td><td></td></tr>-->
-                    <!--<tr><td>K2+534</td><td>651278.22</td><td>64122.09</td><td></td></tr>-->
-                    <!--<tr><td>&nbsp;</td><td>&nbsp; </td><td></td><td></td></tr>-->
-                    <!--<tr><td>&nbsp;</td><td>&nbsp; </td><td></td><td></td></tr>-->
-                    <!--<tr><td>&nbsp;</td><td> &nbsp;</td><td></td><td></td></tr>-->
-                    <!--<tr><td>&nbsp;</td><td> &nbsp;</td><td></td><td></td></tr>-->
-                <!--</table>-->
+                <input class="form-control form-control-sm mb-1" type="text" id="map-name" value="" placeholder="请输入路线名称">
+                <input class="form-control form-control-sm mb-1" type="text" id="map-tips" value="" placeholder="请输入路线标注(可以为空)">
+                <div id="map-color-select" class="input-group mb-1">
+                    <input id="map-color" type="text" placeholder="请选择路线颜色" class="form-control form-control-sm" style="height: 30px" />
+                    <span class="input-group-append"><span class="input-group-text colorpicker-input-addon"><i></i></span></span>
+                </div>
+                <!--<input class="form-control form-control-sm mb-1" type="text" id="map-color" value="#ff0000" placeholder="请选择路线颜色">-->
                 <div class="modal-height-300" style="overflow-y: auto">
                     <div id="map-spread" style="height: 297px; width: 465px;"></div>
                 </div>
             </div>
             <div class="modal-footer">
-                <a href="#bd-set-11-1" class="btn btn-sm btn-secondary" data-toggle="modal" data-target="#bd-set-11-1" data-dismiss="modal">关闭</a>
-                <!--<a href="#bd-set-11" class="btn btn-sm btn-primary" data-toggle="modal" data-target="#bd-set-11-1" data-dismiss="modal">确认修改</a>-->
-                <button type="button" class="btn btn-sm btn-primary" id="save-map" data-mid="">确认修改</button>
+                <button class="btn btn-sm btn-secondary save-map" data-close="1" data-mid="">关闭</button>
+                <button type="button" class="btn btn-sm btn-primary save-map" data-close="0" data-mid="">确认修改</button>
             </div>
         </div>
     </div>
@@ -2074,16 +2069,46 @@
             </div>
             <div class="modal-footer">
                 <a href="#bd-set-11-1" class="btn btn-sm btn-secondary" data-toggle="modal" data-target="#bd-set-11-1" data-dismiss="modal">关闭</a>
-                <!--<button type="button" class="btn btn-sm btn-primary" >确认修改</button>-->
                 <button type="button" class="btn btn-sm btn-danger" id="del-map" data-mid="">确认删除</button>
             </div>
         </div>
     </div>
 </div>
+<!--关闭退出编辑-->
+<div class="modal fade" id="bd-set-11-4" 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>
+            <div class="modal-footer">
+                <a href="javascript:void(0)" class="btn btn-sm btn-secondary" data-dismiss="modal">关闭</a>
+                <button id="back-set-11-1" class="btn btn-sm btn-danger">直接退出</button>
+                <button type="button" class="btn btn-sm btn-primary save-map" data-colse="0" data-mid="">保存并退出</button>
+            </div>
+        </div>
+    </div>
+</div>
+
 <script>
     const hadMap = parseInt(<%- hadMap %>);
-    const tenderMapList = JSON.parse(unescape('<%- escape(JSON.stringify(tenderMapList)) %>'));
     $(function () {
+        $('#bd-set-11').on('show.bs.modal', function () {
+            if (parseInt(hadMap) == 0) {
+                $('#bd-set-11').find('.card').eq(0).addClass('border-dark');
+                $('#bd-set-11').find('.card').eq(0).find('.btn').removeClass('select-map').addClass('disabled').text('当前');
+                $('#bd-set-11').find('.card').eq(1).removeClass('border-dark');
+                $('#bd-set-11').find('.card').eq(1).find('.btn').removeClass('disabled').addClass('select-map').text('选择');
+            } else {
+                $('#bd-set-11').find('.card').eq(1).addClass('border-dark');
+                $('#bd-set-11').find('.card').eq(1).find('.btn').removeClass('select-map').addClass('disabled').text('当前');
+                $('#bd-set-11').find('.card').eq(0).removeClass('border-dark');
+                $('#bd-set-11').find('.card').eq(0).find('.btn').removeClass('disabled').addClass('select-map').text('选择');
+            }
+        })
         $('body').on('click', '#bd-set-11 .select-map', function () {
             // const val = parseInt($(this).data('value'));
             $(this).parents('.card').addClass('border-dark');
@@ -2108,7 +2133,6 @@
                 toastr.warning('未更改当前设置,无需提交');
             }
         })
-        $('#color-select').colorpicker();
         $('#add-map').click(function () {
             const num = $('#map-table tr').length;
             const name = '路线' + (num+1);
@@ -2130,13 +2154,35 @@
                 $('#bd-set-11-1').modal('show');
             });
         });
+        $('#map-color-select').colorpicker({
+            // container: true,
+            color: '#ff0000',
+            useAlpha: false,
+            extensions: [
+                {
+                    name: 'swatches', // extension name to load
+                    options: { // extension options
+                        colors: {
+                            '#ffffff': '#ffffff',
+                            '#337ab7': '#337ab7',
+                            '#5cb85c': '#5cb85c',
+                            '#5bc0de': '#5bc0de',
+                            '#f0ad4e': '#f0ad4e',
+                            '#d9534f': '#d9534f'
+                        },
+                        namesAsValues: true
+                    }
+                }
+            ]
+        });
+        const mapSpread = SpreadJsObj.createNewSpread($('#map-spread')[0]);
         const mapSpreadSetting = {
             cols: [
-                {title: '坐标/备注', colSpan: '1', rowSpan: '1', field: 'b_code', hAlign: 0, width: 100, formatter: '@'},
-                {title: '经度', colSpan: '1', rowSpan: '1', field: 'x', hAlign: 2, width: 120, type: 'Number'},
-                {title: '纬度', colSpan: '1', rowSpan: '1', field: 'y', hAlign: 2, width: 120, type: 'Number'},
+                {title: '坐标/备注', colSpan: '1', rowSpan: '1', field: 'tip', hAlign: 0, width: 100, formatter: '@'},
+                {title: '经度', colSpan: '1', rowSpan: '1', field: 'lng', hAlign: 2, width: 120, type: 'number'},
+                {title: '纬度', colSpan: '1', rowSpan: '1', field: 'lat', hAlign: 2, width: 120, type: '@'},
             ],
-            emptyRows: 20,
+            emptyRows: 5,
             headRows: 1,
             headRowHeight: [25, 25],
             defaultRowHeight: 21,
@@ -2144,20 +2190,312 @@
             font: '12px 微软雅黑',
             readOnly: false,
         };
-        const mapSpread = SpreadJsObj.createNewSpread($('#map-spread')[0]);
         SpreadJsObj.initSheet(mapSpread.getActiveSheet(), mapSpreadSetting);
         $('body').on('click', '#bd-set-11-1 .save-map-btn', function () {
             const id = parseInt($(this).data('mid'));
-            $('#save-map').attr('data-mid', id);
+            $('.save-map').attr('data-mid', id);
             // 加载sjs
             const mapInfo = _.find(tenderMapList, { id });
-            console.log(mapInfo);
-            SpreadJsObj.loadSheetData(mapSpread.getActiveSheet(), SpreadJsObj.DataType.Data, (mapInfo.map_json ? mapInfo.map_json : []));
+            $('#map-name').val(mapInfo.name);
+            $('#map-tips').val(mapInfo.tips);
+            $('#map-color').val(mapInfo.color);
+            $('#map-color').attr('value', mapInfo.color);
+            $('#map-color-select').colorpicker("setValue", mapInfo.color);
+            SpreadJsObj.loadSheetData(mapSpread.getActiveSheet(), SpreadJsObj.DataType.Data, (mapInfo.map_json ? JSON.parse(unescape(escape(mapInfo.map_json))) : []));
+        });
+        const xPattern = /^-?(\d{1,2}(\.\d{1,8})?|1[0-7]\d(\.\d{1,8})?|180)$/;
+        const yPattern = /^-?(\d(\.\d{1,8})?|[1-8]\d(\.\d{1,8})?|90)$/;
+        const mapSpreadObj = {
+            del: function (row) {
+                const select = SpreadJsObj.getSelectObject(mapSpread.getActiveSheet());
+                const delSel = mapSpread.getActiveSheet().getSelections()[0];
+                mapSpread.getActiveSheet().deleteRows(delSel.row, delSel.rowCount);
+                const sel = mapSpread.getActiveSheet().getSelections();
+                mapSpread.getActiveSheet().setSelection(0, 0, 1, 1);
+            },
+            batchAdd: function(num, site = mapSpread.getActiveSheet().getRowCount()) {
+                mapSpread.getActiveSheet().addRows(site, parseInt(num));
+            },
+            editEnding: function (e, info) {
+                if (info.sheet.zh_setting) {
+                    const curRow = info.row;
+                    info.sheet.zh_data[curRow] = {
+                        tip: info.sheet.getText(curRow, 0),
+                        lng: info.sheet.getText(curRow, 1) !== '' ? _.toNumber(info.sheet.getText(curRow, 1)) : '',
+                        lat: info.sheet.getText(curRow, 2) !== '' ? _.toNumber(info.sheet.getText(curRow, 2)) : '',
+                    }
+                }
+            },
+            editEnded: function (e, info) {
+                if (info.sheet.zh_setting) {
+                    const select = SpreadJsObj.getSelectObject(info.sheet);
+                    const col = info.sheet.zh_setting.cols[info.col];
+                    const validText = info.editingText ? info.editingText.replace('\n', '') : '';
+                    if (validText === '') {
+                        return;
+                    }
+                    if (col.field === 'lng' && !xPattern.test(validText)) {
+                        toastr.error('请输入正常范围内的经度(-180 ~ 180)');
+                        SpreadJsObj.reLoadRowData(info.sheet, info.row);
+                        return;
+                    }
+                    if (col.field === 'lat' && !yPattern.test(validText)) {
+                        toastr.error('请输入正常范围内的纬度(-90 ~ 90)');
+                        SpreadJsObj.reLoadRowData(info.sheet, info.row);
+                        return;
+                    }
+                }
+            },
+            clipboardPasting(e, info) {
+                const range = info.cellRange;
+                for (let iRow = 0; iRow < range.rowCount; iRow++) {
+                    const curRow = range.row + iRow;
+                    info.sheet.zh_data[curRow] = {
+                        tip: info.sheet.getText(curRow, 0),
+                        lng: info.sheet.getText(curRow, 1) !== '' ? _.toNumber(info.sheet.getText(curRow, 1)) : '',
+                        lat: info.sheet.getText(curRow, 2) !== '' ? _.toNumber(info.sheet.getText(curRow, 2)) : '',
+                    }
+                }
+            },
+            clipboardPasted(e, info) {
+                const hint = {
+                    cellError: {type: 'error', msg: '粘贴内容超出了表格范围'},
+                    xExpr: {type: 'error', msg: '请粘贴正常范围内的经度(-180 ~ 180)'},
+                    yExpr: {type: 'error', msg: '请粘贴正常范围内的纬度(-90 ~ 90)'},
+                };
+                const range = info.cellRange;
+                console.log(range);
+                if (range.col + range.colCount > 3) {
+                    toastMessageUniq(hint.cellError);
+                    SpreadJsObj.reLoadSheetHeader(mapSpread.getActiveSheet());
+                    // SpreadJsObj.reLoadSheetData(mapSpread.getActiveSheet());
+                    // continue;
+                }
+                for (let iRow = 0; iRow < range.rowCount; iRow++) {
+                    let bPaste = true;
+                    const curRow = range.row + iRow;
+                    for (let iCol = 0; iCol < range.colCount; iCol++) {
+                        const curCol = range.col + iCol;
+                        const colSetting = info.sheet.zh_setting.cols[curCol];
+                        const validText = info.sheet.getText(curRow, curCol);
+                        if (validText === '') {
+                            continue;
+                        }
+                        if (colSetting.field === 'lng' && !xPattern.test(validText)) {
+                            toastMessageUniq(hint.xExpr);
+                            bPaste = false;
+                            continue;
+                        }
+                        if (colSetting.field === 'lat' && !yPattern.test(validText)) {
+                            toastMessageUniq(hint.yExpr);
+                            bPaste = false;
+                            continue;
+                        }
+                    }
+                    if (!bPaste) {
+                        SpreadJsObj.reLoadRowData(info.sheet, curRow);
+                    }
+                }
+            },
+        }
+        mapSpread.bind(spreadNS.Events.EditEnding, mapSpreadObj.editEnding);
+        mapSpread.bind(spreadNS.Events.EditEnded, mapSpreadObj.editEnded);
+        mapSpread.bind(spreadNS.Events.ClipboardPasting, mapSpreadObj.clipboardPasting);
+        mapSpread.bind(spreadNS.Events.ClipboardPasted, mapSpreadObj.clipboardPasted);
+        let batchInsertObj;
+        $.contextMenu.types.batchInsert = function (item, opt, root) {
+            const self = this;
+            if ($.isFunction(item.icon)) {
+                item._icon = item.icon.call(this, this, $t, key, item);
+            } else {
+                if (typeof(item.icon) === 'string' && item.icon.substring(0, 3) === 'fa-') {
+                    // to enable font awesome
+                    item._icon = root.classNames.icon + ' ' + root.classNames.icon + '--fa fa ' + item.icon;
+                } else {
+                    item._icon = root.classNames.icon + ' ' + root.classNames.icon + '-' + item.icon;
+                }
+            }
+            this.addClass(item._icon);
+            const $obj = $('<div>' + item.name + '<input class="text-right ml-1 mr-1" type="tel" max="100" min="1" value="' + item.value + '" style="width: 30px; height: 18px; padding-right: 4px;">行</div>')
+                .appendTo(this);
+            const $input = $obj.find('input');
+            const event = () => {
+                if (self.hasClass('context-menu-disabled')) return;
+                item.batchInsert($input[0], root);
+            };
+            $obj.on('click', event).keypress(function (e) {if (e.keyCode === 13) { event(); }});
+            $input.click((e) => {e.stopPropagation();})
+                .keyup((e) => {if (e.keyCode === 13) item.batchInsert($input[0], root);})
+                .on('input', function () {this.value = this.value.replace(/[^\d]/g, '');});
+        };
+        // 右键菜单
+        $.contextMenu({
+            selector: '#map-spread',
+            build: function ($trigger, e) {
+                const target = SpreadJsObj.safeRightClickSelection($trigger, e, mapSpread);
+                return target.hitTestType === GC.Spread.Sheets.SheetArea.viewport || target.hitTestType === GC.Spread.Sheets.SheetArea.rowHeader;
+            },
+            items: {
+                'batchInsert': {
+                    name: '批量新增',
+                    type: 'batchInsert',
+                    value: '1',
+                    icon: 'fa-sign-in',
+                    batchInsert: function (obj, root) {
+                        if (_.toNumber(obj.value) > _.toNumber(obj.max)) {
+                            obj.value = obj.max;
+                            toastr.warning('批量添加不可多于' + obj.max);
+                        } else if(_.toNumber(obj.value) < _.toNumber(obj.min)) {
+                            obj.value = obj.min;
+                            toastr.warning('批量添加不可少于' + obj.min);
+                        } else {
+                            mapSpreadObj.batchAdd(obj.value);
+                            root.$menu.trigger('contextmenu:hide');
+                        }
+                    },
+                },
+                'batchInsert2': {
+                    name: '批量插入',
+                    type: 'batchInsert',
+                    value: '1',
+                    icon: 'fa-sign-in',
+                    batchInsert: function (obj, root) {
+                        if (_.toNumber(obj.value) > _.toNumber(obj.max)) {
+                            obj.value = obj.max;
+                            toastr.warning('批量插入不可多于' + obj.max);
+                        } else if(_.toNumber(obj.value) < _.toNumber(obj.min)) {
+                            obj.value = obj.min;
+                            toastr.warning('批量插入不可少于' + obj.min);
+                        } else {
+                            const select = SpreadJsObj.getSelectObject(mapSpread.getActiveSheet());
+                            const sel = mapSpread.getActiveSheet().getSelections()[0];
+                            mapSpreadObj.batchAdd(obj.value, sel.row+1);
+                            root.$menu.trigger('contextmenu:hide');
+                        }
+                    },
+                    disabled: function (key, opt) {
+                        const select = SpreadJsObj.getSelectObject(mapSpread.getActiveSheet());
+                        const sel = mapSpread.getActiveSheet().getSelections()[0];
+                        if (sel.row !== undefined && sel.rowCount === 1) {
+                            return false;
+                        } else {
+                            return true;
+                        }
+                    }
+                },
+                'delete': {
+                    name: '删除',
+                    icon: 'fa-remove',
+                    callback: function (key, opt) {
+                        mapSpreadObj.del();
+                    },
+                    disabled: function (key, opt) {
+                        const select = SpreadJsObj.getSelectObject(mapSpread.getActiveSheet());
+                        const sel = mapSpread.getActiveSheet().getSelections()[0];
+                        if (sel.row !== undefined) {
+                            return false;
+                        } else {
+                            return true;
+                        }
+                    }
+                },
+            }
         });
-        $('#save-map').on('click', function () {
+
+        $('.save-map').on('click', function () {
             const id = parseInt($(this).attr('data-mid'));
-            console.log(id);
+            const is_close = parseInt($(this).attr('data-close'));
+            // 获取sjs值
+            const mapData = [];
+            const sheet = mapSpread.getActiveSheet();
+            let pass = true;
+            let wrongRow = [];
+            for (let i = 0; i < sheet.getRowCount(); i++) {
+                const rowData = {
+                    tip: sheet.getText(i, 0),
+                    lng: sheet.getText(i, 1),
+                    lat: sheet.getText(i, 2),
+                }
+                if ((rowData.tip !== '' && rowData.lng === '' && rowData.lat === '') ||
+                    (rowData.lng !== '' && rowData.lat === '') ||
+                    (rowData.lng === '' && rowData.lat !== '')) {
+                    pass = false;
+                    wrongRow.push(i+1);
+                } else if (rowData.lng !== '' && rowData.lat !== '') {
+                    rowData.lng = _.toNumber(rowData.lng);
+                    rowData.lat = _.toNumber(rowData.lat);
+                    mapData.push(rowData);
+                }
+            }
+            if (!is_close) {
+                const colorPattern = /(^#[0-9a-fA-F]{6}$)|(^#[0-9a-fA-F]{3}$)/g;
+                if (!colorPattern.test($('#map-color').val())) {
+                    $('#bd-set-11-4').modal('hide');
+                    toastr.error('请选择或输入正确的颜色编码');
+                    return;
+                }
+                if ($('#map-tips').val().length > 255) {
+                    toastr.error('路线标注太长啦~');
+                    return;
+                }
+            }
+            if (!pass) {
+                const str = wrongRow.join('、');
+                // $('#bd-set-11-4').modal('hide');
+                toastr.error('第 ' + str + ' 行请填写完整的经纬度数据或清空该行或删除该行');
+                return;
+            }
+            // 获取路线绝对中心点
+            let centerPoints = { lng: '', lat: '' };
+            if (mapData.length > 0) {
+                const points = [];
+                for (const m of mapData) {
+                    points.push(turf.point([m.lng, m.lat]));
+                }
+                const features = turf.featureCollection(points);
+                const center = turf.center(features);
+                if (center && center.geometry && center.geometry.coordinates && center.geometry.coordinates.length === 2) {
+                    centerPoints.lng = _.round(center.geometry.coordinates[0], 4);
+                    centerPoints.lat = _.round(center.geometry.coordinates[1], 4);
+                }
+            }
+            const oneMapData = {
+                id,
+                name: $('#map-name').val(),
+                color: $('#map-color').val(),
+                tips: $('#map-tips').val(),
+                map_json: mapData.length > 0 ? JSON.stringify(mapData) : null,
+                center: centerPoints.lng !== '' ? JSON.stringify(centerPoints) : null,
+
+            }
+            const mapInfo = _.find(tenderMapList, { id });
+            oneMapData.create_time = mapInfo.create_time;
+            oneMapData.tid = mapInfo.tid;
+            // 比较对象是否一致,一致则不提交,不一致则提交,关闭提示是否保存修改
+            if (!_.isEqual(oneMapData, mapInfo)) {
+                console.log(oneMapData, mapInfo);
+                if (!is_close) {
+                    postData('/tender/' + tenderId + '/map/save', { type: 'save-map', mapData: oneMapData }, function (result) {
+                        const index = _.findIndex(tenderMapList, { id });
+                        tenderMapList.splice(index, 1, oneMapData);
+                        $('#map-table tr').eq(index).children('td').eq(0).text(oneMapData.name);
+                        $('#bd-set-11-4').modal('hide');
+                        $('#bd-set-11-2').modal('hide');
+                        $('#bd-set-11-1').modal('show');
+                    });
+                } else {
+                    $('#bd-set-11-4').modal('show');
+                }
+            } else {
+                $('#bd-set-11-2').modal('hide');
+                $('#bd-set-11-1').modal('show');
+            }
         });
+        $('#back-set-11-1').on('click', function () {
+            $('#bd-set-11-4').modal('hide');
+            $('#bd-set-11-2').modal('hide');
+            $('#bd-set-11-1').modal('show');
+        })
     })
 </script>
 <% } %>

+ 1 - 1
app/view/wap/dashboard.ejs

@@ -66,7 +66,7 @@
                     <div class="card mb-3">
                         <div class="card-header d-flex justify-content-between">
                             <span><%- JSON.parse(revise.deal_info).buildName %></span>
-                            <span class="badge badge-pill badge-info">台修订</span>
+                            <span class="badge badge-pill badge-info">台修订</span>
                         </div>
                         <div class="bg-light p-2 px-3"><b><%- revise.t_name %></b></div>
                         <div class="card-body">

+ 1 - 1
app/view/wap/tender.ejs

@@ -58,7 +58,7 @@
                 <a class="px-1 nav-link" data-toggle="tab" href="#yufukuan" role="tab">预付款</a>
             </li>
             <li class="nav-item">
-                <a class="px-1 nav-link" data-toggle="tab" href="#tzxiuding" role="tab">台修订</a>
+                <a class="px-1 nav-link" data-toggle="tab" href="#tzxiuding" role="tab">台修订</a>
             </li>
             <li class="nav-item">
                 <a class="px-1 nav-link" data-toggle="tab" href="#jlqi" role="tab">计量期</a>

+ 0 - 34
sql/update.sql

@@ -1,34 +0,0 @@
-CREATE TABLE `calculation`.`zh_rpt_archive_encryption` (
-  `id` INT NOT NULL AUTO_INCREMENT,
-  `prj_id` INT NULL,
-  `stage_id` INT NULL,
-  `content` JSON NULL,
-  PRIMARY KEY (`id`),
-  INDEX `PRJ_STG` (`prj_id` ASC, `stage_id` ASC))
-COMMENT = '归档文档的需要加密签名的坐标及其他key信息(如签名角色id,签名角色名称等)';
-
-ALTER TABLE `zh_material_list` ADD `expr` VARCHAR(500) NULL DEFAULT '' COMMENT '公式' AFTER `quantity`;
-
-ALTER TABLE `zh_s2b_proj`
-ADD COLUMN `gxby_ratio_valid`  tinyint(1) NULL DEFAULT 0 COMMENT '工序报验,ratio是否生效' AFTER `gxby_status`,
-ADD COLUMN `dagl_ratio_valid`  tinyint(1) NOT NULL DEFAULT 1 COMMENT '工序报验,ratio是否生效' AFTER `dagl_status`;
-
-CREATE TABLE `zh_ledger_attachment` (
-  `id` INT(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
-  `tid` INT(11) NOT NULL COMMENT '标段id',
-  `lid` VARCHAR(100) CHARACTER SET 'utf8' NOT NULL COMMENT '台账节点id(uuid)',
-  `uid` INT(11) NOT NULL COMMENT '上传者id',
-  `filename` VARCHAR(1000) NOT NULL COMMENT '文件名称',
-  `fileext` VARCHAR(10) NOT NULL COMMENT '文件后缀',
-  `filesize` VARCHAR(255) NOT NULL COMMENT '文件大小',
-  `filepath` VARCHAR(500) NOT NULL COMMENT '文件存储路径',
-  `remark` VARCHAR(100) NOT NULL COMMENT '备注',
-  `status` TINYINT(1) NOT NULL DEFAULT '1' COMMENT '状态:1存在,2回收站',
-  `in_time` VARCHAR(15) NOT NULL COMMENT '创建时间',
-  `extra_upload` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '是否为审核通过后再次上传的文件,0为否',
-  PRIMARY KEY (`id`));
-
-
-ALTER TABLE `zh_tender_tourist` ADD `permission` VARCHAR(1000) NULL DEFAULT NULL COMMENT '游客权限JSON格式' AFTER `user_id`;
-
-ALTER TABLE `zh_tender` ADD `had_map` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '是否显示地图' AFTER `s2b_dagl_limit`;

+ 73 - 0
sql/update20210831.sql

@@ -0,0 +1,73 @@
+CREATE TABLE `calculation`.`zh_rpt_archive_encryption` (
+  `id` INT NOT NULL AUTO_INCREMENT,
+  `prj_id` INT NULL,
+  `stage_id` INT NULL,
+  `content` JSON NULL,
+  PRIMARY KEY (`id`),
+  INDEX `PRJ_STG` (`prj_id` ASC, `stage_id` ASC))
+COMMENT = '归档文档的需要加密签名的坐标及其他key信息(如签名角色id,签名角色名称等)';
+
+ALTER TABLE `zh_material_list` ADD `expr` VARCHAR(500) NULL DEFAULT '' COMMENT '公式' AFTER `quantity`;
+
+ALTER TABLE `zh_s2b_proj`
+ADD COLUMN `gxby_ratio_valid`  tinyint(1) NULL DEFAULT 0 COMMENT '工序报验,ratio是否生效' AFTER `gxby_status`,
+ADD COLUMN `dagl_ratio_valid`  tinyint(1) NOT NULL DEFAULT 1 COMMENT '工序报验,ratio是否生效' AFTER `dagl_status`;
+
+CREATE TABLE `zh_ledger_attachment` (
+  `id` INT(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
+  `tid` INT(11) NOT NULL COMMENT '标段id',
+  `lid` VARCHAR(100) CHARACTER SET 'utf8' NOT NULL COMMENT '台账节点id(uuid)',
+  `uid` INT(11) NOT NULL COMMENT '上传者id',
+  `filename` VARCHAR(1000) NOT NULL COMMENT '文件名称',
+  `fileext` VARCHAR(10) NOT NULL COMMENT '文件后缀',
+  `filesize` VARCHAR(255) NOT NULL COMMENT '文件大小',
+  `filepath` VARCHAR(500) NOT NULL COMMENT '文件存储路径',
+  `remark` VARCHAR(100) NOT NULL COMMENT '备注',
+  `status` TINYINT(1) NOT NULL DEFAULT '1' COMMENT '状态:1存在,2回收站',
+  `in_time` VARCHAR(15) NOT NULL COMMENT '创建时间',
+  `extra_upload` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '是否为审核通过后再次上传的文件,0为否',
+  PRIMARY KEY (`id`));
+
+
+ALTER TABLE `zh_tender_tourist` ADD `permission` VARCHAR(1000) NULL DEFAULT NULL COMMENT '游客权限JSON格式' AFTER `user_id`;
+
+ALTER TABLE `zh_tender` ADD `had_map` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '是否显示地图' AFTER `s2b_dagl_limit`;
+
+CREATE TABLE `zh_tender_map` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `tid` int(11) NOT NULL COMMENT '标段id',
+  `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL COMMENT '路线名称',
+  `color` varchar(10) COLLATE utf8_unicode_ci NOT NULL DEFAULT '#ff0000' COMMENT '路线颜色标记(默认红色)',
+  `map_json` mediumtext COLLATE utf8_unicode_ci COMMENT '坐标json',
+  `center` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '路线的绝对中心点',
+  `create_time` datetime NOT NULL COMMENT '入库时间',
+  PRIMARY KEY (`id`),
+  KEY `tid` (`tid`)
+) ENGINE=InnoDB AUTO_INCREMENT=111 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='标段地图路线坐标表';
+
+CREATE TABLE `zh_netcasign` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `pid` int(11) NOT NULL COMMENT '项目id',
+  `uid` int(11) NOT NULL COMMENT '用户id',
+  `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL COMMENT 'ukey里的主题(名字)',
+  `keyId` varchar(255) COLLATE utf8_unicode_ci NOT NULL COMMENT 'ukey里的key',
+  `sign_base64` mediumtext COLLATE utf8_unicode_ci COMMENT '签名图(base64保存)',
+  `create_time` datetime NOT NULL COMMENT '添加时间',
+  PRIMARY KEY (`id`),
+  KEY `uid` (`uid`)
+) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='网证通ukey签名图绑定表';
+
+CREATE TABLE `zh_netcasign_log` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `tid` int(11) NOT NULL COMMENT '标段id',
+  `uid` int(11) NOT NULL COMMENT '用户id',
+  `role` varchar(255) COLLATE utf8_unicode_ci NOT NULL COMMENT '报表签名人角色名称',
+  `uuid` varchar(255) COLLATE utf8_unicode_ci NOT NULL COMMENT '报表对应的pdf id',
+  `versionid` varchar(255) COLLATE utf8_unicode_ci NOT NULL COMMENT 'pdf版本控制id',
+  `create_time` datetime NOT NULL COMMENT '签名时间',
+  PRIMARY KEY (`id`),
+  KEY `tid` (`tid`),
+  KEY `uid` (`uid`)
+) ENGINE=InnoDB AUTO_INCREMENT=254 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='签名记录信息表';
+
+ALTER TABLE `zh_tender_map` ADD `tips` VARCHAR(255) NULL DEFAULT '' COMMENT '路线备注' AFTER `center`;