mirror of
https://github.com/kuaifan/dootask.git
synced 2026-02-07 05:55:38 +00:00
Compare commits
2 Commits
0b0c2f7cc6
...
ab4640382d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ab4640382d | ||
|
|
e4cfa4b405 |
@ -388,9 +388,6 @@ class UsersController extends AbstractController
|
|||||||
$data['nickname_original'] = $user->getRawOriginal('nickname');
|
$data['nickname_original'] = $user->getRawOriginal('nickname');
|
||||||
$data['department_name'] = $user->getDepartmentName();
|
$data['department_name'] = $user->getDepartmentName();
|
||||||
$data['department_owner'] = UserDepartment::where('parent_id',0)->where('owner_userid', $user->userid)->exists(); // 适用默认部门下第1级负责人才能添加部门OKR
|
$data['department_owner'] = UserDepartment::where('parent_id',0)->where('owner_userid', $user->userid)->exists(); // 适用默认部门下第1级负责人才能添加部门OKR
|
||||||
$tagMeta = UserTag::listWithMeta($user->userid, $user);
|
|
||||||
$data['personal_tags'] = $tagMeta['top'];
|
|
||||||
$data['personal_tags_total'] = $tagMeta['total'];
|
|
||||||
return Base::retSuccess('success', $data);
|
return Base::retSuccess('success', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -809,12 +806,8 @@ class UsersController extends AbstractController
|
|||||||
public function basic()
|
public function basic()
|
||||||
{
|
{
|
||||||
$sharekey = Request::header('sharekey');
|
$sharekey = Request::header('sharekey');
|
||||||
$shareInfo = $sharekey ? Meeting::getShareInfo($sharekey) : null;
|
if (empty($sharekey) || !Meeting::getShareInfo($sharekey)) {
|
||||||
$viewer = null;
|
User::auth();
|
||||||
if (empty($shareInfo)) {
|
|
||||||
$viewer = User::auth();
|
|
||||||
} elseif (Doo::userId() > 0) {
|
|
||||||
$viewer = User::whereUserid(Doo::userId())->first();
|
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
$userid = Request::input('userid');
|
$userid = Request::input('userid');
|
||||||
@ -832,16 +825,75 @@ class UsersController extends AbstractController
|
|||||||
$basic = UserDelete::userid2basic($id);
|
$basic = UserDelete::userid2basic($id);
|
||||||
}
|
}
|
||||||
if ($basic) {
|
if ($basic) {
|
||||||
$tagMeta = UserTag::listWithMeta($basic->userid, $viewer);
|
|
||||||
$basic->personal_tags = $tagMeta['top'];
|
|
||||||
$basic->personal_tags_total = $tagMeta['total'];
|
|
||||||
//
|
|
||||||
$retArray[] = $basic;
|
$retArray[] = $basic;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Base::retSuccess('success', $retArray);
|
return Base::retSuccess('success', $retArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @api {get} api/users/extra 获取会员扩展信息
|
||||||
|
*
|
||||||
|
* @apiDescription 需要token身份
|
||||||
|
* @apiVersion 1.0.0
|
||||||
|
* @apiGroup users
|
||||||
|
* @apiName extra
|
||||||
|
*
|
||||||
|
* @apiParam {Number} [userid] 会员ID(不传默认为当前用户)
|
||||||
|
*
|
||||||
|
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||||
|
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||||
|
* @apiSuccess {Object} data 返回数据
|
||||||
|
*/
|
||||||
|
public function extra()
|
||||||
|
{
|
||||||
|
$user = User::auth();
|
||||||
|
//
|
||||||
|
$userid = intval(Request::input('userid'));
|
||||||
|
if ($userid <= 0) {
|
||||||
|
$userid = $user->userid;
|
||||||
|
}
|
||||||
|
if ($userid <= 0) {
|
||||||
|
return Base::retError('会员不存在');
|
||||||
|
}
|
||||||
|
|
||||||
|
$user = User::query()
|
||||||
|
->select(['userid', 'birthday', 'address', 'introduction'])
|
||||||
|
->whereUserid($userid)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
$birthday = null;
|
||||||
|
$address = null;
|
||||||
|
$introduction = null;
|
||||||
|
|
||||||
|
if ($user) {
|
||||||
|
$birthday = $user->birthday;
|
||||||
|
$address = $user->address;
|
||||||
|
$introduction = $user->introduction;
|
||||||
|
} else {
|
||||||
|
$deleted = UserDelete::whereUserid($userid)->first();
|
||||||
|
if (empty($deleted) || empty($deleted->cache)) {
|
||||||
|
return Base::retError('会员不存在');
|
||||||
|
}
|
||||||
|
$birthday = $deleted->cache['birthday'] ?? null;
|
||||||
|
$address = $deleted->cache['address'] ?? null;
|
||||||
|
$introduction = $deleted->cache['introduction'] ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$tagMeta = UserTag::listWithMeta($userid, $user);
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'userid' => $userid,
|
||||||
|
'birthday' => $birthday,
|
||||||
|
'address' => $address,
|
||||||
|
'introduction' => $introduction,
|
||||||
|
'personal_tags' => $tagMeta['top'],
|
||||||
|
'personal_tags_total' => $tagMeta['total'],
|
||||||
|
];
|
||||||
|
|
||||||
|
return Base::retSuccess('success', $data);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {get} api/users/lists 会员列表(限管理员)
|
* @api {get} api/users/lists 会员列表(限管理员)
|
||||||
*
|
*
|
||||||
|
|||||||
@ -92,7 +92,7 @@ class User extends AbstractModel
|
|||||||
public static $defaultAvatarMode = 'auto';
|
public static $defaultAvatarMode = 'auto';
|
||||||
|
|
||||||
// 基本信息的字段
|
// 基本信息的字段
|
||||||
public static $basicField = ['userid', 'email', 'nickname', 'profession', 'birthday', 'address', 'introduction', 'department', 'userimg', 'bot', 'az', 'pinyin', 'line_at', 'disable_at'];
|
public static $basicField = ['userid', 'email', 'nickname', 'profession', 'department', 'userimg', 'bot', 'az', 'pinyin', 'line_at', 'disable_at'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 昵称
|
* 昵称
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
:fullscreen="isFullscreen"
|
:fullscreen="isFullscreen"
|
||||||
:mask-closable="false"
|
:mask-closable="false"
|
||||||
:footer-hide="true"
|
:footer-hide="true"
|
||||||
width="420"
|
width="480"
|
||||||
>
|
>
|
||||||
<div class="user-detail-body">
|
<div class="user-detail-body">
|
||||||
<div class="profile-header">
|
<div class="profile-header">
|
||||||
@ -13,7 +13,7 @@
|
|||||||
<div class="profile-avatar">
|
<div class="profile-avatar">
|
||||||
<UserAvatar
|
<UserAvatar
|
||||||
:userid="userData.userid"
|
:userid="userData.userid"
|
||||||
:size="80"
|
:size="96"
|
||||||
:show-state-dot="false"
|
:show-state-dot="false"
|
||||||
@on-click="onOpenAvatar"
|
@on-click="onOpenAvatar"
|
||||||
/>
|
/>
|
||||||
@ -21,46 +21,22 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="profile-content">
|
<div class="profile-content">
|
||||||
<div class="user-info-top">
|
<div class="user-info-top">
|
||||||
<span class="username"
|
<h1 class="username">
|
||||||
>@{{ userData.profession || "管理员" }}</span
|
{{ userData.nickname }}
|
||||||
>
|
|
||||||
<h1 class="fullname">
|
|
||||||
{{ userData.nickname}}
|
|
||||||
</h1>
|
</h1>
|
||||||
<div class="meta">
|
<div class="meta">
|
||||||
<!-- <span>{{userData.address || 'Bandung'}}</span> -->
|
<span @click="commonDialogShow = true" class="common-dialog">{{ $L(userId == userData.userid ? "我的群组" : "共同群组") }}:<em>{{ $L("(*)个", commonDialog.total) }}</em></span>
|
||||||
<span @click="commonDialogShow = true"
|
|
||||||
class="common-dialog"
|
|
||||||
>{{ $L("共同群组") }}:
|
|
||||||
{{ $L("(*)个", commonDialog.total) }}</span
|
|
||||||
>
|
|
||||||
<span class="separator">|</span>
|
<span class="separator">|</span>
|
||||||
<span
|
<span>{{ $L("最后在线") }}: {{$A.newDateString( userData.line_at, "YYYY-MM-DD HH:mm") || "-"}}</span>
|
||||||
>{{ $L("最后在线") }}:
|
|
||||||
{{
|
|
||||||
$A.newDateString(
|
|
||||||
userData.line_at,
|
|
||||||
"YYYY-MM-DD HH:mm"
|
|
||||||
) || "-"
|
|
||||||
}}</span
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="profile-actions">
|
<div class="profile-actions">
|
||||||
<Button
|
<Button @click="onOpenDialog"><i class="taskfont"></i>{{ $L("开始聊天") }}</Button>
|
||||||
icon="md-chatbubbles"
|
<Button @click="onCreateGroup"><i class="taskfont"></i>{{ $L("创建群组") }}</Button>
|
||||||
@click="onOpenDialog"
|
|
||||||
>{{ $L("开始聊天") }}</Button
|
|
||||||
>
|
|
||||||
<Button
|
|
||||||
icon="md-people"
|
|
||||||
@click="onCreateGroup"
|
|
||||||
>{{ $L("创建群组") }}</Button
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="profile-bio">
|
<div v-if="userData.introduction" class="profile-bio">
|
||||||
<p>{{ userData.introduction }}</p>
|
<p>{{ userData.introduction }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -68,57 +44,57 @@
|
|||||||
<h2>{{ $L("个人信息") }}</h2>
|
<h2>{{ $L("个人信息") }}</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<Icon type="ios-person-outline" />
|
<Icon type="ios-briefcase-outline" />
|
||||||
|
<span class="label">{{ $L("职位/职称") }}</span>
|
||||||
|
<span class="value">{{userData.profession || "-"}}</span>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<Icon type="ios-people-outline" />
|
||||||
<span class="label">{{ $L("部门") }}</span>
|
<span class="label">{{ $L("部门") }}</span>
|
||||||
<span class="value">{{
|
<span class="value">{{userData.department_name || "-"}}</span>
|
||||||
userData.department_name || "-"
|
|
||||||
}}</span>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<Icon type="ios-mail-outline" />
|
<Icon type="ios-mail-outline" />
|
||||||
<span class="label">{{ $L("邮箱") }}</span>
|
<span class="label">{{ $L("邮箱") }}</span>
|
||||||
<span class="value">{{
|
<span @click="onOpenEmail" class="value" :class="{ 'clickable': userData.email }">{{userData.email || "-"}}</span>
|
||||||
userData.email || "-"
|
|
||||||
}}</span>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<Icon type="ios-call-outline" />
|
<Icon type="ios-call-outline" />
|
||||||
<span class="label">{{ $L("电话") }}</span>
|
<span class="label">{{ $L("电话") }}</span>
|
||||||
<span class="value">{{ userData.tel || "-" }}</span>
|
<span @click="onOpenTel" class="value" :class="{ 'clickable': userData.tel }">{{ userData.tel || "-" }}</span>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li v-if="userData.birthday">
|
||||||
<Icon type="ios-calendar-outline" />
|
<Icon type="ios-calendar-outline" />
|
||||||
<span class="label">{{ $L("生日") }}</span>
|
<span class="label">{{ $L("生日") }}</span>
|
||||||
<span class="value">{{
|
<span class="value">{{userData.birthday || "-"}}</span>
|
||||||
userData.birthday || "-"
|
|
||||||
}}</span>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div class="profile-tags" @click.capture="onOpenTagsModal">
|
<div class="profile-tags">
|
||||||
<div v-if="displayTags.length" class="tags-list">
|
<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
|
<Button
|
||||||
v-for="tag in displayTags"
|
v-for="tag in displayTags"
|
||||||
:key="tag.id"
|
:key="tag.id"
|
||||||
:type="tag.recognized ? 'primary' : 'default'"
|
:type="tag.recognized ? 'primary' : 'default'"
|
||||||
|
@click="onOpenTagsModal"
|
||||||
>
|
>
|
||||||
{{ tag.name }}
|
{{ tag.name }}
|
||||||
|
<span v-if="tag.recognition_total > 0" class="recognition-total">{{tag.recognition_total}}</span>
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
type="dashed"
|
||||||
|
class="manage-tags-btn icon"
|
||||||
|
@click="onOpenTagsModal"
|
||||||
|
>
|
||||||
|
<Icon type="ios-settings-outline" /> 管理
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="tags-empty">
|
<div v-else class="tags-empty">
|
||||||
<Button
|
<Button
|
||||||
type="dashed"
|
type="dashed"
|
||||||
size="small"
|
|
||||||
icon="md-add"
|
icon="md-add"
|
||||||
class="add-tag-btn"
|
class="add-tag-btn"
|
||||||
@click.stop="onOpenTagsModal"
|
@click="onOpenTagsModal"
|
||||||
>{{ $L("添加标签") }}</Button
|
>{{ $L("添加标签") }}</Button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@ -222,10 +198,14 @@ export default {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.$store.dispatch("showSpinner", 600);
|
this.$store.dispatch("showSpinner", 600);
|
||||||
this.$store
|
Promise.all([
|
||||||
.dispatch("getUserData", userid)
|
this.$store.dispatch("getUserData", userid).catch(() => null),
|
||||||
.then((user) => {
|
this.$store.dispatch("getUserExtra", userid).catch(() => null),
|
||||||
this.userData = user;
|
])
|
||||||
|
.then(([user, extra]) => {
|
||||||
|
const baseData = $A.isJson(user) ? user : {};
|
||||||
|
const extraData = $A.isJson(extra) ? extra : {};
|
||||||
|
this.userData = Object.assign({}, baseData, extraData);
|
||||||
this.ensureTagDefaults();
|
this.ensureTagDefaults();
|
||||||
this.showModal = true;
|
this.showModal = true;
|
||||||
this.loadCommonDialogCount();
|
this.loadCommonDialogCount();
|
||||||
@ -407,11 +387,37 @@ export default {
|
|||||||
$A.modalError(msg);
|
$A.modalError(msg);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onOpenEmail() {
|
||||||
|
if (!this.userData.email) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$A.modalConfirm({
|
||||||
|
content: `是否发送邮件给 ${this.userData.nickname}?`,
|
||||||
|
onOk: () => {
|
||||||
|
window.open(`mailto:${this.userData.email}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onOpenTel() {
|
||||||
|
if (!this.userData.tel) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$A.modalConfirm({
|
||||||
|
content: `是否拨打电话给 ${this.userData.nickname}?`,
|
||||||
|
onOk: () => {
|
||||||
|
if ($A.isEEUIApp()) {
|
||||||
|
$A.eeuiAppSendMessage({
|
||||||
|
action: 'callTel',
|
||||||
|
tel: this.userData.tel
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
window.open(`tel:${this.userData.tel}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
// The styles will be moved to the SCSS file as requested.
|
|
||||||
// This scoped style block can be removed if not needed for specific overrides.
|
|
||||||
</style>
|
|
||||||
|
|||||||
@ -2,17 +2,12 @@
|
|||||||
<ModalAlive
|
<ModalAlive
|
||||||
v-model="visible"
|
v-model="visible"
|
||||||
class-name="user-tags-manage-modal"
|
class-name="user-tags-manage-modal"
|
||||||
|
:title="$L('个性标签管理')"
|
||||||
:mask-closable="false"
|
:mask-closable="false"
|
||||||
:footer-hide="true"
|
:footer-hide="true"
|
||||||
width="520"
|
width="520"
|
||||||
:closable="true">
|
:closable="true">
|
||||||
<div class="tag-modal-container">
|
<div class="tag-modal-container">
|
||||||
<div class="tag-modal-header">
|
|
||||||
<h3>{{$L('个性标签管理')}}</h3>
|
|
||||||
<p class="tag-modal-meta">
|
|
||||||
<span>{{$L('当前共(*)个标签', total)}}</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="tag-modal-form">
|
<div class="tag-modal-form">
|
||||||
<Input
|
<Input
|
||||||
v-model="newTagName"
|
v-model="newTagName"
|
||||||
@ -43,7 +38,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 ? '#84C56A' : 'default'" class="tag-pill">{{tag.name}}</Tag>
|
<div class="tag-pill" :class="{'is-recognized': tag.recognized}">{{tag.name}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="tag-name edit" v-else>
|
<div class="tag-name edit" v-else>
|
||||||
<Input
|
<Input
|
||||||
@ -62,7 +57,7 @@
|
|||||||
:loading="isPending(tag.id, 'recognize')"
|
:loading="isPending(tag.id, 'recognize')"
|
||||||
@click="toggleRecognize(tag)">
|
@click="toggleRecognize(tag)">
|
||||||
<Icon type="md-thumbs-up" />
|
<Icon type="md-thumbs-up" />
|
||||||
<span>{{tag.recognition_total}}</span>
|
<span v-if="tag.recognition_total > 0">{{tag.recognition_total}}</span>
|
||||||
<span class="recognize-text">{{$L('认可')}}</span>
|
<span class="recognize-text">{{$L('认可')}}</span>
|
||||||
</Button>
|
</Button>
|
||||||
<template v-if="editId === tag.id">
|
<template v-if="editId === tag.id">
|
||||||
@ -92,11 +87,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="tag-meta-info" v-if="tag.created_by_name">
|
<div class="tag-meta-info" v-if="tag.created_by_name">
|
||||||
<span>{{$L('由(*)创建', tag.created_by_name)}}</span>
|
<span>{{$L('由 (*) 创建', tag.created_by_name)}}</span>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-if="total > 0" class="tag-modal-footer">
|
||||||
|
<span>{{$L('当前共 (*) 个标签', total)}}</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ModalAlive>
|
</ModalAlive>
|
||||||
</template>
|
</template>
|
||||||
@ -215,17 +213,14 @@ export default {
|
|||||||
},
|
},
|
||||||
emitUpdated(payload) {
|
emitUpdated(payload) {
|
||||||
this.$emit('updated', payload);
|
this.$emit('updated', payload);
|
||||||
if (this.userid === this.$store.state.userInfo.userid) {
|
this.$store.dispatch('saveUserExtra', {
|
||||||
const info = Object.assign({}, this.$store.state.userInfo, {
|
|
||||||
personal_tags: payload.top,
|
|
||||||
personal_tags_total: payload.total
|
|
||||||
});
|
|
||||||
this.$store.dispatch('saveUserInfoBase', info);
|
|
||||||
}
|
|
||||||
this.$store.dispatch('saveUserBasic', {
|
|
||||||
userid: this.userid,
|
userid: this.userid,
|
||||||
personal_tags: payload.top,
|
data: {
|
||||||
personal_tags_total: payload.total
|
personal_tags: Array.isArray(payload?.top) ? payload.top : [],
|
||||||
|
personal_tags_total: typeof payload?.total === 'number'
|
||||||
|
? payload.total
|
||||||
|
: (Array.isArray(payload?.top) ? payload.top.length : 0)
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
handleAdd() {
|
handleAdd() {
|
||||||
@ -364,23 +359,7 @@ export default {
|
|||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.user-tags-manage-modal {
|
.user-tags-manage-modal {
|
||||||
.tag-modal-container {
|
.tag-modal-container {
|
||||||
padding: 16px 20px 12px;
|
padding-bottom: 20px;
|
||||||
}
|
|
||||||
.tag-modal-header {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
h3 {
|
|
||||||
margin: 0;
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
.tag-modal-meta {
|
|
||||||
margin: 0;
|
|
||||||
color: #909399;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.tag-modal-form {
|
.tag-modal-form {
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
@ -388,6 +367,7 @@ export default {
|
|||||||
.tag-modal-body {
|
.tag-modal-body {
|
||||||
max-height: 360px;
|
max-height: 360px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
margin-bottom: 16px;
|
||||||
}
|
}
|
||||||
.tag-loading {
|
.tag-loading {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -396,7 +376,7 @@ export default {
|
|||||||
}
|
}
|
||||||
.tag-empty {
|
.tag-empty {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 32px 0;
|
padding: 36px 0 32px;
|
||||||
color: #909399;
|
color: #909399;
|
||||||
p {
|
p {
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
@ -432,7 +412,21 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.tag-pill {
|
.tag-pill {
|
||||||
cursor: default;
|
padding: 6px 12px;
|
||||||
|
border-radius: 12px;
|
||||||
|
font-size: 13px;
|
||||||
|
user-select: none;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
color: #606266;
|
||||||
|
line-height: 14px;
|
||||||
|
height: 26px;
|
||||||
|
max-width: 160px;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
&.is-recognized {
|
||||||
|
color: #67c23a;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.tag-actions {
|
.tag-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -442,9 +436,12 @@ export default {
|
|||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
|
.ivu-icon {
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
.recognize-text {
|
.recognize-text {
|
||||||
|
padding-left: 4px;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #606266;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -455,5 +452,9 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.tag-modal-footer {
|
||||||
|
color: #909399;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -45,13 +45,17 @@
|
|||||||
:placeholder="$L('请输入个人简介')"></Input>
|
:placeholder="$L('请输入个人简介')"></Input>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
<FormItem :label="$L('个性标签')">
|
<FormItem :label="$L('个性标签')">
|
||||||
<div class="user-tags-preview" @click="openTagModal">
|
<div class="user-tags-preview">
|
||||||
<template v-if="displayTags.length">
|
<template v-if="displayTags.length">
|
||||||
<Tag
|
<div
|
||||||
v-for="tag in displayTags"
|
v-for="tag in displayTags"
|
||||||
:key="tag.id"
|
:key="tag.id"
|
||||||
:color="tag.recognized ? '#84C56A' : 'default'"
|
class="tag-pill"
|
||||||
class="tag-pill">{{tag.name}}</Tag>
|
:class="{'is-recognized': tag.recognized}"
|
||||||
|
@click="openTagModal">
|
||||||
|
{{tag.name}}
|
||||||
|
<span v-if="tag.recognition_total > 0">{{tag.recognition_total}}</span>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<span v-else class="tags-empty">{{$L('暂无个性标签')}}</span>
|
<span v-else class="tags-empty">{{$L('暂无个性标签')}}</span>
|
||||||
<span v-if="personalTagTotal > displayTags.length" class="tags-total">{{$L('共(*)个', personalTagTotal)}}</span>
|
<span v-if="personalTagTotal > displayTags.length" class="tags-total">{{$L('共(*)个', personalTagTotal)}}</span>
|
||||||
@ -85,16 +89,20 @@ export default {
|
|||||||
loadIng: 0,
|
loadIng: 0,
|
||||||
|
|
||||||
formData: {
|
formData: {
|
||||||
|
// 基本信息
|
||||||
userimg: '',
|
userimg: '',
|
||||||
email: '',
|
email: '',
|
||||||
tel: '',
|
tel: '',
|
||||||
nickname: '',
|
nickname: '',
|
||||||
profession: '',
|
profession: '',
|
||||||
|
// 拓展信息 生日、地址、个人简介
|
||||||
birthday: '',
|
birthday: '',
|
||||||
address: '',
|
address: '',
|
||||||
introduction: ''
|
introduction: ''
|
||||||
},
|
},
|
||||||
|
|
||||||
|
extraInfo: {},
|
||||||
|
|
||||||
ruleData: {
|
ruleData: {
|
||||||
email: [
|
email: [
|
||||||
{required: true, message: this.$L('请输入邮箱地址!'), trigger: 'change'},
|
{required: true, message: this.$L('请输入邮箱地址!'), trigger: 'change'},
|
||||||
@ -116,6 +124,7 @@ export default {
|
|||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.initData();
|
this.initData();
|
||||||
|
this.loadUserExtra();
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(['userInfo', 'formOptions']),
|
...mapState(['userInfo', 'formOptions']),
|
||||||
@ -127,27 +136,60 @@ export default {
|
|||||||
watch: {
|
watch: {
|
||||||
userInfo() {
|
userInfo() {
|
||||||
this.initData();
|
this.initData();
|
||||||
|
this.loadUserExtra();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
initData() {
|
initData() {
|
||||||
|
const extra = this.extraInfo || {};
|
||||||
this.$set(this.formData, 'userimg', $A.strExists(this.userInfo.userimg, '/avatar') ? '' : this.userInfo.userimg);
|
this.$set(this.formData, 'userimg', $A.strExists(this.userInfo.userimg, '/avatar') ? '' : this.userInfo.userimg);
|
||||||
this.$set(this.formData, 'email', this.userInfo.email);
|
this.$set(this.formData, 'email', this.userInfo.email);
|
||||||
this.$set(this.formData, 'tel', this.userInfo.tel);
|
this.$set(this.formData, 'tel', this.userInfo.tel);
|
||||||
this.$set(this.formData, 'nickname', typeof this.userInfo.nickname_original !== "undefined" ? this.userInfo.nickname_original : this.userInfo.nickname);
|
this.$set(this.formData, 'nickname', typeof this.userInfo.nickname_original !== "undefined" ? this.userInfo.nickname_original : this.userInfo.nickname);
|
||||||
this.$set(this.formData, 'profession', this.userInfo.profession);
|
this.$set(this.formData, 'profession', this.userInfo.profession);
|
||||||
this.$set(this.formData, 'birthday', this.userInfo.birthday || '');
|
this.$set(this.formData, 'birthday', extra.birthday || '');
|
||||||
this.$set(this.formData, 'address', this.userInfo.address || '');
|
this.$set(this.formData, 'address', extra.address || '');
|
||||||
this.$set(this.formData, 'introduction', this.userInfo.introduction || '');
|
this.$set(this.formData, 'introduction', extra.introduction || '');
|
||||||
this.formData_bak = $A.cloneJSON(this.formData);
|
this.formData_bak = $A.cloneJSON(this.formData);
|
||||||
this.syncPersonalTags();
|
this.syncPersonalTags();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
loadUserExtra(force = false) {
|
||||||
|
const userid = this.userInfo?.userid;
|
||||||
|
if (!userid) {
|
||||||
|
this.applyExtraInfo({});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const payload = force ? {userid, force: true} : userid;
|
||||||
|
this.$store.dispatch("getUserExtra", payload)
|
||||||
|
.then((data) => {
|
||||||
|
if ($A.isJson(data)) {
|
||||||
|
this.applyExtraInfo(data);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
if (!this.extraInfo || Object.keys(this.extraInfo).length === 0) {
|
||||||
|
this.applyExtraInfo({});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
applyExtraInfo(extra) {
|
||||||
|
const info = $A.isJson(extra) ? extra : {};
|
||||||
|
this.extraInfo = info;
|
||||||
|
this.$set(this.formData, 'birthday', info.birthday || '');
|
||||||
|
this.$set(this.formData, 'address', info.address || '');
|
||||||
|
this.$set(this.formData, 'introduction', info.introduction || '');
|
||||||
|
this.syncPersonalTags();
|
||||||
|
this.formData_bak = $A.cloneJSON(this.formData);
|
||||||
|
},
|
||||||
|
|
||||||
syncPersonalTags() {
|
syncPersonalTags() {
|
||||||
const tags = Array.isArray(this.userInfo.personal_tags) ? this.userInfo.personal_tags : [];
|
const extra = this.extraInfo || {};
|
||||||
|
const tags = Array.isArray(extra.personal_tags) ? extra.personal_tags : [];
|
||||||
this.personalTags = tags.slice(0, 10);
|
this.personalTags = tags.slice(0, 10);
|
||||||
this.personalTagTotal = typeof this.userInfo.personal_tags_total === 'number'
|
this.personalTagTotal = typeof extra.personal_tags_total === 'number'
|
||||||
? this.userInfo.personal_tags_total
|
? extra.personal_tags_total
|
||||||
: this.personalTags.length;
|
: this.personalTags.length;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -162,7 +204,24 @@ export default {
|
|||||||
data,
|
data,
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
$A.messageSuccess('修改成功');
|
$A.messageSuccess('修改成功');
|
||||||
this.$store.dispatch('getUserInfo').catch(() => {});
|
const userid = this.userInfo?.userid;
|
||||||
|
const extraPayload = {
|
||||||
|
birthday: data.birthday || '',
|
||||||
|
address: data.address || '',
|
||||||
|
introduction: data.introduction || ''
|
||||||
|
};
|
||||||
|
if (userid) {
|
||||||
|
this.$store.dispatch('saveUserExtra', {
|
||||||
|
userid,
|
||||||
|
data: extraPayload
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.applyExtraInfo(Object.assign({}, this.extraInfo, extraPayload));
|
||||||
|
this.$store.dispatch('getUserInfo')
|
||||||
|
.catch(() => {})
|
||||||
|
.finally(() => {
|
||||||
|
this.loadUserExtra(true);
|
||||||
|
});
|
||||||
}).catch(({msg}) => {
|
}).catch(({msg}) => {
|
||||||
$A.modalError(msg);
|
$A.modalError(msg);
|
||||||
}).finally(_ => {
|
}).finally(_ => {
|
||||||
@ -186,6 +245,10 @@ export default {
|
|||||||
onTagsUpdated({top, total}) {
|
onTagsUpdated({top, total}) {
|
||||||
this.personalTags = Array.isArray(top) ? top : [];
|
this.personalTags = Array.isArray(top) ? top : [];
|
||||||
this.personalTagTotal = typeof total === 'number' ? total : this.personalTags.length;
|
this.personalTagTotal = typeof total === 'number' ? total : this.personalTags.length;
|
||||||
|
this.extraInfo = Object.assign({}, this.extraInfo, {
|
||||||
|
personal_tags: this.personalTags,
|
||||||
|
personal_tags_total: this.personalTagTotal
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -198,10 +261,39 @@ export default {
|
|||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
min-height: 32px;
|
min-height: 32px;
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
.tag-pill {
|
.tag-pill {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
padding: 6px 12px;
|
||||||
|
border-radius: 12px;
|
||||||
|
font-size: 13px;
|
||||||
|
user-select: none;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
color: #606266;
|
||||||
|
line-height: 14px;
|
||||||
|
height: 26px;
|
||||||
|
max-width: 160px;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
&.is-recognized {
|
||||||
|
color: #67c23a;
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
padding-left: 8px;
|
||||||
|
position: relative;
|
||||||
|
&:before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
left: 2px;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
width: 2px;
|
||||||
|
height: 2px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: currentColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.tags-empty {
|
.tags-empty {
|
||||||
|
|||||||
60
resources/assets/js/store/actions.js
vendored
60
resources/assets/js/store/actions.js
vendored
@ -714,6 +714,64 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取会员扩展信息
|
||||||
|
* @param state
|
||||||
|
* @param dispatch
|
||||||
|
* @param userid
|
||||||
|
* @returns {Promise<unknown>}
|
||||||
|
*/
|
||||||
|
getUserExtra({state, dispatch}, userid) {
|
||||||
|
return new Promise(async (resolve, reject) => {
|
||||||
|
if (!userid) {
|
||||||
|
reject({msg: "userid missing"});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const cacheMap = state.cacheUserExtra || {};
|
||||||
|
const cacheItem = cacheMap[`${userid}`];
|
||||||
|
const now = Date.now();
|
||||||
|
if (cacheItem && cacheItem.data && (now - cacheItem.updatedAt) < 30000) {
|
||||||
|
resolve(cacheItem.data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const {data} = await dispatch("call", {
|
||||||
|
url: 'users/extra',
|
||||||
|
data: {userid},
|
||||||
|
});
|
||||||
|
state.cacheUserExtra = Object.assign({}, cacheMap, {
|
||||||
|
[`${userid}`]: {
|
||||||
|
data,
|
||||||
|
updatedAt: Date.now()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
resolve(data);
|
||||||
|
} catch (error) {
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存会员扩展信息
|
||||||
|
* @param state
|
||||||
|
* @param payload {userid, data}
|
||||||
|
*/
|
||||||
|
saveUserExtra({state}, payload) {
|
||||||
|
const userid = $A.runNum(payload?.userid);
|
||||||
|
if (!userid || !$A.isJson(payload?.data)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const cacheMap = state.cacheUserExtra || {};
|
||||||
|
const current = cacheMap[`${userid}`]?.data || {};
|
||||||
|
state.cacheUserExtra = Object.assign({}, cacheMap, {
|
||||||
|
[`${userid}`]: {
|
||||||
|
data: Object.assign({}, current, payload.data),
|
||||||
|
updatedAt: Date.now()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新会员信息
|
* 更新会员信息
|
||||||
* @param state
|
* @param state
|
||||||
@ -856,7 +914,7 @@ export default {
|
|||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
if (tempUser) {
|
if (tempUser) {
|
||||||
resolve(tempUser);
|
resolve($A.cloneJSON(tempUser));
|
||||||
} else {
|
} else {
|
||||||
reject();
|
reject();
|
||||||
}
|
}
|
||||||
|
|||||||
1
resources/assets/js/store/state.js
vendored
1
resources/assets/js/store/state.js
vendored
@ -90,6 +90,7 @@ export default {
|
|||||||
// User
|
// User
|
||||||
cacheUserWait: [],
|
cacheUserWait: [],
|
||||||
cacheUserBasic: [],
|
cacheUserBasic: [],
|
||||||
|
cacheUserExtra: {},
|
||||||
|
|
||||||
// 日历
|
// 日历
|
||||||
cacheCalendarView: null,
|
cacheCalendarView: null,
|
||||||
|
|||||||
@ -1,18 +1,32 @@
|
|||||||
.common-user-detail-modal {
|
.common-user-detail-modal {
|
||||||
|
.ivu-modal-fullscreen {
|
||||||
|
.ivu-modal-content {
|
||||||
|
margin-top: calc(var(--status-bar-height) + 46px) !important;
|
||||||
|
}
|
||||||
|
.ivu-modal-body {
|
||||||
|
border-radius: 16px 16px 0 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
.ivu-modal-content {
|
.ivu-modal-content {
|
||||||
border-radius: 16px !important;
|
background-color: transparent;
|
||||||
margin-top: calc(var(--status-bar-height) + 46px) !important;
|
}
|
||||||
|
.ivu-modal-close {
|
||||||
|
.ivu-icon-ios-close {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.ivu-modal-body {
|
.ivu-modal-body {
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 16px;
|
||||||
}
|
}
|
||||||
.user-detail-body {
|
.user-detail-body {
|
||||||
.profile-header {
|
.profile-header {
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 160px;
|
height: 180px;
|
||||||
.cover-photo {
|
.cover-photo {
|
||||||
background: $primary-color;
|
background: $primary-color;
|
||||||
height: 120px;
|
height: 130px;
|
||||||
border-top-left-radius: 16px;
|
border-top-left-radius: 16px;
|
||||||
border-top-right-radius: 16px;
|
border-top-right-radius: 16px;
|
||||||
}
|
}
|
||||||
@ -34,45 +48,59 @@
|
|||||||
|
|
||||||
.user-info-top {
|
.user-info-top {
|
||||||
.username {
|
.username {
|
||||||
color: $primary-desc-color;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
.fullname {
|
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
margin: 4px 0;
|
|
||||||
}
|
}
|
||||||
.meta {
|
.meta {
|
||||||
|
margin-top: 8px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
color: #808695;
|
color: #808695;
|
||||||
font-size: 12px;
|
font-size: 13px;
|
||||||
.common-dialog {
|
.common-dialog {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
em {
|
||||||
|
padding-left: 4px;
|
||||||
|
font-style: normal;
|
||||||
|
color: $primary-color;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.separator {
|
.separator {
|
||||||
margin: 0 8px;
|
margin: 0 8px;
|
||||||
|
opacity: 0.3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.profile-actions {
|
.profile-actions {
|
||||||
margin: 16px 0;
|
margin-top: 16px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
gap: 8px;
|
gap: 12px;
|
||||||
|
.ivu-btn {
|
||||||
|
border-radius: 6px;
|
||||||
|
border-color: #ececec;
|
||||||
|
&:hover {
|
||||||
|
border-color: #a2d98d;
|
||||||
|
}
|
||||||
|
.taskfont {
|
||||||
|
margin-right: 6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.profile-bio {
|
.profile-bio {
|
||||||
color: $primary-title-color;
|
color: $primary-title-color;
|
||||||
line-height: 1.5;
|
line-height: 1.6;
|
||||||
margin: 16px 0;
|
margin-top: 16px;
|
||||||
padding: 0 50px;
|
padding: 0 50px;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
|
|
||||||
.profile-information {
|
.profile-information {
|
||||||
|
margin-top: 24px;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
background-color: #f8f8f9;
|
background-color: #f8f8f9;
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
@ -90,7 +118,7 @@
|
|||||||
|
|
||||||
li {
|
li {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start; // 避免多行内容导致垂直居中不齐
|
align-items: flex-start;
|
||||||
padding: 8px 0;
|
padding: 8px 0;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
|
||||||
@ -118,6 +146,9 @@
|
|||||||
white-space: normal;
|
white-space: normal;
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
overflow-wrap: break-word;
|
overflow-wrap: break-word;
|
||||||
|
&.clickable {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -126,14 +157,35 @@
|
|||||||
.profile-tags {
|
.profile-tags {
|
||||||
margin-top: 12px;
|
margin-top: 12px;
|
||||||
padding-top: 12px;
|
padding-top: 12px;
|
||||||
border-top: 1px solid #80869550;
|
border-top: 1px solid #e5e5e5;
|
||||||
cursor: pointer;
|
display: flex;
|
||||||
.tags-list {
|
.tags-list {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
justify-content: center;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
|
.recognition-total {
|
||||||
|
padding-left: 8px;
|
||||||
|
position: relative;
|
||||||
|
&:before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
left: 2px;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
width: 2px;
|
||||||
|
height: 2px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: currentColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.ivu-btn {
|
||||||
|
border-radius: 6px;
|
||||||
|
&.ivu-btn-primary {
|
||||||
|
background-color: #ffffff;
|
||||||
|
color: $primary-color;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.ivu-tag {
|
.ivu-tag {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user