const SHARE_TO = (() => { const ShareType = { CREATE: 'create', UPDATE: 'update', CANCEL: 'cancel', }; const { SharePermissionChangeType: PermissionType, PageTarget, ShareLibType } = commonConstants; const Mode = { PROJECT: 1, RATION_LIB: 2, GLJ_LIB: 3, BLOCK_LIB: 4, }; const ModeToLibType = { [Mode.RATION_LIB]: ShareLibType.RATION_LIB, [Mode.GLJ_LIB]: ShareLibType.GLJ_LIB, [Mode.BLOCK_LIB]: ShareLibType.BLOCK_LIB, }; // 当前模式 let curMode = Mode.PROJECT; // 当前分享的项目ID let curProjectID; // 当前项目的已分享列表 let curSharedUsers = []; // 清除缓存 function clearCache() { curProjectID = null; curSharedUsers = []; } // 最近联系人显示数量 const rencentCount = 5; // 获取初始数据:1.最近分享人 2.联系人 3.已分享人 async function getInitialData(projectID) { return await ajaxPost('/pm/api/getInitialShareData', { user_id: userID, count: rencentCount, projectID }, false); } // 获取分享库的初始数据 async function getInitialLibData(libType) { return await ajaxPost('/pm/api/getInitialShareLibData', { user_id: userID, count: rencentCount, libType }, false); } // 获取头像视图html function getAvatarHTML(mobile, realName) { // 手机最后一位 const lastMobileNumer = mobile.substr(-1); // 显示名称为真实名称后两位 const nickName = realName.substr(-2); return `${nickName}`; } /** * 获取用户列表视图html:最近分享和联系人用 * @param {Array} users - 排序过的用户数据 * @param {Boolean} showAlphabet - 是否显示字母表分类 * @return {HTMLString} * */ function getUserHTML(users, showAlphabet) { let curLetter = ''; return users.reduce((html, user) => { const mobile = user.mobile || ''; const realName = user.real_name || ''; const company = user.company || ''; if (showAlphabet) { // 名字首个字符对应拼音 const letter = pinyinUtil.getFirstLetter(realName).substr(0, 1); if (letter !== curLetter) { curLetter = letter; html += `
  • ${letter}
  • `; } } const avatarHtml = getAvatarHTML(mobile, realName); return html + `
  • ${avatarHtml}
    ${realName}
    ${mobile}
  • `; }, ''); } // 初始化最近分享视图 function initRecentView(recentUsers) { const recentShareHTML = getUserHTML(recentUsers, false); $('#recent-share').html(recentShareHTML); // 点击最近分享列表自动添加该用户添加到搜索框中 $('#recent-share li').click(function () { const mobile = $(this).find('div span')[0].textContent; $('#share-phone').val(mobile); handleSearch() }) } // 初始化联系人视图 function initContactsView(contacts) { // 联系人按拼英首字母降序排序 contacts.sort((a, b) => { const realNameA = a.real_name || ''; const realNameB = b.real_name || ''; return realNameA.localeCompare(realNameB, 'zh-Hans-CN', { sensitivity: 'accent' }) }); const contactsHTML = getUserHTML(contacts, true); $('#contacts').html(contactsHTML); // 点击联系人自动添加该联系人添加到搜索框中 $('#contacts li:not(.letter)').click(function () { const mobile = $(this).find('div span')[0].textContent; $('#share-phone').val(mobile); $('#contacts-menue').removeClass('show'); handleSearch() }); } // 初始化已分享视图 function initSharedView(sharedUsers) { const html = sharedUsers.reduce((html, user, index) => { const mobile = user.mobile || ''; const realName = user.real_name || ''; const company = user.company || ''; const avatarHTML = getAvatarHTML(mobile, realName); const copyLabelFor = `allowCopy${index}`; const editLabelFor = `allowEdit${index}`; return html + `
  • ${avatarHTML}
    ${realName}
    ${mobile}
    ${company}
    ${curMode === Mode.PROJECT ? `
    ` : ''}
  • `; }, ''); $('#shared-list').html(html); // 编辑允许拷贝 $('#shared-list .allow-copy').click(function () { handleCheckBoxClick.call(this); handleShareAction.call(this, ShareType.UPDATE); }); // 编辑允许编辑 $('#shared-list .allow-edit').click(function () { handleCheckBoxClick.call(this); handleShareAction.call(this, ShareType.UPDATE); }); // 取消分享 $('#shared-list .cancel-share').click(function () { if (curMode === Mode.PROJECT) { handleShareAction.call(this, ShareType.CANCEL); } else { handleShareLibAction.call(this, ShareType.CANCEL, ModeToLibType[curMode]); } }); } // 初始化搜索结果视图 function initSearchResultView(user) { if (!user) { $('#share-search-result').html('') } else { const mobile = user.mobile || ''; const realName = user.real_name || ''; const company = user.company || ''; const avatarHTML = getAvatarHTML(mobile, realName); const html = `
  • ${avatarHTML}
    ${realName}
    ${mobile}
    ${company}
    ${curMode === Mode.PROJECT ? `
    ` : ''}
  • `; $('#share-search-result').html(html); // 允许拷贝 $('#allow-copy').click(function () { handleCheckBoxClick.call(this); }); // 允许编辑 $('#allow-edit').click(function () { handleCheckBoxClick.call(this); }); // 分享给事件 $('#share-to').click(function () { if (curMode === Mode.PROJECT) { handleShareAction.call(this, ShareType.CREATE, user); } else { handleShareLibAction.call(this, ShareType.CREATE, ModeToLibType[curMode], user); } }); } } // 复选框框的状态随点击更改,不处理的话input的checked并不会自动处理 function handleCheckBoxClick() { const curChecked = !$(this).attr('checked'); if (curChecked) { $(this).attr('checked', 'checked'); } else { $(this).removeAttr('checked'); } } async function handleShareLibAction(shareType, libType, user) { try { $.bootstrapLoading.start(); const receiver = $(this).data('user'); let shareData; if (shareType === ShareType.CREATE) { shareData = [{ receiver }]; } else if (shareType === ShareType.CANCEL) { shareData = [{ receiver, isCancel: true }]; } const postData = { type: shareType, user_id: userID, count: rencentCount, libType, shareData }; const rst = await ajaxPost('/pm/api/shareLib', postData); // 请求成功后刷新视图 if (shareType === ShareType.CREATE || shareType === ShareType.CANCEL) { if (shareType === ShareType.CREATE) { curSharedUsers.unshift(user); $('#share-phone').val(''); initSearchResultView(); } else { curSharedUsers = curSharedUsers.filter(user => user._id !== receiver); } if (libType === ShareLibType.BLOCK_LIB) { const shareTip = curSharedUsers.length ? curSharedUsers.reduce((acc, user) => acc += ` ${user.real_name}`, '已分享给') : ''; blockLibObj.initialShareTip = shareTip; $('#btn_block_share').attr('data-original-title', shareTip); } if (Array.isArray(rst.recentUsers)) { initRecentView(rst.recentUsers); } if (Array.isArray(rst.contacts)) { initContactsView(rst.contacts) } initSharedView(curSharedUsers); refreshShareTip(curSharedUsers); refreshTreeView(); } } catch (err) { console.log(err); alert(`${String(err)} 请重试。`); initSharedView(curSharedUsers); } finally { $.bootstrapLoading.end(); } } // 添加分享、编辑分享、取消分享的动作 async function handleShareAction(shareType, user) { try { $.bootstrapLoading.start(); const receiver = $(this).data('user'); let shareData; let type = ShareType.UPDATE; if (shareType === ShareType.CREATE) { const allowCopy = $('#allow-copy').prop('checked'); const allowCooperate = $('#allow-edit').prop('checked'); shareData = [{ userID: receiver, allowCopy, allowCooperate }]; type = ShareType.CREATE; // 上传的服务器的type,删除跟更新是一样的 } else if (shareType === ShareType.UPDATE) { const allowCopy = $(`[data-user=${receiver}].allow-copy`).prop('checked'); const allowCooperate = $(`[data-user=${receiver}].allow-edit`).prop('checked'); shareData = [{ userID: receiver, allowCopy, allowCooperate }]; } else { shareData = [{ userID: receiver, isCancel: true }]; } // 获取权限变更的类型 const permissionType = getPermissionType(shareType, curSharedUsers, shareData[0]); const postData = { user_id: userID, type, permissionType, projectID: curProjectID, count: rencentCount, shareData }; const rst = await ajaxPost('/pm/api/share', postData); // 请求成功后刷新视图 if (shareType === ShareType.CREATE || shareType === ShareType.CANCEL) { if (shareType === ShareType.CREATE) { user.allowCopy = shareData[0].allowCopy; user.allowCooperate = shareData[0].allowCooperate; curSharedUsers.unshift(user); $('#share-phone').val(''); initSearchResultView(); } else { curSharedUsers = curSharedUsers.filter(user => user._id !== receiver); } if (Array.isArray(rst.recentUsers)) { initRecentView(rst.recentUsers); } if (Array.isArray(rst.contacts)) { initContactsView(rst.contacts) } initSharedView(curSharedUsers); refreshShareTip(curSharedUsers); refreshTreeView(); } else { const matchItem = curSharedUsers.find(item => item._id === receiver); if (matchItem) { matchItem.allowCopy = shareData[0].allowCopy; matchItem.allowCooperate = shareData[0].allowCooperate; } } if (permissionType !== null) { const payload = [PermissionType.UPDATE_COOPERATE, PermissionType.UPDATE_COPY].includes(permissionType) ? { prop: { allowCopy: shareData[0].allowCopy, allowCooperate: shareData[0].allowCooperate } } : null; emitPermissionChange(permissionType, receiver, curProjectID, rst.emitTenders, payload); } } catch (err) { console.log(err); alert(`${String(err)} 请重试。`); initSharedView(curSharedUsers); } finally { $.bootstrapLoading.end(); } } // 获取权限变更的类型 function getPermissionType(shareType, cache, curShareData) { if (shareType === ShareType.CANCEL) { return PermissionType.CANCEL; } if (shareType === ShareType.CREATE) { return PermissionType.SHARE; } if (!cache) { return null; } const match = cache.find(item => item._id === curShareData.userID); if (!match) { return null; } if (match.allowCooperate !== curShareData.allowCooperate) { return PermissionType.UPDATE_COOPERATE; } if (match.allowCopy !== curShareData.allowCopy) { return PermissionType.UPDATE_COPY; } return null; } // 权限变更消息推送 function emitPermissionChange(permissionType, userID, projectID, emitTenders, payload) { const compilationID = typeof projectObj !== 'undefined' ? projectObj.project.projectInfo.compilation : compilationData._id; socket.emit('sharePermissionChange', { permissionType, userID, compilationID, projectID, emitTenders, payload }); } // 权限变更处理监听 function permissionChangeListener() { socket.on('sharePermissionChange', ({ permissionType, target, payload }) => { const type = `${permissionType}-${target}`; switch (type) { case `${PermissionType.READ}-${PageTarget.PM}`: handleShareItemRead(payload); break; case `${PermissionType.UPDATE_COOPERATE}-${PageTarget.PM}`: case `${PermissionType.UPDATE_COPY}-${PageTarget.PM}`: handlePMPropChange(payload); break; case `${PermissionType.UPDATE_COOPERATE}-${PageTarget.MAIN}`: handleMainCooperateChange(payload); break; case `${PermissionType.CANCEL}-${PageTarget.PM}`: handlePMCancelPermission(payload); break; case `${PermissionType.CANCEL}-${PageTarget.MAIN}`: handleMainCancelPermission(); break; case `${PermissionType.SHARE}-${PageTarget.PM}`: handlePMSharePermission(payload); break; } }); } // 项目管理页面分享权限变更后相关处理函数 // 已读分享项目 function handleShareItemRead({ markReadProjectIDs }) { const isActive = $('#tab_pm_share').hasClass('active'); if (isActive) { pmShare.handleMarkRead(unreadShareList, markReadProjectIDs); } else { markReadProjectIDs.forEach(projectID => { removeUnread(projectID, unreadShareList); }); } } // 分享条数属性变更(是否可拷贝、是否可编辑) // @param {Object} prop - 属性变更对象 eg: { allowCopy: false } function handlePMPropChange({ projectID, prop }) { // 如果当前在项目管理的分享页面,需要刷新相关节点 const isActive = $('#tab_pm_share').hasClass('active'); if (isActive) { pmShare.handlePropChange(projectID, prop); } } // 已读某未读分享项目 function removeUnread(projectID, list) { const idx = list.indexOf(projectID); if (idx >= 0) { list.splice(idx, 1); refreshUnreadCount(list.length); } } // 取消分享后项目管理页面接收到推送后到操作 function handlePMCancelPermission({ projectID }) { removeUnread(projectID, unreadShareList); // 如果当前停留在分享标签界面,清楚分享项目 const isActive = $('#tab_pm_share').hasClass('active'); if (isActive) { pmShare.handleCancelShare(projectID); } } // 通知信息点击事件 function notify() { pmShare.initShareTree(); $("#notify").hide(); } // 新增分享后项目管理页面接收到推送后的操作 function handlePMSharePermission({ projectID }) { unreadShareList.push(projectID); unreadShareList = [...new Set(unreadShareList)]; refreshUnreadCount(unreadShareList.length); // 如果当前停留在分享标签界面,需要弹出提示 const isActive = $('#tab_pm_share').hasClass('active'); if (isActive) { $("#message").html('您有新的分享项目,点击刷新列表'); $("#notify").show(); } } // 刷新未读分享标记 function refreshUnreadCount(count) { if (count) { $('#unread-share-count').text(count); $('#unread-share-count').show(); } else { $('#unread-share-count').hide(); } } // 主页面的分享权限变更后相关处理函数 function handleMainCooperateChange({ allowCooperate }) { if (projectObj.project.projectInfo.shareState && projectObj.project.projectInfo.shareState.allowCooperate !== allowCooperate) { setLocalCache(commonConstants.StorageKey.ONCE_MAIN_LOADED, '分享设置已被修改,当前项目已自动刷新。'); window.location.reload(); } } function handleMainCancelPermission() { // 定位到空白页 window.location.replace(`/blank?type=${commonConstants.BlankType.SHARE_CANCEL}`); } // 刷新项目管理树视图 // 如果是在项目管理页面,需要刷新树(分享图标可能需要清除) function refreshTreeView() { if (typeof projTreeObj !== 'undefined' && projTreeObj.tree.selected) { projTreeObj.tree.selected.data.shareInfo = curSharedUsers; const sheet = projTreeObj.workBook.getSheet(0); projTreeObj.renderSheetFuc(sheet, function () { sheet.invalidateLayout(); sheet.repaint(); }); } } // 刷新造价书的分享按钮tooltip提示 function refreshShareTip(sharedUsers) { const $shareTip = $('#share-tip'); if (!$shareTip) { return; } const limit = 2; const count = sharedUsers.length; const users = sharedUsers.slice(0, 2); const tip = users.reduce((acc, user, index) => { if (index === 0) { acc += '已分享给'; acc += user.real_name; } else { acc += ` ${user.real_name}`; } if (index === users.length - 1 && count > limit) { acc += `等${count}人`; } return acc; }, ''); $shareTip.attr('data-original-title', tip); } // 初始化分享给的页面 // mode: 模式,分享项目、分享库 async function initModal(mode, projectID) { try { curMode = mode; $.bootstrapLoading.start(); // 恢复 $('#share-phone').val(''); initSearchResultView(); $('#share-hint').text(''); let sharedUsers = []; let recentUsers = []; let contacts = []; let data; if (mode === Mode.PROJECT) { curProjectID = projectID; data = await getInitialData(projectID); if (data.isFree) { return hintBox.versionBox('此功能仅在专业版中提供,免费版可选择单位工程进行分享。'); } } else { data = await getInitialLibData(ModeToLibType[curMode]); } sharedUsers = data.sharedUsers; recentUsers = data.recentUsers; contacts = data.contacts; curSharedUsers = sharedUsers; initSharedView(sharedUsers); initRecentView(recentUsers); initContactsView(contacts); setTimeout(() => $('#share-phone').focus(), 200); $('#share').modal('show'); } catch (err) { console.log(err); alert(err); } finally { $.bootstrapLoading.end(); } } // 退出分享给页面 function exitModal() { clearCache(); } // 分享给 async function handleSearch() { let phone = $('#share-phone').val(); phone = phone && phone.trim() || ''; //$('#share-hint').text(''); initSearchResultView(); if (!phone) { $('#share-hint').text('请输入手机号码。'); return; } // 根据手机号获取用户 const user = await ajaxPost('/user/getUserByMobile', { mobile: phone }); if (!user) { $('#share-hint').text('账号不存在。'); return; } if (user._id === userID) { $('#share-hint').text('不可分享给自己。'); return; } const matched = curSharedUsers.find(item => item._id === user._id); if (matched) { $('#share-hint').text('已与该用户分享。'); return; } $('#share-hint').text(''); initSearchResultView(user); } // 一些事件的监听 function handleEventListener() { // 界面消失 $('#share').on('hide.bs.modal', function () { exitModal(); }); // 联系人下拉 $('#contacts-dropdown').click(function () { const $subMenu = $('#contacts-menue'); const visible = $subMenu.is(':visible'); if (visible) { $subMenu.removeClass('show'); } else { $subMenu.addClass('show'); } }); // 点击body时,联系人菜单的处理 $('body').click(function (e) { const body = $(this)[0]; const $contactsMenu = $('#contacts-menue'); const contactsMenu = $contactsMenu[0]; const dropdownButton = $('#contacts-dropdown')[0] if (!$contactsMenu.is(':visible')) { return; } let target = e.target; while (target !== body) { if ([contactsMenu, dropdownButton].includes(target)) { return; } target = target.parentElement; } $(contactsMenu.parentElement).removeClass('show'); $contactsMenu.removeClass('show'); }); // 输入手机号查找要分享给的用户 let keyupTime = 0; let delayTime = 500; function delayKeyup(callback) { const nowTime = Date.now(); keyupTime = nowTime; setTimeout(function () { if (nowTime - keyupTime == 0) { callback(); } }, delayTime); } $('#share-phone').on('keyup', function () { delayKeyup(function () { console.log(curSharedUsers); handleSearch(); }); }); $('#sharePhone').on('keypress', function (e) { if (e.keyCode === 13) { $(this).blur(); } }); } return { Mode, initModal, handleEventListener, permissionChangeListener, emitPermissionChange, getAvatarHTML, notify, removeUnread, } })();