Merge remote-tracking branch 'origin/dev' into dev

This commit is contained in:
xieyonghong 2023-03-01 10:30:05 +08:00
commit 020a917b13
11 changed files with 368 additions and 27 deletions

View File

@ -0,0 +1,3 @@
import server from '@/utils/request'
export const getSsoBinds_api = (): any =>server.get(`/application/sso/me/bindings`)

View File

@ -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);

View File

@ -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: 测试用, 可删除

View File

@ -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>

View File

@ -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');

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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[];