236 lines
6.5 KiB
Vue
236 lines
6.5 KiB
Vue
<template>
|
||
<div class="dev-page">
|
||
<!-- 工具栏:创建按钮 -->
|
||
<div class="page-toolbar">
|
||
<a-button type="primary" class="create-btn" @click="showCreate = true">
|
||
<template #icon><PlusOutlined /></template>
|
||
创建企业自建应用
|
||
</a-button>
|
||
</div>
|
||
|
||
<!-- 提示条 -->
|
||
<div class="notice-bar">
|
||
<InfoCircleOutlined class="notice-icon" />
|
||
<span>
|
||
<b>温馨提示:</b>
|
||
应用仅供本企业内部使用,应用发布需经过企业管理员审核,请仔细阅读
|
||
<a href="javascript:void(0)" class="notice-link">应用审核说明</a>。
|
||
</span>
|
||
</div>
|
||
|
||
<!-- 应用列表 -->
|
||
<AppsCenter ref="appsCenterRef" :user-id="userId" @create="showCreate = true" />
|
||
|
||
<!-- 创建应用弹窗 -->
|
||
<a-modal
|
||
v-model:open="showCreate"
|
||
title="创建企业自建应用"
|
||
:confirm-loading="createLoading"
|
||
ok-text="创建"
|
||
cancel-text="取消"
|
||
width="520px"
|
||
@ok="handleCreate"
|
||
@cancel="resetCreateForm"
|
||
>
|
||
<a-form
|
||
ref="createFormRef"
|
||
:model="createForm"
|
||
:rules="createRules"
|
||
layout="vertical"
|
||
style="margin-top: 8px"
|
||
>
|
||
<a-form-item label="应用名称" name="productName">
|
||
<a-input
|
||
v-model:value="createForm.productName"
|
||
placeholder="请输入应用名称,如:人事管理系统"
|
||
:maxlength="50"
|
||
show-count
|
||
/>
|
||
</a-form-item>
|
||
|
||
<a-form-item label="应用标识" name="productCode" required>
|
||
<a-input
|
||
v-model:value="createForm.productCode"
|
||
placeholder="如:hr-system、my-app(创建后不可修改)"
|
||
:maxlength="30"
|
||
/>
|
||
<div class="form-hint">必须以小写字母开头,只能包含小写字母、数字和连字符,连字符不能连续或结尾,创建后不可修改</div>
|
||
</a-form-item>
|
||
|
||
<a-form-item label="应用描述" name="description">
|
||
<a-textarea
|
||
v-model:value="createForm.description"
|
||
placeholder="简单描述应用的功能和用途(选填)"
|
||
:rows="3"
|
||
:maxlength="200"
|
||
show-count
|
||
/>
|
||
</a-form-item>
|
||
|
||
<a-form-item label="应用类型" name="appType">
|
||
<a-select v-model:value="createForm.appType" placeholder="请选择应用类型">
|
||
<a-select-option
|
||
v-for="opt in APP_TYPE_OPTIONS"
|
||
:key="opt.type"
|
||
:value="opt.type"
|
||
>
|
||
{{ opt.name }}
|
||
</a-select-option>
|
||
</a-select>
|
||
</a-form-item>
|
||
</a-form>
|
||
</a-modal>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { InfoCircleOutlined, PlusOutlined } from '@ant-design/icons-vue'
|
||
import { message } from 'ant-design-vue'
|
||
import type { FormInstance } from 'ant-design-vue'
|
||
import AppsCenter from '@/components/developer/AppsCenter.vue'
|
||
import { addAppProduct } from '@/api/app/appProduct'
|
||
import { addAppEvent } from '@/api/app/appEvent/index'
|
||
|
||
definePageMeta({ layout: 'developer' })
|
||
useHead({ title: '应用管理 - 开发者中心' })
|
||
|
||
const userId = import.meta.client ? localStorage.getItem('UserId') : null
|
||
const appsCenterRef = ref<{ refresh: () => void } | null>(null)
|
||
|
||
const APP_TYPE_OPTIONS = [
|
||
{ type: 10, appType: 'web', name: 'Web 应用' },
|
||
{ type: 20, appType: 'miniprogram', name: '小程序' },
|
||
{ type: 30, appType: 'mobile', name: '移动 App' },
|
||
{ type: 40, appType: 'api', name: 'API 服务' },
|
||
{ type: 50, appType: 'internal', name: '内部工具' },
|
||
] as const
|
||
|
||
// 创建弹窗
|
||
const showCreate = ref(false)
|
||
const createLoading = ref(false)
|
||
const createFormRef = ref<FormInstance>()
|
||
|
||
const createForm = reactive({
|
||
productName: '',
|
||
productCode: '',
|
||
description: '',
|
||
appType: APP_TYPE_OPTIONS[0].type,
|
||
})
|
||
|
||
const createRules = {
|
||
productName: [
|
||
{ required: true, message: '请输入应用名称', trigger: 'blur' },
|
||
{ min: 2, max: 50, message: '应用名称长度 2~50 个字符', trigger: 'blur' },
|
||
],
|
||
productCode: [
|
||
{ required: true, message: '请输入应用标识', trigger: 'blur' },
|
||
{ min: 2, max: 30, message: '标识长度 2~30 个字符', trigger: 'blur' },
|
||
{
|
||
pattern: /^[a-z]([a-z0-9]|-(?!-))*[a-z0-9]$|^[a-z]$/,
|
||
message: '必须以小写字母开头,只能包含小写字母、数字和连字符,不能以连字符结尾,且连字符不能连续',
|
||
trigger: 'blur',
|
||
},
|
||
],
|
||
appType: [{ required: true, message: '请选择应用类型', trigger: 'change' }],
|
||
}
|
||
|
||
async function handleCreate() {
|
||
try {
|
||
await createFormRef.value?.validateFields()
|
||
} catch {
|
||
return
|
||
}
|
||
createLoading.value = true
|
||
try {
|
||
const created = await addAppProduct({
|
||
productName: createForm.productName,
|
||
productCode: createForm.productCode,
|
||
appType: createForm.appType,
|
||
description: createForm.description,
|
||
publishStatus: 'developing',
|
||
})
|
||
|
||
if (created?.productId) {
|
||
addAppEvent({
|
||
appId: created.productId,
|
||
eventType: 'create',
|
||
title: '创建了应用',
|
||
content: `应用名称:${createForm.productName},标识:${createForm.productCode}`,
|
||
})
|
||
}
|
||
|
||
message.success('应用创建成功')
|
||
showCreate.value = false
|
||
resetCreateForm()
|
||
appsCenterRef.value?.refresh()
|
||
} catch (e: unknown) {
|
||
const msg = e instanceof Error ? e.message : typeof e === 'string' ? e : '创建失败,请重试'
|
||
message.error(msg)
|
||
} finally {
|
||
createLoading.value = false
|
||
}
|
||
}
|
||
|
||
function resetCreateForm() {
|
||
createForm.productName = ''
|
||
createForm.productCode = ''
|
||
createForm.description = ''
|
||
createForm.appType = APP_TYPE_OPTIONS[0].type
|
||
createFormRef.value?.resetFields()
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.dev-page {
|
||
min-height: 100%;
|
||
padding: 20px 24px 28px;
|
||
}
|
||
|
||
/* 工具栏 */
|
||
.page-toolbar {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 14px;
|
||
}
|
||
|
||
.create-btn {
|
||
font-size: 14px;
|
||
height: 36px;
|
||
border-radius: 8px;
|
||
}
|
||
|
||
/* 提示条 */
|
||
.notice-bar {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
gap: 8px;
|
||
background: #f0f5ff;
|
||
border: 1px solid #d6e4ff;
|
||
border-radius: 8px;
|
||
padding: 10px 14px;
|
||
font-size: 13px;
|
||
color: #555;
|
||
margin-bottom: 16px;
|
||
line-height: 1.6;
|
||
}
|
||
|
||
.notice-icon {
|
||
color: #1677ff;
|
||
font-size: 15px;
|
||
flex-shrink: 0;
|
||
margin-top: 2px;
|
||
}
|
||
|
||
.notice-link {
|
||
color: #1677ff;
|
||
text-decoration: none;
|
||
}
|
||
.notice-link:hover { text-decoration: underline; }
|
||
|
||
.form-hint {
|
||
font-size: 12px;
|
||
color: #999;
|
||
margin-top: 4px;
|
||
}
|
||
</style>
|