初始化2
This commit is contained in:
235
app/pages/developer/apps.vue
Normal file
235
app/pages/developer/apps.vue
Normal file
@@ -0,0 +1,235 @@
|
||||
<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>
|
||||
Reference in New Issue
Block a user