0.9.238 • Published 9 months ago
@dao42/clacky-paas-front v0.9.238
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>
</>
);
}
0.9.238
9 months ago
0.9.237
9 months ago
0.9.235
9 months ago
0.9.236
9 months ago
0.9.234
9 months ago
0.9.233
9 months ago
0.9.231
10 months ago
0.9.232
9 months ago
0.9.230
10 months ago
0.9.228
10 months ago
0.9.229
10 months ago
0.9.227
11 months ago
0.9.226
11 months ago
0.9.225
11 months ago
0.9.224
11 months ago
0.9.222
11 months ago
0.9.223
11 months ago
0.9.221
11 months ago
0.9.220
11 months ago
0.9.219
12 months ago
0.9.218
12 months ago
0.9.217
12 months ago
0.9.216
12 months ago
0.9.215
12 months ago
0.9.214
12 months ago