mirror of
https://github.com/kuaifan/dootask.git
synced 2025-12-14 12:42:51 +00:00
perf: 优化用户选择器
This commit is contained in:
parent
7de575e236
commit
d4ef140c8e
@ -19,20 +19,15 @@
|
||||
<!-- 顶部 -->
|
||||
<template #header>
|
||||
<div v-if="isFullscreen" class="user-modal-header">
|
||||
<div class="user-modal-close" @click="[ !multipleChoice && showMultiple ? showMultiple=false : showModal=false]">
|
||||
{{ !multipleChoice && showMultiple ? $L('取消') : $L('关闭') }}
|
||||
</div>
|
||||
<div class="user-modal-close" @click="showModal=false">{{$L('关闭')}}</div>
|
||||
<div class="user-modal-title"><span>{{localTitle}}</span></div>
|
||||
<div v-if="showMultiple" class="user-modal-submit" @click="onSubmit(1)">
|
||||
<div class="user-modal-submit" @click="onSubmit">
|
||||
<div v-if="submittIng > 0" class="submit-loading"><Loading /></div>
|
||||
{{$L('确定')}}
|
||||
<template v-if="selects.length > 0">
|
||||
({{selects.length}}<span v-if="multipleMax">/{{multipleMax}}</span>)
|
||||
</template>
|
||||
</div>
|
||||
<div v-else-if="!forcedRadio" class="user-modal-submit" @click="showMultiple = true">
|
||||
{{$L('多选')}}
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="ivu-modal-header-inner">{{localTitle}}</div>
|
||||
</template>
|
||||
@ -42,7 +37,7 @@
|
||||
|
||||
<!-- 搜索 -->
|
||||
<div class="user-modal-search">
|
||||
<Scrollbar ref="selected" class="search-selected" v-if="showMultiple && selects.length > 0" enable-x :enable-y="false">
|
||||
<Scrollbar ref="selected" class="search-selected" v-if="selects.length > 0" enable-x :enable-y="false">
|
||||
<ul>
|
||||
<li v-for="item in formatSelect(selects)" :data-id="item.userid" @click.stop="onRemoveItem(item.userid)">
|
||||
<template v-if="item.type=='group'">
|
||||
@ -69,7 +64,6 @@
|
||||
<ul v-if="isWhole" class="user-modal-switch">
|
||||
<li
|
||||
v-for="item in switchItems" :key="item.key"
|
||||
v-if="!(forcedRadio && !showMultiple && item.key == 'project')"
|
||||
:class="{active:switchActive===item.key}"
|
||||
@click="switchActive=item.key">{{ $L(item.label) }}</li>
|
||||
</ul>
|
||||
@ -82,19 +76,15 @@
|
||||
v-for="item in lists"
|
||||
:class="selectClass(item.userid_list)"
|
||||
@click="onSelectProject(item.userid_list)">
|
||||
<template v-if="showMultiple">
|
||||
<Icon class="user-modal-icon" :type="selectIcon(item.userid_list)" />
|
||||
</template>
|
||||
<Icon class="user-modal-icon" :type="selectIcon(item.userid_list)" />
|
||||
<div class="user-modal-avatar">
|
||||
<i class="taskfont icon-avatar"></i>
|
||||
<div class="project-name">
|
||||
<div class="label">{{item.name}}</div>
|
||||
<div class="subtitle">
|
||||
{{item.userid_list.length}} {{$L('项目成员')}}
|
||||
<template v-if="showMultiple">
|
||||
<em class="all">{{$L('已全选')}}</em>
|
||||
<em class="some">{{$L('已选部分')}}</em>
|
||||
</template>
|
||||
<em class="all">{{$L('已全选')}}</em>
|
||||
<em class="some">{{$L('已选部分')}}</em>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -103,7 +93,7 @@
|
||||
<!-- 会员、会话 -->
|
||||
<ul v-else>
|
||||
<li
|
||||
v-if="showMultiple && showSelectAll"
|
||||
v-if="showSelectAll"
|
||||
:class="selectClass('all')"
|
||||
@click="onSelectAll">
|
||||
<Icon class="user-modal-icon" :type="selectIcon('all')" />
|
||||
@ -116,10 +106,8 @@
|
||||
disabled: isUncancelable(item.userid) || isDisabled(item.userid)
|
||||
}"
|
||||
@click="onSelectItem(item)">
|
||||
<template v-if="showMultiple">
|
||||
<Icon v-if="selects.includes(item.userid)" class="user-modal-icon" type="ios-checkmark-circle" />
|
||||
<Icon v-else class="user-modal-icon" type="ios-radio-button-off" />
|
||||
</template>
|
||||
<Icon v-if="selects.includes(item.userid)" class="user-modal-icon" type="ios-checkmark-circle" />
|
||||
<Icon v-else class="user-modal-icon" type="ios-radio-button-off" />
|
||||
<div v-if="item.type=='group'" class="user-modal-avatar">
|
||||
<EAvatar v-if="item.avatar" class="img-avatar" :src="item.avatar" :size="40"></EAvatar>
|
||||
<i v-else-if="item.group_type=='department'" class="taskfont icon-avatar department"></i>
|
||||
@ -146,57 +134,12 @@
|
||||
|
||||
<!-- 底部 -->
|
||||
<template #footer>
|
||||
<Button v-if="!forcedRadio && !multipleChoice && showMultiple" @click="showMultiple = false">
|
||||
{{$L('取消')}}
|
||||
</Button>
|
||||
<Button v-if="!forcedRadio && showMultiple" type="primary" :loading="submittIng > 0" @click="onSubmit(1)">
|
||||
<Button type="primary" :loading="submittIng > 0" @click="onSubmit">
|
||||
{{$L('确定')}}
|
||||
<template v-if="selects.length > 0">
|
||||
({{selects.length}}<span v-if="multipleMax">/{{multipleMax}}</span>)
|
||||
</template>
|
||||
</Button>
|
||||
<Button v-else-if="!forcedRadio" type="primary" @click="showMultiple = true">
|
||||
{{$L('多选')}}
|
||||
</Button>
|
||||
</template>
|
||||
</Modal>
|
||||
|
||||
<!-- 二次确认 -->
|
||||
<Modal
|
||||
v-model="showAffirmModal"
|
||||
:title="twiceAffirmTitle"
|
||||
class-name="common-user-select-modal twice-affirm-modal"
|
||||
:mask-closable="false"
|
||||
width="420">
|
||||
<div class="user-modal-search twice-affirm">
|
||||
<Scrollbar class="search-selected" v-if="selects?.length > 0" enable-x :enable-y="false">
|
||||
<ul>
|
||||
<li v-for="item in formatSelect(selects)" :data-id="item.userid">
|
||||
<div v-if="item.type=='group'" class="user-modal-avatar">
|
||||
<EAvatar v-if="item.avatar" class="img-avatar" :src="item.avatar" :size="32"></EAvatar>
|
||||
<i v-else-if="item.group_type=='department'" class="taskfont icon-avatar department"></i>
|
||||
<i v-else-if="item.group_type=='project'" class="taskfont icon-avatar project"></i>
|
||||
<i v-else-if="item.group_type=='task'" class="taskfont icon-avatar task"></i>
|
||||
<i v-else-if="item.group_type=='okr'" class="taskfont icon-avatar task"></i>
|
||||
<Icon v-else class="icon-avatar" type="ios-people" />
|
||||
<div v-if="selects?.length == 1" class="avatar-name">
|
||||
<span>{{item.name}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<UserAvatar v-else :userid="item.userid" :size="32" :show-name="selects?.length == 1" tooltip-disabled />
|
||||
</li>
|
||||
</ul>
|
||||
</Scrollbar>
|
||||
</div>
|
||||
<div class="twice-affirm-body-extend">
|
||||
<slot name="twice-affirm-body-extend"></slot>
|
||||
</div>
|
||||
<template #footer>
|
||||
<slot name="twice-affirm-footer-extend"></slot>
|
||||
<Button type="primary" :loading="submittIng > 0" @click="onSubmit(2)">
|
||||
{{$L('确定')}}
|
||||
<template v-if="selects.length > 0">({{selects.length}})</template>
|
||||
</Button>
|
||||
</template>
|
||||
</Modal>
|
||||
</div>
|
||||
@ -311,40 +254,14 @@ export default {
|
||||
default: false
|
||||
},
|
||||
|
||||
// 是否禁用
|
||||
disable: {
|
||||
// 是否禁用(禁止打开选择)
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
|
||||
// 二次确认框提交按钮的文本
|
||||
submitBtnTwoText: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
// 是否需要确认
|
||||
twiceAffirm: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 确认标题
|
||||
twiceAffirmTitle: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
|
||||
// 是否多选
|
||||
multipleChoice: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 强制单选
|
||||
forcedRadio: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 只显示群组
|
||||
group: {
|
||||
// 仅显示群组
|
||||
onlyGroup: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
@ -355,14 +272,16 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
switchItems: [
|
||||
{ key: 'recent', label: '最近' },
|
||||
{ key: 'contact', label: '通讯录' },
|
||||
{ key: 'project', label: '项目成员' },
|
||||
{key: 'recent', label: '最近'},
|
||||
{key: 'contact', label: '通讯录'},
|
||||
{key: 'project', label: '项目成员'},
|
||||
],
|
||||
switchActive: 'recent',
|
||||
loadIng: 0,
|
||||
waitIng: 0,
|
||||
submittIng: 0,
|
||||
|
||||
loadIng: 0, // 搜索框等待效果
|
||||
waitIng: 0, // 页面等待效果
|
||||
submittIng: 0, // 提交按钮等待效果
|
||||
|
||||
values: [],
|
||||
selects: [],
|
||||
|
||||
@ -374,10 +293,7 @@ export default {
|
||||
|
||||
searchKey: null,
|
||||
searchCache: [],
|
||||
|
||||
showAffirmModal: false,
|
||||
showMultiple: true,
|
||||
};
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value: {
|
||||
@ -395,7 +311,7 @@ export default {
|
||||
|
||||
isWhole: {
|
||||
handler(value) {
|
||||
if (value || this.group) {
|
||||
if (value || this.onlyGroup) {
|
||||
this.switchActive = 'recent'
|
||||
} else {
|
||||
this.switchActive = 'contact'
|
||||
@ -407,14 +323,10 @@ export default {
|
||||
showModal(value) {
|
||||
if (value) {
|
||||
this.searchBefore()
|
||||
this.showMultiple = this.multipleChoice
|
||||
if(this.forcedRadio){
|
||||
this.showMultiple = false
|
||||
}
|
||||
} else {
|
||||
this.searchKey = ""
|
||||
}
|
||||
this.$emit("on-show-change", value, this.values)
|
||||
this.$emit("on-show-change", value)
|
||||
},
|
||||
|
||||
searchKey() {
|
||||
@ -430,15 +342,15 @@ export default {
|
||||
'cacheDialogs',
|
||||
]),
|
||||
|
||||
isFullscreen({ windowWidth }) {
|
||||
isFullscreen({windowWidth}) {
|
||||
return windowWidth < 576
|
||||
},
|
||||
|
||||
isWhole({ projectId, noProjectId, dialogId }) {
|
||||
return projectId === 0 && noProjectId === 0 && dialogId === 0 && !this.group
|
||||
isWhole({projectId, noProjectId, dialogId, onlyGroup}) {
|
||||
return projectId === 0 && noProjectId === 0 && dialogId === 0 && !onlyGroup
|
||||
},
|
||||
|
||||
lists({ switchActive, searchKey, recents, contacts, projects }) {
|
||||
lists({switchActive, searchKey, recents, contacts, projects}) {
|
||||
switch (switchActive) {
|
||||
case 'recent':
|
||||
if (searchKey) {
|
||||
@ -457,7 +369,7 @@ export default {
|
||||
return []
|
||||
},
|
||||
|
||||
isSelectAll({ lists, selects }) {
|
||||
isSelectAll({lists, selects}) {
|
||||
return lists.length > 0 && lists.filter(item => selects.includes(item.userid)).length === lists.length;
|
||||
},
|
||||
|
||||
@ -469,14 +381,14 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
addStyle({ avatarSize }) {
|
||||
addStyle({avatarSize}) {
|
||||
return {
|
||||
width: avatarSize + 'px',
|
||||
height: avatarSize + 'px',
|
||||
}
|
||||
},
|
||||
|
||||
localTitle({ title }) {
|
||||
localTitle({title}) {
|
||||
if (title === undefined) {
|
||||
return this.$L('选择会员')
|
||||
} else {
|
||||
@ -484,7 +396,7 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
localPlaceholder({ placeholder }) {
|
||||
localPlaceholder({placeholder}) {
|
||||
if (placeholder === undefined) {
|
||||
return this.$L('搜索')
|
||||
} else {
|
||||
@ -560,7 +472,7 @@ export default {
|
||||
|
||||
searchRecent() {
|
||||
this.recents = this.cacheDialogs.filter(dialog => {
|
||||
if(this.group && dialog.type != 'group'){
|
||||
if (this.onlyGroup && dialog.type != 'group') {
|
||||
return false
|
||||
}
|
||||
if (dialog.name === undefined || dialog.dialog_delete === 1) {
|
||||
@ -578,7 +490,7 @@ export default {
|
||||
return b.todo_num - a.todo_num;
|
||||
}
|
||||
return $A.Date(b.last_at) - $A.Date(a.last_at);
|
||||
}).map(({ id, name, type, group_type, avatar, dialog_user }) => {
|
||||
}).map(({id, name, type, group_type, avatar, dialog_user}) => {
|
||||
return {
|
||||
name,
|
||||
type,
|
||||
@ -618,18 +530,18 @@ export default {
|
||||
},
|
||||
take: 50
|
||||
},
|
||||
}).then(({ data }) => {
|
||||
data = data.map(item => Object.assign(item, { type: 'user' }))
|
||||
}).then(({data}) => {
|
||||
data = data.map(item => Object.assign(item, {type: 'user'}))
|
||||
this.contacts = data
|
||||
//
|
||||
const index = this.searchCache.findIndex(item => item.key == key);
|
||||
const tmpData = { type: 'contact', key, data, time: $A.Time() };
|
||||
const tmpData = {type: 'contact', key, data, time: $A.Time()};
|
||||
if (index > -1) {
|
||||
this.searchCache.splice(index, 1, tmpData)
|
||||
} else {
|
||||
this.searchCache.push(tmpData)
|
||||
}
|
||||
}).catch(({ msg }) => {
|
||||
}).catch(({msg}) => {
|
||||
this.contacts = []
|
||||
$A.messageWarning(msg)
|
||||
}).finally(_ => {
|
||||
@ -665,18 +577,18 @@ export default {
|
||||
getuserid: 'yes',
|
||||
getstatistics: 'no'
|
||||
},
|
||||
}).then(({ data }) => {
|
||||
data = data.data.map(item => Object.assign(item, { type: 'project' }))
|
||||
this.projects = data;
|
||||
}).then(({data}) => {
|
||||
data = data.data.map(item => Object.assign(item, {type: 'project'}))
|
||||
this.projects = data
|
||||
//
|
||||
const index = this.searchCache.findIndex(item => item.key == key);
|
||||
const tmpData = { type: 'project', key, data, time: $A.Time() };
|
||||
const tmpData = {type: 'project', key, data, time: $A.Time()};
|
||||
if (index > -1) {
|
||||
this.searchCache.splice(index, 1, tmpData)
|
||||
} else {
|
||||
this.searchCache.push(tmpData)
|
||||
}
|
||||
}).catch(({ msg }) => {
|
||||
}).catch(({msg}) => {
|
||||
this.projects = []
|
||||
$A.messageWarning(msg)
|
||||
}).finally(_ => {
|
||||
@ -687,7 +599,7 @@ export default {
|
||||
},
|
||||
|
||||
onSelection() {
|
||||
if (this.disable) {
|
||||
if (this.disabled) {
|
||||
return
|
||||
}
|
||||
this.$nextTick(_ => {
|
||||
@ -715,10 +627,7 @@ export default {
|
||||
})
|
||||
},
|
||||
|
||||
onSelectItem({ userid }) {
|
||||
if (!this.showMultiple) {
|
||||
this.selects = []
|
||||
}
|
||||
onSelectItem({userid}) {
|
||||
if (this.selects.includes(userid)) {
|
||||
if (this.isUncancelable(userid)) {
|
||||
return
|
||||
@ -735,18 +644,12 @@ export default {
|
||||
this.selects.push(userid)
|
||||
// 滚动到选中的位置
|
||||
this.$nextTick(() => {
|
||||
$A.scrollIntoViewIfNeeded(this.$refs.selected?.querySelector(`li[data-id="${userid}"]`))
|
||||
$A.scrollIntoViewIfNeeded(this.$refs.selected.querySelector(`li[data-id="${userid}"]`))
|
||||
})
|
||||
}
|
||||
if(!this.showMultiple){
|
||||
this.onSubmit(1)
|
||||
}
|
||||
},
|
||||
|
||||
onSelectProject(userid_list) {
|
||||
if (!this.showMultiple) {
|
||||
this.selects = []
|
||||
}
|
||||
switch (this.selectIcon(userid_list)) {
|
||||
case 'ios-checkmark-circle':
|
||||
// 去除
|
||||
@ -770,9 +673,6 @@ export default {
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!this.showMultiple) {
|
||||
this.onSubmit(1)
|
||||
}
|
||||
},
|
||||
|
||||
onRemoveItem(userid) {
|
||||
@ -782,36 +682,24 @@ export default {
|
||||
this.selects = this.selects.filter(value => value != userid)
|
||||
},
|
||||
|
||||
onSubmit(index) {
|
||||
onSubmit() {
|
||||
if (this.submittIng > 0) {
|
||||
return
|
||||
}
|
||||
const clone = $A.cloneJSON(this.values)
|
||||
this.values = $A.cloneJSON(this.selects)
|
||||
//
|
||||
if (index !=2 && this.twiceAffirm) {
|
||||
if (this.values.length < 1) {
|
||||
$A.messageError("请选择对话或成员")
|
||||
return
|
||||
}
|
||||
this.showAffirmModal = true
|
||||
return
|
||||
}
|
||||
//
|
||||
this.$emit('input', this.values)
|
||||
this.$emit('onSubmit', this.values)
|
||||
this.$emit('on-submit', this.values)
|
||||
|
||||
if (!this.beforeSubmit) {
|
||||
this.showModal = false
|
||||
this.showAffirmModal = false
|
||||
this.hide()
|
||||
return
|
||||
}
|
||||
const before = this.beforeSubmit();
|
||||
if (before && before.then) {
|
||||
this.submittIng++
|
||||
before.then(() => {
|
||||
this.showModal = false
|
||||
this.showAffirmModal = false
|
||||
this.hide()
|
||||
}).catch(() => {
|
||||
this.values = clone
|
||||
this.$emit('input', this.values)
|
||||
@ -819,10 +707,17 @@ export default {
|
||||
this.submittIng--
|
||||
})
|
||||
} else {
|
||||
this.showModal = false
|
||||
this.showAffirmModal = false
|
||||
this.hide()
|
||||
}
|
||||
},
|
||||
|
||||
show() {
|
||||
this.onSelection()
|
||||
},
|
||||
|
||||
hide() {
|
||||
this.showModal = false
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
@ -189,16 +189,15 @@
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
<!-- 发起接龙 -->
|
||||
<!-- 发起群投票、接龙 -->
|
||||
<UserSelect
|
||||
ref="wordChainAndVoteRef"
|
||||
v-model="sendData"
|
||||
:multiple-max="50"
|
||||
:multiple-max="1"
|
||||
:title="sendType == 'vote' ? $L('选择群组发起投票') : $L('选择群组发起接龙')"
|
||||
:before-submit="goWordChainAndVote"
|
||||
:show-select-all="false"
|
||||
:forced-radio="true"
|
||||
:group="true"
|
||||
:only-group="true"
|
||||
show-dialog
|
||||
module/>
|
||||
|
||||
@ -584,23 +583,24 @@ export default {
|
||||
});
|
||||
},
|
||||
// 前往接龙与投票
|
||||
goWordChainAndVote(){
|
||||
goWordChainAndVote() {
|
||||
const dialog_id = Number(this.sendData[0].replace('d:', ''))
|
||||
if(this.windowPortrait){
|
||||
this.$store.dispatch("openDialog", dialog_id ).then(() => {
|
||||
this.$store.state[ this.sendType == 'word-chain' ?'dialogDroupWordChain' : 'dialogGroupVote'] = {
|
||||
const type = this.sendType == 'word-chain' ? 'dialogDroupWordChain' : 'dialogGroupVote'
|
||||
if (this.windowPortrait) {
|
||||
this.$store.dispatch("openDialog", dialog_id).then(() => {
|
||||
this.$store.state[type] = {
|
||||
type: 'create',
|
||||
dialog_id: dialog_id
|
||||
}
|
||||
})
|
||||
}else{
|
||||
this.goForward({ name: 'manage-messenger', params: { dialog_id: dialog_id}});
|
||||
setTimeout(()=>{
|
||||
this.$store.state[ this.sendType == 'word-chain' ?'dialogDroupWordChain' : 'dialogGroupVote'] = {
|
||||
} else {
|
||||
this.goForward({name: 'manage-messenger', params: {dialog_id: dialog_id}});
|
||||
setTimeout(() => {
|
||||
this.$store.state[type] = {
|
||||
type: 'create',
|
||||
dialog_id: dialog_id
|
||||
}
|
||||
},100)
|
||||
}, 100)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -387,20 +387,44 @@
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
<!-- 转发 -->
|
||||
<!-- 转发选择 -->
|
||||
<UserSelect
|
||||
ref="forwardSelect"
|
||||
v-model="forwardData"
|
||||
:multiple-max="50"
|
||||
:title="$L('转发')"
|
||||
:twice-affirm="true"
|
||||
:twice-affirm-title="$L('转发给:')"
|
||||
:before-submit="onForward"
|
||||
:before-submit="onForwardBefore"
|
||||
:show-select-all="false"
|
||||
:multiple-choice="false"
|
||||
show-dialog
|
||||
module>
|
||||
<template #twice-affirm-body-extend>
|
||||
module/>
|
||||
|
||||
<!-- 转发确认 -->
|
||||
<Modal
|
||||
v-model="forwardhow"
|
||||
:title="$L('转发给:')"
|
||||
class-name="common-user-select-modal dialog-forward-message-modal"
|
||||
:mask-closable="false"
|
||||
width="420">
|
||||
<div class="user-modal-search">
|
||||
<Scrollbar class="search-selected" enable-x :enable-y="false">
|
||||
<ul>
|
||||
<li v-for="item in forwardData" :data-id="item.userid">
|
||||
<div v-if="item.type=='group'" class="user-modal-avatar">
|
||||
<EAvatar v-if="item.avatar" class="img-avatar" :src="item.avatar" :size="32"></EAvatar>
|
||||
<i v-else-if="item.group_type=='department'" class="taskfont icon-avatar department"></i>
|
||||
<i v-else-if="item.group_type=='project'" class="taskfont icon-avatar project"></i>
|
||||
<i v-else-if="item.group_type=='task'" class="taskfont icon-avatar task"></i>
|
||||
<i v-else-if="item.group_type=='okr'" class="taskfont icon-avatar task"></i>
|
||||
<Icon v-else class="icon-avatar" type="ios-people" />
|
||||
<div v-if="forwardData.length == 1" class="avatar-name">
|
||||
<span>{{item.name}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<UserAvatar v-else :userid="item.userid" :size="32" :show-name="forwardData.length == 1" tooltip-disabled />
|
||||
</li>
|
||||
</ul>
|
||||
</Scrollbar>
|
||||
</div>
|
||||
<div class="twice-affirm-body-extend">
|
||||
<div class="dialog-wrapper-forward-body">
|
||||
<div class="dialog-wrapper ">
|
||||
<div class="dialog-scroller">
|
||||
@ -408,18 +432,22 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="leave-message">
|
||||
<Input type="textarea" :autosize="{minRows: 1,maxRows: 3}" v-model="forwardLeaveMessage" :placeholder="$L('留言')" clearable />
|
||||
<Input type="textarea" :autosize="{minRows: 1,maxRows: 3}" v-model="forwardMessage" :placeholder="$L('留言')" clearable />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #twice-affirm-footer-extend>
|
||||
<div class="dialog-wrapper-forward-footer" :class="{'selected': !forwardShowOriginal}" @click="forwardShowOriginal = !forwardShowOriginal">
|
||||
<Icon v-if="!forwardShowOriginal" class="user-modal-icon" type="ios-checkmark-circle" />
|
||||
<Icon v-else class="user-modal-icon" type="ios-radio-button-off" />
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="dialog-wrapper-forward-footer" :class="{selected: !forwardSource}" @click="forwardSource = !forwardSource">
|
||||
<Icon class="user-modal-icon" :type="forwardSource ? 'ios-radio-button-off' : 'ios-checkmark-circle'" />
|
||||
{{$L('不显示原发送者信息')}}
|
||||
</div>
|
||||
<Button type="primary" :loading="forwardLoad > 0" @click="onForwardAffirm">
|
||||
{{$L('确定')}}
|
||||
<template v-if="forwardData.length > 0">({{forwardData.length}})</template>
|
||||
</Button>
|
||||
</template>
|
||||
</UserSelect>
|
||||
</Modal>
|
||||
|
||||
|
||||
<!-- 设置待办 -->
|
||||
<Modal
|
||||
@ -633,9 +661,11 @@ export default {
|
||||
modifyData: {},
|
||||
modifyLoad: 0,
|
||||
|
||||
forwardhow: false,
|
||||
forwardData: [],
|
||||
forwardShowOriginal: true,
|
||||
forwardLeaveMessage: '',
|
||||
forwardLoad: 0,
|
||||
forwardMessage: '',
|
||||
forwardSource: true,
|
||||
|
||||
openId: 0,
|
||||
dialogDrag: false,
|
||||
@ -2353,36 +2383,51 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
onForward() {
|
||||
onForwardBefore() {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.forwardData = this.$refs.forwardSelect.formatSelect(this.$refs.forwardSelect.selects);
|
||||
if (this.forwardData.length === 0) {
|
||||
$A.messageError("请选择转发对话或成员");
|
||||
reject();
|
||||
return
|
||||
} else {
|
||||
this.forwardMessage = '';
|
||||
this.forwardSource = true;
|
||||
this.forwardhow = true;
|
||||
}
|
||||
const dialogids = this.forwardData.filter(value => $A.leftExists(value, 'd:')).map(value => value.replace('d:', ''));
|
||||
const userids = this.forwardData.filter(value => !$A.leftExists(value, 'd:'));
|
||||
this.$store.dispatch("call", {
|
||||
url: 'dialog/msg/forward',
|
||||
data: {
|
||||
dialogids,
|
||||
userids,
|
||||
msg_id: this.operateItem.id,
|
||||
show_source: this.forwardShowOriginal ? 1 : 0,
|
||||
leave_message: this.forwardLeaveMessage
|
||||
}
|
||||
}).then(({data, msg}) => {
|
||||
this.$store.dispatch("saveDialogMsg", data.msgs);
|
||||
this.$store.dispatch("updateDialogLastMsg", data.msgs);
|
||||
$A.messageSuccess(msg);
|
||||
resolve();
|
||||
}).catch(({msg}) => {
|
||||
$A.modalError(msg);
|
||||
reject();
|
||||
});
|
||||
reject();
|
||||
})
|
||||
},
|
||||
|
||||
onForwardAffirm() {
|
||||
const selects = this.$refs.forwardSelect.selects;
|
||||
if (selects.length === 0) {
|
||||
$A.messageError("请选择转发对话或成员");
|
||||
return
|
||||
}
|
||||
const dialogids = selects.filter(value => $A.leftExists(value, 'd:')).map(value => value.replace('d:', ''));
|
||||
const userids = selects.filter(value => !$A.leftExists(value, 'd:'));
|
||||
this.forwardLoad++;
|
||||
this.$store.dispatch("call", {
|
||||
url: 'dialog/msg/forward',
|
||||
data: {
|
||||
dialogids,
|
||||
userids,
|
||||
msg_id: this.operateItem.id,
|
||||
show_source: this.forwardSource ? 1 : 0,
|
||||
leave_message: this.forwardMessage
|
||||
}
|
||||
}).then(({data, msg}) => {
|
||||
this.$store.dispatch("saveDialogMsg", data.msgs);
|
||||
this.$store.dispatch("updateDialogLastMsg", data.msgs);
|
||||
$A.messageSuccess(msg);
|
||||
this.$refs.forwardSelect.hide()
|
||||
this.forwardhow = false;
|
||||
}).catch(({msg}) => {
|
||||
$A.modalError(msg);
|
||||
}).finally(_ => {
|
||||
this.forwardLoad--;
|
||||
});
|
||||
},
|
||||
|
||||
onActivity(activity) {
|
||||
this.msgPreparedStatus = !activity
|
||||
},
|
||||
@ -2580,9 +2625,6 @@ export default {
|
||||
break;
|
||||
|
||||
case "forward":
|
||||
this.forwardData = [];
|
||||
this.forwardLeaveMessage = '';
|
||||
this.forwardShowOriginal = true;
|
||||
this.$refs.forwardSelect.onSelection()
|
||||
break;
|
||||
|
||||
|
||||
@ -21,23 +21,23 @@
|
||||
</div>
|
||||
<div class="task-move-row" :class="{'not-flex': windowPortrait}">
|
||||
<span class="label">{{$L('负责人')}}:</span>
|
||||
<UserSelect class="item-content user"
|
||||
<UserSelect
|
||||
v-model="ownerUserids"
|
||||
class="item-content user"
|
||||
:avatar-size="28"
|
||||
:project-id="task.project_id"
|
||||
:add-icon="false"
|
||||
disable
|
||||
/>
|
||||
disabled/>
|
||||
</div>
|
||||
<div class="task-move-row" :class="{'not-flex': windowPortrait}">
|
||||
<span class="label">{{$L('协助人')}}:</span>
|
||||
<UserSelect class="item-content user"
|
||||
<UserSelect
|
||||
class="item-content user"
|
||||
v-model="assistUserids"
|
||||
:avatar-size="28"
|
||||
:project-id="task.project_id"
|
||||
:add-icon="false"
|
||||
disable
|
||||
/>
|
||||
disabled/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="task-move-content-new">
|
||||
@ -66,8 +66,7 @@
|
||||
:multiple-max="10"
|
||||
:avatar-size="28"
|
||||
:project-id="cascader[0]"
|
||||
:add-icon="false"
|
||||
/>
|
||||
:add-icon="false"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="task-move-row" :class="{'not-flex': windowPortrait}">
|
||||
@ -79,8 +78,7 @@
|
||||
:multiple-max="10"
|
||||
:avatar-size="28"
|
||||
:project-id="cascader[0]"
|
||||
:add-icon="false"
|
||||
/>
|
||||
:add-icon="false"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -172,21 +172,6 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.twice-affirm{
|
||||
padding-bottom: 16px;
|
||||
.search-selected{
|
||||
max-width: 100%;
|
||||
}
|
||||
.user-modal-avatar{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
.avatar-name{
|
||||
max-width: 90%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.user-modal-switch {
|
||||
@ -431,19 +416,12 @@
|
||||
border-radius: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.twice-affirm-body-extend{
|
||||
margin: 0 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.ivu-modal-footer {
|
||||
border-top: 1px solid #f2f2f2 !important;
|
||||
padding: 12px 0 !important;
|
||||
margin: 0 24px !important;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
&.ivu-modal-fullscreen {
|
||||
@ -484,10 +462,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
&.twice-affirm-modal{
|
||||
.ivu-modal {
|
||||
max-width: 90%;
|
||||
margin: 10px auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -447,8 +447,7 @@
|
||||
|
||||
.dialog-tag,
|
||||
.dialog-todo,
|
||||
.dialog-notice,
|
||||
.dialog-new {
|
||||
.dialog-notice {
|
||||
font-size: 12px;
|
||||
max-width: 80%;
|
||||
margin: 0 auto;
|
||||
@ -965,48 +964,57 @@
|
||||
color: $primary-title-color;
|
||||
}
|
||||
|
||||
.content-word-chain{
|
||||
ul{
|
||||
list-style-type:none;
|
||||
.content-word-chain {
|
||||
ul {
|
||||
list-style-type: none;
|
||||
margin-top: 20px;
|
||||
li{
|
||||
|
||||
li {
|
||||
margin-top: 5px;
|
||||
.expand{
|
||||
|
||||
.expand {
|
||||
cursor: pointer;
|
||||
color: #0bc037;
|
||||
}
|
||||
.shrink{
|
||||
|
||||
.shrink {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
li.participate{
|
||||
|
||||
li.participate {
|
||||
cursor: pointer;
|
||||
margin-top: 10px;
|
||||
color: #0bc037;
|
||||
>span{
|
||||
|
||||
> span {
|
||||
font-size: 12px;
|
||||
margin-left: 2px;
|
||||
}
|
||||
}
|
||||
&.expand,li:nth-last-child(2){
|
||||
.expand{
|
||||
|
||||
&.expand, li:nth-last-child(2) {
|
||||
.expand {
|
||||
display: none;
|
||||
}
|
||||
.shrink{
|
||||
|
||||
.shrink {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content-word-vote{
|
||||
.content-word-vote {
|
||||
min-width: 200px;
|
||||
max-width: 260px;
|
||||
.vote-msg-head{
|
||||
|
||||
.vote-msg-head {
|
||||
margin-bottom: 8px;
|
||||
color: #0bc037;
|
||||
line-height: 18px;
|
||||
span{
|
||||
|
||||
span {
|
||||
padding: 2px 4px;
|
||||
border-radius: 3px;
|
||||
background-color: #dee2fa;
|
||||
@ -1015,43 +1023,54 @@
|
||||
color: #7076e4;
|
||||
}
|
||||
}
|
||||
.ivu-checkbox-group,.ivu-radio-group{
|
||||
|
||||
.ivu-checkbox-group, .ivu-radio-group {
|
||||
margin-top: 10px;
|
||||
width: 100%;
|
||||
.ivu-checkbox-wrapper,.ivu-radio-wrapper{
|
||||
|
||||
.ivu-checkbox-wrapper, .ivu-radio-wrapper {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 34px;
|
||||
line-height: 34px;
|
||||
.ivu-checkbox-inner{
|
||||
|
||||
.ivu-checkbox-inner {
|
||||
border-radius: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.vote-result-body{
|
||||
|
||||
.vote-result-body {
|
||||
font-size: 12px;
|
||||
margin-top: 14px;
|
||||
ul{
|
||||
list-style-type:none;
|
||||
li{
|
||||
|
||||
ul {
|
||||
list-style-type: none;
|
||||
|
||||
li {
|
||||
margin-bottom: 14px;
|
||||
.vote-option-title{
|
||||
|
||||
.vote-option-title {
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
.ivu-progress-inner{
|
||||
|
||||
.ivu-progress-inner {
|
||||
background-color: #e2e2e2;
|
||||
}
|
||||
.avatar-row{
|
||||
|
||||
.avatar-row {
|
||||
gap: 2px;
|
||||
margin-top: 2px;
|
||||
display: flex;
|
||||
overflow: auto;
|
||||
padding-bottom: 4px;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
background: none;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: #d4d4d4;
|
||||
-webkit-border-radius: 10px;
|
||||
@ -1060,20 +1079,24 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
li:last-child{
|
||||
|
||||
li:last-child {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
>span,.ticket-num span{
|
||||
|
||||
> span, .ticket-num span {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
.btn-row{
|
||||
|
||||
.btn-row {
|
||||
display: flex;
|
||||
text-align: center;
|
||||
padding: 10px 0 5px 0;
|
||||
gap: 10px;
|
||||
.ivu-btn{
|
||||
|
||||
.ivu-btn {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
@ -1353,16 +1376,17 @@
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.content-word-chain{
|
||||
ul{
|
||||
li.participate, li .expand{
|
||||
.content-word-chain {
|
||||
ul {
|
||||
li.participate,
|
||||
li .expand {
|
||||
color: #23241f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content-word-vote{
|
||||
.vote-msg-head{
|
||||
.content-word-vote {
|
||||
.vote-msg-head {
|
||||
color: #23241f;
|
||||
}
|
||||
}
|
||||
@ -1430,9 +1454,6 @@
|
||||
height: 14px;
|
||||
font-size: 14px;
|
||||
line-height: 14px;
|
||||
&.down{
|
||||
transform: rotate(-180deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1621,79 +1642,131 @@
|
||||
}
|
||||
}
|
||||
|
||||
.dialog-wrapper-forward-body{
|
||||
.dialog-wrapper{
|
||||
position: relative !important;
|
||||
.dialog-scroller{
|
||||
padding: 0 !important;
|
||||
.dialog-item{
|
||||
.dialog-view{
|
||||
width: 100%;
|
||||
max-width: 100% !important;
|
||||
margin: 0 !important;
|
||||
.dialog-head{
|
||||
width: 100%;
|
||||
border-radius: 8px !important;
|
||||
}
|
||||
.dialog-foot{
|
||||
display: none !important;
|
||||
.dialog-forward-message-modal {
|
||||
.ivu-modal {
|
||||
margin: 10px auto;
|
||||
|
||||
.ivu-modal-body {
|
||||
.user-modal-search {
|
||||
padding-bottom: 16px;
|
||||
|
||||
.search-selected {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.user-modal-avatar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
|
||||
.avatar-name {
|
||||
max-width: 90%;
|
||||
}
|
||||
}
|
||||
.dialog-avatar{
|
||||
display: none;
|
||||
}
|
||||
&.self {
|
||||
.dialog-head{
|
||||
background-color: #F4F5F7;
|
||||
.content-text{
|
||||
color: #303133 !important;
|
||||
.markdown-body{
|
||||
color: #303133 !important;
|
||||
}
|
||||
|
||||
.twice-affirm-body-extend {
|
||||
margin: 0 24px;
|
||||
|
||||
.dialog-wrapper-forward-body {
|
||||
.dialog-wrapper {
|
||||
position: relative !important;
|
||||
|
||||
.dialog-scroller {
|
||||
padding: 0 !important;
|
||||
|
||||
.dialog-item {
|
||||
.dialog-view {
|
||||
width: 100%;
|
||||
max-width: 100% !important;
|
||||
margin: 0 !important;
|
||||
|
||||
.dialog-head {
|
||||
width: 100%;
|
||||
border-radius: 8px !important;
|
||||
}
|
||||
|
||||
.dialog-foot {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.dialog-avatar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.self {
|
||||
.dialog-head {
|
||||
background-color: #F4F5F7;
|
||||
|
||||
.content-text {
|
||||
color: #303133 !important;
|
||||
|
||||
.markdown-body {
|
||||
color: #303133 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.dialog-reply {
|
||||
&:after {
|
||||
background-color: rgba(132, 197, 106, 0.7);
|
||||
}
|
||||
|
||||
.bot, .common-avatar {
|
||||
color: #84C56A !important;
|
||||
}
|
||||
}
|
||||
|
||||
.dialog-emoji {
|
||||
.avatar-name {
|
||||
color: #818181;
|
||||
}
|
||||
|
||||
> li.hasme {
|
||||
background-color: #e1e1e1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.dialog-reply{
|
||||
&:after{
|
||||
background-color: rgba(132, 197, 106, 0.7);
|
||||
}
|
||||
.bot,.common-avatar{
|
||||
color: #84C56A !important;
|
||||
}
|
||||
}
|
||||
.dialog-emoji{
|
||||
.avatar-name{
|
||||
color: #818181;
|
||||
}
|
||||
> li.hasme{
|
||||
background-color: #e1e1e1;
|
||||
}
|
||||
}
|
||||
|
||||
.leave-message {
|
||||
padding-bottom: 16px;
|
||||
|
||||
textarea {
|
||||
background: #f7f7f7;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.leave-message{
|
||||
padding-bottom: 16px;
|
||||
textarea{
|
||||
background: #f7f7f7;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dialog-wrapper-forward-footer{
|
||||
display: flex;
|
||||
line-height: 34px;
|
||||
cursor: pointer;
|
||||
.user-modal-icon {
|
||||
flex-shrink: 0;
|
||||
font-size: 22px;
|
||||
margin-right: 5px;
|
||||
color: rgba($primary-desc-color, 0.7);
|
||||
margin-top: 6px;
|
||||
}
|
||||
&.selected {
|
||||
.user-modal-icon {
|
||||
color: $primary-color;
|
||||
.ivu-modal-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 20px;
|
||||
|
||||
.dialog-wrapper-forward-footer {
|
||||
display: flex;
|
||||
line-height: 34px;
|
||||
cursor: pointer;
|
||||
|
||||
.user-modal-icon {
|
||||
flex-shrink: 0;
|
||||
font-size: 22px;
|
||||
margin-right: 5px;
|
||||
color: rgba($primary-desc-color, 0.7);
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
&.selected {
|
||||
.user-modal-icon {
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user