mirror of
https://github.com/hpd840321/craftlabs-authorization-sdk.git
synced 2026-06-09 10:00:30 +08:00
feat(web): I4 delivery and license SN UI
Add routes, menu entries, platform API helpers, and views for delivery batches and license SN management. Made-with: Cursor
This commit is contained in:
@@ -0,0 +1,162 @@
|
||||
<template>
|
||||
<el-card v-loading="pageLoading" shadow="never">
|
||||
<template #header>
|
||||
<div class="toolbar">
|
||||
<span class="title">新建许可 SN</span>
|
||||
<el-button @click="goBack">返回列表</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="120px" style="max-width: 560px">
|
||||
<el-form-item label="SN 编码" prop="snCode">
|
||||
<el-input v-model="form.snCode" maxlength="128" show-word-limit placeholder="唯一 SN" />
|
||||
</el-form-item>
|
||||
<el-form-item label="项目">
|
||||
<el-select
|
||||
v-model="form.projectId"
|
||||
clearable
|
||||
filterable
|
||||
placeholder="选填"
|
||||
style="width: 100%"
|
||||
:loading="projectsLoading"
|
||||
>
|
||||
<el-option v-for="p in projectOptions" :key="p.id" :label="p.name || String(p.id)" :value="p.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="合同行 ID">
|
||||
<el-input-number
|
||||
v-model="form.contractLineId"
|
||||
:min="1"
|
||||
clearable
|
||||
controls-position="right"
|
||||
style="width: 100%"
|
||||
placeholder="选填,MVP 手工录入"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="激活备注">
|
||||
<el-input v-model="form.activationRemark" maxlength="512" show-word-limit type="textarea" :rows="2" placeholder="选填" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<div class="footer-actions">
|
||||
<el-button :loading="submitting" @click="submit(false)">创建并返回列表</el-button>
|
||||
<el-button type="primary" :loading="submitting" @click="submit(true)">创建并进入详情</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { useAuthStore } from "../stores/auth";
|
||||
import { listProjects, createLicenseSn } from "../api/platform";
|
||||
import { apiErrorMessage } from "../utils/apiErrorMessage";
|
||||
|
||||
const auth = useAuthStore();
|
||||
const router = useRouter();
|
||||
|
||||
const pageLoading = ref(false);
|
||||
const projectsLoading = ref(false);
|
||||
const submitting = ref(false);
|
||||
const projectOptions = ref([]);
|
||||
const formRef = ref(null);
|
||||
|
||||
const form = reactive({
|
||||
snCode: "",
|
||||
projectId: undefined,
|
||||
contractLineId: undefined,
|
||||
activationRemark: "",
|
||||
});
|
||||
|
||||
const rules = {
|
||||
snCode: [{ required: true, message: "请输入 SN 编码", trigger: "blur" }],
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
auth.restoreAxiosAuth();
|
||||
pageLoading.value = true;
|
||||
try {
|
||||
await loadProjects();
|
||||
} finally {
|
||||
pageLoading.value = false;
|
||||
}
|
||||
});
|
||||
|
||||
function goBack() {
|
||||
router.push({ name: "license-sn-list" });
|
||||
}
|
||||
|
||||
async function loadProjects() {
|
||||
projectsLoading.value = true;
|
||||
try {
|
||||
const { data } = await listProjects({ page: 0, size: 500 });
|
||||
const body = data && typeof data === "object" ? data : {};
|
||||
projectOptions.value = Array.isArray(body.content) ? body.content : [];
|
||||
} catch (e) {
|
||||
ElMessage.error(apiErrorMessage(e, "加载项目失败"));
|
||||
projectOptions.value = [];
|
||||
} finally {
|
||||
projectsLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {boolean} goDetail
|
||||
*/
|
||||
async function submit(goDetail) {
|
||||
const f = formRef.value;
|
||||
if (!f) return;
|
||||
try {
|
||||
await f.validate();
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
submitting.value = true;
|
||||
const body = {
|
||||
snCode: form.snCode.trim(),
|
||||
projectId: form.projectId ?? undefined,
|
||||
contractLineId: form.contractLineId ?? undefined,
|
||||
activationRemark: form.activationRemark?.trim() || undefined,
|
||||
};
|
||||
try {
|
||||
const { data } = await createLicenseSn(body);
|
||||
const id = data?.id;
|
||||
if (id == null) {
|
||||
ElMessage.error("创建成功但未返回 SN ID");
|
||||
router.push({ name: "license-sn-list" });
|
||||
return;
|
||||
}
|
||||
ElMessage.success("已创建许可 SN");
|
||||
if (goDetail) {
|
||||
router.push({ name: "license-sn-detail", params: { id: String(id) } });
|
||||
} else {
|
||||
router.push({ name: "license-sn-list" });
|
||||
}
|
||||
} catch (e) {
|
||||
ElMessage.error(apiErrorMessage(e, "创建许可 SN 失败"));
|
||||
} finally {
|
||||
submitting.value = false;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
}
|
||||
.title {
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
}
|
||||
.footer-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 12px;
|
||||
padding-top: 16px;
|
||||
border-top: 1px solid var(--el-border-color-lighter);
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user