| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438 | const SHARE_TO = (() => {    const ShareType = {        CREATE: 'create',        UPDATE: 'update',        CANCEL: 'cancel',    };    // 当前分享的项目ID    let curProjectID;    // 当前项目的已分享列表    let curSharedUsers = [];    // 清除缓存    function clearCache() {        curProjectID = null;        curSharedUsers = [];    }    // 最近联系人显示数量    const rencentCount = 5;    // 获取初始数据:1.最近分享人 2.联系人 3.已分享人    async function getInitalData(projectID) {        return await ajaxPost('/pm/api/getInitialShareData', { user_id: userID, count: rencentCount, projectID }, false);    }    // 获取头像视图html    function getAvatarHTML(mobile, realName) {        // 手机最后一位        const lastMobileNumer = mobile.substr(-1);        // 显示名称为真实名称后两位        const nickName = realName.substr(-2);        return `<span class="avatar bg-${lastMobileNumer}">${nickName}</span>`;    }    /**     * 获取用户列表视图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 += `<li class="letter">${letter}</li>`;                }            }            const avatarHtml = getAvatarHTML(mobile, realName);            return html +                `<li>                    ${avatarHtml}                    <div class="book-body">                        <h5 class="mt-0" title="${company}">${realName}</h5>                        <span>${mobile}</span>                    </div>                </li>`;        }, '');    }    // 初始化最近分享视图    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 +                `<li class="card mb-1">                    <div class="card-body p-1 row m-0">                        ${avatarHTML}                        <div class="book-body col-auto pl-0">                            <h5 class="mt-0">${realName}</h5>                            ${mobile}                        </div>                        <div class="col-5">${company}</div>                        <div class="col ml-auto p-0">                            <div class="d-flex justify-content-end">                                <div>                                    <div class="custom-control custom-checkbox">                                        <input type="checkbox" class="custom-control-input allow-copy" id="${copyLabelFor}" data-user="${user._id}" ${user.allowCopy ? 'checked' : ''}>                                        <label class="custom-control-label" for="${copyLabelFor}">允许拷贝</label>                                    </div>                                    <div class="custom-control custom-checkbox">                                        <input type="checkbox" class="custom-control-input allow-edit" id="${editLabelFor}" data-user="${user._id}" ${user.allowCooperate ? 'checked' : ''}>                                        <label class="custom-control-label" for="${editLabelFor}">允许编辑</label>                                    </div>                                </div>                                <div class="ml-3 d-flex align-items-center">                                    <button class="btn btn-sm btn-outline-danger cancel-share" data-user="${user._id}">取消分享</button>                                </div>                            </div>                        </div>                    </div>                </li>`;        }, '');        $('#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 () {            handleShareAction.call(this, ShareType.CANCEL);        });    }    // 初始化搜索结果视图    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 =                `<li class="card mb-1">                        <div class="card-body p-1 row m-0">                            ${avatarHTML}                            <div class="book-body col-auto pl-0">                                <h5 class="mt-0">${realName}</h5>                                ${mobile}                            </div>                            <div class="col-5">${company}</div>                            <div class="col ml-auto p-0">                                    <div class="d-flex justify-content-end">                                        <div>                                            <div class="custom-control custom-checkbox">                                                <input type="checkbox" class="custom-control-input" id="allow-copy" checked="">                                                <label class="custom-control-label" for="allow-copy">允许拷贝</label>                                            </div>                                            <div class="custom-control custom-checkbox">                                                <input type="checkbox" class="custom-control-input" id="allow-edit">                                                <label class="custom-control-label" for="allow-edit">允许编辑</label>                                            </div>                                        </div>                                        <div class="ml-3 d-flex align-items-center"><button class="btn btn-sm btn-primary" id="share-to" data-user="${user._id}">分享给Ta</button></div>                                    </div>                                </div>                        </div>                    </li>`;            $('#share-search-result').html(html);            // 允许拷贝            $('#allow-copy').click(function () {                handleCheckBoxClick.call(this);            });            // 允许编辑            $('#allow-edit').click(function () {                handleCheckBoxClick.call(this);            });            // 分享给事件            $('#share-to').click(function () {                handleShareAction.call(this, ShareType.CREATE, user);            });        }    }    // 复选框框的状态随点击更改,不处理的话input的checked并不会自动处理    function handleCheckBoxClick() {        const curChecked = !$(this).attr('checked');        if (curChecked) {            $(this).attr('checked', 'checked');        } else {            $(this).removeAttr('checked');        }    }    // 添加分享、编辑分享、取消分享的动作    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').attr('checked');                const allowCooperate = !!$('#allow-edit').attr('checked');                shareData = [{ userID: receiver, allowCopy, allowCooperate }];                type = ShareType.CREATE; // 上传的服务器的type,删除跟更新是一样的            } else if (shareType === ShareType.UPDATE) {                const allowCopy = !!$(`[data-user=${receiver}].allow-copy`).attr('checked');                const allowCooperate = !!$(`[data-user=${receiver}].allow-edit`).attr('checked');                shareData = [{ userID: receiver, allowCopy, allowCooperate }];            } else {                shareData = [{ userID: receiver, isCancel: true }];            }            const postData = {                user_id: userID,                type,                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();            }        } catch (err) {            console.log(err);            alert(`${String(err)} 请重试。`);            initSharedView(curSharedUsers);        } finally {            $.bootstrapLoading.end();        }    }    // 刷新项目管理树视图    // 如果是在项目管理页面,需要刷新树(分享图标可能需要清除)    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);    }    // 初始化分享给的页面    async function initModal(projectID) {        try {            curProjectID = projectID;            $.bootstrapLoading.start();            // 恢复            $('#share-phone').val('');            initSearchResultView();            $('#share-hint').text('');            const { sharedUsers, recentUsers, contacts } = await getInitalData(projectID);            curSharedUsers = sharedUsers;            initSharedView(sharedUsers);            initRecentView(recentUsers);            initContactsView(contacts);            $.bootstrapLoading.end();            setTimeout(() => $('#sharePhone').focus(), 200);            $('#share').modal('show');        } catch (err) {            console.log(err);            alert(err);            $.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 () {                handleSearch();            });        });        $('#sharePhone').on('keypress', function (e) {            if (e.keyCode === 13) {                $(this).blur();            }        });    }    return {        initModal,        handleEventListener,        getAvatarHTML,    }})();
 |