go-wxhelper-web/src/views/infra/robot/index.vue

373 lines
9.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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/avatar/defaultWeChatAvatar.gif";
defineOptions({
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(e => {
const response = e.response.data;
message(
response.message + (response.errMsg ? ": " + response.errMsg : ""),
{ 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>
<template>
<div>
<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>
</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 {
display: flex;
flex-wrap: wrap;
gap: 20px;
justify-content: flex-start; /* 改为 flex-start 以优先横向排列 */
width: 100%;
margin: 10px;
}
.robot-card {
width: 32%;
min-width: 380px;
height: 330px;
}
.robot-header {
display: flex;
align-items: center;
justify-content: space-between;
}
.robot-name {
font-size: 18px;
font-weight: bold;
}
.robot-remark {
font-size: 14px;
color: #666;
}
.vncIframe {
width: 1280px;
height: 747px;
transform: scale(0.95, 0.95);
transform-origin: left top;
}
</style>