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,
}
})();