@dao42/clacky-paas-front
v0.9.244
Published
clacky paas front
Downloads
895
Readme
PaaS SDK 示例
欢迎来到PaaS SDK示例,本文是DaoPaaS的一个简单使用示例。
温馨提示
- SDK接口文档api地址
- 本案例的axios为封装后的axios, baseUrl默认为“www.1024paas.com”。
- 真实接口请求过程中,请按照接口文档的要求携带头信息。
- 本案例使用React,非React项目请参考逻辑。
- 请用户自行优化代码逻辑并做合适的错误处理。
PART-ONE 请求获取ticket(票)流程
第一步:定义接口
/*
* 获取codeZone环境列表
* @returns { {id: int, versionList: {id: string, name: string}[]}[] }
*/
export async function getEnvironmentsApi() {
const res = await axios.get('/api/v1/sdk/environments')
return res.data // 环境列表(数组)
}
/*
* 创建codeZone, 获取codeZoneId
* @param { string } environmentVerId 环境id
* @returns { string }
*/
async function getCodeZoneIdApi(environmentVerId: string): string {
const res = await axios.post('/api/v1/sdk/codeZones',{environmentVerId})
return res.data.id
}
/*
* 通过 codeZoneId 获取 playgroundId
* @param { string } codeZoneId
* @returns { string }
*/
async function getPlaygroundIdApi(codeZoneId: string): string {
const res = await axios.get('/api/v1/sdk/codeZones/'+codeZoneId+'/playground')
return res.data.id
}
/*
* 通过 playgroundId 获取 ticket
* @param { string } playgroundId
* @returns { string }
*/
async function getTicketApi(playgroundId: string): string {
const res = await axios.post('/api/v1/sdk/ticket', {
playgroundId,
tillTime: Date.now() + 12*60*60*1000, // 截止时间(时间戳)
userInfo: {}, // 数据格式请参考接口文档
})
return res.data.ticket
}
第二步:封装逻辑
// 通过调用 getEnvironmentsApi() 我们获取到了codeZone环境列表, 并渲染到页面上
const environments = await getEnvironmentsApi()
// 假设用户点击了某一个环境,我们得到了一个具体的 environmentVerId
const environmentVerId = environments[0].versionList[0].id
// 封装获取ticket(票)逻辑
export async function handleGetTicket(environmentVerId: string) {
const codeZoneId = await getCodeZoneIdApi(environmentVerId)
const playgroundId = await getPlaygroundIdApi(codeZoneId)
const ticket = await getTicketApi(playgroundId)
return ticket
}
PART-TWO 在组件中使用
第一步:引入SDK和样式
import { DaoPaaS, Messages } from 'DaoPaaS.cjs';
import 'style.css'
第二步:初始化实例
- 创建实例
const dao = new DaoPaaS({
tenantId: '租户id',
ticket: '动态获取的ticket', // ticket(票)
userInfo: { username: '用户名'}, // 用户信息
});
- 监听消息
dao.onMessage((message: Message) => {
const { name, payload } = message;
let status: PlaygroundStatus;
let dockerStatus: DockerStatus;
let lspStatus: LspStatusEnum;
switch (name) {
case Messages.Ready:
console.log('appStatus readyBasic');
console.log('playgroundInfo状态', dao.playgroundInfo.status);
console.log('语法补全状态', dao.playgroundInfo.lspStatus);
console.log('docker运行状态', dao.playgroundInfo.runStatus);
break;
case Messages.Online:
console.log('网络已恢复');
setSpinLoading(false);
break;
case Messages.Offline:
console.log('网络掉线');
break;
case Messages.StatusChanged:
console.log('playground状态发生变化', payload.status);
break;
case Messages.PlaygroundChanged:
console.log('playground环境变了,比如换题');
break;
case Messages.LspStatusChanged:
console.log('Lsp状态发生变化', payload.status);
break;
case Messages.RunStatusChanged:
console.log('docker运行状态变化', payload.status);
if (dockerStatus != 'STOP') {
return;
} else if (payload.runResult === 0) {
console.log(`运行结果成功`);
} else {
console.log(`运行结果失败: ${payload.runResult}`);
}
break;
}
});
- 监听错误消息
dao.onError((message: Message) => {
const { name, error } = message;
switch (name) {
case Messages.ConnectionBroken:
console.log('与服务器的连接中断,可以尝试连接到另一个服务器');
break;
case Messages.AuthorizationFailed:
console.log('授权失败,所以您需要再次登录或获得一个新的ticket');
break;
case 'errorFromServer':
console.log('与服务器的连接中断');
break;
}
});
- 把实例的组件挂载到dom节点
// container: 项目中真实节点的选择器, item: 要挂载的dao内部组件的名称
// 这个方法运行后,会把item对应名称的dao内部组件挂载到container配置类名的dom节点上
dao.mapRender([
{ container: '.tree-section', item: 'Tree' },
{ container: '.editor-section', item: 'Editor' },
{ container: '.browser-section', item: 'Browser'},
{ container: '.terminal-section', item: 'Shell' },
{ container: '.console-section', item: 'Console' },
]);
- 创建HTML标签
运行dao.mapRender([...])
方法后,会把dao内部组件渲染到对应的dom节点
<div>
<div className="tree-section"></div>
<div className="editor-section"></div>
<div className="browser-section"></div>
<div className="console-section"></div>
<div className="terminal-section"></div>
</div>
第三步:销毁实例
在页面卸载的时候需要销毁dao实例和相关的缓存数据
useEffect(() => {
// ...
return () => {
dao.dispose()
}
}, [])
PART-THREE SDK部分其他方法
// 配置是否在控制台开启DaoPaaS内部打印
dao.loggerEnable(true);
// 修改主题
dao.loadTheme('dark')
// 激活容器
dao.activePlayground()
// 运行容器
dao.runPlayground()
// 停止容器运行
dao.stopPlayground()
// ...
PART-FOUR 基础案例
import React, { useEffect, useState } from 'react';
import { DaoPaaS, Messages } from '~/DaoPaaS';
enum LspStatusEnum {
NOT_SUPPORT = 'notSupport',
LOADING = 'loading',
RUNNING = 'running',
SHUTDOWN = 'shutdown',
}
export default function SimpleExample({environmentVerId}) {
const [daoPaasObj, setDaoPaasObj] = useState<DaoPaaS | null>(null);
const [playgroundStatus, setPlaygroundStatus] =
useState<PlaygroundStatus>('EMPTY');
const [dockerStatus, setDockerStatus] = useState<DockerStatus>('STOP');
const {setLspStatus, LspStatusFC} = useLspStatus();
const [remindVisible, setRemindVisible] = useState(false);
// SDK初始化
const initSDK = async () => {
console.log('开始连接运行环境...')
// 获取ticket(票)
const ticket = handleGetTicket(environmentVerId)
// 生成实例
const dao = new DaoPaaS({
paasDomain: 'www.1024paas.com',
tenantId: '请输入租户id',
ticket: ticket,
userInfo: { username: "***" },
});
// 保存实例
setDaoPaasObj(dao);
// 监听消息
dao.onMessage((message: Message) => {
const { name, payload } = message;
let status: PlaygroundStatus;
let dockerStatus: DockerStatus;
let lspStatus: LspStatusEnum;
switch (name) {
case Messages.Ready:
console.log('连接运行环境已经停止')
setRemindVisible(dao.playgroundInfo.status === 'INACTIVE');
setPlaygroundStatus(dao.playgroundInfo.status);
setLspStatus(
dao.playgroundInfo.lspStatus as LspStatusEnum,
);
setDockerStatus(
dao.playgroundInfo.runStatus as DockerStatus,
);
break;
case Messages.Online:
console.log('网络已恢复');
console.log('连接运行环境已经停止')
break;
case Messages.Offline:
console.log('网络掉线');
break;
case Messages.StatusChanged:
status = payload.status;
setRemindVisible(status === 'INACTIVE');
setPlaygroundStatus(payload.status);
break;
case Messages.PlaygroundChanged:
setRemindVisible(false);
break;
case Messages.LspStatusChanged:
lspStatus = payload.status;
setLspStatus(lspStatus);
break;
case Messages.RunStatusChanged:
dockerStatus = payload.status;
setDockerStatus(dockerStatus);
if (dockerStatus != 'STOP') {
return;
}
if (payload.runResult === 0) {
console.log(`运行结果成功`);
} else {
console.warn(`运行结果失败: ${payload.runResult}`);
}
break;
}
});
// 监听报错消息
dao.onError((message: Message) => {
const { name, error } = message;
switch (name) {
case Messages.ConnectionBroken:
console.error(error, 0);
break;
case Messages.AuthorizationFailed:
console.error(error, 0);
break;
case 'errorFromServer':
console.log('连接运行环境已经停止')
console.error(error, 0);
break;
}
});
// 挂载实例组件
dao.mapRender([
{ container: '.tree-section', item: 'Tree'},
{ container: '.editor-section', item: 'Editor'},
{ container: '.browser-section', item: 'Browser'},
{ container: '.terminal-section', item: 'Shell'},
{ container: '.console-section', item: 'Console'},
]);
};
// 语法补全连接状态
function useLspStatus() {
const [lspStatus, setLspStatus] = useState<LspStatusEnum>(
LspStatusEnum.LOADING,
);
function LspStatusFC() {
const textMap = {
[LspStatusEnum.NOT_SUPPORT]: '不支持',
[LspStatusEnum.LOADING]: '连接中',
[LspStatusEnum.RUNNING]: '运行中',
[LspStatusEnum.SHUTDOWN]: '已关闭',
};
return (
<div> 代码补全·({textMap[lspStatus]})</div>
);
}
return {
setLspStatus,
LspStatusFC,
};
}
useEffect(() => {
initSDK();
return () => {
// 在页面卸载的时候需要销毁实例和相关的缓存数据
daoPaasObj && daoPaasObj.dispose();
setDaoPaasObj(null);
};
}, []);
return (
<>
{remindVisible && <button
onClick={() => {
daoPaasObj?.activePlayground();
setRemindVisible(false);
}}
>
容器状态为失活,点击确认激活容器
</button>}
<div>
<LspStatusFC />
<div>
{playgroundStatus !== 'ACTIVE' ? (
<button onClick={() => daoPaasObj?.activePlayground() }>激活</button>
) : (
<div>已激活</div>
)}
{dockerStatus !== 'RUNNING' ? (
<button
disabled={playgroundStatus !== 'ACTIVE'}
onClick={() => {
daoPaasObj?.runPlayground();
}}
>
运行
</button>
) : (
<button
disabled={playgroundStatus !== 'ACTIVE'}
onClick={() => daoPaasObj?.stopPlayground()}
>
停止
</button>
)}
</div>
</div>
<div>
<div className="tree-section"></div>
<div className="editor-section"></div>
<div className="browser-section"></div>
<div className="console-section"></div>
<div className="terminal-section"></div>
</div>
</>
);
}