第一次提交

This commit is contained in:
2026-04-03 09:56:14 +08:00
commit 60e2c8debd
3598 changed files with 746659 additions and 0 deletions

View File

@@ -0,0 +1,271 @@
<template>
<a-spin :spinning="confirmLoading">
<a-row :span="24" style="margin-bottom: 10px">
<a-col :span="12" v-for="item in apiList" @click="handleSelect(item)">
<a-card :style="item.checked ? { border: '1px solid #3370ff' } : {}" hoverable class="checkbox-card" :body-style="{ width: '100%', padding: '10px' }">
<div class="checkbox-name" style="display: flex; width: 100%; justify-content: space-between">
<span>接口名称: {{ item.name }}</span>
<a-checkbox v-model:checked="item.checked" @click.stop class="quantum-checker" @change="(e) => handleChange(e, item)"> </a-checkbox>
</div>
<div class="checkbox-name" style="margin-top: 4px">
请求方式: <span>{{item.requestMethod}}</span>
</div>
</a-card>
</a-col>
</a-row>
<Pagination
v-if="apiList.length > 0"
:current="pageNo"
:page-size="pageSize"
:page-size-options="pageSizeOptions"
:total="total"
:showQuickJumper="true"
:showSizeChanger="true"
@change="handlePageChange"
class="list-footer"
size="small"
/>
</a-spin>
</template>
<script lang="ts" setup>
import { computed, defineExpose, defineProps, nextTick, reactive, ref } from "vue";
import { useMessage } from '/@/hooks/web/useMessage';
import { getApiList, getPermissionList, permissionAddFunction } from '../OpenApiAuth.api';
import { Form, Pagination } from 'ant-design-vue';
const props = defineProps({
formDisabled: { type: Boolean, default: false },
formData: { type: Object, default: () => ({}) },
formBpm: { type: Boolean, default: true },
});
const useForm = Form.useForm;
const emit = defineEmits(['register', 'ok']);
const { createMessage } = useMessage();
const confirmLoading = ref<boolean>(false);
//认证ID
const apiAuthId = ref<string>('');
//表单验证
const validatorRules = reactive({});
//api列表
const apiList = ref<any>([]);
//选中的值
const selectedRowKeys = ref<any>([]);
//选中的数据
const selectedRows = ref<any>([]);
//当前页数
const pageNo = ref<number>(1);
//每页条数
const pageSize = ref<number>(10);
//总条数
const total = ref<number>(0);
//可选择的页数
const pageSizeOptions = ref<any>(['10', '20', '30']);
// 表单禁用
const disabled = computed(() => {
if (props.formBpm === true) {
if (props.formData.disabled === false) {
return false;
} else {
return true;
}
}
return props.formDisabled;
});
/**
* 加载数据
*/
function reload() {
getApiList({ pageNo: pageNo.value, pageSize: pageSize.value, column: 'createTime', order: 'desc'}).then((res)=>{
if (res.success) {
for (const item of res.result.records) {
item.checked = false;
}
apiList.value = res.result.records;
total.value = res.result.total;
setChecked();
} else {
apiList.value = [];
total.value = 0;
}
});
}
/**
* 新增
*/
function add() {
edit({});
}
/**
* 编辑
*/
async function edit(record) {
selectedRowKeys.value = [];
selectedRows.value = [];
pageNo.value = 1;
pageSize.value = 10;
apiAuthId.value = record.id;
await nextTick(() => {
// 获取当前已授权的项目
getPermissionList({ apiAuthId: record.id }).then((res) => {
if (res.length > 0) {
res.forEach((item) => {
if(item.ifCheckBox == "1"){
selectedRowKeys.value.push(item.id);
selectedRows.value.push(item);
}
});
//设置选中
setChecked();
}
});
reload();
});
}
/**
* 提交数据
*/
async function submitForm() {
confirmLoading.value = true;
//时间格式化
let model = {};
let apiId = ""
selectedRowKeys.value.forEach((item) => {
apiId += item +",";
})
model['apiId'] = apiId;
model['apiAuthId'] = apiAuthId.value;
await permissionAddFunction(model)
.then((res) => {
if (res.success) {
createMessage.success(res.message);
emit('ok');
cleanData()
} else {
createMessage.warning(res.message);
}
})
.finally(() => {
confirmLoading.value = false;
});
}
const cleanData = () => {
selectedRows.value = []
selectedRowKeys.value = []
};
/**
* 复选框选中事件
* @param item
*/
function handleSelect(item) {
let id = item.id;
const target = apiList.value.find((item) => item.id === id);
if (target) {
target.checked = !target.checked;
}
//存放选中的知识库的id
if (!selectedRowKeys.value || selectedRowKeys.value.length == 0) {
selectedRowKeys.value.push(id);
selectedRows.value.push(item);
return;
}
let findIndex = selectedRowKeys.value.findIndex((item) => item === id);
if (findIndex === -1) {
selectedRowKeys.value.push(id);
selectedRows.value.push(item);
} else {
selectedRowKeys.value.splice(findIndex, 1);
selectedRows.value.splice(findIndex, 1);
}
}
/**
* 复选框选中事件
*
* @param e
* @param item
*/
function handleChange(e, item: any) {
if (e.target.checked) {
selectedRowKeys.value.push(item.id);
selectedRows.value.push(item);
} else {
let findIndex = selectedRowKeys.value.findIndex((val) => val === item.id);
if (findIndex != -1) {
selectedRowKeys.value.splice(findIndex, 1);
selectedRows.value.splice(findIndex, 1);
}
}
}
/**
* 分页改变事件
* @param page
* @param current
*/
function handlePageChange(page, current) {
pageNo.value = page;
pageSize.value = current;
reload();
}
/**
* 设置选装状态
*/
function setChecked() {
if (apiList.value && apiList.value.length > 0){
let value = selectedRowKeys.value.join(',');
apiList.value = apiList.value.map((item) => {
if (value.indexOf(item.id) !== -1) {
item.checked = true;
} else {
item.checked = false;
}
return item;
});
}
}
defineExpose({
add,
edit,
submitForm,
cleanData
});
</script>
<style lang="less" scoped>
.antd-modal-form {
padding: 14px;
}
.list-footer {
position: absolute;
bottom: -22px;
right: 10px;
text-align: center;
}
.checkbox-card {
margin-bottom: 10px;
margin-right: 10px;
}
.checkbox-img {
width: 30px;
height: 30px;
}
.checkbox-name {
margin-left: 4px;
font-size: 13px;
}
.use-select {
color: #646a73;
position: absolute;
bottom: 0;
left: 20px;
}
</style>

View File

@@ -0,0 +1,100 @@
<template>
<!-- <j-modal :title="title" :width="width" :visible="visible" @ok="handleOk" :okButtonProps="{ class: { 'jee-hidden': disableSubmit } }" @cancel="handleCancel" cancelText="关闭">-->
<div style="position: relative;">
<a-modal
v-model:open="authDrawerOpen"
class="custom-class"
root-class-name="root-class-name"
:root-style="{ color: 'blue' }"
:body-style="{ padding: '20px' }"
style="color: red"
:title="title"
:width="600"
@after-open-change="authDrawerOpenChange"
@ok="handleOk"
>
<AuthForm ref="registerForm" @ok="submitCallback" :formDisabled="disableSubmit" :formBpm="false"></AuthForm>
</a-modal>
</div>
<!-- </j-modal>-->
</template>
<script lang="ts" setup>
import { ref, nextTick, defineExpose } from 'vue';
import AuthForm from './AuthForm.vue';
import JModal from '/@/components/Modal/src/JModal/JModal.vue';
const title = ref<string>('');
const width = ref<number>(800);
const visible = ref<boolean>(false);
const disableSubmit = ref<boolean>(false);
const registerForm = ref();
const emit = defineEmits(['register', 'success']);
const authDrawerOpen = ref(false);
const authDrawerOpenChange = (val: any) => {
if(!val)
registerForm.value.cleanData()
};
/**
* 新增
*/
function add() {
title.value = '新增';
visible.value = true;
nextTick(() => {
registerForm.value.add();
});
}
/**
* 授权
* @param record
*/
function edit(record) {
title.value = disableSubmit.value ? '详情' : '授权';
visible.value = true;
authDrawerOpen.value = true;
nextTick(() => {
registerForm.value.edit(record);
});
}
/**
* 确定按钮点击事件
*/
function handleOk() {
registerForm.value.submitForm();
}
/**
* form保存回调事件
*/
function submitCallback() {
handleCancel();
emit('success');
}
/**
* 取消按钮回调事件
*/
function handleCancel() {
visible.value = false;
authDrawerOpen.value = false;
}
defineExpose({
add,
edit,
disableSubmit,
});
</script>
<style lang="less">
/**隐藏样式-modal确定按钮 */
.jee-hidden {
display: none !important;
}
</style>
<style lang="less" scoped></style>

View File

@@ -0,0 +1,175 @@
<template>
<a-spin :spinning="confirmLoading">
<JFormContainer :disabled="disabled">
<template #detail>
<a-form ref="formRef" class="antd-modal-form" :labelCol="labelCol" :wrapperCol="wrapperCol" name="OpenApiAuthForm">
<a-row>
<a-col :span="24">
<a-form-item label="授权名称" v-bind="validateInfos.name" id="OpenApiAuthForm-name" name="name">
<a-input v-model:value="formData.name" placeholder="请输入授权名称" allow-clear ></a-input>
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="AK" v-bind="validateInfos.ak" id="OpenApiAuthForm-ak" name="ak">
<a-input v-model:value="formData.ak" placeholder="请输入AK" disabled allow-clear ></a-input>
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="SK" v-bind="validateInfos.sk" id="OpenApiAuthForm-sk" name="sk">
<a-input v-model:value="formData.sk" placeholder="请输入SK" disabled allow-clear ></a-input>
</a-form-item>
</a-col>
<!-- <a-col :span="24">-->
<!-- <a-form-item label="关联系统用户名" v-bind="validateInfos.systemUserId" id="OpenApiAuthForm-systemUserId" name="systemUserId">-->
<!-- <JSearchSelect dict="sys_user,username,id" v-model:value="formData.systemUserId" placeholder="请输入关联系统用户名" allow-clear ></JSearchSelect>-->
<!-- </a-form-item>-->
<!-- </a-col>-->
</a-row>
</a-form>
</template>
</JFormContainer>
</a-spin>
</template>
<script lang="ts" setup>
import { ref, reactive, defineExpose, nextTick, defineProps, computed, } from 'vue';
import { USER_INFO_KEY} from '/@/enums/cacheEnum';
import { useMessage } from '/@/hooks/web/useMessage';
import { getValueType } from '/@/utils';
import { saveOrUpdate,getGenAKSK } from '../OpenApiAuth.api';
import { Form } from 'ant-design-vue';
import JFormContainer from '/@/components/Form/src/container/JFormContainer.vue';
import JSearchSelect from '/@/components/Form/src/jeecg/components/JSearchSelect.vue';
import { getAuthCache } from "@/utils/auth";
const props = defineProps({
formDisabled: { type: Boolean, default: false },
formData: { type: Object, default: () => ({})},
formBpm: { type: Boolean, default: true },
title: { type: String, default: "" },
});
const formRef = ref();
const useForm = Form.useForm;
const emit = defineEmits(['register', 'ok']);
const formData = reactive<Record<string, any>>({
id: '',
name: '',
ak: '',
sk: '',
systemUserId: '',
});
const { createMessage } = useMessage();
const labelCol = ref<any>({ xs: { span: 24 }, sm: { span: 5 } });
const wrapperCol = ref<any>({ xs: { span: 24 }, sm: { span: 16 } });
const confirmLoading = ref<boolean>(false);
//表单验证
const validatorRules = reactive({
name:[{ required: true, message: '请输入授权名称!'},],
systemUserId:[{ required: true, message: '请输入关联系统用户名!'},],
});
const { resetFields, validate, validateInfos } = useForm(formData, validatorRules, { immediate: false });
// 表单禁用
const disabled = computed(()=>{
if(props.formBpm === true){
if(props.formData.disabled === false){
return false;
}else{
return true;
}
}
return props.formDisabled;
});
/**
* 新增
*/
async function add() {
edit({});
const AKSKObj = await getGenAKSK({});
formData.ak = AKSKObj[0];
formData.sk = AKSKObj[1];
}
/**
* 编辑
*/
function edit(record) {
const userData = getAuthCache(USER_INFO_KEY)
if(props.title == "新增"){
record.systemUserId = userData.id
}
nextTick(() => {
resetFields();
const tmpData = {};
Object.keys(formData).forEach((key) => {
if(record.hasOwnProperty(key)){
tmpData[key] = record[key]
}
})
//赋值
Object.assign(formData, tmpData);
});
}
/**
* 提交数据
*/
async function submitForm() {
try {
// 触发表单验证
await validate();
} catch ({ errorFields }) {
if (errorFields) {
const firstField = errorFields[0];
if (firstField) {
formRef.value.scrollToField(firstField.name, { behavior: 'smooth', block: 'center' });
}
}
return Promise.reject(errorFields);
}
confirmLoading.value = true;
const isUpdate = ref<boolean>(false);
//时间格式化
let model = formData;
if (model.id) {
isUpdate.value = true;
}
//循环数据
for (let data in model) {
//如果该数据是数组并且是字符串类型
if (model[data] instanceof Array) {
let valueType = getValueType(formRef.value.getProps, data);
//如果是字符串类型的需要变成以逗号分割的字符串
if (valueType === 'string') {
model[data] = model[data].join(',');
}
}
}
await saveOrUpdate(model, isUpdate.value)
.then((res) => {
if (res.success) {
createMessage.success(res.message);
emit('ok');
} else {
createMessage.warning(res.message);
}
})
.finally(() => {
confirmLoading.value = false;
});
}
defineExpose({
add,
edit,
submitForm,
});
</script>
<style lang="less" scoped>
.antd-modal-form {
padding: 14px;
}
</style>

View File

@@ -0,0 +1,77 @@
<template>
<j-modal :title="title" :width="width" :maxHeight="200" :visible="visible" @ok="handleOk" :okButtonProps="{ class: { 'jee-hidden': disableSubmit } }" @cancel="handleCancel" cancelText="关闭">
<OpenApiAuthForm ref="registerForm" @ok="submitCallback" :title="title" :formDisabled="disableSubmit" :formBpm="false"></OpenApiAuthForm>
</j-modal>
</template>
<script lang="ts" setup>
import { ref, nextTick, defineExpose } from 'vue';
import OpenApiAuthForm from './OpenApiAuthForm.vue'
import JModal from '/@/components/Modal/src/JModal/JModal.vue';
const title = ref<string>('');
const width = ref<number>(800);
const visible = ref<boolean>(false);
const disableSubmit = ref<boolean>(false);
const registerForm = ref();
const emit = defineEmits(['register', 'success']);
/**
* 新增
*/
function add() {
title.value = '新增';
visible.value = true;
nextTick(() => {
registerForm.value.add();
});
}
/**
* 编辑
* @param record
*/
function edit(record) {
title.value = disableSubmit.value ? '详情' : '编辑';
visible.value = true;
nextTick(() => {
registerForm.value.edit(record);
});
}
/**
* 确定按钮点击事件
*/
function handleOk() {
registerForm.value.submitForm();
}
/**
* form保存回调事件
*/
function submitCallback() {
handleCancel();
emit('success');
}
/**
* 取消按钮回调事件
*/
function handleCancel() {
visible.value = false;
}
defineExpose({
add,
edit,
disableSubmit,
});
</script>
<style lang="less">
/**隐藏样式-modal确定按钮 */
.jee-hidden {
display: none !important;
}
</style>
<style lang="less" scoped></style>

View File

@@ -0,0 +1,178 @@
<template>
<BasicModal :bodyStyle="{ padding: '20px' }" v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" width="80%" @ok="handleSubmit">
<a-row :gutter="24">
<a-col :span="10">
<BasicForm @register="registerForm" ref="formRef" name="OpenApiForm" />
</a-col>
<a-col :span="14">
<a-row :gutter="24">
<a-col :span="24" style="margin-top: -0.6em">
<JVxeTable
keep-source
ref="openApiHeader"
:loading="openApiHeaderTable.loading"
:columns="openApiHeaderTable.columns"
:dataSource="openApiHeaderTable.dataSource"
:height="240"
:disabled="formDisabled"
:rowNumber="true"
:rowSelection="true"
:toolbar="true"
size="mini"
/>
</a-col>
<a-col :span="24">
<JVxeTable
keep-source
ref="openApiParam"
:loading="openApiParamTable.loading"
:columns="openApiParamTable.columns"
:dataSource="openApiParamTable.dataSource"
:height="240"
:disabled="formDisabled"
:rowNumber="true"
:rowSelection="true"
:toolbar="true"
size="mini"
/>
</a-col>
</a-row>
</a-col>
</a-row>
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, computed, unref, reactive } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { BasicForm, useForm } from '/@/components/Form/index';
import { JVxeTable } from '/@/components/jeecg/JVxeTable';
import { useJvxeMethod } from '/@/hooks/system/useJvxeMethods.ts';
import { formSchema, openApiHeaderJVxeColumns, openApiParamJVxeColumns } from '../OpenApi.data';
import { saveOrUpdate, queryOpenApiHeader, queryOpenApiParam, getGenPath } from '../OpenApi.api';
import { VALIDATE_FAILED } from '/@/utils/common/vxeUtils';
import { useMessage } from "@/hooks/web/useMessage";
// Emits声明
const $message = useMessage();
const emit = defineEmits(['register', 'success']);
const isUpdate = ref(true);
const formDisabled = ref(false);
const refKeys = ref(['openApiHeader', 'openApiParam']);
const activeKey = ref('openApiHeader');
const openApiHeader = ref();
const openApiParam = ref();
const tableRefs = { openApiHeader, openApiParam };
const openApiHeaderTable = reactive({
loading: false,
dataSource: [],
columns: openApiHeaderJVxeColumns,
});
const openApiParamTable = reactive({
loading: false,
dataSource: [],
columns: openApiParamJVxeColumns,
});
//表单配置
const [registerForm, { setProps, resetFields, setFieldsValue, validate }] = useForm({
labelWidth: 100,
schemas: formSchema,
showActionButtonGroup: false,
baseColProps: { span: 24 },
wrapperCol: { span: 24 },
});
//表单赋值
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
//重置表单
await reset();
setModalProps({ confirmLoading: false, showCancelBtn: data?.showFooter, showOkBtn: data?.showFooter });
isUpdate.value = !!data?.isUpdate;
formDisabled.value = !data?.showFooter;
if (unref(isUpdate)) {
//表单赋值
await setFieldsValue({
...data.record,
});
// 请求后端接口获取数据
// requestSubTableData(queryOpenApiHeader, {id:data?.record?.id}, openApiHeaderTable)
// requestSubTableData(queryOpenApiParam, {id:data?.record?.id}, openApiParamTable)
openApiHeaderTable.dataSource = !!data.record.headersJson?JSON.parse(data.record.headersJson):[];
openApiParamTable.dataSource = !!data.record.paramsJson?JSON.parse(data.record.paramsJson):[];
} else {
// /openapi/genpath
const requestUrlObj = await getGenPath({});
await setFieldsValue({
requestUrl: requestUrlObj.result
});
}
// 隐藏底部时禁用整个表单
setProps({ disabled: !data?.showFooter });
});
//方法配置
const [handleChangeTabs, handleSubmit, requestSubTableData, formRef] = useJvxeMethod(
requestAddOrEdit,
classifyIntoFormData,
tableRefs,
activeKey,
refKeys
);
//设置标题
const title = computed(() => (!unref(isUpdate) ? '新增' : !unref(formDisabled) ? '编辑' : '详情'));
async function reset() {
await resetFields();
activeKey.value = 'openApiHeader';
openApiHeaderTable.dataSource = [];
openApiParamTable.dataSource = [];
}
function classifyIntoFormData(allValues) {
let main = Object.assign({}, allValues.formValue);
return {
...main, // 展开
headersJson: allValues.tablesValue[0].tableData,
paramsJson: allValues.tablesValue[1].tableData,
};
}
//表单提交事件
async function requestAddOrEdit(values) {
let headersJson = !!values.headersJson?JSON.stringify(values.headersJson):null;
let paramsJson = !!values.headersJson?JSON.stringify(values.paramsJson):null;
try {
if (!!values.body){
try {
if (typeof JSON.parse(values.body)!='object'){
$message.createMessage.error("JSON格式化错误,请检查输入数据");
return;
}
} catch (e) {
$message.createMessage.error("JSON格式化错误,请检查输入数据");
return;
}
}
setModalProps({ confirmLoading: true });
values.headersJson = headersJson
values.paramsJson = paramsJson
//提交表单
await saveOrUpdate(values, isUpdate.value);
//关闭弹窗
closeModal();
//刷新列表
emit('success');
} finally {
setModalProps({ confirmLoading: false });
}
}
</script>
<style lang="less" scoped>
/** 时间和数字输入框样式 */
:deep(.ant-input-number) {
width: 100%;
}
:deep(.ant-calendar-picker) {
width: 100%;
}
</style>