feat: 办事大厅用户面前端(hall)首版入库——由 app/public 改名去 app 层;build.yml 修并发撞名容exit137
build / build (push) Successful in 3m6s
build / build (push) Successful in 3m6s
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
import { Method } from "alova";
|
||||
import { alovaInstance } from "@/utils/alova/alova-iview";
|
||||
import type { SchoolTreeNode } from "@/types/svc";
|
||||
|
||||
/**
|
||||
* 基础平台接口(Notice baseApi 平移):用户信息与已授权模块列表(菜单渲染数据源)。
|
||||
* 模块清单在 UserBase 按本应用 appKey 配置(app_module),按登录人过滤下发。
|
||||
*/
|
||||
const BASE = "/api/base";
|
||||
|
||||
function get<T = any>(url: string, params?: Record<string, any>): Method<T> {
|
||||
return new Method<T>("GET", alovaInstance, url, { params });
|
||||
}
|
||||
|
||||
class BaseApi {
|
||||
/** 当前登录用户信息 */
|
||||
getUserInfo() {
|
||||
return get<SchoolTreeNode>(`${BASE}/GetUserInfo`);
|
||||
}
|
||||
/** 当前用户已授权的模块列表(左侧菜单数据源) */
|
||||
getUserMod() {
|
||||
return get<SchoolTreeNode[]>(`${BASE}/GetUserMod`);
|
||||
}
|
||||
}
|
||||
|
||||
export const baseApi = new BaseApi();
|
||||
@@ -0,0 +1,126 @@
|
||||
import { Method } from "alova";
|
||||
import { alovaInstance } from "@/utils/alova/alova-iview";
|
||||
import config from "@/assets/config/host.config";
|
||||
import type {
|
||||
ApplySubmitRequest,
|
||||
ApplyVo,
|
||||
FlowProgressVo,
|
||||
HallFilters,
|
||||
HallItem,
|
||||
PageResult,
|
||||
} from "@/types/svc";
|
||||
|
||||
/**
|
||||
* 公共办事大厅接口封装(全部为同源 /api/**,CAS 保护)。
|
||||
*
|
||||
* 纪律(2026-09-16 治理,务必遵守):
|
||||
* 本文件里**不得出现任何 flow-center 地址**(无 flowHost、无直连外部 /api/flow/**)。
|
||||
* 撤回/进度/流程图都是流程中心的能力,一律经办事大厅后端中转(后端用 YschFlowOpenApi 出站,
|
||||
* 对端 appKey 验签 + 撤回按 submitterId 复核)。浏览器侧因此不需要跨应用票据,
|
||||
* 也不存在"img 带不了签名"的问题——流程图就是一个同源 <img src>。
|
||||
*/
|
||||
const HALL = "/api/hall";
|
||||
const APPLY = "/api/apply";
|
||||
const FILE = "/api/file";
|
||||
|
||||
function get<T = any>(url: string, params?: Record<string, any>): Method<T> {
|
||||
return new Method<T>("GET", alovaInstance, url, { params });
|
||||
}
|
||||
|
||||
function postJSON<T = any>(url: string, data?: Record<string, any> | any[]): Method<T> {
|
||||
return new Method<T>(
|
||||
"POST",
|
||||
alovaInstance,
|
||||
url,
|
||||
{ headers: { "Content-Type": "application/json;charset=UTF-8" } },
|
||||
data ? JSON.stringify(data) : undefined
|
||||
);
|
||||
}
|
||||
|
||||
/** POST 表单(@RequestParam) */
|
||||
function postForm<T = any>(url: string, data?: Record<string, any>): Method<T> {
|
||||
const form = data
|
||||
? Object.entries(data)
|
||||
.filter(([, v]) => v !== undefined && v !== null)
|
||||
.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`)
|
||||
.join("&")
|
||||
: undefined;
|
||||
return new Method<T>(
|
||||
"POST",
|
||||
alovaInstance,
|
||||
url,
|
||||
{ headers: { "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8" } },
|
||||
form
|
||||
);
|
||||
}
|
||||
|
||||
class HallApi {
|
||||
/** 已发布事项分页(关键词/分类/服务对象/部门筛选) */
|
||||
items(params: Record<string, any>) {
|
||||
return get<PageResult<HallItem>>(`${HALL}/items`, params);
|
||||
}
|
||||
/** 筛选项(服务对象/分类/部门 + 已发布计数) */
|
||||
filters(siteCode: string) {
|
||||
return get<HallFilters>(`${HALL}/filters`, { siteCode });
|
||||
}
|
||||
}
|
||||
|
||||
class ApplyApi {
|
||||
/** 发起(后端落待提交行 + AFTER_COMMIT 异步代发起;出参见 flowEnabled 判断是否已接入) */
|
||||
submit(data: ApplySubmitRequest) {
|
||||
return postJSON<ApplyVo>(APPLY, data);
|
||||
}
|
||||
/** 待提交态重试(复用同一 bizId,流程中心 uk 幂等) */
|
||||
retry(id: number) {
|
||||
return postForm<ApplyVo>(`${APPLY}/${id}/retry`);
|
||||
}
|
||||
/** 一键重提(仅驳回/撤回态;同 bizId,流程中心 R4 重启推进) */
|
||||
resubmit(id: number) {
|
||||
return postForm<ApplyVo>(`${APPLY}/${id}/resubmit`);
|
||||
}
|
||||
/** 撤回(后端经 SDK 调流程中心托管件;仅提交人本人 + 审批中) */
|
||||
withdraw(id: number) {
|
||||
return postForm<void>(`${APPLY}/${id}/withdraw`);
|
||||
}
|
||||
/** 审批进度(结构化轨迹;与详情同可见性守卫) */
|
||||
progress(id: number) {
|
||||
return get<FlowProgressVo>(`${APPLY}/${id}/progress`);
|
||||
}
|
||||
/** 流程示意图地址(同源 <img src>;token 与字节都在后端流转)。
|
||||
* img 标签不走 alova(无 baseUrl 拼接),必须显式带 serviceHost——
|
||||
* 部署在 {ctx}/public/ 子路径时裸 /api 会落到网关根导致 404。 */
|
||||
diagramUrl(id: number, mode = "dept") {
|
||||
return `${config.serviceHost}${APPLY}/${id}/diagram.png?mode=${encodeURIComponent(mode)}`;
|
||||
}
|
||||
my(params?: Record<string, any>) {
|
||||
return get<PageResult<ApplyVo>>(`${APPLY}/my`, params);
|
||||
}
|
||||
/** 发起页数据(事项要点 + 表单 schema) */
|
||||
item(siteCode: string, itemCode: string) {
|
||||
return get<Record<string, any>>(`${APPLY}/item`, { siteCode, itemCode });
|
||||
}
|
||||
detail(id: number) {
|
||||
return get<ApplyVo>(`${APPLY}/${id}`);
|
||||
}
|
||||
}
|
||||
|
||||
class FileApi {
|
||||
/** 上传(返回完整 URL 与附件行 id;绑定在提交动作完成) */
|
||||
upload(file: File, type: "image" | "file", siteCode?: string) {
|
||||
const form = new FormData();
|
||||
form.append("file", file);
|
||||
form.append("type", type);
|
||||
if (siteCode) form.append("siteCode", siteCode);
|
||||
return new Method<{ id: number; fileName: string; fileUrl: string; fileSize: number }>(
|
||||
"POST",
|
||||
alovaInstance,
|
||||
`${FILE}/upload`,
|
||||
{ headers: {} },
|
||||
form
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const hallApi = new HallApi();
|
||||
export const applyApi = new ApplyApi();
|
||||
export const fileApi = new FileApi();
|
||||
Reference in New Issue
Block a user