update: 应用管理、api配置、第三方用户首页over
This commit is contained in:
parent
ff52e85331
commit
1bcdb93455
|
@ -0,0 +1,3 @@
|
|||
import server from '@/utils/request'
|
||||
|
||||
export const getSsoBinds_api = (): any =>server.get(`/application/sso/me/bindings`)
|
|
@ -12,7 +12,7 @@ export const delApply_api = (id: string) => server.remove(`/application/${id}`)
|
|||
|
||||
// 获取组织列表
|
||||
export const getDepartmentList_api = () => server.get(`/organization/_all/tree`);
|
||||
// 获取组织列表
|
||||
// 获取应用详情
|
||||
export const getAppInfo_api = (id: string) => server.get(`/application/${id}`);
|
||||
// 新增应用
|
||||
export const addApp_api = (data: object) => server.post(`/application`, data);
|
||||
|
|
|
@ -31,6 +31,10 @@ export default [
|
|||
path: '/system/Api',
|
||||
component: () => import('@/views/system/Platforms/index.vue')
|
||||
},
|
||||
{
|
||||
path: '/account/center',
|
||||
component: () => import('@/views/account/Center/index.vue')
|
||||
},
|
||||
|
||||
// end: 测试用, 可删除
|
||||
|
||||
|
|
|
@ -0,0 +1,266 @@
|
|||
<template>
|
||||
<page-container>
|
||||
<div class="center-container">
|
||||
<div class="card">
|
||||
<div class="content" style="margin-top: 0">
|
||||
<div
|
||||
class="content-item flex-item"
|
||||
style="width: 350px; justify-content: center"
|
||||
>
|
||||
<img
|
||||
:src="userInfo.avatar"
|
||||
style="width: 140px; border-radius: 70px"
|
||||
alt=""
|
||||
/>
|
||||
<div
|
||||
style="
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
margin-top: 20px;
|
||||
"
|
||||
>
|
||||
<a-upload
|
||||
v-model:file-list="upload.fileList"
|
||||
accept=".jpg,.png,.jfif,.pjp,.pjpeg,.jpeg"
|
||||
:maxCount="1"
|
||||
:show-upload-list="false"
|
||||
:headers="{
|
||||
[TOKEN_KEY]: LocalStore.get(TOKEN_KEY),
|
||||
}"
|
||||
:action="`${BASE_API_PATH}/file/static`"
|
||||
@change="upload.changeBackUpload"
|
||||
>
|
||||
<a-button>
|
||||
<AIcon type="UploadOutlined" />
|
||||
更换头像
|
||||
</a-button>
|
||||
</a-upload>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="content-item flex-item"
|
||||
style="flex: 1; padding: 15px 0"
|
||||
>
|
||||
<div class="info-card">
|
||||
<p>用户名</p>
|
||||
<p>{{ userInfo.username }}</p>
|
||||
</div>
|
||||
<div class="info-card">
|
||||
<p>账号ID</p>
|
||||
<p>{{ userInfo.id }}</p>
|
||||
</div>
|
||||
<div class="info-card">
|
||||
<p>注册时间</p>
|
||||
<p>{{ userInfo.createTime }}</p>
|
||||
</div>
|
||||
<div class="info-card">
|
||||
<p>电话</p>
|
||||
<p>{{ userInfo.telephone }}</p>
|
||||
</div>
|
||||
<div class="info-card">
|
||||
<p>姓名</p>
|
||||
<p>{{ userInfo.name }}</p>
|
||||
</div>
|
||||
<div class="info-card">
|
||||
<p>角色</p>
|
||||
<p>{{ userInfo.roleList.join(',') || '-' }}</p>
|
||||
</div>
|
||||
<div class="info-card">
|
||||
<p>组织</p>
|
||||
<p>{{ userInfo.orgList.join(',') || '-' }}</p>
|
||||
</div>
|
||||
<div class="info-card">
|
||||
<p>邮箱</p>
|
||||
<p>{{ userInfo.email || '-' }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<AIcon
|
||||
type="EditOutlined"
|
||||
class="edit"
|
||||
style="right: 40px"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h3>修改密码</h3>
|
||||
<div class="content">
|
||||
<div class="content" style="align-items: flex-end">
|
||||
<lock-outlined
|
||||
style="color: #1d39c4; font-size: 70px"
|
||||
/>
|
||||
<!-- <AIcon type="LockOutlined" /> -->
|
||||
<span
|
||||
style="margin-left: 5px; color: rgba(0, 0, 0, 0.55)"
|
||||
>安全性高的密码可以使帐号更安全。建议您定期更换密码,设置一个包含字母,符号或数字中至少两项且长度超过8位的密码</span
|
||||
>
|
||||
</div>
|
||||
<AIcon type="EditOutlined" class="edit" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h3>绑定三方账号</h3>
|
||||
<div class="content">
|
||||
<div class="account-card" v-for="item in bindList">
|
||||
<img
|
||||
:src="getImage(bindIcon[item.provider])"
|
||||
style="height: 50px"
|
||||
alt=""
|
||||
/>
|
||||
<div class="text">
|
||||
<div v-if="item.bound">
|
||||
<div>绑定名:{{ item.others.name }}</div>
|
||||
<div>
|
||||
绑定时间:{{
|
||||
moment(item.bindTime).format(
|
||||
'YYYY-MM-DD HH:mm:ss',
|
||||
)
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>{{ item.name }}未绑定</div>
|
||||
</div>
|
||||
|
||||
<a-button v-if="item.bound">解除绑定</a-button>
|
||||
<a-button v-else type="primary">立即绑定</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h3>首页视图</h3>
|
||||
</div>
|
||||
</div>
|
||||
</page-container>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { LockOutlined } from '@ant-design/icons-vue';
|
||||
import { BASE_API_PATH, TOKEN_KEY } from '@/utils/variable';
|
||||
import { LocalStore, getImage } from '@/utils/comm';
|
||||
import { useUserInfo } from '@/store/userInfo';
|
||||
import { message, UploadChangeParam, UploadFile } from 'ant-design-vue';
|
||||
import { getSsoBinds_api } from '@/api/account/center';
|
||||
import moment from 'moment';
|
||||
|
||||
const userInfo = useUserInfo().$state.userInfos as any as userInfoType;
|
||||
const bindList = ref<any[]>([]);
|
||||
const bindIcon = {
|
||||
'dingtalk-ent-app': '/notice/dingtalk.png',
|
||||
'wechat-webapp': '/notice/wechat.png',
|
||||
'internal-standalone': '/apply/provider1.png',
|
||||
'third-party': '/apply/provider5.png',
|
||||
};
|
||||
const upload = reactive({
|
||||
fileList: [] as any[],
|
||||
uploadLoading: false,
|
||||
changeBackUpload: (info: UploadChangeParam<UploadFile<any>>) => {
|
||||
if (info.file.status === 'uploading') {
|
||||
upload.uploadLoading = true;
|
||||
} else if (info.file.status === 'done') {
|
||||
info.file.url = info.file.response?.result;
|
||||
upload.uploadLoading = false;
|
||||
userInfo.avatar = info.file.response?.result;
|
||||
} else if (info.file.status === 'error') {
|
||||
console.log(info.file);
|
||||
upload.uploadLoading = false;
|
||||
message.error('logo上传失败,请稍后再试');
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
init();
|
||||
function init() {
|
||||
getSsoBinds_api().then((resp: any) => {
|
||||
if (resp.status === 200) bindList.value = resp.result;
|
||||
});
|
||||
}
|
||||
|
||||
type userInfoType = {
|
||||
avatar: string;
|
||||
createTime: number;
|
||||
email: string;
|
||||
id: string;
|
||||
name: string;
|
||||
orgList: string[];
|
||||
roleList: string[];
|
||||
status: number;
|
||||
telephone: string;
|
||||
tenantDisabled: boolean;
|
||||
type: { name: string; id: string };
|
||||
username: string;
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.center-container {
|
||||
background-color: #f0f2f5;
|
||||
min-height: 100vh;
|
||||
.card {
|
||||
margin: 24px;
|
||||
padding: 24px;
|
||||
background-color: #fff;
|
||||
position: relative;
|
||||
|
||||
h3 {
|
||||
font-size: 22px;
|
||||
|
||||
&::before {
|
||||
display: inline-block;
|
||||
width: 3px;
|
||||
height: 0.7em;
|
||||
content: '';
|
||||
background-color: #2f54eb;
|
||||
margin: 0 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
margin-top: 24px;
|
||||
.content-item {
|
||||
margin-right: 24px;
|
||||
.info-card {
|
||||
width: 25%;
|
||||
|
||||
:first-child {
|
||||
font-weight: bold;
|
||||
}
|
||||
:last-child {
|
||||
color: #666363d9;
|
||||
}
|
||||
}
|
||||
&.flex-item {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
}
|
||||
|
||||
.edit {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
top: 30px;
|
||||
right: 24px;
|
||||
color: #1d39c4;
|
||||
}
|
||||
|
||||
.account-card {
|
||||
margin-right: 24px;
|
||||
width: 415px;
|
||||
background-image: url(/images/notice/dingtalk-background.png);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 24px;
|
||||
|
||||
.text {
|
||||
display: -webkit-box;
|
||||
font-size: 22px;
|
||||
width: 150px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
word-break: break-all;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -10,7 +10,7 @@
|
|||
:class="{ selected: selectValue === 'device' }"
|
||||
@click="selectValue = 'device'"
|
||||
>
|
||||
<img src="/images/home/device.png" alt="" />
|
||||
<img :src="getImage('/home/device.png')" alt="" />
|
||||
</a-col>
|
||||
<a-col
|
||||
:span="8"
|
||||
|
@ -18,7 +18,7 @@
|
|||
:class="{ selected: selectValue === 'ops' }"
|
||||
@click="selectValue = 'ops'"
|
||||
>
|
||||
<img src="/images/home/ops.png" alt="" />
|
||||
<img :src="getImage('/home/ops.png')" alt="" />
|
||||
</a-col>
|
||||
<a-col
|
||||
:span="8"
|
||||
|
@ -26,7 +26,7 @@
|
|||
:class="{ selected: selectValue === 'comprehensive' }"
|
||||
@click="selectValue = 'comprehensive'"
|
||||
>
|
||||
<img src="/images/home/comprehensive.png" alt="" />
|
||||
<img :src="getImage('/home/comprehensive.png')" alt="" />
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-button type="primary" class="btn" @click="confirm"
|
||||
|
@ -38,6 +38,7 @@
|
|||
|
||||
<script lang="ts" setup>
|
||||
import { setView_api } from '@/api/home';
|
||||
import { getImage } from '@/utils/comm';
|
||||
|
||||
const emits = defineEmits(['refresh']);
|
||||
const selectValue = ref('device');
|
||||
|
|
|
@ -6,8 +6,26 @@
|
|||
<DevOpsHome v-else-if="currentView === 'ops'" />
|
||||
<ComprehensiveHome v-else-if="currentView === 'comprehensive'" />
|
||||
|
||||
<Api :mode="'home'" hasHome showTitle>
|
||||
<template #top> </template>
|
||||
<Api
|
||||
v-else-if="currentView === 'api'"
|
||||
:mode="'home'"
|
||||
hasHome
|
||||
showTitle
|
||||
:code="clientId"
|
||||
>
|
||||
<template #top>
|
||||
<div class="card">
|
||||
<h3 style="margin: 0 0 24px 0">基本信息</h3>
|
||||
<p>
|
||||
<span style="font-weight: bold">clientId: </span>
|
||||
<span>{{ clientId }}</span>
|
||||
</p>
|
||||
<p>
|
||||
<span style="font-weight: bold">secureKey:</span>
|
||||
<span>{{ secureKey }}</span>
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
</Api>
|
||||
</div>
|
||||
</page-container>
|
||||
|
@ -19,14 +37,16 @@ import DeviceHome from './components/DeviceHome/index.vue';
|
|||
import DevOpsHome from './components/DevOpsHome/index.vue';
|
||||
import ComprehensiveHome from './components/ComprehensiveHome/index.vue';
|
||||
import Api from '@/views/system/Platforms/Api/index.vue';
|
||||
import { useUserInfo } from '@/store/userInfo';
|
||||
|
||||
import { isNoCommunity } from '@/utils/utils';
|
||||
import { getMe_api, getView_api } from '@/api/home';
|
||||
|
||||
const router = useRouter();
|
||||
import { getAppInfo_api } from '@/api/system/apply';
|
||||
|
||||
const currentView = ref<string>('');
|
||||
const loading = ref<boolean>(true);
|
||||
const clientId = useUserInfo().$state.userInfos.id;
|
||||
const secureKey = ref<string>('');
|
||||
|
||||
// 获取选择的视图
|
||||
const setCurrentView = () => {
|
||||
|
@ -49,7 +69,12 @@ if (isNoCommunity) {
|
|||
item.type === 'api-client' || item.type.id === 'api-client',
|
||||
);
|
||||
|
||||
isApiUser ? router.push('/system/api') : setCurrentView();
|
||||
if (isApiUser) {
|
||||
currentView.value = 'api';
|
||||
getAppInfo_api(clientId).then((resp: any) => {
|
||||
secureKey.value = resp.result.apiServer.secureKey;
|
||||
});
|
||||
} else setCurrentView();
|
||||
}
|
||||
});
|
||||
} else setCurrentView();
|
||||
|
@ -57,7 +82,15 @@ if (isNoCommunity) {
|
|||
|
||||
<style lang="less" scoped>
|
||||
.iot-home-container {
|
||||
background: #f0f2f5;
|
||||
overflow: hidden;
|
||||
.card {
|
||||
background-color: #fff;
|
||||
padding: 24px;
|
||||
margin-bottom: 24px;
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
<template>
|
||||
<page-container>
|
||||
<Api :mode="'appManger'" hasHome>
|
||||
</Api>
|
||||
<Api :mode="'appManger'" hasHome :code="code" />
|
||||
</page-container>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="apiPage">
|
||||
import Api from '@/views/system/Platforms/Api/index.vue';
|
||||
const route = useRoute()
|
||||
const code = route.query.code as string
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
|
|
|
@ -1,14 +1,45 @@
|
|||
<template>
|
||||
<page-container>
|
||||
<Api :mode="'appManger'" hasHome showTitle :code="code">
|
||||
<Api :mode="'home'" hasHome showTitle :code="clientId">
|
||||
<template #top>
|
||||
<div class="card">
|
||||
<h3 style="margin: 0 0 24px 0">基本信息</h3>
|
||||
<p>
|
||||
<span style="font-weight: bold">clientId: </span>
|
||||
<span>{{ clientId }}</span>
|
||||
</p>
|
||||
<p>
|
||||
<span style="font-weight: bold">secureKey:</span>
|
||||
<span>{{ secureKey }}</span>
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
</Api>
|
||||
</page-container>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="apiPage">
|
||||
import { getAppInfo_api } from '@/api/system/apply';
|
||||
import Api from '@/views/system/Platforms/Api/index.vue';
|
||||
const route = useRoute()
|
||||
const code = route.query.code as string
|
||||
const route = useRoute();
|
||||
const clientId = route.query.code as string;
|
||||
|
||||
const secureKey = ref<string>('');
|
||||
|
||||
getAppInfo_api(clientId).then((resp: any) => {
|
||||
secureKey.value = resp.result.apiServer.secureKey;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
<style lang="less" scoped>
|
||||
.card {
|
||||
background-color: #fff;
|
||||
padding: 24px;
|
||||
margin-bottom: 24px;
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<JTable
|
||||
:columns="columns"
|
||||
:dataSource="props.tableData"
|
||||
:rowSelection="rowSelection"
|
||||
:rowSelection="props.mode !== 'home' ? rowSelection : undefined"
|
||||
noPagination
|
||||
model="TABLE"
|
||||
>
|
||||
|
@ -16,7 +16,9 @@
|
|||
</template>
|
||||
</JTable>
|
||||
|
||||
<a-button type="primary" @click="save">保存</a-button>
|
||||
<a-button type="primary" @click="save" v-if="props.mode !== 'home'"
|
||||
>保存</a-button
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -132,11 +132,9 @@ const filterPath = (path: object, filterArr: string[]) => {
|
|||
delete value[prop];
|
||||
}
|
||||
}
|
||||
if(Object.keys(value).length === 0) delete path[key]
|
||||
if (Object.keys(value).length === 0) delete path[key];
|
||||
}
|
||||
}
|
||||
console.log(path, filterArr);
|
||||
|
||||
return path;
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<div class="top">
|
||||
<slot name="top" />
|
||||
</div>
|
||||
<a-row :gutter="24" style="background-color: #fff; padding: 20px">
|
||||
<a-row :gutter="24" style="background-color: #fff; padding: 20px;margin: 0;">
|
||||
<a-col
|
||||
:span="24"
|
||||
v-if="props.showTitle"
|
||||
|
@ -16,6 +16,7 @@
|
|||
:mode="props.mode"
|
||||
:has-home="props.hasHome"
|
||||
:filter-array="treeFilter"
|
||||
:code="props.code"
|
||||
/>
|
||||
</a-col>
|
||||
<a-col :span="19">
|
||||
|
@ -71,7 +72,6 @@ import ChooseApi from './components/ChooseApi.vue';
|
|||
import ApiDoes from './components/ApiDoes.vue';
|
||||
import ApiTest from './components/ApiTest.vue';
|
||||
|
||||
const route = useRoute();
|
||||
const props = defineProps<{
|
||||
mode: modeType;
|
||||
showTitle?: boolean;
|
||||
|
@ -117,15 +117,17 @@ const initSelectedApi: apiDetailsType = {
|
|||
};
|
||||
const selectedApi = ref<apiDetailsType>(initSelectedApi);
|
||||
|
||||
const canSelectKeys = ref<string[]>([]); // 左侧可展示的项
|
||||
const selectedKeys = ref<string[]>([]); // 右侧默认勾选的项
|
||||
let selectSourceKeys = ref<string[]>([]);
|
||||
init();
|
||||
|
||||
function init() {
|
||||
const code = route.query.code;
|
||||
// 右侧默认选中初始化
|
||||
if (props.mode === 'appManger') {
|
||||
} else if (props.mode === 'home') {
|
||||
getApiGranted_api(props.code as string).then((resp) => {
|
||||
selectedKeys.value = resp.result as string[];
|
||||
selectSourceKeys.value = [...(resp.result as string[])];
|
||||
})
|
||||
} else if (props.mode === 'api') {
|
||||
apiOperations_api().then((resp) => {
|
||||
selectedKeys.value = resp.result as string[];
|
||||
|
|
Loading…
Reference in New Issue