Commit 167cacff by Jony.L

Merge remote-tracking branch 'origin/fixbug' into develop

parents 3f6d4c2d 222d9ef6
......@@ -20,6 +20,11 @@ export const ApiEndpointRelApi = {
return await request.get({ url: `/apihub/api-endpoint-rel/get?id=` + id })
},
// 根据接口ID查询关联的API应用
getApisByEndpointId: async (apiEndpointId: number) => {
return await request.get({ url: `/apihub/api-endpoint-rel/list-by-endpoint?apiEndpointId=` + apiEndpointId })
},
// 新增API 应用与接口关系
createApiEndpointRel: async (data: ApiEndpointRel) => {
return await request.post({ url: `/apihub/api-endpoint-rel/create`, data })
......
......@@ -101,12 +101,12 @@
</el-card>
</el-col>
<!-- 第三个图表:折线图-->
<el-col :xl="24" :lg="24" :md="24" :sm="24" :xs="24">
<!-- 算力订单统计图表 -->
<el-col :xl="12" :lg="12" :md="12" :sm="24" :xs="24">
<div style="display: flex; justify-content: flex-end; margin-bottom: 10px;">
<el-radio-group
v-model="orderDateType"
@change="handleOrderDateDateTypeChange"
v-model="computeOrderDateType"
@change="handleComputeOrderDateTypeChange"
size="small"
>
<el-radio label="d">日数据(近7天)</el-radio>
......@@ -116,7 +116,27 @@
</div>
<el-card shadow="hover" class="mb-8px">
<el-skeleton :loading="loading" animated>
<Echart :options="orderChartOptions" :height="420"/>
<Echart :options="computeOrderChartOptions" :height="420"/>
</el-skeleton>
</el-card>
</el-col>
<!-- API订单统计图表 -->
<el-col :xl="12" :lg="12" :md="12" :sm="24" :xs="24">
<div style="display: flex; justify-content: flex-end; margin-bottom: 10px;">
<el-radio-group
v-model="apiOrderDateType"
@change="handleApiOrderDateTypeChange"
size="small"
>
<el-radio label="d">日数据(近7天)</el-radio>
<el-radio label="m">月数据(近30天)</el-radio>
<el-radio label="y">年数据(近12个月)</el-radio>
</el-radio-group>
</div>
<el-card shadow="hover" class="mb-8px">
<el-skeleton :loading="loading" animated>
<Echart :options="apiOrderChartOptions" :height="420"/>
</el-skeleton>
</el-card>
</el-col>
......@@ -154,7 +174,8 @@ const username = userStore.getUser.nickname
// 切换状态(d=日,m=月)
const userDateType = ref('d');
const apiCallsDateType = ref('d');
const orderDateType = ref('d');
const computeOrderDateType = ref('d');
const apiOrderDateType = ref('d');
const handleUserDateTypeChange = () => {
getUsersChartData(userDateType.value);
......@@ -165,8 +186,12 @@ const handleApiCallsDateTypeChange = () => {
getApiCallsChartData(apiCallsDateType.value);
}
const handleOrderDateDateTypeChange = () => {
getOrderChartData(orderDateType.value);
const handleComputeOrderDateTypeChange = () => {
getComputeOrderChartData(computeOrderDateType.value);
}
const handleApiOrderDateTypeChange = () => {
getApiOrderChartData(apiOrderDateType.value);
}
// 统计数据
......@@ -250,10 +275,10 @@ const getApiCallsChartData = async (apiCallsDateType) => {
apiCallChartOptions.value.series![0].data = data.map(item => item.callsCount)
}
//订单折线图配置
const orderChartOptions = ref<EChartsOption>({
// 算力订单折线图配置
const computeOrderChartOptions = ref<EChartsOption>({
title: {
text: '订单相关统计',
text: '算力订单统计',
left: 'center'
},
tooltip: {
......@@ -284,24 +309,7 @@ const orderChartOptions = ref<EChartsOption>({
itemStyle: {
color: '#67C23A' // 自定义颜色
}
}, {
name: 'API订单',
data: [], // 后续会动态填充
type: 'line', // 明确指定为折线图
smooth: false, // 平滑曲线
itemStyle: {
color: '#409EFF' // 自定义颜色
}
}, {
name: '总订单',
data: [], // 后续会动态填充
type: 'line', // 明确指定为折线图
smooth: false, // 平滑曲线
itemStyle: {
color: '#F59E0B' // 自定义颜色
}
},
// ---------------------- 新增3个金额系列(都绑右侧轴)----------------------
{
name: '算力订单金额',
data: [], // 算力金额数据
......@@ -309,6 +317,44 @@ const orderChartOptions = ref<EChartsOption>({
smooth: false,
itemStyle: {color: '#94D274'}, // 浅绿(和算力订单数颜色呼应)
yAxisIndex: 1 // 关键:绑右侧金额轴
}
]
})
// API订单折线图配置
const apiOrderChartOptions = ref<EChartsOption>({
title: {
text: 'API订单统计',
left: 'center'
},
tooltip: {
trigger: 'axis'
},
xAxis: {
type: 'category',
data: [] // 后续会动态填充
},
yAxis: [
{
type: 'value',
name: '订单数量'
},
{
// 右Y轴:金额(新增轴,index=1)
type: 'value',
name: '金额(元)', // 轴名称
position: 'right' // 放在右侧
}
],
series: [
{
name: 'API订单',
data: [], // 后续会动态填充
type: 'line', // 明确指定为折线图
smooth: false, // 平滑曲线
itemStyle: {
color: '#409EFF' // 自定义颜色
}
},
{
name: 'API订单金额',
......@@ -317,29 +363,26 @@ const orderChartOptions = ref<EChartsOption>({
smooth: false,
itemStyle: {color: '#7CB6FF'}, // 浅蓝(和API订单数颜色呼应)
yAxisIndex: 1 // 绑右侧金额轴
},
{
name: '总金额',
data: [], // 总金额数据
type: 'line',
smooth: false,
itemStyle: {color: '#FFC53D'}, // 浅黄(和总订单数颜色呼应)
yAxisIndex: 1 // 绑右侧金额轴
}
]
})
//订单折线图数据
const getOrderChartData = async (orderDateType) => {
// 算力订单折线图数据
const getComputeOrderChartData = async (orderDateType) => {
let ordersData = await IndexCountApi.getOrdersData(orderDateType);
computeOrderChartOptions.value.xAxis!.data = ordersData.map(item => t(item.countDate))
computeOrderChartOptions.value.series![0].data = ordersData.map(item => item.computeOrdersCount)
computeOrderChartOptions.value.series![1].data = ordersData.map(item => item.computeOrdersAmount)
}
// API订单折线图数据
const getApiOrderChartData = async (orderDateType) => {
let ordersData = await IndexCountApi.getOrdersData(orderDateType);
orderChartOptions.value.xAxis!.data = ordersData.map(item => t(item.countDate))
orderChartOptions.value.series![0].data = ordersData.map(item => item.computeOrdersCount)
orderChartOptions.value.series![1].data = ordersData.map(item => item.apiOrdersCount)
orderChartOptions.value.series![2].data = ordersData.map(item => item.totalOrdersCount)
orderChartOptions.value.series![3].data = ordersData.map(item => item.computeOrdersAmount)
orderChartOptions.value.series![4].data = ordersData.map(item => item.apiOrdersAmount)
orderChartOptions.value.series![5].data = ordersData.map(item => item.totalOrdersAmount)
apiOrderChartOptions.value.xAxis!.data = ordersData.map(item => t(item.countDate))
apiOrderChartOptions.value.series![0].data = ordersData.map(item => item.apiOrdersCount)
apiOrderChartOptions.value.series![1].data = ordersData.map(item => item.apiOrdersAmount)
}
// 初始化数据
......@@ -348,7 +391,8 @@ const initData = async () => {
getCount(),
getUsersChartData(userDateType.value),
getApiCallsChartData(apiCallsDateType.value),
getOrderChartData(orderDateType.value)
getComputeOrderChartData(computeOrderDateType.value),
getApiOrderChartData(apiOrderDateType.value)
])
loading.value = false
}
......
......@@ -24,7 +24,12 @@
oninput="this.value = this.value.replace(/\D/g,'')"
/>
</el-form-item>
<el-form-item label="是否上架" prop="isShelf">
<el-radio-group v-model="formData.isShelf">
<el-radio :label="true">已上架</el-radio>
<el-radio :label="false">未上架</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="关联行业应用">
<!-- 添加接口按钮独占一行 -->
......@@ -94,6 +99,7 @@
</template>
<script setup lang="ts">
import { ApiEndpointApi, ApiEndpoint, IndustryApplication} from '@/api/apihub/apiendpoint'
import { ApiEndpointRelApi } from '@/api/apihub/apiendpointrel'
/** API 接口 表单 */
defineOptions({ name: 'ApiEndpointForm' })
......@@ -111,14 +117,13 @@ const formData = ref({
path: undefined,
method: undefined,
consumptionPoints: undefined,
industryApplications: [
{ title: 'AI诗词', image: 'https://', id: null }
]
industryApplications: [],
isShelf: undefined
// params: undefined,
// response: undefined,
// authType: undefined,
// rateLimit: undefined,
// remark: undefined
// remark: undefined
})
const formRules = reactive({
name: [{ required: true, message: '接口名称不能为空', trigger: 'blur' }],
......@@ -142,10 +147,6 @@ const open = async (type: string, id?: number) => {
formLoading.value = true
try {
const res = await ApiEndpointApi.getApiEndpoint(id)
// 确保 industryApplications 至少有一行
if (!res.industryApplications || res.industryApplications.length === 0) {
res.industryApplications = [{ title: '', image: '', id: null }]
}
formData.value = res
} finally {
formLoading.value = false
......@@ -159,6 +160,30 @@ const emit = defineEmits(['success']) // 定义 success 事件,用于操作成
const submitForm = async () => {
// 校验表单
await formRef.value.validate()
// 如果处于上架状态,检查是否被API关联(适用于创建和修改)
if (formData.value.isShelf) {
// 对于修改操作,需要检查是否有API关联
if (formData.value.id) {
try {
const relatedApis = await ApiEndpointRelApi.getApisByEndpointId(formData.value.id)
if (!relatedApis || relatedApis.length === 0) {
// 若不满足条件,给出错误提示并终止提交
message.error('上架状态下,接口必须被至少一个API关联')
return
}
} catch (e) {
console.error('检查API关联失败', e)
message.error('检查API关联失败,请稍后再试')
return
}
} else {
// 对于新建操作,不允许直接上架,因为新建的接口还没有被API关联
message.error('新建接口不能直接上架,请先创建接口并关联到API后再上架')
return
}
}
// 提交请求
formLoading.value = true
try {
......@@ -186,9 +211,8 @@ const resetForm = () => {
path: undefined,
method: undefined,
consumptionPoints: undefined,
industryApplications: [
{ title: 'AI诗词', image: 'https://', id: null }
]
industryApplications: [],
isShelf: undefined
// params: undefined,
// response: undefined,
// authType: undefined,
......
......@@ -153,6 +153,13 @@
:formatter="dateFormatter"
width="180px"
/>
<el-table-column label="是否上架" align="center" prop="isShelf">
<template #default="scope">
<span :class="{ 'shelved': scope.row.isShelf, 'unshelved':!scope.row.isShelf }">
{{ scope.row.isShelf? '已上架' : '未上架' }}
</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" min-width="120px">
<template #default="scope">
<el-button
......@@ -297,4 +304,4 @@ const handleExport = async () => {
onMounted(() => {
getList()
})
</script>
</script>
\ No newline at end of file
......@@ -15,24 +15,24 @@
的文件
</p>
</el-form-item>
<el-form-item label="内容" prop="information">
<!-- <el-form-item label="内容" prop="information">
<el-input v-model="formData.information" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="标题" prop="title">
</el-form-item>-->
<!-- <el-form-item label="标题" prop="title">
<el-input v-model="formData.title" placeholder="请输入标题" />
</el-form-item>
</el-form-item>-->
<el-form-item label="链接地址" prop="url">
<el-input v-model="formData.url" placeholder="请输入链接地址" />
</el-form-item>
<el-form-item label="描述内容" prop="description">
<!-- <Editor v-model="formData.description" height="150px" />-->
<!-- <el-form-item label="描述内容" prop="description">
<Editor v-model="formData.description" height="150px" />
<el-input
v-model="formData.description"
:rows="2"
type="textarea"
placeholder="请输入描述内容"
/>
</el-form-item>
</el-form-item>-->
<el-form-item label="排序值" prop="orderNum">
<el-input v-model="formData.orderNum" placeholder="请输入排序值" />
</el-form-item>
......@@ -89,8 +89,8 @@ const formData = ref({
remark: undefined
})
const formRules = reactive({
information: [{ required: true, message: '内容不能为空', trigger: 'blur' }],
title: [{ required: true, message: '标题不能为空', trigger: 'blur' }],
//information: [{ required: true, message: '内容不能为空', trigger: 'blur' }],
//title: [{ required: true, message: '标题不能为空', trigger: 'blur' }],
showStatus: [{ required: true, message: '状态不能为空', trigger: 'blur' }],
orderNum: [{ required: true, message: '排序值不能为空', trigger: 'blur' }]
})
......
......@@ -103,10 +103,10 @@
</template>
</el-table-column>
<el-table-column label="内容" align="center" prop="information" />
<el-table-column label="标题" align="center" prop="title" />
<!-- <el-table-column label="内容" align="center" prop="information" />-->
<!-- <el-table-column label="标题" align="center" prop="title" />-->
<el-table-column label="链接地址" align="center" prop="url" />
<el-table-column label="描述内容" align="center" prop="description" />
<!-- <el-table-column label="描述内容" align="center" prop="description" />-->
<el-table-column label="状态" align="center" prop="showStatus">
<template #default="scope">
<dict-tag :type="DICT_TYPE.HOME_INFO_STATUS" :value="Number(scope.row.showStatus)" />
......
......@@ -20,9 +20,9 @@
<el-form-item label="链接地址" prop="url">
<el-input v-model="formData.url" placeholder="请输入链接地址" />
</el-form-item>
<el-form-item label="描述内容" prop="description">
<!-- <el-form-item label="描述内容" prop="description">
<Editor v-model="formData.description" height="150px" />
</el-form-item>
</el-form-item>-->
<!-- <el-form-item label="计算资源应用类别" prop="category">-->
<!-- <el-select-->
......
......@@ -122,7 +122,7 @@
<el-table-column label="内容" align="center" prop="information" />
<el-table-column label="标题" align="center" prop="title" />
<el-table-column label="链接地址" align="center" prop="url" />
<el-table-column label="描述内容" align="center" prop="description" />
<!-- <el-table-column label="描述内容" align="center" prop="description" />-->
<!-- <el-table-column label="计算资源应用类别" align="center" prop="category">-->
<!-- <template #default="scope">-->
<!-- <dict-tag :type="DICT_TYPE.HOME_INFO_COMPUTILITY_TYPE" :value="scope.row.category" />-->
......
......@@ -21,9 +21,9 @@
<el-form-item label="标题" prop="title">
<el-input v-model="formData.title" placeholder="请输入标题" />
</el-form-item>
<el-form-item label="链接地址" prop="url">
<!-- <el-form-item label="链接地址" prop="url">
<el-input v-model="formData.url" placeholder="请输入链接地址" />
</el-form-item>
</el-form-item>-->
<el-form-item label="描述内容" prop="description">
<Editor v-model="formData.description" height="150px" />
</el-form-item>
......@@ -52,7 +52,7 @@
</p>
</el-form-item>
<el-form-item label="组件类型" prop="assemblyType">
<!-- <el-form-item label="组件类型" prop="assemblyType">
<el-select
v-model="formData.assemblyType"
placeholder="请选择组件类型"
......@@ -66,7 +66,7 @@
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-form-item>-->
<el-form-item label="排序值" prop="orderNum">
<el-input v-model="formData.orderNum" placeholder="请输入排序值" />
......
......@@ -121,7 +121,7 @@
<!-- <el-table-column label="首页展示图片" align="center" prop="homeImage" />-->
<el-table-column label="内容" align="center" prop="information" />
<el-table-column label="标题" align="center" prop="title" />
<el-table-column label="链接地址" align="center" prop="url" />
<!-- <el-table-column label="链接地址" align="center" prop="url" />-->
<!-- <el-table-column label="组件类型" align="center" prop="assemblyType">-->
<!-- <template #default="scope">-->
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment