mirror of
https://github.com/kuaifan/dootask.git
synced 2025-12-15 13:22:49 +00:00
commit
789062e85e
@ -0,0 +1,131 @@
|
|||||||
|
<template>
|
||||||
|
<Modal v-model="visibleProxy" :title="$L('共同群组') + ' (' + $L('(*)个', totalCount) + ')'" :footer-hide="true" width="500">
|
||||||
|
<div class="common-dialog-content">
|
||||||
|
<div v-if="loading > 0 && list.length === 0" class="loading-wrapper">
|
||||||
|
<Loading/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="list.length === 0" class="empty-wrapper">
|
||||||
|
<div class="empty-content">
|
||||||
|
<Icon type="ios-people-outline" size="48"/>
|
||||||
|
<p>{{$L('暂无共同群组')}}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else class="dialog-list">
|
||||||
|
<div
|
||||||
|
v-for="dialog in list"
|
||||||
|
:key="dialog.id"
|
||||||
|
class="dialog-item"
|
||||||
|
@click="onEnterDialog(dialog)">
|
||||||
|
<div class="dialog-avatar">
|
||||||
|
<EAvatar v-if="dialog.avatar" :src="dialog.avatar" :size="42"></EAvatar>
|
||||||
|
<i v-else-if="dialog.group_type=='department'" class="taskfont icon-avatar department"></i>
|
||||||
|
<i v-else-if="dialog.group_type=='project'" class="taskfont icon-avatar project"></i>
|
||||||
|
<i v-else-if="dialog.group_type=='task'" class="taskfont icon-avatar task"></i>
|
||||||
|
<i v-else-if="dialog.group_type=='okr'" class="taskfont icon-avatar task"></i>
|
||||||
|
<Icon v-else class="icon-avatar" type="ios-people" />
|
||||||
|
</div>
|
||||||
|
<div class="dialog-info">
|
||||||
|
<div class="dialog-name" v-html="transformEmojiToHtml(dialog.name)"></div>
|
||||||
|
<div class="dialog-meta">
|
||||||
|
<span class="member-count">{{$L('(*)人', dialog.people || 0)}}</span>
|
||||||
|
<span v-if="dialog.last_at" class="last-time">{{$A.timeFormat(dialog.last_at)}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Icon class="enter-icon" type="ios-arrow-forward" />
|
||||||
|
</div>
|
||||||
|
<div v-if="hasMore" class="load-more-wrapper">
|
||||||
|
<Button type="primary" @click="loadList(true)" :loading="loading > 0">{{$L('加载更多')}}</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import transformEmojiToHtml from "../../../utils/emoji";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'CommonDialogModal',
|
||||||
|
|
||||||
|
props: {
|
||||||
|
value: { // v-model
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
targetUserId: {
|
||||||
|
type: [Number, String],
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
totalCount: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
list: [],
|
||||||
|
page: 1,
|
||||||
|
hasMore: false,
|
||||||
|
loading: 0,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
visibleProxy: {
|
||||||
|
get() { return this.value; },
|
||||||
|
set(v) { this.$emit('input', v); }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
visibleProxy(val) {
|
||||||
|
if (val && this.list.length === 0) {
|
||||||
|
this.loadList(false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
targetUserId() {
|
||||||
|
// reset when user changes
|
||||||
|
this.list = [];
|
||||||
|
this.page = 1;
|
||||||
|
this.hasMore = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
transformEmojiToHtml,
|
||||||
|
|
||||||
|
loadList(loadMore = false) {
|
||||||
|
if (!this.targetUserId) return;
|
||||||
|
this.loading++;
|
||||||
|
const page = loadMore ? this.page + 1 : 1;
|
||||||
|
this.$store.dispatch('call', {
|
||||||
|
url: 'dialog/common/list',
|
||||||
|
data: {
|
||||||
|
target_userid: this.targetUserId,
|
||||||
|
page
|
||||||
|
}
|
||||||
|
}).then(({data}) => {
|
||||||
|
const newList = loadMore ? [...this.list, ...data.data] : data.data;
|
||||||
|
this.list = Array.isArray(newList) ? newList : [];
|
||||||
|
this.page = data.current_page || page;
|
||||||
|
this.hasMore = !!data.next_page_url;
|
||||||
|
}).catch(({msg}) => {
|
||||||
|
$A.modalError(msg || this.$L('加载失败'));
|
||||||
|
}).finally(() => {
|
||||||
|
this.loading--;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onEnterDialog(dialog) {
|
||||||
|
this.$emit('open-chat', dialog);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/* 组件自身不引入额外样式,复用全局样式类名 */
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
@ -5,149 +5,162 @@
|
|||||||
:fullscreen="isFullscreen"
|
:fullscreen="isFullscreen"
|
||||||
:mask-closable="false"
|
:mask-closable="false"
|
||||||
:footer-hide="true"
|
:footer-hide="true"
|
||||||
width="600">
|
width="420"
|
||||||
|
>
|
||||||
<div class="user-detail-body">
|
<div class="user-detail-body">
|
||||||
<UserAvatar
|
<div class="profile-header">
|
||||||
:userid="userData.userid"
|
<div class="cover-photo"></div>
|
||||||
:size="120"
|
<div class="profile-avatar">
|
||||||
:show-state-dot="false"
|
<UserAvatar
|
||||||
@on-click="onOpenAvatar"/>
|
:userid="userData.userid"
|
||||||
<ul class="user-select-auto">
|
:size="80"
|
||||||
<li class="user-name">
|
:show-state-dot="false"
|
||||||
<h1>{{userData.nickname}}</h1>
|
@on-click="onOpenAvatar"
|
||||||
<em v-if="userData.delete_at" class="deleted no-dark-content">{{$L('已删除')}}</em>
|
/>
|
||||||
<em v-else-if="userData.disable_at" class="disabled no-dark-content">{{$L('已离职')}}</em>
|
</div>
|
||||||
</li>
|
</div>
|
||||||
<li v-if="userData.userid != userId && commonDialog.total !== null">
|
<div class="profile-content">
|
||||||
<span>{{$L('共同群聊')}}: </span>
|
<div class="user-info-top">
|
||||||
<a href="javascript:void(0)" @click="commonDialogShow=true">{{ $L('(*)个', commonDialog.total) }}</a>
|
<span class="username"
|
||||||
</li>
|
>@{{ userData.profession || "管理员" }}</span
|
||||||
<template v-if="!userData.bot">
|
>
|
||||||
<li>
|
<h1 class="fullname">
|
||||||
<span>{{$L('部门')}}: </span>
|
{{ userData.nickname}}
|
||||||
{{userData.department_name || '-'}}
|
</h1>
|
||||||
</li>
|
<div class="meta">
|
||||||
<li>
|
<!-- <span>{{userData.address || 'Bandung'}}</span> -->
|
||||||
<span>{{$L('职位/职称')}}: </span>
|
<span @click="commonDialogShow = true"
|
||||||
{{userData.profession || '-'}}
|
class="common-dialog"
|
||||||
</li>
|
>{{ $L("共同群组") }}:
|
||||||
<li>
|
{{ $L("(*)个", commonDialog.total) }}</span
|
||||||
<span>{{$L('生日')}}: </span>
|
>
|
||||||
{{userData.birthday ? ($A.newDateString(userData.birthday, 'YYYY-MM-DD') || userData.birthday) : '-'}}
|
<span class="separator">|</span>
|
||||||
</li>
|
<span
|
||||||
<li>
|
>{{ $L("最后在线") }}:
|
||||||
<span>{{$L('地址')}}: </span>
|
{{
|
||||||
{{userData.address || '-'}}
|
$A.newDateString(
|
||||||
</li>
|
userData.line_at,
|
||||||
<li>
|
"YYYY-MM-DD HH:mm"
|
||||||
<span>{{$L('个人简介')}}: </span>
|
) || "-"
|
||||||
{{userData.introduction || '-'}}
|
}}</span
|
||||||
</li>
|
>
|
||||||
<li class="user-tags-line">
|
</div>
|
||||||
<span>{{$L('个性标签')}}: </span>
|
</div>
|
||||||
<div class="tags-content" @click="onOpenTagsModal">
|
|
||||||
<div v-if="displayTags.length" class="tags-list">
|
<div class="profile-actions">
|
||||||
<Tag
|
<Button
|
||||||
v-for="tag in displayTags"
|
icon="md-chatbubbles"
|
||||||
:key="tag.id"
|
@click="onOpenDialog"
|
||||||
:color="tag.recognized ? 'primary' : 'default'"
|
>{{ $L("开始聊天") }}</Button
|
||||||
class="tag-pill">{{tag.name}}</Tag>
|
>
|
||||||
</div>
|
<Button
|
||||||
<span v-else class="tags-empty">{{$L('暂无个性标签')}}</span>
|
icon="md-people"
|
||||||
<div class="tags-extra">
|
@click="onCreateGroup"
|
||||||
<span v-if="personalTagTotal > displayTags.length" class="tags-total">{{$L('共(*)个', personalTagTotal)}}</span>
|
>{{ $L("创建群组") }}</Button
|
||||||
<Button type="text" size="small" class="manage-button" @click.stop="onOpenTagsModal">{{$L('管理')}}</Button>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="profile-bio">
|
||||||
|
<p>{{ userData.introduction }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="profile-information">
|
||||||
|
<h2>{{ $L("个人信息") }}</h2>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<Icon type="ios-person-outline" />
|
||||||
|
<span class="label">{{ $L("部门") }}</span>
|
||||||
|
<span class="value">{{
|
||||||
|
userData.department_name || "-"
|
||||||
|
}}</span>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<Icon type="ios-mail-outline" />
|
||||||
|
<span class="label">{{ $L("邮箱") }}</span>
|
||||||
|
<span class="value">{{
|
||||||
|
userData.email || "-"
|
||||||
|
}}</span>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<Icon type="ios-call-outline" />
|
||||||
|
<span class="label">{{ $L("电话") }}</span>
|
||||||
|
<span class="value">{{ userData.tel || "-" }}</span>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<Icon type="ios-calendar-outline" />
|
||||||
|
<span class="label">{{ $L("生日") }}</span>
|
||||||
|
<span class="value">{{
|
||||||
|
userData.birthday || "-"
|
||||||
|
}}</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="profile-tags" @click.capture="onOpenTagsModal">
|
||||||
|
<div v-if="displayTags.length" class="tags-list">
|
||||||
|
<Button
|
||||||
|
type="dashed"
|
||||||
|
class="manage-tags-btn icon"
|
||||||
|
@click.stop="onOpenTagsModal"
|
||||||
|
>
|
||||||
|
<Icon type="ios-settings-outline" /> 管理
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
v-for="tag in displayTags"
|
||||||
|
:key="tag.id"
|
||||||
|
:type="tag.recognized ? 'primary' : 'default'"
|
||||||
|
>
|
||||||
|
{{ tag.name }}
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
<div v-else class="tags-empty">
|
||||||
<li>
|
<Button
|
||||||
<span>{{$L('最后在线')}}: </span>
|
type="dashed"
|
||||||
{{$A.newDateString(userData.line_at, 'YYYY-MM-DD HH:mm') || '-'}}
|
size="small"
|
||||||
</li>
|
icon="md-add"
|
||||||
<li v-if="userData.delete_at">
|
class="add-tag-btn"
|
||||||
<strong><span>{{$L('删除时间')}}: </span>{{$A.newDateString(userData.delete_at, 'YYYY-MM-DD HH:mm')}}</strong>
|
@click.stop="onOpenTagsModal"
|
||||||
</li>
|
>{{ $L("添加标签") }}</Button
|
||||||
<li v-else-if="userData.disable_at">
|
>
|
||||||
<strong><span>{{$L('离职时间')}}: </span>{{$A.newDateString(userData.disable_at, 'YYYY-MM-DD HH:mm')}}</strong>
|
</div>
|
||||||
</li>
|
</div>
|
||||||
</template>
|
</div>
|
||||||
</ul>
|
|
||||||
<div class="user-detail-actions">
|
|
||||||
<Button icon="md-chatbubbles" :disabled="!!userData.delete_at" @click="onOpenDialog">{{ $L('开始聊天') }}</Button>
|
|
||||||
<Button icon="md-people" :disabled="!!userData.delete_at" @click="onOpenCreateGroup">{{ $L('创建群组') }}</Button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 共同群组 -->
|
|
||||||
<Modal v-model="commonDialogShow" :title="$L('共同群组') + ' (' + $L('(*)个', commonDialog.total) + ')'" :footer-hide="true" width="500">
|
|
||||||
<div class="common-dialog-content">
|
|
||||||
<div v-if="commonDialogLoading > 0 && commonDialog.list.length === 0" class="loading-wrapper">
|
|
||||||
<Loading/>
|
|
||||||
</div>
|
|
||||||
<div v-else-if="commonDialogList.length === 0" class="empty-wrapper">
|
|
||||||
<div class="empty-content">
|
|
||||||
<Icon type="ios-people-outline" size="48"/>
|
|
||||||
<p>{{$L('暂无共同群组')}}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div v-else class="dialog-list">
|
|
||||||
<div
|
|
||||||
v-for="dialog in commonDialogList"
|
|
||||||
:key="dialog.id"
|
|
||||||
class="dialog-item"
|
|
||||||
@click="onOpenCommonDialogChat(dialog)">
|
|
||||||
<div class="dialog-avatar">
|
|
||||||
<EAvatar v-if="dialog.avatar" :src="dialog.avatar" :size="42"></EAvatar>
|
|
||||||
<i v-else-if="dialog.group_type=='department'" class="taskfont icon-avatar department"></i>
|
|
||||||
<i v-else-if="dialog.group_type=='project'" class="taskfont icon-avatar project"></i>
|
|
||||||
<i v-else-if="dialog.group_type=='task'" class="taskfont icon-avatar task"></i>
|
|
||||||
<i v-else-if="dialog.group_type=='okr'" class="taskfont icon-avatar task"></i>
|
|
||||||
<Icon v-else class="icon-avatar" type="ios-people" />
|
|
||||||
</div>
|
|
||||||
<div class="dialog-info">
|
|
||||||
<div class="dialog-name" v-html="transformEmojiToHtml(dialog.name)"></div>
|
|
||||||
<div class="dialog-meta">
|
|
||||||
<span class="member-count">{{$L('(*)人', dialog.people || 0)}}</span>
|
|
||||||
<span v-if="dialog.last_at" class="last-time">{{$A.timeFormat(dialog.last_at)}}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Icon class="enter-icon" type="ios-arrow-forward" />
|
|
||||||
</div>
|
|
||||||
<div v-if="commonDialog.has_more" class="load-more-wrapper">
|
|
||||||
<Button type="primary" @click="loadCommonDialogList(true)" :loading="commonDialogLoading > 0">{{$L('加载更多')}}</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Modal>
|
|
||||||
<UserTagsModal
|
<UserTagsModal
|
||||||
v-if="userData.userid"
|
v-if="userData.userid"
|
||||||
v-model="tagModalVisible"
|
v-model="tagModalVisible"
|
||||||
:userid="userData.userid"
|
:userid="userData.userid"
|
||||||
@updated="onTagsUpdated"/>
|
@updated="onTagsUpdated"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<CommonDialogModal
|
||||||
|
v-model="commonDialogShow"
|
||||||
|
:target-user-id="userData.userid"
|
||||||
|
:total-count="commonDialog.total || 0"
|
||||||
|
@open-chat="onOpenCommonDialogChat"
|
||||||
|
/>
|
||||||
</ModalAlive>
|
</ModalAlive>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import emitter from "../../../store/events";
|
import emitter from "../../../store/events";
|
||||||
|
import { mapState } from "vuex";
|
||||||
import transformEmojiToHtml from "../../../utils/emoji";
|
import transformEmojiToHtml from "../../../utils/emoji";
|
||||||
import {mapState} from "vuex";
|
|
||||||
import UserTagsModal from "./UserTagsModal.vue";
|
import UserTagsModal from "./UserTagsModal.vue";
|
||||||
|
import CommonDialogModal from "./CommonDialogModal.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'UserDetail',
|
name: "UserDetail",
|
||||||
|
|
||||||
components: {UserTagsModal},
|
components: { UserTagsModal, CommonDialogModal },
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
userData: {
|
userData: {
|
||||||
userid: 0
|
userid: 0,
|
||||||
},
|
},
|
||||||
|
|
||||||
showModal: false,
|
showModal: false,
|
||||||
|
|
||||||
tagModalVisible: false,
|
tagModalVisible: false,
|
||||||
|
|
||||||
commonDialog: {
|
commonDialog: {
|
||||||
userid: null,
|
userid: null,
|
||||||
total: null,
|
total: null,
|
||||||
@ -157,105 +170,111 @@ export default {
|
|||||||
},
|
},
|
||||||
commonDialogShow: false,
|
commonDialogShow: false,
|
||||||
commonDialogLoading: 0,
|
commonDialogLoading: 0,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
emitter.on('openUser', this.onShow);
|
emitter.on("openUser", this.onShow);
|
||||||
},
|
},
|
||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
emitter.off('openUser', this.onShow);
|
emitter.off("openUser", this.onShow);
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
...mapState(['cacheUserBasic']),
|
...mapState(["cacheUserBasic"]),
|
||||||
|
|
||||||
commonDialogShow() {
|
commonDialogShow() {
|
||||||
if (!this.commonDialogShow || this.commonDialog.list.length > 0) {
|
if (!this.commonDialogShow || this.commonDialog.list.length > 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.loadCommonDialogList(false);
|
this.loadCommonDialogList(false);
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
isFullscreen({windowWidth}) {
|
isFullscreen({ windowWidth }) {
|
||||||
return windowWidth < 576
|
return windowWidth < 576;
|
||||||
|
},
|
||||||
|
|
||||||
|
displayTags() {
|
||||||
|
return Array.isArray(this.userData.personal_tags)
|
||||||
|
? this.userData.personal_tags
|
||||||
|
: [];
|
||||||
|
},
|
||||||
|
|
||||||
|
personalTagTotal() {
|
||||||
|
if (typeof this.userData.personal_tags_total === "number") {
|
||||||
|
return this.userData.personal_tags_total;
|
||||||
|
}
|
||||||
|
return this.displayTags.length;
|
||||||
},
|
},
|
||||||
|
|
||||||
commonDialogList() {
|
commonDialogList() {
|
||||||
return this.commonDialog.list || [];
|
return this.commonDialog.list || [];
|
||||||
},
|
},
|
||||||
|
|
||||||
displayTags() {
|
|
||||||
return Array.isArray(this.userData.personal_tags) ? this.userData.personal_tags : [];
|
|
||||||
},
|
|
||||||
|
|
||||||
personalTagTotal() {
|
|
||||||
if (typeof this.userData.personal_tags_total === 'number') {
|
|
||||||
return this.userData.personal_tags_total;
|
|
||||||
}
|
|
||||||
return this.displayTags.length;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
transformEmojiToHtml,
|
transformEmojiToHtml,
|
||||||
|
|
||||||
onShow(userid) {
|
onShow(userid) {
|
||||||
if (!/^\d+$/.test(userid)) {
|
if (!/^\d+$/.test(userid)) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
this.$store.dispatch("showSpinner", 600)
|
this.$store.dispatch("showSpinner", 600);
|
||||||
this.$store.dispatch('getUserData', userid).then(user => {
|
this.$store
|
||||||
this.userData = user;
|
.dispatch("getUserData", userid)
|
||||||
this.ensureTagDefaults();
|
.then((user) => {
|
||||||
this.showModal = true;
|
this.userData = user;
|
||||||
this.loadCommonDialogCount()
|
this.ensureTagDefaults();
|
||||||
}).finally(_ => {
|
this.showModal = true;
|
||||||
this.$store.dispatch("hiddenSpinner")
|
this.loadCommonDialogCount();
|
||||||
});
|
})
|
||||||
|
.finally((_) => {
|
||||||
|
this.$store.dispatch("hiddenSpinner");
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
onHide() {
|
onHide() {
|
||||||
this.commonDialogShow = false;
|
|
||||||
this.showModal = false;
|
this.showModal = false;
|
||||||
this.tagModalVisible = false;
|
this.tagModalVisible = false;
|
||||||
|
this.commonDialogShow = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
onOpenAvatar() {
|
onOpenAvatar() {
|
||||||
this.$store.dispatch("previewImage", this.userData.userimg)
|
this.$store.dispatch("previewImage", this.userData.userimg);
|
||||||
},
|
},
|
||||||
|
|
||||||
onOpenDialog() {
|
onOpenDialog() {
|
||||||
this.$store.dispatch("openDialogUserid", this.userData.userid).then(_ => {
|
this.$store
|
||||||
this.onHide()
|
.dispatch("openDialogUserid", this.userData.userid)
|
||||||
}).catch(({msg}) => {
|
.then((_) => {
|
||||||
$A.modalError(msg)
|
this.onHide();
|
||||||
});
|
})
|
||||||
|
.catch(({ msg }) => {
|
||||||
|
$A.modalError(msg);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
onOpenCreateGroup() {
|
onCreateGroup() {
|
||||||
const userids = [];
|
const userids = [this.$store.state.userId];
|
||||||
if (this.userId) {
|
if (this.userData.userid && this.$store.state.userId != this.userData.userid) {
|
||||||
userids.push(this.userId);
|
|
||||||
}
|
|
||||||
if (this.userData.userid && this.userData.userid !== this.userId) {
|
|
||||||
userids.push(this.userData.userid);
|
|
||||||
}
|
|
||||||
if (userids.length === 0 && this.userData.userid) {
|
|
||||||
userids.push(this.userData.userid);
|
userids.push(this.userData.userid);
|
||||||
}
|
}
|
||||||
emitter.emit('createGroup', userids);
|
emitter.emit('createGroup', userids);
|
||||||
|
this.onHide();
|
||||||
},
|
},
|
||||||
|
|
||||||
ensureTagDefaults() {
|
ensureTagDefaults() {
|
||||||
if (!Array.isArray(this.userData.personal_tags)) {
|
if (!Array.isArray(this.userData.personal_tags)) {
|
||||||
this.$set(this.userData, 'personal_tags', []);
|
this.$set(this.userData, "personal_tags", []);
|
||||||
}
|
}
|
||||||
if (typeof this.userData.personal_tags_total !== 'number') {
|
if (typeof this.userData.personal_tags_total !== "number") {
|
||||||
this.$set(this.userData, 'personal_tags_total', this.userData.personal_tags.length);
|
this.$set(
|
||||||
|
this.userData,
|
||||||
|
"personal_tags_total",
|
||||||
|
this.userData.personal_tags.length
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -266,9 +285,19 @@ export default {
|
|||||||
this.tagModalVisible = true;
|
this.tagModalVisible = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
onTagsUpdated({top, total}) {
|
onTagsUpdated({ top, total }) {
|
||||||
this.$set(this.userData, 'personal_tags', Array.isArray(top) ? top : []);
|
this.$set(
|
||||||
this.$set(this.userData, 'personal_tags_total', typeof total === 'number' ? total : this.userData.personal_tags.length);
|
this.userData,
|
||||||
|
"personal_tags",
|
||||||
|
Array.isArray(top) ? top : []
|
||||||
|
);
|
||||||
|
this.$set(
|
||||||
|
this.userData,
|
||||||
|
"personal_tags_total",
|
||||||
|
typeof total === "number"
|
||||||
|
? total
|
||||||
|
: this.userData.personal_tags.length
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
loadCommonDialogCount() {
|
loadCommonDialogCount() {
|
||||||
@ -299,123 +328,90 @@ export default {
|
|||||||
|
|
||||||
const cacheMap = this.$store.state.dialogCommonCountCache || {};
|
const cacheMap = this.$store.state.dialogCommonCountCache || {};
|
||||||
const cached = cacheMap[String(target_userid)];
|
const cached = cacheMap[String(target_userid)];
|
||||||
if (cached && typeof cached.total !== 'undefined') {
|
if (cached && typeof cached.total !== "undefined") {
|
||||||
this.commonDialog = {
|
this.commonDialog = {
|
||||||
...this.commonDialog,
|
...this.commonDialog,
|
||||||
total: cached.total,
|
total: cached.total,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$store.dispatch('call', {
|
this.$store
|
||||||
url: 'dialog/common/list',
|
.dispatch("call", {
|
||||||
data: {
|
url: "dialog/common/list",
|
||||||
target_userid,
|
data: {
|
||||||
only_count: 'yes'
|
target_userid,
|
||||||
}
|
only_count: "yes",
|
||||||
}).then(({data}) => {
|
},
|
||||||
if (target_userid !== this.userData.userid) {
|
})
|
||||||
return
|
.then(({ data }) => {
|
||||||
}
|
if (target_userid !== this.userData.userid) {
|
||||||
const parsedTotal = Number(data.total);
|
return;
|
||||||
const total = Number.isNaN(parsedTotal) ? 0 : parsedTotal;
|
}
|
||||||
this.commonDialog = {
|
const parsedTotal = Number(data.total);
|
||||||
...this.commonDialog,
|
const total = Number.isNaN(parsedTotal) ? 0 : parsedTotal;
|
||||||
userid: target_userid,
|
this.commonDialog = {
|
||||||
total,
|
...this.commonDialog,
|
||||||
list: [],
|
userid: target_userid,
|
||||||
page: 1,
|
total,
|
||||||
has_more: false,
|
list: [],
|
||||||
};
|
page: 1,
|
||||||
this.$store.commit('common/dialog/count/save', {
|
has_more: false,
|
||||||
userid: target_userid,
|
};
|
||||||
total,
|
this.$store.commit("common/dialog/count/save", {
|
||||||
|
userid: target_userid,
|
||||||
|
total,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
loadCommonDialogList(loadMore = false) {
|
loadCommonDialogList(loadMore = false) {
|
||||||
this.commonDialogLoading++;
|
this.commonDialogLoading++;
|
||||||
const target_userid = this.userData.userid;
|
const target_userid = this.userData.userid;
|
||||||
this.$store.dispatch('call', {
|
this.$store
|
||||||
url: 'dialog/common/list',
|
.dispatch("call", {
|
||||||
data: {
|
url: "dialog/common/list",
|
||||||
target_userid,
|
data: {
|
||||||
page: loadMore ? this.commonDialog.page + 1 : 1
|
target_userid,
|
||||||
}
|
page: loadMore ? this.commonDialog.page + 1 : 1,
|
||||||
}).then(({data}) => {
|
},
|
||||||
if (target_userid !== this.userData.userid) {
|
})
|
||||||
return;
|
.then(({ data }) => {
|
||||||
}
|
if (target_userid !== this.userData.userid) {
|
||||||
this.commonDialog = {
|
return;
|
||||||
...this.commonDialog,
|
}
|
||||||
list: loadMore ? [...this.commonDialog.list, ...data.data] : data.data,
|
this.commonDialog = {
|
||||||
total: data.total,
|
...this.commonDialog,
|
||||||
page: data.current_page,
|
list: loadMore
|
||||||
has_more: !!data.next_page_url
|
? [...this.commonDialog.list, ...data.data]
|
||||||
}
|
: data.data,
|
||||||
}).catch(({msg}) => {
|
total: data.total,
|
||||||
$A.modalError(msg || this.$L('加载失败'));
|
page: data.current_page,
|
||||||
}).finally(() => {
|
has_more: !!data.next_page_url,
|
||||||
this.commonDialogLoading--;
|
};
|
||||||
});
|
})
|
||||||
|
.catch(({ msg }) => {
|
||||||
|
$A.modalError(msg || this.$L("加载失败"));
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.commonDialogLoading--;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
onOpenCommonDialogChat(dialog) {
|
onOpenCommonDialogChat(dialog) {
|
||||||
this.$store.dispatch("openDialog", dialog.id).then(() => {
|
this.$store
|
||||||
this.onHide();
|
.dispatch("openDialog", dialog.id)
|
||||||
}).catch(({msg}) => {
|
.then(() => {
|
||||||
$A.modalError(msg);
|
this.onHide();
|
||||||
});
|
})
|
||||||
|
.catch(({ msg }) => {
|
||||||
|
$A.modalError(msg);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.user-tags-line {
|
// The styles will be moved to the SCSS file as requested.
|
||||||
display: flex;
|
// This scoped style block can be removed if not needed for specific overrides.
|
||||||
align-items: flex-start;
|
|
||||||
gap: 8px;
|
|
||||||
|
|
||||||
span:first-child {
|
|
||||||
flex: 0 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tags-content {
|
|
||||||
flex: 1;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 6px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tags-list {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 6px;
|
|
||||||
|
|
||||||
.tag-pill {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.tags-empty {
|
|
||||||
color: #909399;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tags-extra {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
|
|
||||||
.tags-total {
|
|
||||||
color: #909399;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.manage-button {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -43,7 +43,7 @@
|
|||||||
:class="{'is-editing': editId === tag.id}">
|
:class="{'is-editing': editId === tag.id}">
|
||||||
<div class="tag-item-main">
|
<div class="tag-item-main">
|
||||||
<div class="tag-name" v-if="editId !== tag.id">
|
<div class="tag-name" v-if="editId !== tag.id">
|
||||||
<Tag :color="tag.recognized ? 'primary' : 'default'" class="tag-pill">{{tag.name}}</Tag>
|
<Tag :color="tag.recognized ? '#84C56A' : 'default'" class="tag-pill">{{tag.name}}</Tag>
|
||||||
</div>
|
</div>
|
||||||
<div class="tag-name edit" v-else>
|
<div class="tag-name edit" v-else>
|
||||||
<Input
|
<Input
|
||||||
|
|||||||
@ -50,7 +50,7 @@
|
|||||||
<Tag
|
<Tag
|
||||||
v-for="tag in displayTags"
|
v-for="tag in displayTags"
|
||||||
:key="tag.id"
|
:key="tag.id"
|
||||||
:color="tag.recognized ? 'primary' : 'default'"
|
:color="tag.recognized ? '#84C56A' : 'default'"
|
||||||
class="tag-pill">{{tag.name}}</Tag>
|
class="tag-pill">{{tag.name}}</Tag>
|
||||||
</template>
|
</template>
|
||||||
<span v-else class="tags-empty">{{$L('暂无个性标签')}}</span>
|
<span v-else class="tags-empty">{{$L('暂无个性标签')}}</span>
|
||||||
|
|||||||
@ -1,89 +1,144 @@
|
|||||||
.common-user-detail-modal {
|
.common-user-detail-modal {
|
||||||
.ivu-modal {
|
.ivu-modal-content {
|
||||||
max-width: 90%;
|
border-radius: 16px !important;
|
||||||
|
margin-top: calc(var(--status-bar-height) + 46px) !important;
|
||||||
&.ivu-modal-fullscreen {
|
}
|
||||||
max-width: none;
|
.ivu-modal-body {
|
||||||
|
padding: 0 !important;
|
||||||
.ivu-modal-content {
|
}
|
||||||
margin-top: calc(var(--status-bar-height) + 46px);
|
.user-detail-body {
|
||||||
margin-bottom: 0;
|
.profile-header {
|
||||||
border-top-left-radius: 18px !important;
|
position: relative;
|
||||||
border-top-right-radius: 18px !important;
|
height: 160px;
|
||||||
|
.cover-photo {
|
||||||
.ivu-modal-body {
|
background: $primary-color;
|
||||||
.user-detail-body {
|
height: 120px;
|
||||||
padding-bottom: var(--navigation-bar-height);
|
border-top-left-radius: 16px;
|
||||||
}
|
border-top-right-radius: 16px;
|
||||||
|
}
|
||||||
|
.profile-avatar {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
border: 4px solid #fff;
|
||||||
|
border-radius: 50%;
|
||||||
|
.user-avatar {
|
||||||
|
display: block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.profile-content {
|
||||||
|
padding: 16px 24px 24px;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
.user-detail-actions {
|
.user-info-top {
|
||||||
display: flex;
|
.username {
|
||||||
gap: 10px;
|
color: $primary-desc-color;
|
||||||
}
|
font-size: 14px;
|
||||||
|
}
|
||||||
.ivu-modal-content {
|
.fullname {
|
||||||
overflow: hidden;
|
font-size: 20px;
|
||||||
|
font-weight: bold;
|
||||||
.ivu-modal-body {
|
margin: 4px 0;
|
||||||
padding: 0 !important;
|
}
|
||||||
display: flex;
|
.meta {
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
.user-detail-body {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 16px;
|
color: #808695;
|
||||||
padding: 84px 24px;
|
font-size: 12px;
|
||||||
|
.common-dialog {
|
||||||
.avatar-wrapper {
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
.separator {
|
||||||
|
margin: 0 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
> ul {
|
.profile-actions {
|
||||||
width: 80%;
|
margin: 16px 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
> li {
|
.profile-bio {
|
||||||
list-style: none;
|
color: $primary-title-color;
|
||||||
display: flex;
|
line-height: 1.5;
|
||||||
justify-content: center;
|
margin: 16px 0;
|
||||||
margin: 12px auto;
|
padding: 0 50px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
&.user-name {
|
.profile-information {
|
||||||
align-items: center;
|
text-align: left;
|
||||||
}
|
background-color: #f8f8f9;
|
||||||
|
padding: 16px;
|
||||||
|
border-radius: 8px;
|
||||||
|
|
||||||
> em {
|
h2 {
|
||||||
font-style: normal;
|
font-size: 16px;
|
||||||
&.disabled,
|
margin-bottom: 12px;
|
||||||
&.deleted {
|
}
|
||||||
display: inline-block;
|
|
||||||
margin-left: 2px;
|
|
||||||
white-space: nowrap;
|
|
||||||
font-size: 12px;
|
|
||||||
height: 20px;
|
|
||||||
line-height: 20px;
|
|
||||||
padding: 0 6px;
|
|
||||||
border-radius: 3px;
|
|
||||||
transform: scale(0.9);
|
|
||||||
transform-origin: right center;
|
|
||||||
color: #ffffff;
|
|
||||||
background-color: #ED4014;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> span {
|
ul {
|
||||||
flex-shrink: 0;
|
list-style: none;
|
||||||
opacity: 0.8;
|
padding: 0;
|
||||||
padding-right: 4px;
|
margin: 0;
|
||||||
}
|
|
||||||
|
li {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start; // 避免多行内容导致垂直居中不齐
|
||||||
|
padding: 8px 0;
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
.ivu-icon {
|
||||||
|
font-size: 20px;
|
||||||
|
margin-right: 12px;
|
||||||
|
color: $primary-desc-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
color: #808695;
|
||||||
|
flex: 0 0 64px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
line-height: 22px;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value {
|
||||||
|
color: $primary-title-color;
|
||||||
|
font-weight: 500;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
min-width: 0;
|
||||||
|
margin-left: 0;
|
||||||
|
text-align: right;
|
||||||
|
white-space: normal;
|
||||||
|
word-break: break-word;
|
||||||
|
overflow-wrap: break-word;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.profile-tags {
|
||||||
|
margin-top: 12px;
|
||||||
|
padding-top: 12px;
|
||||||
|
border-top: 1px solid #80869550;
|
||||||
|
cursor: pointer;
|
||||||
|
.tags-list {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 8px;
|
||||||
|
justify-content: center;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.ivu-tag {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user