Files
gva/web/src/view/systemTools/autoCodeAdmin/index.vue

547 lines
16 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.

<template>
<div>
<div class="gva-table-box">
<div class="gva-btn-list">
<el-button type="primary" icon="plus" @click="goAutoCode(null)">
新增
</el-button>
</div>
<el-table :data="tableData">
<el-table-column type="selection" width="55" />
<el-table-column align="left" label="id" width="60" prop="ID" />
<el-table-column align="left" label="日期" width="180">
<template #default="scope">
{{
formatDate(scope.row.CreatedAt)
}}
</template>
</el-table-column>
<el-table-column
align="left"
label="结构体名"
min-width="150"
prop="structName"
/>
<el-table-column
align="left"
label="结构体描述"
min-width="150"
prop="description"
/>
<el-table-column
align="left"
label="表名称"
min-width="150"
prop="tableName"
/>
<el-table-column
align="left"
label="回滚标记"
min-width="150"
prop="flag"
>
<template #default="scope">
<el-tag v-if="scope.row.flag" type="danger" effect="dark">
已回滚
</el-tag>
<el-tag v-else type="success" effect="dark">
未回滚
</el-tag>
</template>
</el-table-column>
<el-table-column align="left" label="操作" min-width="240">
<template #default="scope">
<div>
<el-button
type="primary"
link
:disabled="scope.row.flag === 1"
@click="addFuncBtn(scope.row)"
>
增加方法
</el-button>
<el-button type="primary" link @click="goAutoCode(scope.row,1)">
增加字段
</el-button>
<el-button
type="primary"
link
:disabled="scope.row.flag === 1"
@click="openDialog(scope.row)"
>
回滚
</el-button>
<el-button type="primary" link @click="goAutoCode(scope.row)">
复用
</el-button>
<el-button type="primary" link @click="deleteRow(scope.row)">
删除
</el-button>
</div>
</template>
</el-table-column>
</el-table>
<div class="gva-pagination">
<el-pagination
:current-page="page"
:page-size="pageSize"
:page-sizes="[10, 30, 50, 100]"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
@current-change="handleCurrentChange"
@size-change="handleSizeChange"
/>
</div>
</div>
<el-dialog
v-model="dialogFormVisible"
:title="dialogFormTitle"
:before-close="closeDialog"
width="600px"
>
<el-form :inline="true" :model="formData" label-width="80px">
<el-form-item label="选项:">
<el-checkbox
v-model="formData.deleteApi"
label="删除接口"
/>
<el-checkbox
v-model="formData.deleteMenu"
label="删除菜单"
/>
<el-checkbox
v-model="formData.deleteTable"
label="删除表"
@change="deleteTableCheck"
/>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="closeDialog">
</el-button>
<el-popconfirm
title="此操作将回滚生成文件和勾选项目, 是否继续?"
@confirm="enterDialog"
>
<template #reference>
<el-button type="primary">
</el-button>
</template>
</el-popconfirm>
</div>
</template>
</el-dialog>
<el-drawer
v-model="funcFlag"
size="60%"
:show-close="false"
:close-on-click-modal="false"
>
<template #header>
<div class="flex justify-between items-center">
<span class="text-lg">操作栏</span>
<div>
<el-button
type="primary"
@click="runFunc"
:loading="aiLoading"
>
生成
</el-button>
<el-button
type="primary"
@click="closeFunc"
:loading="aiLoading"
>
取消
</el-button>
</div>
</div>
</template>
<div class="">
<el-form v-loading="aiLoading" label-position="top" element-loading-text="小淼正在思考,请稍候..." :model="autoFunc" label-width="80px">
<el-form-item label="包名:">
<el-input v-model="autoFunc.package" placeholder="请输入包名" disabled />
</el-form-item>
<el-form-item label="结构体名:">
<el-input v-model="autoFunc.structName" placeholder="请输入结构体名" disabled />
</el-form-item>
<el-form-item label="前端文件名:">
<el-input v-model="autoFunc.packageName" placeholder="请输入文件名" disabled />
</el-form-item>
<el-form-item label="后端文件名:">
<el-input v-model="autoFunc.humpPackageName" placeholder="请输入文件名" disabled />
</el-form-item>
<el-form-item label="描述:">
<el-input v-model="autoFunc.description" placeholder="请输入描述" disabled />
</el-form-item>
<el-form-item label="缩写:">
<el-input v-model="autoFunc.abbreviation" placeholder="请输入缩写" disabled />
</el-form-item>
<el-form-item label="是否AI填充">
<el-switch v-model="autoFunc.isAi" /> <span class="text-sm text-red-600 p-2">当前ai帮写存在不稳定因素生成代码后请注意手动调整部分内容</span>
</el-form-item>
<template v-if="autoFunc.isAi">
<el-form-item label="Ai帮写:">
<div class="relative w-full">
<el-input type="textarea" placeholder="AI帮写功能输入提示信息自动生成代码" v-model="autoFunc.prompt" :rows="5" @input="autoFunc.router = autoFunc.router.replace(/\//g, '')" />
<el-button @click="aiAddFunc" type="primary" class="absolute right-2 bottom-2"><ai-gva />帮写</el-button>
</div>
</el-form-item>
<el-form-item label="Api方法:">
<v-ace-editor v-model:value="autoFunc.apiFunc" lang="golang" theme="github_dark" class="h-80 w-full" />
</el-form-item>
<el-form-item label="Server方法:">
<v-ace-editor v-model:value="autoFunc.serverFunc" lang="golang" theme="github_dark" class="h-80 w-full" />
</el-form-item>
<el-form-item label="前端JSAPI方法:">
<v-ace-editor v-model:value="autoFunc.jsFunc" lang="javascript" theme="github_dark" class="h-80 w-full" />
</el-form-item>
</template>
<el-form-item label="方法介绍:">
<div class="flex w-full gap-2">
<el-input class="flex-1" v-model="autoFunc.funcDesc" placeholder="请输入方法介绍" />
<el-button type="primary" @click="autoComplete"><ai-gva />补全</el-button>
</div>
</el-form-item>
<el-form-item label="方法名:">
<el-input @blur="autoFunc.funcName = toUpperCase(autoFunc.funcName)" v-model="autoFunc.funcName" placeholder="请输入方法名" />
</el-form-item>
<el-form-item label="方法:">
<el-select v-model="autoFunc.method" placeholder="请选择方法">
<el-option
v-for="item in ['GET', 'POST', 'PUT', 'DELETE']"
:key="item"
:label="item"
:value="item"
/>
</el-select>
</el-form-item>
<el-form-item label="是否鉴权:">
<el-switch v-model="autoFunc.isAuth" active-text="是" inactive-text="否" />
</el-form-item>
<el-form-item label="路由path:">
<el-input v-model="autoFunc.router" placeholder="路由path" @input="autoFunc.router = autoFunc.router.replace(/\//g, '')" />
<div>API路径: [{{ autoFunc.method }}] /{{ autoFunc.abbreviation }}/{{ autoFunc.router }}</div>
</el-form-item>
</el-form>
</div>
</el-drawer>
</div>
</template>
<script setup>
import { getSysHistory, rollback, delSysHistory,addFunc,butler } from "@/api/autoCode.js";
import { useRouter } from "vue-router";
import { ElMessage, ElMessageBox } from "element-plus";
import { ref } from "vue";
import { formatDate } from "@/utils/format";
import { toUpperCase } from "@/utils/stringFun"
import {useAppStore} from "@/pinia";
import { VAceEditor } from "vue3-ace-editor"
import 'ace-builds/src-noconflict/mode-javascript';
import 'ace-builds/src-noconflict/mode-golang';
import 'ace-builds/src-noconflict/theme-github_dark';
const appStore = useAppStore()
defineOptions({
name: "AutoCodeAdmin",
});
const aiLoading = ref(false)
const formData = ref({
id: undefined,
deleteApi: true,
deleteMenu: true,
deleteTable: false,
});
const router = useRouter();
const dialogFormVisible = ref(false);
const dialogFormTitle = ref("");
const page = ref(1);
const total = ref(0);
const pageSize = ref(10);
const tableData = ref([]);
const activeInfo = ref("")
const autoFunc = ref({
package:"",
funcName:"",
structName:"",
packageName:"",
description:"",
abbreviation:"",
humpPackageName:"",
businessDB:"",
method:"",
funcDesc: "",
isAuth:false,
isAi:false,
apiFunc:"",
serverFunc:"",
jsFunc:"",
})
const addFuncBtn = (row) => {
const req = JSON.parse(row.request)
activeInfo.value = row.request
autoFunc.value.package = req.package
autoFunc.value.structName = req.structName
autoFunc.value.packageName = req.packageName
autoFunc.value.description = req.description
autoFunc.value.abbreviation = req.abbreviation
autoFunc.value.humpPackageName = req.humpPackageName
autoFunc.value.businessDB = req.businessDB
autoFunc.value.method = ""
autoFunc.value.funcName = ""
autoFunc.value.router = ""
autoFunc.value.funcDesc = ""
autoFunc.value.isAuth = false
autoFunc.value.isAi = false
autoFunc.value.apiFunc = ""
autoFunc.value.serverFunc = ""
autoFunc.value.jsFunc = ""
funcFlag.value = true;
};
const funcFlag = ref(true);
const closeFunc = () => {
funcFlag.value = false;
};
const runFunc = async () =>{
// 首字母自动转换为大写
autoFunc.value.funcName = toUpperCase(autoFunc.value.funcName)
if (!autoFunc.value.funcName) {
ElMessage.error("请输入方法名")
return
}
if (!autoFunc.value.method) {
ElMessage.error("请选择方法")
return
}
if (!autoFunc.value.router) {
ElMessage.error("请输入路由")
return
}
if (!autoFunc.value.funcDesc) {
ElMessage.error("请输入方法介绍")
return
}
if (autoFunc.value.isAi){
if (!autoFunc.value.apiFunc || !autoFunc.value.serverFunc || !autoFunc.value.jsFunc) {
ElMessage.error("请先使用AI帮写完成基础代码如果生成失败请重新调用")
return
}
}
const res = await addFunc(autoFunc.value)
if (res.code === 0) {
ElMessage.success("增加方法成功");
closeFunc()
}
}
// 分页
const handleSizeChange = (val) => {
pageSize.value = val;
getTableData();
};
const handleCurrentChange = (val) => {
page.value = val;
getTableData();
};
// 查询
const getTableData = async () => {
const table = await getSysHistory({
page: page.value,
pageSize: pageSize.value,
});
if (table.code === 0) {
tableData.value = table.data.list;
total.value = table.data.total;
page.value = table.data.page;
pageSize.value = table.data.pageSize;
}
};
getTableData();
const deleteRow = async (row) => {
ElMessageBox.confirm("此操作将删除本历史, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(async () => {
const res = await delSysHistory({ id: Number(row.ID) });
if (res.code === 0) {
ElMessage.success("删除成功");
getTableData();
}
});
};
// 打开弹窗
const openDialog = (row) => {
dialogFormTitle.value = "回滚:" + row.structName;
formData.value.id = row.ID;
dialogFormVisible.value = true;
};
// 关闭弹窗
const closeDialog = () => {
dialogFormVisible.value = false;
formData.value = {
id: undefined,
deleteApi: true,
deleteMenu: true,
deleteTable: false,
};
};
// 确认删除表
const deleteTableCheck = (flag) => {
if (flag) {
ElMessageBox.confirm(
`此操作将删除自动创建的文件和api会删除表, 是否继续?`,
"提示",
{
closeOnClickModal: false,
distinguishCancelAndClose: true,
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}
)
.then(() => {
ElMessageBox.confirm(
`此操作将删除自动创建的文件和api会删除表, 请继续确认!!!`,
"会删除表",
{
closeOnClickModal: false,
distinguishCancelAndClose: true,
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}
).catch(() => {
formData.value.deleteTable = false;
});
})
.catch(() => {
formData.value.deleteTable = false;
});
}
};
const enterDialog = async () => {
const res = await rollback(formData.value);
if (res.code === 0) {
ElMessage.success("回滚成功");
getTableData();
}
};
const goAutoCode = (row,isAdd) => {
if (row) {
router.push({
name: "autoCodeEdit",
params: {
id: row.ID,
},
query: {
isAdd: isAdd
},
});
} else {
router.push({ name: "autoCode" });
}
};
const aiAddFunc = async () =>{
aiLoading.value = true
autoFunc.value.apiFunc = ""
autoFunc.value.serverFunc = ""
autoFunc.value.jsFunc = ""
if (!autoFunc.value.prompt) {
ElMessage.error("请输入提示信息")
return
}
const res = await addFunc({...autoFunc.value,isPreview:true})
if (res.code !== 0) {
aiLoading.value = false
ElMessage.error(res.msg)
return
}
const aiRes = await butler({
structInfo:activeInfo.value,
template:JSON.stringify(res.data),
prompt: autoFunc.value.prompt,
command: "addFunc"
})
aiLoading.value = false
if (aiRes.code === 0) {
try{
const aiData = JSON.parse(aiRes.data)
autoFunc.value.apiFunc = aiData.api
autoFunc.value.serverFunc = aiData.server
autoFunc.value.jsFunc = aiData.js
autoFunc.value.method = aiData.method
autoFunc.value.funcName = aiData.funcName
const routerArr = aiData.router.split("/")
autoFunc.value.router = routerArr[routerArr.length - 1]
autoFunc.value.funcDesc = autoFunc.value.prompt
} catch (e) {
ElMessage.error("小淼忙碌,请重新调用")
}
}
}
const autoComplete = async () =>{
aiLoading.value = true
const aiRes = await butler({
prompt: autoFunc.value.funcDesc,
command: "autoCompleteFunc"
})
aiLoading.value = false
if (aiRes.code === 0) {
try{
const aiData = JSON.parse(aiRes.data)
autoFunc.value.method = aiData.method
autoFunc.value.funcName = aiData.funcName
autoFunc.value.router = aiData.router
autoFunc.value.prompt = autoFunc.value.funcDesc
} catch (e) {
ElMessage.error("小淼开小差了,请重新调用")
}
}
}
</script>