完成机器人页面及相关功能
This commit is contained in:
parent
3624842e22
commit
1084399033
49
src/api/robot.ts
Normal file
49
src/api/robot.ts
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import { http } from "@/utils/http";
|
||||||
|
import { BaseResponse } from "@/api/base";
|
||||||
|
|
||||||
|
/** 机器人信息 */
|
||||||
|
export type RobotInfo = {
|
||||||
|
id: string;
|
||||||
|
createdAt: string;
|
||||||
|
updatedAt: string;
|
||||||
|
wxid: string;
|
||||||
|
account: string;
|
||||||
|
name: string;
|
||||||
|
avatar: string;
|
||||||
|
mobile: string;
|
||||||
|
currentDataPath: string;
|
||||||
|
dataSavePath: string;
|
||||||
|
dbKey: string;
|
||||||
|
hookApi: string;
|
||||||
|
remark: string;
|
||||||
|
version: number;
|
||||||
|
vncUrl: string;
|
||||||
|
tag: string;
|
||||||
|
/* 页面使用参数,后端不返回 */
|
||||||
|
saveLoading: boolean;
|
||||||
|
edit: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 获取所有机器人 */
|
||||||
|
export const getAllRobot = (data: any) => {
|
||||||
|
return http.request<BaseResponse<Array<RobotInfo>>>(
|
||||||
|
"get",
|
||||||
|
"/admin/v1/robot",
|
||||||
|
{ data }
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 保存机器人 */
|
||||||
|
export const saveRobot = (data: any) => {
|
||||||
|
return http.request<BaseResponse<RobotInfo>>("post", "/admin/v1/robot", {
|
||||||
|
data
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 删除机器人信息 */
|
||||||
|
export const deleteRobot = (id: string) => {
|
||||||
|
return http.request<BaseResponse<RobotInfo>>(
|
||||||
|
"delete",
|
||||||
|
`/admin/v1/robot/${id}`
|
||||||
|
);
|
||||||
|
};
|
BIN
src/assets/defaultWeChatAvatar.gif
Normal file
BIN
src/assets/defaultWeChatAvatar.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 60 KiB |
@ -1,12 +1,368 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { onMounted, reactive, ref } from "vue";
|
||||||
|
import { getAllRobot, RobotInfo, saveRobot, deleteRobot } from "@/api/robot";
|
||||||
|
import { message } from "@/utils/message";
|
||||||
|
import defaultWeChatAvatar from "@/assets/defaultWeChatAvatar.gif";
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "RobotList"
|
name: "RobotList"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 是否在新增
|
||||||
|
const showCreateDialog = ref(false);
|
||||||
|
// 是否在展示远程桌面
|
||||||
|
const showVncDialog = ref(false);
|
||||||
|
// 页面是否加载中
|
||||||
|
const dataLoading = ref(false);
|
||||||
|
// 定义可使用的微信版本
|
||||||
|
const versionList = ref([
|
||||||
|
{ name: "v3.9.2.23", value: 39223 },
|
||||||
|
{ name: "v3.9.5.81", value: 39581 },
|
||||||
|
{ name: "v3.9.8.25", value: 39825 }
|
||||||
|
]);
|
||||||
|
// 列表数据
|
||||||
|
const robotList = ref([] as RobotInfo[]);
|
||||||
|
// 当前展示的远程桌面地址
|
||||||
|
const vncUrl = ref("");
|
||||||
|
|
||||||
|
// 翻译微信版本
|
||||||
|
const translateVersion = (value: number) => {
|
||||||
|
return versionList.value.find(item => item.value === value)?.name;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 新增机器人参数
|
||||||
|
const createRobotParam = reactive({
|
||||||
|
id: "",
|
||||||
|
hookApi: "",
|
||||||
|
version: 39581,
|
||||||
|
vncUrl: "",
|
||||||
|
remark: "",
|
||||||
|
tag: "",
|
||||||
|
saveLoading: false
|
||||||
|
});
|
||||||
|
|
||||||
|
// 重置新增参数
|
||||||
|
const clearCreateParam = (done: () => void) => {
|
||||||
|
createRobotParam.hookApi = "";
|
||||||
|
createRobotParam.version = 39581;
|
||||||
|
createRobotParam.vncUrl = "";
|
||||||
|
createRobotParam.remark = "";
|
||||||
|
createRobotParam.tag = "";
|
||||||
|
done();
|
||||||
|
};
|
||||||
|
// 关闭远程桌面
|
||||||
|
const closeVncIframe = (done: () => void) => {
|
||||||
|
showVncDialog.value = false;
|
||||||
|
vncUrl.value = "";
|
||||||
|
done();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 打开远程桌面
|
||||||
|
const showVncDialogHandle = (url: string) => {
|
||||||
|
vncUrl.value = url;
|
||||||
|
showVncDialog.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取机器人列表
|
||||||
|
const getAllRobotHandle = async () => {
|
||||||
|
// 设置为加载中
|
||||||
|
dataLoading.value = true;
|
||||||
|
// 调用接口,获取数据
|
||||||
|
getAllRobot({ keyword: "", tag: "" })
|
||||||
|
.then(res => {
|
||||||
|
// 获取成功,设置数据
|
||||||
|
robotList.value = res.data;
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
message("获取机器人列表失败", { type: "error" });
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
// 关闭加载动画
|
||||||
|
dataLoading.value = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 新增机器人
|
||||||
|
const saveRobotHandle = async (item: any, isCreate?: boolean) => {
|
||||||
|
// 设置为加载中
|
||||||
|
item.saveLoading = true;
|
||||||
|
// 拷贝
|
||||||
|
const param = JSON.parse(JSON.stringify(item));
|
||||||
|
// 处理hookApi和vnc地址
|
||||||
|
if (param.hookApi !== "" && !param.hookApi.startsWith("http://")) {
|
||||||
|
param.hookApi = `http://${item.hookApi}`;
|
||||||
|
}
|
||||||
|
if (param.vncUrl !== "" && !param.vncUrl.startsWith("http://")) {
|
||||||
|
param.vncUrl = `http://${param.vncUrl}/vnc_lite.html`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调用接口,保存数据
|
||||||
|
saveRobot(param)
|
||||||
|
.then(() => {
|
||||||
|
message("保存成功", { type: "success" });
|
||||||
|
if (isCreate) {
|
||||||
|
showCreateDialog.value = false;
|
||||||
|
}
|
||||||
|
// 保存成功,重新加载数据
|
||||||
|
getAllRobotHandle();
|
||||||
|
})
|
||||||
|
.catch(e => {
|
||||||
|
const response = e.response.data;
|
||||||
|
message(
|
||||||
|
response.message + (response.errMsg ? ": " + response.errMsg : ""),
|
||||||
|
{ type: "error" }
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
// 关闭加载动画
|
||||||
|
item.saveLoading = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 删除机器人
|
||||||
|
const deleteRobotHandle = (id: string) => {
|
||||||
|
deleteRobot(id)
|
||||||
|
.then(() => {
|
||||||
|
message("删除成功", { type: "success" });
|
||||||
|
getAllRobotHandle();
|
||||||
|
})
|
||||||
|
.catch(e => {
|
||||||
|
const response = e.response.data;
|
||||||
|
message(
|
||||||
|
response.message + (response.errMsg ? ": " + response.errMsg : ""),
|
||||||
|
{ type: "error" }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// 获取机器人信息
|
||||||
|
getAllRobotHandle();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="flex justify-center items-center h-[640px]">
|
<div>
|
||||||
<h1>机器人列表</h1>
|
<div style="margin: 20px">
|
||||||
|
<el-button type="primary" @click="showCreateDialog = true"
|
||||||
|
>新增机器人</el-button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="flex h-[640px]">
|
||||||
|
<div class="card-container">
|
||||||
|
<el-card
|
||||||
|
class="robot-card"
|
||||||
|
shadow="hover"
|
||||||
|
v-for="item in robotList"
|
||||||
|
:key="item.id"
|
||||||
|
v-loading="item.saveLoading"
|
||||||
|
>
|
||||||
|
<template #header>
|
||||||
|
<div class="robot-header">
|
||||||
|
<div style="display: flex; align-items: center">
|
||||||
|
<el-avatar
|
||||||
|
:size="50"
|
||||||
|
:src="item.avatar ? item.avatar : defaultWeChatAvatar"
|
||||||
|
/>
|
||||||
|
<span style="margin-left: 10px">
|
||||||
|
<p class="robot-name">{{ item.name }}</p>
|
||||||
|
<p v-if="!item.edit" class="robot-remark">
|
||||||
|
{{ item.remark }}
|
||||||
|
</p>
|
||||||
|
<el-input
|
||||||
|
v-else
|
||||||
|
v-model="item.remark"
|
||||||
|
style="width: 80%"
|
||||||
|
size="small"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-button-group>
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
:type="item.edit ? 'primary' : 'warning'"
|
||||||
|
@click="item.edit = !item.edit"
|
||||||
|
>
|
||||||
|
{{ item.edit ? "取消" : "编辑" }}
|
||||||
|
</el-button>
|
||||||
|
<el-popconfirm
|
||||||
|
v-if="!item.edit"
|
||||||
|
title="是否删除当前机器人?"
|
||||||
|
confirm-button-text="是"
|
||||||
|
cancel-button-text="否"
|
||||||
|
@confirm="deleteRobotHandle(item.id)"
|
||||||
|
>
|
||||||
|
<template #reference>
|
||||||
|
<el-button link type="danger">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-popconfirm>
|
||||||
|
<el-button
|
||||||
|
v-else
|
||||||
|
link
|
||||||
|
type="success"
|
||||||
|
@click="saveRobotHandle(item)"
|
||||||
|
>保存</el-button
|
||||||
|
>
|
||||||
|
</el-button-group>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<el-descriptions :column="1" size="default">
|
||||||
|
<el-descriptions-item label="微信Id">
|
||||||
|
{{ item.wxid }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="手机号">
|
||||||
|
{{ item.mobile }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="HOOK地址">
|
||||||
|
{{ item.hookApi }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="VNC地址">
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="primary"
|
||||||
|
@click="showVncDialogHandle(item.vncUrl)"
|
||||||
|
>
|
||||||
|
{{ item.vncUrl }}
|
||||||
|
</el-button>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="微信版本">
|
||||||
|
{{ translateVersion(item.version) }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="标签">
|
||||||
|
<el-tag
|
||||||
|
:key="t"
|
||||||
|
v-show="item.tag != ''"
|
||||||
|
v-for="t in item.tag.split(',')"
|
||||||
|
type="success"
|
||||||
|
>
|
||||||
|
{{ t }}
|
||||||
|
</el-tag>
|
||||||
|
</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-dialog
|
||||||
|
v-model="showCreateDialog"
|
||||||
|
title="新增机器人"
|
||||||
|
width="40%"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
:before-close="clearCreateParam"
|
||||||
|
>
|
||||||
|
<el-form :model="createRobotParam" label-width="100px">
|
||||||
|
<el-form-item
|
||||||
|
label="HOOK地址"
|
||||||
|
prop="hookApi"
|
||||||
|
:rules="[
|
||||||
|
{ required: true, message: '请输入HOOK地址', trigger: 'blur' }
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<el-input
|
||||||
|
v-model="createRobotParam.hookApi"
|
||||||
|
placeholder="请输入Hook接口地址,格式: 10.0.0.71:19088"
|
||||||
|
>
|
||||||
|
<template #prepend>http://</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="微信版本" prop="version">
|
||||||
|
<el-select
|
||||||
|
v-model="createRobotParam.version"
|
||||||
|
placeholder="请选择微信版本"
|
||||||
|
:rules="[
|
||||||
|
{ required: true, message: '请选择微信版本', trigger: 'blur' }
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in versionList"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="VNC地址">
|
||||||
|
<el-input
|
||||||
|
v-model="createRobotParam.vncUrl"
|
||||||
|
placeholder="请输入VNC页面地址,格式: 10.0.0.71:19087"
|
||||||
|
>
|
||||||
|
<template #prepend>http://</template>
|
||||||
|
<template #append>/vnc_lite.html</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="备注">
|
||||||
|
<el-input
|
||||||
|
v-model="createRobotParam.remark"
|
||||||
|
placeholder="请输入备注"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
v-loading="createRobotParam.saveLoading"
|
||||||
|
@click="saveRobotHandle(createRobotParam, true)"
|
||||||
|
>
|
||||||
|
保存
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<el-dialog
|
||||||
|
v-model="showVncDialog"
|
||||||
|
width="1280px"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
:before-close="closeVncIframe"
|
||||||
|
center
|
||||||
|
>
|
||||||
|
<div style="margin: 0 auto">
|
||||||
|
<iframe :src="vncUrl" class="vncIframe" />
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.card-container {
|
||||||
|
margin: 10px;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 20px;
|
||||||
|
justify-content: flex-start; /* 改为 flex-start 以优先横向排列 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.robot-card {
|
||||||
|
width: 24%;
|
||||||
|
min-width: 380px;
|
||||||
|
height: 330px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.robot-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.robot-name {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.robot-remark {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vncIframe {
|
||||||
|
width: 1280px;
|
||||||
|
height: 747px;
|
||||||
|
transform-origin: left top;
|
||||||
|
transform: scale(0.95, 0.95);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
Loading…
Reference in New Issue
Block a user