一单四制优化及加入工作流
This commit is contained in:
321
pages/personalcenter/identity.vue
Normal file
321
pages/personalcenter/identity.vue
Normal file
@@ -0,0 +1,321 @@
|
||||
<template>
|
||||
<view class="page">
|
||||
<!-- 当前生效身份 -->
|
||||
<view v-if="currentIdentity" class="current-banner">
|
||||
<view class="banner-label">当前生效身份</view>
|
||||
<view class="banner-name">{{ getIdentityTitle(currentIdentity) }}</view>
|
||||
<view class="banner-sub">{{ getIdentitySubtitle(currentIdentity) }}</view>
|
||||
</view>
|
||||
|
||||
<!-- 加载中 -->
|
||||
<view v-if="loading" class="state-box">
|
||||
<u-loading-icon mode="circle" color="#007aff"></u-loading-icon>
|
||||
<text class="state-text">加载中...</text>
|
||||
</view>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<view v-else-if="!identityList.length" class="state-box">
|
||||
<text class="state-text">暂无可用身份</text>
|
||||
</view>
|
||||
|
||||
<!-- 身份列表 -->
|
||||
<view v-else class="identity-list">
|
||||
<view
|
||||
v-for="item in identityList"
|
||||
:key="item.identityId"
|
||||
class="identity-card"
|
||||
:class="{
|
||||
'is-current': isCurrentIdentity(item),
|
||||
'is-default': item.isDefault
|
||||
}"
|
||||
>
|
||||
<view class="card-header">
|
||||
<view class="card-title">{{ getIdentityTitle(item) }}</view>
|
||||
<view class="card-tags">
|
||||
<view v-if="isCurrentIdentity(item)" class="tag tag-current">当前使用</view>
|
||||
<view v-if="item.isDefault" class="tag tag-default">默认</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="info-list">
|
||||
<view class="info-row">
|
||||
<text class="info-label">所属部门</text>
|
||||
<text class="info-value">{{ item.deptName || '-' }}</text>
|
||||
</view>
|
||||
<view class="info-row">
|
||||
<text class="info-label">所属角色</text>
|
||||
<text class="info-value">{{ item.roleName || '-' }}</text>
|
||||
</view>
|
||||
<view class="info-row">
|
||||
<text class="info-label">角色标识</text>
|
||||
<text class="info-value">{{ item.roleKey || '-' }}</text>
|
||||
</view>
|
||||
<view v-if="item.postName" class="info-row">
|
||||
<text class="info-label">所属岗位</text>
|
||||
<text class="info-value">{{ item.postName }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<button
|
||||
class="switch-btn"
|
||||
:class="{ 'switch-btn--disabled': isCurrentIdentity(item) }"
|
||||
:loading="switchingId === item.identityId"
|
||||
:disabled="isCurrentIdentity(item) || !!switchingId"
|
||||
@click="handleSwitch(item)"
|
||||
>
|
||||
{{ isCurrentIdentity(item) ? '当前使用中' : '切换到此身份' }}
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { onShow } from '@dcloudio/uni-app';
|
||||
import { getMyIdentity } from '@/request/identity.js';
|
||||
import { performIdentitySwitch, reLaunchAfterSwitch } from '@/utils/identitySwitch.js';
|
||||
|
||||
const loading = ref(false);
|
||||
const switchingId = ref(null);
|
||||
const identityList = ref([]);
|
||||
const currentIdentity = ref(null);
|
||||
|
||||
function unwrapIdentityData(res) {
|
||||
if (!res) return { identities: [], currentIdentity: null };
|
||||
const data = res.data && typeof res.data === 'object' ? res.data : res;
|
||||
return {
|
||||
identities: data.identities || [],
|
||||
currentIdentity: data.currentIdentity || null
|
||||
};
|
||||
}
|
||||
|
||||
function getIdentityTitle(item) {
|
||||
return item.identityName || item.roleName || '未命名身份';
|
||||
}
|
||||
|
||||
function getIdentitySubtitle(item) {
|
||||
const parts = [];
|
||||
if (item.deptName) parts.push(item.deptName);
|
||||
if (item.roleName && item.roleName !== item.identityName) parts.push(item.roleName);
|
||||
return parts.join(' · ') || '-';
|
||||
}
|
||||
|
||||
function isCurrentIdentity(item) {
|
||||
if (item.current) return true;
|
||||
return currentIdentity.value && currentIdentity.value.identityId === item.identityId;
|
||||
}
|
||||
|
||||
async function fetchIdentityList() {
|
||||
loading.value = true;
|
||||
try {
|
||||
const res = await getMyIdentity();
|
||||
if (res.code === 0 || res.code === 200) {
|
||||
const { identities, currentIdentity: current } = unwrapIdentityData(res);
|
||||
identityList.value = identities;
|
||||
currentIdentity.value = current;
|
||||
} else {
|
||||
identityList.value = [];
|
||||
currentIdentity.value = null;
|
||||
uni.showToast({ title: res.msg || '获取身份列表失败', icon: 'none' });
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('获取身份列表失败:', e);
|
||||
identityList.value = [];
|
||||
currentIdentity.value = null;
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function handleSwitch(item) {
|
||||
if (isCurrentIdentity(item) || switchingId.value) return;
|
||||
|
||||
const identityName = getIdentityTitle(item);
|
||||
const confirmMsg = `确认切换到「${identityName}」吗?切换后数据将按新身份刷新。`;
|
||||
|
||||
uni.showModal({
|
||||
title: '切换身份',
|
||||
content: confirmMsg,
|
||||
confirmText: '确认切换',
|
||||
success: async (modalRes) => {
|
||||
if (!modalRes.confirm) return;
|
||||
|
||||
switchingId.value = item.identityId;
|
||||
try {
|
||||
await performIdentitySwitch(item.identityId);
|
||||
reLaunchAfterSwitch();
|
||||
} catch (e) {
|
||||
console.error('身份切换失败:', e);
|
||||
} finally {
|
||||
switchingId.value = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onShow(() => {
|
||||
fetchIdentityList();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page {
|
||||
min-height: 100vh;
|
||||
background: #f4f7fb;
|
||||
padding: 24rpx;
|
||||
padding-bottom: 48rpx;
|
||||
}
|
||||
|
||||
.current-banner {
|
||||
background: linear-gradient(135deg, #3e95f1 0%, #4269f5 100%);
|
||||
border-radius: 20rpx;
|
||||
padding: 32rpx;
|
||||
margin-bottom: 24rpx;
|
||||
color: #fff;
|
||||
|
||||
.banner-label {
|
||||
font-size: 24rpx;
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
.banner-name {
|
||||
font-size: 34rpx;
|
||||
font-weight: bold;
|
||||
margin-top: 12rpx;
|
||||
}
|
||||
|
||||
.banner-sub {
|
||||
font-size: 26rpx;
|
||||
opacity: 0.9;
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.state-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 120rpx 0;
|
||||
|
||||
.state-text {
|
||||
margin-top: 24rpx;
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
.identity-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24rpx;
|
||||
}
|
||||
|
||||
.identity-card {
|
||||
background: #fff;
|
||||
border-radius: 20rpx;
|
||||
padding: 32rpx;
|
||||
border: 2rpx solid transparent;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.04);
|
||||
|
||||
&.is-current {
|
||||
border-color: #67c23a;
|
||||
}
|
||||
|
||||
&.is-default {
|
||||
border-color: #e6a23c;
|
||||
}
|
||||
|
||||
&.is-current.is-default {
|
||||
border-color: #67c23a;
|
||||
}
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
gap: 16rpx;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
flex: 1;
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.card-tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.tag {
|
||||
font-size: 22rpx;
|
||||
padding: 4rpx 12rpx;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.tag-current {
|
||||
background: #e8f8ef;
|
||||
color: #67c23a;
|
||||
}
|
||||
|
||||
.tag-default {
|
||||
background: #fdf6ec;
|
||||
color: #e6a23c;
|
||||
}
|
||||
|
||||
.info-list {
|
||||
margin-bottom: 28rpx;
|
||||
}
|
||||
|
||||
.info-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
padding: 16rpx 0;
|
||||
border-bottom: 1rpx dashed #eee;
|
||||
font-size: 28rpx;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
|
||||
.info-label {
|
||||
color: #999;
|
||||
flex-shrink: 0;
|
||||
margin-right: 24rpx;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
color: #333;
|
||||
text-align: right;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.switch-btn {
|
||||
width: 100%;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
background: linear-gradient(90deg, #3e95f1 0%, #4269f5 100%);
|
||||
color: #fff;
|
||||
font-size: 30rpx;
|
||||
border-radius: 40rpx;
|
||||
border: none;
|
||||
|
||||
&::after {
|
||||
border: none;
|
||||
}
|
||||
|
||||
&--disabled {
|
||||
background: #e8e8e8;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user