Browse Source

项目管理分享页面

zhongzewei 7 years ago
parent
commit
a1df2586f3

+ 1 - 1
modules/all_models/projects.js

@@ -8,7 +8,7 @@ const deleteSchema = require('../all_schemas/delete_schema');
 
 const collectionName = 'projects';
 const shareSchema = new Schema({
-    receiver: String, //userID
+    userID: String, //userID
     allowCopy: {type: Boolean, default: false},
     shareDate: String,
 }, {versionKey: false, _id: false});

+ 56 - 1
modules/pm/controllers/pm_controller.js

@@ -2,6 +2,7 @@
  * Created by Mai on 2017/1/18.
  */
 import UnitPriceFileModel from "../../glj/models/unit_price_file_model";
+import moment from 'moment';
 let mongoose = require('mongoose');
 let ProjectsData = require('../models/project_model').project;
 let labourCoe = require('../../main/facade/labour_coe_facade');
@@ -17,6 +18,7 @@ let unitPriceFileModel = mongoose.model('unit_price_file');
 let feeRateFileModel = mongoose.model('fee_rate_file');
 let asyncTool = require('async');
 let pm_facade = require('../facade/pm_facade');
+const userModel = mongoose.model('user');
 
 //统一回调函数
 let callback = function(req, res, err, message, data){
@@ -423,11 +425,64 @@ module.exports = {
     projectShareInfo: async function(req, res){
         try{
             let data = JSON.parse(req.body.data);
-            let shareInfo = await projectModel.findOne({ID: data.projectID, $or: [{deleteInfo: null}, {'deleteInfo.deleted': false}]}, 'shareInfo');
+            let shareInfo = await projectModel.findOne({ID: data.projectID, $or: [{deleteInfo: null}, {'deleteInfo.deleted': false}]}, '-_id shareInfo');
             callback(req, res, 0, 'success', shareInfo);
         }
         catch (err){
             callback(req, res, 1, err, null);
         }
+    },
+    share: async function(req, res){
+        try{
+            let data = JSON.parse(req.body.data);
+            //添加分享
+            let shareData = {userID: data.userID, allowCopy: data.allowCopy, shareDate: moment(Date.now()).format('YYYY-MM-DD HH:mm:ss')};
+            if(data.type === 'create'){
+                await projectModel.update({ID: data.projectID, $or: [{deleteInfo: null}, {'deleteInfo.deleted': false}]}, {$addToSet: {shareInfo: shareData}});
+            }
+            //取消分享
+            else {
+                await projectModel.update({ID: data.projectID, $or: [{deleteInfo: null}, {'deleteInfo.deleted': false}]}, {$pull: {shareInfo: {userID: data.userID}}});
+            }
+            callback(req, res, 0, 'success', null);
+        }
+        catch (err){
+            callback(req, res, 1, err, null);
+        }
+    },
+    getShareProjects: async function (req, res) {
+        try {
+            let userID = req.session.sessionUser.id;
+            let rst = {receive: [], share: []}//接收的、由我分享的
+            let receiveProjects = await projectModel.find({$or: [{deleteInfo: null}, {'deleteInfo.deleted': false}], 'shareInfo.userID': userID});
+            //设置原项目用户信息
+            if(receiveProjects.length > 0){
+                let orgUserIDs = [];
+                for(let proj of receiveProjects){
+                    orgUserIDs.push(proj.userID);
+                }
+                orgUserIDs = Array.from(new Set(orgUserIDs));
+                let userObjIDs = [];
+                for(let uID of orgUserIDs){
+                    userObjIDs.push(mongoose.Types.ObjectId(uID));
+                }
+                let orgUsersInfo = await userModel.find({_id: {$in : userObjIDs}});
+                for(let proj of receiveProjects){
+                    for(let userInfo of orgUsersInfo){
+                        if(proj.userID == userInfo._id.toString()){
+                            let userInfo = {name: userInfo.name, mobile: userInfo.mobile, company: userInfo.company};
+                            proj._doc.userInfo = userInfo
+                        }
+                    }
+                }
+            }
+            rst.receive = receiveProjects;
+            let shareProjects = await projectModel.find({$or: [{deleteInfo: null}, {'deleteInfo.deleted': false}], 'shareInfo.0': {$exists: true}});
+            rst.share = shareProjects;
+            callback(req, res, 0, 'success', rst);
+        }
+        catch (err){
+            callback(req, res, 1, err, null);
+        }
     }
 };

+ 2 - 0
modules/pm/routes/pm_route.js

@@ -52,6 +52,8 @@ module.exports = function (app) {
     pmRouter.post('/delGC', pmController.delGC);
     //share
     pmRouter.post('/getProjectShareInfo', pmController.projectShareInfo);
+    pmRouter.post('/share', pmController.share);
+    pmRouter.post('/getShareProjects', pmController.getShareProjects);
 
     app.use('/pm/api', pmRouter);
 };

+ 38 - 0
web/building_saas/pm/html/project-management-share.html

@@ -0,0 +1,38 @@
+<div class="toolsbar">
+    <legend class="m-0 pb-1">分享</legend>
+</div>
+<div class="share-list" id="shareSpread">
+    <table class="table table-hover table-sm mb-5">
+        <thead>
+        <tr>
+            <th width="40%">工程列表</th>
+            <th width="10%">由...分享</th>
+            <th width="10%">分享给...</th>
+            <th width="10%">操作</th>
+        </tr>
+        </thead>
+        <tbody>
+        <!--别人共享给我有拷贝权限-->
+        <tr>
+            <td class="in-1">&nbsp;<a href="#">建筑工程2</a></td>
+            <td>由 <a href="javacript:void(0);" data-toggle="modal" data-target="#userinfo">张三</a> 分享</td>
+            <td>分享给 我</td>
+            <td><a href="javacript:void(0);" data-toggle="modal" data-target="#copytomy">拷贝工程</a></td>
+        </tr>
+        <!--别人共享给我无拷贝权限-->
+        <tr>
+            <td class="in-1">&nbsp;<a href="#">建筑工程2</a></td>
+            <td>由 <a href="javacript:void(0);" data-toggle="modal" data-target="#userinfo">张三</a> 分享</td>
+            <td>分享给 我</td>
+            <td></td>
+        </tr>
+        <!--我分享给别人-->
+        <tr>
+            <td class="in-1">&nbsp;<a href="#">建筑工程2</a></td>
+            <td>由 我 分享</td>
+            <td>分享给 <a href="javacript:void(0);" data-toggle="modal" data-target="#userinfo2">张三 <i class="fa fa-files-o"></i></a>、<a href="javacript:void(0);" data-toggle="modal" data-target="#userinfo2">王五</a></td>
+            <td><a href="javacript:void(0);" data-toggle="modal" data-target="#share">添加分享</a></td>
+        </tr>
+        </tbody>
+    </table>
+</div>

+ 4 - 4
web/building_saas/pm/html/project-management.html

@@ -501,15 +501,15 @@
                     <p>分享后,该用户仅可查阅工程,不具备任何编辑修改功能。</p>
                 </div>
                 <div class="form-check">
-                    <input type="checkbox" class="form-check-input" id="exampleCheck1">
-                    <label class="form-check-label" for="exampleCheck1">允许该用户拷贝该工程</label>
+                    <input type="checkbox" class="form-check-input" id="allowCopy">
+                    <label class="form-check-label" for="allowCopy">允许该用户拷贝该工程</label>
                     <!--打勾后出现提示-->
-                    <div id="emailHelp" class="form-text text-danger"><i class="fa fa-exclamation-triangle"></i> 该用户可以把你的项目拷贝成为他的数据,请谨慎勾选。 </div>
+                    <div id="allowCopyHint" class="form-text text-danger"><i class="fa fa-exclamation-triangle"></i> 该用户可以把你的项目拷贝成为他的数据,请谨慎勾选。 </div>
                 </div>
             </div>
             <div class="modal-footer">
                 <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
-                <a href="" class="btn btn-primary">确定分享</a>
+                <a id="share-confirm" href="javascript:void(0);" class="btn btn-primary">确定分享</a>
             </div>
         </div>
     </div>

+ 87 - 36
web/building_saas/pm/js/pm_newMain.js

@@ -259,13 +259,15 @@ const projTreeObj = {
                     icon: 'fa-share',
                     disabled: function () {
                         let selectedItem = projTreeObj.tree.selected;
-                        return true;
-                        // return !(selectedItem && selectedItem.data.projType === projectType.tender);
+                        return !(selectedItem && selectedItem.data.projType === projectType.tender);
                     },
                     callback: function (key, opt) {
+                        $('#sharePhone').val('');
                         $('#share-info').hide();
                         $('#share').find('.card').hide();
                         $('#share').modal('show');
+                        $('#allowCopy').prop('checked', false);
+                        $('#allowCopyHint').hide();
                     }
                 },
             }
@@ -315,6 +317,7 @@ const projTreeObj = {
             return;//如果是复制到表,不用做后面的操作
         }
         me.tree.selected = node;
+        shareSeleted = node;
         me.preSelection = newSel;
         $(".tools-btn > a").not(".disabled").addClass("disabled");
         $("#add-engineering-btn").addClass("disabled");
@@ -2817,55 +2820,103 @@ function refreshTenderFile(tenders, type, newName){
        }
    });
 }
-
-//添加分享
-$('#sharePhone').change(function () {
-    let phone = $(this).val();
-    let hintInfo = $('#share-info');
+//添加分享 pm share共用
+const shareType = {create: 'create', cancel: 'cancel'};
+let shareSeleted = null;
+let shareUserID = null;
+let canShare = false;
+$('#sharePhone').bind('keypress', function (e) {
+    if(e.keyCode === 13){
+        $(this).blur();
+    }
+});
+function shareTender(){
+    canShare = false;
+    let phone = $('#sharePhone').val();
+    const hintInfo = $('#share-info');
+    const userInfo = $('#share').find('.card');
     if(!phone || phone.trim() === ''){
-        replaceClass(hintInfo, 'text-info', 'text-danger');
         setDangerInfo(hintInfo, '请输入手机号码。', true);
+        if(userInfo.is(':visible')){
+            userInfo.hide();
+        }
         return;
     }
     //根据手机号获取用户
-    CommonAjax.post('/user/getUserByMobile', {mobile: phone}, function (rstData) {
-        if(!rstData){
-            replaceClass(hintInfo, 'text-info', 'text-danger');
+    CommonAjax.post('/user/getUserByMobile', {mobile: phone}, function (userData) {
+        if(!userData){
             setDangerInfo(hintInfo, '账号不存在。', true);
+            if(userInfo.is(':visible')){
+                userInfo.hide();
+            }
+            return;
         }
         else{
-            console.log(rstData);
-            $('#user_name').text(rstData.real_name ? rstData.real_name : '');
-            $('#user_company').text(rstData.company ? rstData.company : '');
-            $('#user_mobile').text(rstData.mobile ? rstData.mobile : '');
-            $('#user_email').text(rstData.email ? rstData.email : '');
-            $('#share').find('.card').show();
+            if(userData._id === userID){
+                setDangerInfo(hintInfo, '不可分享给自己。', true);
+                return;
+            }
+            shareUserID = userData._id;
+            setDangerInfo(hintInfo, '', false);
+            $('#user_name').text(userData.real_name ? userData.real_name : '');
+            $('#user_company').text(userData.company ? userData.company : '');
+            let mobileHtml = `<i class="fa fa-tablet"> ${userData.mobile ? userData.mobile : ''}</i>`;
+            $('#user_mobile').html(mobileHtml);
+            let emailHtml = `<i class="fa fa-envelope-o"> ${userData.email ? userData.email : ''}</i>`;
+            $('#user_email').html(emailHtml);
+            userInfo.show();
             //判断项目是否已经分享
-            //CommonAjax.post('/pm/api/getProjectShareInfo');
+            CommonAjax.post('/pm/api/getProjectShareInfo', {user_id: userID, projectID: shareSeleted.data.ID}, function (rstData) {
+                for(let shareData of rstData.shareInfo){
+                    if(shareData.userID === userData._id){
+                        setDangerInfo(hintInfo, '已与该用户分享。', true);
+                        return;
+                    }
+                }
+                canShare = true;
+            });
         }
     });
+}
+$('#sharePhone').on('keyup',function () {
+    shareTender();
 });
-
-function shareTender(){
+//确认分享
+$('#share-confirm').click(function(){
     let phone = $('#sharePhone').val();
-    let hintInfo = $('#share-info');
+    const hintInfo = $('#share-info');
+    const userInfo = $('#share').find('.card');
     if(!phone || phone.trim() === ''){
-        replaceClass(hintInfo, 'text-info', 'text-danger');
         setDangerInfo(hintInfo, '请输入手机号码。', true);
+        if(userInfo.is(':visible')){
+            userInfo.hide();
+        }
         return;
     }
-    //根据手机号获取用户
-    CommonAjax.post('/user/getUserByMobile', {mobile: phone}, function (rstData) {
-        if(!rstData){
-            replaceClass(hintInfo, 'text-info', 'text-danger');
-            setDangerInfo(hintInfo, '账号不存在。', true);
-        }
-        else{
-            $('#user_name').text(rstData.real_name ? rstData.real_name : '');
-            $('#user_company').text(rstData.company ? rstData.company : '');
-            $('#user_mobile').text(rstData.mobile ? rstData.mobile : '');
-            $('#user_email').text(rstData.email ? rstData.email : '');
-            $('#share').find('.card').show();
-        }
+    if(!canShare){
+        return;
+    }
+    $('#share-confirm').addClass('disabled');
+    $.bootstrapLoading.start();
+    let allowCopy = $('#allowCopy').prop('checked');
+    //分享
+    CommonAjax.post('/pm/api/share', {user_id: userID, type: shareType.create,  projectID: shareSeleted.data.ID, userID: shareUserID, allowCopy: allowCopy}, function (rstData) {
+        $.bootstrapLoading.end();
+        $('#share-confirm').removeClass('disabled');
+        $('#share').modal('hide');
+    }, function () {
+        $.bootstrapLoading.end();
+        $('#share-confirm').removeClass('disabled');
+        $('#share').modal('hide');
     });
-}
+});
+//允许拷贝
+$('#allowCopy').change(function () {
+    let checked = $(this).prop('checked');
+    if(checked){
+        $('#allowCopyHint').show();
+    }
+    else{
+        $('#allowCopyHint').hide();
+    }
+});

+ 108 - 0
web/building_saas/pm/js/pm_share.js

@@ -0,0 +1,108 @@
+'use strict';
+
+/**
+ *
+ *
+ * @author Zhong
+ * @date 2018/6/28
+ * @version
+ */
+
+const pmShare = (function () {
+    const spreadDom = $('#shareSpread');
+    let spread = null;
+    const headers = [
+        {name: '工程列表', dataCode: 'name', width: 0.55, vAlign: 'center', hAlign: 'left'},
+        {name: '由...分享', dataCode: 'from', width: 0.15, vAlign: 'center', hAlign: 'right'},
+        {name: '分享给...', dataCode: 'to', width: 0.15, vAlign: 'center', hAlign: 'left'},
+        {name: '操作', dataCode: 'operation', width: 0.15, vAlign: 'center', hAlign: 'left'},
+    ];
+    const spreadOpts = {
+        workBook: {
+            tabStripVisible:  false,
+            allowContextMenu: false,
+            allowCopyPasteExcelStyle : false,
+            allowExtendPasteRange: false,
+            allowUserDragDrop : false,
+            allowUserDragFill: false,
+            scrollbarMaxAlign : true
+        },
+        sheet: {
+            isProtected: true,
+            protectionOptions: {allowResizeRows: true, allowResizeColumns: true},
+            clipBoardOptions: GC.Spread.Sheets.ClipboardPasteOptions.values
+        }
+    };
+
+    //渲染时方法,停止渲染
+    //@param {Object}sheet {Function}func @return {void}
+    function renderSheetFunc(sheet, func){
+        sheet.suspendEvent();
+        sheet.suspendPaint();
+        if(func){
+            func();
+        }
+        sheet.resumeEvent();
+        sheet.resumePaint();
+    }
+    //设置表选项
+    //@param {Object}workBook {Object}opts @return {void}
+    function setSpreadOptions (workBook, opts) {
+        for(let opt in opts.workBook){
+            workBook.options[opt] = opts.workBook[opt];
+        }
+        for(let opt in opts.sheet){
+            workBook.getActiveSheet().options[opt] = opts.sheet[opt];
+        }
+    }
+    //建表头
+    //@param {Object}sheet {Array}headers @return {void}
+    function buildHeader(sheet, headers) {
+        let fuc = function () {
+            sheet.setColumnCount(headers.length);
+            sheet.setRowHeight(0, 40, GC.Spread.Sheets.SheetArea.colHeader);
+            for(let i = 0, len = headers.length; i < len; i++){
+                sheet.setValue(0, i, headers[i].name, GC.Spread.Sheets.SheetArea.colHeader);
+                sheet.setColumnWidth(i, headers[i].width, GC.Spread.Sheets.SheetArea.colHeader);
+                if(headers[i].formatter){
+                    sheet.setFormatter(-1, i, headers[i].formatter);
+                }
+                sheet.getRange(-1, i, -1, 1).hAlign(GC.Spread.Sheets.HorizontalAlign[headers[i]['hAlign']]);
+                sheet.getRange(-1, i, -1, 1).vAlign(GC.Spread.Sheets.VerticalAlign[headers[i]['vAlign']]);
+            }
+        };
+        renderSheetFunc(sheet, fuc);
+    }
+    //表监听事件
+    //@param {Object}workBook @return {void}
+    function bindEvent(workBook, events) {
+        if(Object.keys(events).length === 0){
+            return;
+        }
+        const Events = GC.Spread.Sheets.Events;
+        for(let event in events){
+            workBook.bind(Events[event], events[event]);
+        }
+    }
+    //建表
+    //
+    function buildSheet(){
+        if(spread){
+            spread.destroy();
+            return;
+        }
+        spread = new GC.Spread.Sheets.Workbook(spreadDom[0], {sheetCount: 1});
+        setSpreadOptions(spread, spreadOpts);
+        const sheet = spread.getActiveSheet();
+        buildHeader(sheet, headers);
+        //全表不可编辑
+        sheet.getRange(-1, -1, -1, -1).locked(true);
+
+    }
+
+    return {buildSheet}
+})();
+
+$(document).ready(function () {
+
+});